617bf70c08150ed428cc96870e6425ed768bbc57
[blender.git] / source / blender / blenkernel / intern / subsurf_ccg.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/subsurf_ccg.c
29  *  \ingroup bke
30  */
31
32 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
33 #  define USE_DYNSIZE
34 #endif
35
36 #include <stdlib.h>
37 #include <string.h>
38 #include <stdio.h>
39 #include <math.h>
40 #include <float.h>
41
42 #include "MEM_guardedalloc.h"
43
44 #include "DNA_mesh_types.h"
45 #include "DNA_meshdata_types.h"
46 #include "DNA_modifier_types.h"
47 #include "DNA_object_types.h"
48 #include "DNA_scene_types.h"
49
50 #include "BLI_utildefines.h"
51 #include "BLI_bitmap.h"
52 #include "BLI_blenlib.h"
53 #include "BLI_edgehash.h"
54 #include "BLI_math.h"
55 #include "BLI_memarena.h"
56 #include "BLI_threads.h"
57
58 #include "BKE_pbvh.h"
59 #include "BKE_ccg.h"
60 #include "BKE_cdderivedmesh.h"
61 #include "BKE_global.h"
62 #include "BKE_mesh.h"
63 #include "BKE_mesh_mapping.h"
64 #include "BKE_multires.h"
65 #include "BKE_paint.h"
66 #include "BKE_scene.h"
67 #include "BKE_subsurf.h"
68
69 #ifndef USE_DYNSIZE
70 #  include "BLI_array.h"
71 #endif
72
73 #include "GPU_draw.h"
74 #include "GPU_extensions.h"
75 #include "GPU_glew.h"
76 #include "GPU_buffers.h"
77
78 #include "CCGSubSurf.h"
79
80 #ifdef WITH_OPENSUBDIV
81 #  include "opensubdiv_capi.h"
82 #endif
83
84 /* assumes MLoop's are layed out 4 for each poly, in order */
85 #define USE_LOOP_LAYOUT_FAST
86
87 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
88
89 static ThreadRWMutex loops_cache_rwlock = BLI_RWLOCK_INITIALIZER;
90 static ThreadRWMutex origindex_cache_rwlock = BLI_RWLOCK_INITIALIZER;
91
92 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
93                                          int drawInteriorEdges,
94                                          int useSubsurfUv,
95                                          DerivedMesh *dm,
96                                          bool use_gpu_backend);
97 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm);
98
99 ///
100
101 static void *arena_alloc(CCGAllocatorHDL a, int numBytes)
102 {
103         return BLI_memarena_alloc(a, numBytes);
104 }
105
106 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize)
107 {
108         void *p2 = BLI_memarena_alloc(a, newSize);
109         if (ptr) {
110                 memcpy(p2, ptr, oldSize);
111         }
112         return p2;
113 }
114
115 static void arena_free(CCGAllocatorHDL UNUSED(a), void *UNUSED(ptr))
116 {
117         /* do nothing */
118 }
119
120 static void arena_release(CCGAllocatorHDL a)
121 {
122         BLI_memarena_free(a);
123 }
124
125 typedef enum {
126         CCG_USE_AGING = 1,
127         CCG_USE_ARENA = 2,
128         CCG_CALC_NORMALS = 4,
129         /* add an extra four bytes for a mask layer */
130         CCG_ALLOC_MASK = 8,
131         CCG_SIMPLE_SUBDIV = 16
132 } CCGFlags;
133
134 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels,
135                                int numLayers, CCGFlags flags)
136 {
137         CCGMeshIFC ifc;
138         CCGSubSurf *ccgSS;
139         int useAging = !!(flags & CCG_USE_AGING);
140         int useArena = flags & CCG_USE_ARENA;
141         int normalOffset = 0;
142
143         /* (subdivLevels == 0) is not allowed */
144         subdivLevels = MAX2(subdivLevels, 1);
145
146         if (prevSS) {
147                 int oldUseAging;
148
149                 ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
150
151                 if ((oldUseAging != useAging) ||
152                     (ccgSubSurf_getSimpleSubdiv(prevSS) != !!(flags & CCG_SIMPLE_SUBDIV)))
153                 {
154                         ccgSubSurf_free(prevSS);
155                 }
156                 else {
157                         ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
158
159                         return prevSS;
160                 }
161         }
162
163         if (useAging) {
164                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
165         }
166         else {
167                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
168         }
169         ifc.numLayers = numLayers;
170         ifc.vertDataSize = sizeof(float) * numLayers;
171         normalOffset += sizeof(float) * numLayers;
172         if (flags & CCG_CALC_NORMALS)
173                 ifc.vertDataSize += sizeof(float) * 3;
174         if (flags & CCG_ALLOC_MASK)
175                 ifc.vertDataSize += sizeof(float);
176         ifc.simpleSubdiv = !!(flags & CCG_SIMPLE_SUBDIV);
177
178         if (useArena) {
179                 CCGAllocatorIFC allocatorIFC;
180                 CCGAllocatorHDL allocator = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "subsurf arena");
181
182                 allocatorIFC.alloc = arena_alloc;
183                 allocatorIFC.realloc = arena_realloc;
184                 allocatorIFC.free = arena_free;
185                 allocatorIFC.release = arena_release;
186
187                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
188         }
189         else {
190                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
191         }
192
193         if (useAging) {
194                 ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
195         }
196
197         if (flags & CCG_ALLOC_MASK) {
198                 normalOffset += sizeof(float);
199                 /* mask is allocated after regular layers */
200                 ccgSubSurf_setAllocMask(ccgSS, 1, sizeof(float) * numLayers);
201         }
202         
203         if (flags & CCG_CALC_NORMALS)
204                 ccgSubSurf_setCalcVertexNormals(ccgSS, 1, normalOffset);
205         else
206                 ccgSubSurf_setCalcVertexNormals(ccgSS, 0, 0);
207
208         return ccgSS;
209 }
210
211 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize)
212 {
213         CCGVert *v0 = ccgSubSurf_getEdgeVert0(e);
214         CCGVert *v1 = ccgSubSurf_getEdgeVert1(e);
215         int v0idx = *((int *) ccgSubSurf_getVertUserData(ss, v0));
216         int v1idx = *((int *) ccgSubSurf_getVertUserData(ss, v1));
217         int edgeBase = *((int *) ccgSubSurf_getEdgeUserData(ss, e));
218
219         if (x == 0) {
220                 return v0idx;
221         }
222         else if (x == edgeSize - 1) {
223                 return v1idx;
224         }
225         else {
226                 return edgeBase + x - 1;
227         }
228 }
229
230 static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize)
231 {
232         int faceBase = *((int *) ccgSubSurf_getFaceUserData(ss, f));
233         int numVerts = ccgSubSurf_getFaceNumVerts(f);
234
235         if (x == gridSize - 1 && y == gridSize - 1) {
236                 CCGVert *v = ccgSubSurf_getFaceVert(f, S);
237                 return *((int *) ccgSubSurf_getVertUserData(ss, v));
238         }
239         else if (x == gridSize - 1) {
240                 CCGVert *v = ccgSubSurf_getFaceVert(f, S);
241                 CCGEdge *e = ccgSubSurf_getFaceEdge(f, S);
242                 int edgeBase = *((int *) ccgSubSurf_getEdgeUserData(ss, e));
243                 if (v == ccgSubSurf_getEdgeVert0(e)) {
244                         return edgeBase + (gridSize - 1 - y) - 1;
245                 }
246                 else {
247                         return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - y) - 1);
248                 }
249         }
250         else if (y == gridSize - 1) {
251                 CCGVert *v = ccgSubSurf_getFaceVert(f, S);
252                 CCGEdge *e = ccgSubSurf_getFaceEdge(f, (S + numVerts - 1) % numVerts);
253                 int edgeBase = *((int *) ccgSubSurf_getEdgeUserData(ss, e));
254                 if (v == ccgSubSurf_getEdgeVert0(e)) {
255                         return edgeBase + (gridSize - 1 - x) - 1;
256                 }
257                 else {
258                         return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - x) - 1);
259                 }
260         }
261         else if (x == 0 && y == 0) {
262                 return faceBase;
263         }
264         else if (x == 0) {
265                 S = (S + numVerts - 1) % numVerts;
266                 return faceBase + 1 + (gridSize - 2) * S + (y - 1);
267         }
268         else if (y == 0) {
269                 return faceBase + 1 + (gridSize - 2) * S + (x - 1);
270         }
271         else {
272                 return faceBase + 1 + (gridSize - 2) * numVerts + S * (gridSize - 2) * (gridSize - 2) + (y - 1) * (gridSize - 2) + (x - 1);
273         }
274 }
275
276 static void get_face_uv_map_vert(UvVertMap *vmap, struct MPoly *mpoly, struct MLoop *ml, int fi, CCGVertHDL *fverts)
277 {
278         UvMapVert *v, *nv;
279         int j, nverts = mpoly[fi].totloop;
280
281         for (j = 0; j < nverts; j++) {
282                 for (nv = v = BKE_mesh_uv_vert_map_get_vert(vmap, ml[j].v); v; v = v->next) {
283                         if (v->separate)
284                                 nv = v;
285                         if (v->f == fi)
286                                 break;
287                 }
288
289                 fverts[j] = SET_UINT_IN_POINTER(mpoly[nv->f].loopstart + nv->tfindex);
290         }
291 }
292
293 static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MLoopUV *mloopuv)
294 {
295         MPoly *mpoly = dm->getPolyArray(dm);
296         MLoop *mloop = dm->getLoopArray(dm);
297         MVert *mvert = dm->getVertArray(dm);
298         int totvert = dm->getNumVerts(dm);
299         int totface = dm->getNumPolys(dm);
300         int i, seam;
301         UvMapVert *v;
302         UvVertMap *vmap;
303         float limit[2];
304 #ifndef USE_DYNSIZE
305         CCGVertHDL *fverts = NULL;
306         BLI_array_declare(fverts);
307 #endif
308         EdgeSet *eset;
309         float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
310         float uv[3] = {0.0f, 0.0f, 0.0f}; /* only first 2 values are written into */
311
312         limit[0] = limit[1] = STD_UV_CONNECT_LIMIT;
313         /* previous behavior here is without accounting for winding, however this causes stretching in
314          * UV map in really simple cases with mirror + subsurf, see second part of T44530. Also, initially
315          * intention is to treat merged vertices from mirror modifier as seams, see code below with ME_VERT_MERGED
316          * This fixes a very old regression (2.49 was correct here) */
317         vmap = BKE_mesh_uv_vert_map_create(mpoly, mloop, mloopuv, totface, totvert, limit, false, true);
318         if (!vmap)
319                 return 0;
320         
321         ccgSubSurf_initFullSync(ss);
322
323         /* create vertices */
324         for (i = 0; i < totvert; i++) {
325                 if (!BKE_mesh_uv_vert_map_get_vert(vmap, i))
326                         continue;
327
328                 for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i)->next; v; v = v->next)
329                         if (v->separate)
330                                 break;
331
332                 seam = (v != NULL) || ((mvert + i)->flag & ME_VERT_MERGED);
333
334                 for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i); v; v = v->next) {
335                         if (v->separate) {
336                                 CCGVert *ssv;
337                                 int loopid = mpoly[v->f].loopstart + v->tfindex;
338                                 CCGVertHDL vhdl = SET_INT_IN_POINTER(loopid);
339
340                                 copy_v2_v2(uv, mloopuv[loopid].uv);
341
342                                 ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
343                         }
344                 }
345         }
346
347         /* create edges */
348         eset = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totface));
349
350         for (i = 0; i < totface; i++) {
351                 MPoly *mp = &mpoly[i];
352                 int nverts = mp->totloop;
353                 int j, j_next;
354                 CCGFace *origf = ccgSubSurf_getFace(origss, SET_INT_IN_POINTER(i));
355                 /* unsigned int *fv = &mp->v1; */
356                 MLoop *ml = mloop + mp->loopstart;
357
358 #ifdef USE_DYNSIZE
359                 CCGVertHDL fverts[nverts];
360 #else
361                 BLI_array_empty(fverts);
362                 BLI_array_grow_items(fverts, nverts);
363 #endif
364
365                 get_face_uv_map_vert(vmap, mpoly, ml, i, fverts);
366
367                 for (j = 0, j_next = nverts - 1; j < nverts; j_next = j++) {
368                         unsigned int v0 = GET_UINT_FROM_POINTER(fverts[j_next]);
369                         unsigned int v1 = GET_UINT_FROM_POINTER(fverts[j]);
370                         MVert *mv0 = mvert + (ml[j_next].v);
371                         MVert *mv1 = mvert + (ml[j].v);
372
373                         if (BLI_edgeset_add(eset, v0, v1)) {
374                                 CCGEdge *e, *orige = ccgSubSurf_getFaceEdge(origf, j_next);
375                                 CCGEdgeHDL ehdl = SET_INT_IN_POINTER(mp->loopstart + j_next);
376                                 float crease;
377
378                                 if ((mv0->flag & mv1->flag) & ME_VERT_MERGED)
379                                         crease = creaseFactor;
380                                 else
381                                         crease = ccgSubSurf_getEdgeCrease(orige);
382
383                                 ccgSubSurf_syncEdge(ss, ehdl, fverts[j_next], fverts[j], crease, &e);
384                         }
385                 }
386         }
387
388         BLI_edgeset_free(eset);
389
390         /* create faces */
391         for (i = 0; i < totface; i++) {
392                 MPoly *mp = &mpoly[i];
393                 MLoop *ml = &mloop[mp->loopstart];
394                 int nverts = mp->totloop;
395                 CCGFace *f;
396
397 #ifdef USE_DYNSIZE
398                 CCGVertHDL fverts[nverts];
399 #else
400                 BLI_array_empty(fverts);
401                 BLI_array_grow_items(fverts, nverts);
402 #endif
403
404                 get_face_uv_map_vert(vmap, mpoly, ml, i, fverts);
405                 ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), nverts, fverts, &f);
406         }
407
408 #ifndef USE_DYNSIZE
409         BLI_array_free(fverts);
410 #endif
411
412         BKE_mesh_uv_vert_map_free(vmap);
413         ccgSubSurf_processSync(ss);
414
415         return 1;
416 }
417
418 #ifdef WITH_OPENSUBDIV
419 static void UNUSED_FUNCTION(set_subsurf_osd_ccg_uv)(CCGSubSurf *ss,
420                                                     DerivedMesh *dm,
421                                                     DerivedMesh *result,
422                                                     int layer_index)
423 {
424         CCGFace **faceMap;
425         MTFace *tf;
426         MLoopUV *mluv;
427         CCGFaceIterator fi;
428         int index, gridSize, gridFaces, totface, x, y, S;
429         MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, layer_index);
430         /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
431          * just tface except applying the modifier then looses subsurf UV */
432         MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, layer_index);
433         MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, layer_index);
434
435         if (dmloopuv == NULL || (tface == NULL && mloopuv == NULL)) {
436                 return;
437         }
438
439         ccgSubSurf_evaluatorSetFVarUV(ss, dm, layer_index);
440
441         /* get some info from CCGSubSurf */
442         totface = ccgSubSurf_getNumFaces(ss);
443         gridSize = ccgSubSurf_getGridSize(ss);
444         gridFaces = gridSize - 1;
445
446         /* make a map from original faces to CCGFaces */
447         faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv");
448         for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
449                 CCGFace *f = ccgFaceIterator_getCurrent(&fi);
450                 faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))] = f;
451         }
452
453         /* load coordinates from uvss into tface */
454         tf = tface;
455         mluv = mloopuv;
456         for (index = 0; index < totface; index++) {
457                 CCGFace *f = faceMap[index];
458                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
459                 for (S = 0; S < numVerts; S++) {
460                         for (y = 0; y < gridFaces; y++) {
461                                 for (x = 0; x < gridFaces; x++) {
462                                         const int delta[4][2] = {{0, 0},
463                                                                  {0, 1},
464                                                                  {1, 1},
465                                                                  {1, 0}};
466                                         float uv[4][2];
467                                         int i;
468                                         for (i = 0; i < 4; i++) {
469                                                 const int dx = delta[i][0],
470                                                           dy = delta[i][1];
471                                                 const float grid_u = ((float)(x + dx)) / (gridSize - 1),
472                                                             grid_v = ((float)(y + dy)) / (gridSize - 1);
473                                                 ccgSubSurf_evaluatorFVarUV(ss,
474                                                                            index,
475                                                                            S,
476                                                                            grid_u, grid_v,
477                                                                            uv[i]);
478                                         }
479                                         if (tf) {
480                                                 copy_v2_v2(tf->uv[0], uv[0]);
481                                                 copy_v2_v2(tf->uv[1], uv[1]);
482                                                 copy_v2_v2(tf->uv[2], uv[2]);
483                                                 copy_v2_v2(tf->uv[3], uv[3]);
484                                                 tf++;
485                                         }
486                                         if (mluv) {
487                                                 copy_v2_v2(mluv[0].uv, uv[0]);
488                                                 copy_v2_v2(mluv[1].uv, uv[1]);
489                                                 copy_v2_v2(mluv[2].uv, uv[2]);
490                                                 copy_v2_v2(mluv[3].uv, uv[3]);
491                                                 mluv += 4;
492                                         }
493                                 }
494                         }
495                 }
496         }
497         MEM_freeN(faceMap);
498 }
499 #endif  /* WITH_OPENSUBDIV */
500
501 static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
502 {
503         CCGSubSurf *uvss;
504         CCGFace **faceMap;
505         MTFace *tf;
506         MLoopUV *mluv;
507         CCGFaceIterator fi;
508         int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S;
509         MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, n);
510         /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
511          * just tface except applying the modifier then looses subsurf UV */
512         MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
513         MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, n);
514
515         if (!dmloopuv || (!tface && !mloopuv))
516                 return;
517
518         /* create a CCGSubSurf from uv's */
519         uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 2, CCG_USE_ARENA);
520
521         if (!ss_sync_from_uv(uvss, ss, dm, dmloopuv)) {
522                 ccgSubSurf_free(uvss);
523                 return;
524         }
525
526         /* get some info from CCGSubSurf */
527         totface = ccgSubSurf_getNumFaces(uvss);
528         /* edgeSize = ccgSubSurf_getEdgeSize(uvss); */ /*UNUSED*/
529         gridSize = ccgSubSurf_getGridSize(uvss);
530         gridFaces = gridSize - 1;
531
532         /* make a map from original faces to CCGFaces */
533         faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv");
534         for (ccgSubSurf_initFaceIterator(uvss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
535                 CCGFace *f = ccgFaceIterator_getCurrent(&fi);
536                 faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))] = f;
537         }
538
539         /* load coordinates from uvss into tface */
540         tf = tface;
541         mluv = mloopuv;
542
543         for (index = 0; index < totface; index++) {
544                 CCGFace *f = faceMap[index];
545                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
546
547                 for (S = 0; S < numVerts; S++) {
548                         float (*faceGridData)[2] = ccgSubSurf_getFaceGridDataArray(uvss, f, S);
549
550                         for (y = 0; y < gridFaces; y++) {
551                                 for (x = 0; x < gridFaces; x++) {
552                                         float *a = faceGridData[(y + 0) * gridSize + x + 0];
553                                         float *b = faceGridData[(y + 0) * gridSize + x + 1];
554                                         float *c = faceGridData[(y + 1) * gridSize + x + 1];
555                                         float *d = faceGridData[(y + 1) * gridSize + x + 0];
556
557                                         if (tf) {
558                                                 copy_v2_v2(tf->uv[0], a);
559                                                 copy_v2_v2(tf->uv[1], d);
560                                                 copy_v2_v2(tf->uv[2], c);
561                                                 copy_v2_v2(tf->uv[3], b);
562                                                 tf++;
563                                         }
564
565                                         if (mluv) {
566                                                 copy_v2_v2(mluv[0].uv, a);
567                                                 copy_v2_v2(mluv[1].uv, d);
568                                                 copy_v2_v2(mluv[2].uv, c);
569                                                 copy_v2_v2(mluv[3].uv, b);
570                                                 mluv += 4;
571                                         }
572
573                                 }
574                         }
575                 }
576         }
577
578         ccgSubSurf_free(uvss);
579         MEM_freeN(faceMap);
580 }
581
582 static void set_subsurf_uv(CCGSubSurf *ss,
583                            DerivedMesh *dm,
584                            DerivedMesh *result,
585                            int layer_index)
586 {
587 #ifdef WITH_OPENSUBDIV
588         if (!ccgSubSurf_needGrids(ss)) {
589                 /* GPU backend is used, no need to evaluate UVs on CPU. */
590                 /* TODO(sergey): Think of how to support edit mode of UVs. */
591         }
592         else
593 #endif
594         {
595                 set_subsurf_legacy_uv(ss, dm, result, layer_index);
596         }
597 }
598
599 /* face weighting */
600 typedef struct FaceVertWeightEntry {
601         FaceVertWeight *weight;
602         float *w;
603         int valid;
604 } FaceVertWeightEntry;
605
606 typedef struct WeightTable {
607         FaceVertWeightEntry *weight_table;
608         int len;
609 } WeightTable;
610
611 static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen)
612 {
613         int x, y, i, j;
614         float *w, w1, w2, w4, fac, fac2, fx, fy;
615
616         if (wtable->len <= faceLen) {
617                 void *tmp = MEM_callocN(sizeof(FaceVertWeightEntry) * (faceLen + 1), "weight table alloc 2");
618                 
619                 if (wtable->len) {
620                         memcpy(tmp, wtable->weight_table, sizeof(FaceVertWeightEntry) * wtable->len);
621                         MEM_freeN(wtable->weight_table);
622                 }
623                 
624                 wtable->weight_table = tmp;
625                 wtable->len = faceLen + 1;
626         }
627
628         if (!wtable->weight_table[faceLen].valid) {
629                 wtable->weight_table[faceLen].valid = 1;
630                 wtable->weight_table[faceLen].w = w = MEM_callocN(sizeof(float) * faceLen * faceLen * (gridCuts + 2) * (gridCuts + 2), "weight table alloc");
631                 fac = 1.0f / (float)faceLen;
632
633                 for (i = 0; i < faceLen; i++) {
634                         for (x = 0; x < gridCuts + 2; x++) {
635                                 for (y = 0; y < gridCuts + 2; y++) {
636                                         fx = 0.5f - (float)x / (float)(gridCuts + 1) / 2.0f;
637                                         fy = 0.5f - (float)y / (float)(gridCuts + 1) / 2.0f;
638                                 
639                                         fac2 = faceLen - 4;
640                                         w1 = (1.0f - fx) * (1.0f - fy) + (-fac2 * fx * fy * fac);
641                                         w2 = (1.0f - fx + fac2 * fx * -fac) * (fy);
642                                         w4 = (fx) * (1.0f - fy + -fac2 * fy * fac);
643
644                                         /* these values aren't used for tri's and cause divide by zero */
645                                         if (faceLen > 3) {
646                                                 fac2 = 1.0f - (w1 + w2 + w4);
647                                                 fac2 = fac2 / (float)(faceLen - 3);
648                                                 for (j = 0; j < faceLen; j++) {
649                                                         w[j] = fac2;
650                                                 }
651                                         }
652                                         
653                                         w[i] = w1;
654                                         w[(i - 1 + faceLen) % faceLen] = w2;
655                                         w[(i + 1) % faceLen] = w4;
656
657                                         w += faceLen;
658                                 }
659                         }
660                 }
661         }
662
663         return wtable->weight_table[faceLen].w;
664 }
665
666 static void free_ss_weights(WeightTable *wtable)
667 {
668         int i;
669
670         for (i = 0; i < wtable->len; i++) {
671                 if (wtable->weight_table[i].valid)
672                         MEM_freeN(wtable->weight_table[i].w);
673         }
674         
675         if (wtable->weight_table)
676                 MEM_freeN(wtable->weight_table);
677 }
678
679 static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
680                                          DerivedMesh *dm,
681                                          float (*vertexCos)[3],
682                                          int useFlatSubdiv)
683 {
684         float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
685 #ifndef USE_DYNSIZE
686         CCGVertHDL *fVerts = NULL;
687         BLI_array_declare(fVerts);
688 #endif
689         MVert *mvert = dm->getVertArray(dm);
690         MEdge *medge = dm->getEdgeArray(dm);
691         /* MFace *mface = dm->getTessFaceArray(dm); */ /* UNUSED */
692         MVert *mv;
693         MEdge *me;
694         MLoop *mloop = dm->getLoopArray(dm), *ml;
695         MPoly *mpoly = dm->getPolyArray(dm), *mp;
696         /*MFace *mf;*/ /*UNUSED*/
697         int totvert = dm->getNumVerts(dm);
698         int totedge = dm->getNumEdges(dm);
699         /*int totface = dm->getNumTessFaces(dm);*/ /*UNUSED*/
700         /*int totpoly = dm->getNumFaces(dm);*/ /*UNUSED*/
701         int i, j;
702         int *index;
703
704         ccgSubSurf_initFullSync(ss);
705
706         mv = mvert;
707         index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
708         for (i = 0; i < totvert; i++, mv++) {
709                 CCGVert *v;
710
711                 if (vertexCos) {
712                         ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), vertexCos[i], 0, &v);
713                 }
714                 else {
715                         ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), mv->co, 0, &v);
716                 }
717
718                 ((int *)ccgSubSurf_getVertUserData(ss, v))[1] = (index) ? *index++ : i;
719         }
720
721         me = medge;
722         index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX);
723         for (i = 0; i < totedge; i++, me++) {
724                 CCGEdge *e;
725                 float crease;
726
727                 crease = useFlatSubdiv ? creaseFactor :
728                          me->crease * creaseFactor / 255.0f;
729
730                 ccgSubSurf_syncEdge(ss, SET_INT_IN_POINTER(i), SET_UINT_IN_POINTER(me->v1),
731                                     SET_UINT_IN_POINTER(me->v2), crease, &e);
732
733                 ((int *)ccgSubSurf_getEdgeUserData(ss, e))[1] = (index) ? *index++ : i;
734         }
735
736         mp = mpoly;
737         index = (int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
738         for (i = 0; i < dm->numPolyData; i++, mp++) {
739                 CCGFace *f;
740
741 #ifdef USE_DYNSIZE
742                 CCGVertHDL fVerts[mp->totloop];
743 #else
744                 BLI_array_empty(fVerts);
745                 BLI_array_grow_items(fVerts, mp->totloop);
746 #endif
747
748                 ml = mloop + mp->loopstart;
749                 for (j = 0; j < mp->totloop; j++, ml++) {
750                         fVerts[j] = SET_UINT_IN_POINTER(ml->v);
751                 }
752
753                 /* this is very bad, means mesh is internally inconsistent.
754                  * it is not really possible to continue without modifying
755                  * other parts of code significantly to handle missing faces.
756                  * since this really shouldn't even be possible we just bail.*/
757                 if (ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), mp->totloop,
758                                         fVerts, &f) == eCCGError_InvalidValue)
759                 {
760                         static int hasGivenError = 0;
761
762                         if (!hasGivenError) {
763                                 //XXX error("Unrecoverable error in SubSurf calculation,"
764                                 //      " mesh is inconsistent.");
765
766                                 hasGivenError = 1;
767                         }
768
769                         return;
770                 }
771
772                 ((int *)ccgSubSurf_getFaceUserData(ss, f))[1] = (index) ? *index++ : i;
773         }
774
775         ccgSubSurf_processSync(ss);
776
777 #ifndef USE_DYNSIZE
778         BLI_array_free(fVerts);
779 #endif
780 }
781
782 #ifdef WITH_OPENSUBDIV
783 static void ss_sync_osd_from_derivedmesh(CCGSubSurf *ss,
784                                          DerivedMesh *dm)
785 {
786         ccgSubSurf_initFullSync(ss);
787         ccgSubSurf_prepareTopologyRefiner(ss, dm);
788         ccgSubSurf_processSync(ss);
789 }
790 #endif  /* WITH_OPENSUBDIV */
791
792 static void ss_sync_from_derivedmesh(CCGSubSurf *ss,
793                                      DerivedMesh *dm,
794                                      float (*vertexCos)[3],
795                                      int use_flat_subdiv)
796 {
797 #ifdef WITH_OPENSUBDIV
798         /* Reset all related descriptors if actual mesh topology changed or if
799          * other evlauation-related settings changed.
800          */
801         if (!ccgSubSurf_needGrids(ss)) {
802                 /* TODO(sergey): Use vertex coordinates and flat subdiv flag. */
803                 ccgSubSurf_checkTopologyChanged(ss, dm);
804                 ss_sync_osd_from_derivedmesh(ss, dm);
805         }
806         else
807 #endif
808         {
809                 ss_sync_ccg_from_derivedmesh(ss, dm, vertexCos, use_flat_subdiv);
810         }
811 }
812
813 /***/
814
815 static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v)
816 {
817         return ((int *) ccgSubSurf_getVertUserData(ss, v))[1];
818 }
819
820 static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e)
821 {
822         return ((int *) ccgSubSurf_getEdgeUserData(ss, e))[1];
823 }
824
825 static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f)
826 {
827         return ((int *) ccgSubSurf_getFaceUserData(ss, f))[1];
828 }
829
830 static void minmax_v3_v3v3(const float vec[3], float min[3], float max[3])
831 {
832         if (min[0] > vec[0]) min[0] = vec[0];
833         if (min[1] > vec[1]) min[1] = vec[1];
834         if (min[2] > vec[2]) min[2] = vec[2];
835         if (max[0] < vec[0]) max[0] = vec[0];
836         if (max[1] < vec[1]) max[1] = vec[1];
837         if (max[2] < vec[2]) max[2] = vec[2];
838 }
839
840 static void ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
841 {
842         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
843         CCGSubSurf *ss = ccgdm->ss;
844         CCGVertIterator vi;
845         CCGEdgeIterator ei;
846         CCGFaceIterator fi;
847         CCGKey key;
848         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
849         int gridSize = ccgSubSurf_getGridSize(ss);
850
851 #ifdef WITH_OPENSUBDIV
852         if (ccgdm->useGpuBackend) {
853                 ccgSubSurf_getMinMax(ccgdm->ss, r_min, r_max);
854                 return;
855         }
856 #endif
857
858         CCG_key_top_level(&key, ss);
859
860         if (!ccgSubSurf_getNumVerts(ss))
861                 r_min[0] = r_min[1] = r_min[2] = r_max[0] = r_max[1] = r_max[2] = 0.0;
862
863         for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
864                 CCGVert *v = ccgVertIterator_getCurrent(&vi);
865                 float *co = ccgSubSurf_getVertData(ss, v);
866
867                 minmax_v3_v3v3(co, r_min, r_max);
868         }
869
870         for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
871                 CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
872                 CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
873
874                 for (i = 0; i < edgeSize; i++)
875                         minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), r_min, r_max);
876         }
877
878         for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
879                 CCGFace *f = ccgFaceIterator_getCurrent(&fi);
880                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
881
882                 for (S = 0; S < numVerts; S++) {
883                         CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
884
885                         for (y = 0; y < gridSize; y++)
886                                 for (x = 0; x < gridSize; x++)
887                                         minmax_v3_v3v3(CCG_grid_elem_co(&key, faceGridData, x, y), r_min, r_max);
888                 }
889         }
890 }
891
892 static int ccgDM_getNumVerts(DerivedMesh *dm)
893 {
894         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
895
896         return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
897 }
898
899 static int ccgDM_getNumEdges(DerivedMesh *dm)
900 {
901         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
902
903         return ccgSubSurf_getNumFinalEdges(ccgdm->ss);
904 }
905
906 static int ccgDM_getNumTessFaces(DerivedMesh *dm)
907 {
908         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
909
910         return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
911 }
912
913 static int ccgDM_getNumLoops(DerivedMesh *dm)
914 {
915         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
916
917         /* All subsurf faces are quads */
918         return 4 * ccgSubSurf_getNumFinalFaces(ccgdm->ss);
919 }
920
921 static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
922 {
923         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
924         CCGSubSurf *ss = ccgdm->ss;
925         CCGElem *vd;
926         CCGKey key;
927         int i;
928
929         CCG_key_top_level(&key, ss);
930         memset(mv, 0, sizeof(*mv));
931
932         if ((vertNum < ccgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) {
933                 /* this vert comes from face data */
934                 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
935                 CCGFace *f;
936                 int x, y, grid, numVerts;
937                 int offset;
938                 int gridSize = ccgSubSurf_getGridSize(ss);
939                 int gridSideVerts;
940                 int gridInternalVerts;
941                 int gridSideEnd;
942                 int gridInternalEnd;
943
944                 i = 0;
945                 while (i < lastface && vertNum >= ccgdm->faceMap[i + 1].startVert) {
946                         i++;
947                 }
948
949                 f = ccgdm->faceMap[i].face;
950                 numVerts = ccgSubSurf_getFaceNumVerts(f);
951
952                 gridSideVerts = gridSize - 2;
953                 gridInternalVerts = gridSideVerts * gridSideVerts;
954
955                 gridSideEnd = 1 + numVerts * gridSideVerts;
956                 gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
957
958                 offset = vertNum - ccgdm->faceMap[i].startVert;
959                 if (offset < 1) {
960                         vd = ccgSubSurf_getFaceCenterData(f);
961                         copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
962                         normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
963                 }
964                 else if (offset < gridSideEnd) {
965                         offset -= 1;
966                         grid = offset / gridSideVerts;
967                         x = offset % gridSideVerts + 1;
968                         vd = ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x);
969                         copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
970                         normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
971                 }
972                 else if (offset < gridInternalEnd) {
973                         offset -= gridSideEnd;
974                         grid = offset / gridInternalVerts;
975                         offset %= gridInternalVerts;
976                         y = offset / gridSideVerts + 1;
977                         x = offset % gridSideVerts + 1;
978                         vd = ccgSubSurf_getFaceGridData(ss, f, grid, x, y);
979                         copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
980                         normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
981                 }
982         }
983         else if ((vertNum < ccgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
984                 /* this vert comes from edge data */
985                 CCGEdge *e;
986                 int lastedge = ccgSubSurf_getNumEdges(ss) - 1;
987                 int x;
988
989                 i = 0;
990                 while (i < lastedge && vertNum >= ccgdm->edgeMap[i + 1].startVert) {
991                         i++;
992                 }
993
994                 e = ccgdm->edgeMap[i].edge;
995
996                 x = vertNum - ccgdm->edgeMap[i].startVert + 1;
997                 vd = ccgSubSurf_getEdgeData(ss, e, x);
998                 copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
999                 normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
1000         }
1001         else {
1002                 /* this vert comes from vert data */
1003                 CCGVert *v;
1004                 i = vertNum - ccgdm->vertMap[0].startVert;
1005
1006                 v = ccgdm->vertMap[i].vert;
1007                 vd = ccgSubSurf_getVertData(ss, v);
1008                 copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
1009                 normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
1010         }
1011 }
1012
1013 static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float r_co[3])
1014 {
1015         MVert mvert;
1016
1017         ccgDM_getFinalVert(dm, vertNum, &mvert);
1018         copy_v3_v3(r_co, mvert.co);
1019 }
1020
1021 static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float r_no[3])
1022 {
1023         MVert mvert;
1024
1025         ccgDM_getFinalVert(dm, vertNum, &mvert);
1026         normal_short_to_float_v3(r_no, mvert.no);
1027 }
1028
1029 static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
1030 {
1031         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1032         CCGSubSurf *ss = ccgdm->ss;
1033         int i;
1034
1035         memset(med, 0, sizeof(*med));
1036
1037         if (edgeNum < ccgdm->edgeMap[0].startEdge) {
1038                 /* this edge comes from face data */
1039                 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
1040                 CCGFace *f;
1041                 int x, y, grid /*, numVerts*/;
1042                 int offset;
1043                 int gridSize = ccgSubSurf_getGridSize(ss);
1044                 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1045                 int gridSideEdges;
1046                 int gridInternalEdges;
1047
1048                 /* code added in bmesh but works correctly without, commenting - campbell */
1049 #if 0
1050                 int lasti, previ;
1051                 i = lastface;
1052                 lasti = 0;
1053                 while (1) {
1054                         previ = i;
1055                         if (ccgdm->faceMap[i].startEdge >= edgeNum) {
1056                                 i -= fabsf(i - lasti) / 2.0f;
1057                         }
1058                         else if (ccgdm->faceMap[i].startEdge < edgeNum) {
1059                                 i += fabsf(i - lasti) / 2.0f;
1060                         }
1061                         else {
1062                                 break;
1063                         }
1064
1065                         if (i < 0) {
1066                                 i = 0;
1067                                 break;
1068                         }
1069
1070                         if (i > lastface) {
1071                                 i = lastface;
1072                                 break;
1073
1074                         }
1075
1076                         if (i == lasti)
1077                                 break;
1078
1079                         lasti = previ;
1080                 }
1081
1082                 i = i > 0 ? i - 1 : i;
1083 #endif
1084
1085                 i = 0;
1086                 while (i < lastface && edgeNum >= ccgdm->faceMap[i + 1].startEdge) {
1087                         i++;
1088                 }
1089
1090                 f = ccgdm->faceMap[i].face;
1091                 /* numVerts = ccgSubSurf_getFaceNumVerts(f); */ /*UNUSED*/
1092
1093                 gridSideEdges = gridSize - 1;
1094                 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
1095
1096                 offset = edgeNum - ccgdm->faceMap[i].startEdge;
1097                 grid = offset / (gridSideEdges + gridInternalEdges);
1098                 offset %= (gridSideEdges + gridInternalEdges);
1099
1100                 if (offset < gridSideEdges) {
1101                         x = offset;
1102                         med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, gridSize);
1103                         med->v2 = getFaceIndex(ss, f, grid, x + 1, 0, edgeSize, gridSize);
1104                 }
1105                 else {
1106                         offset -= gridSideEdges;
1107                         x = (offset / 2) / gridSideEdges + 1;
1108                         y = (offset / 2) % gridSideEdges;
1109                         if (offset % 2 == 0) {
1110                                 med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSize, gridSize);
1111                                 med->v2 = getFaceIndex(ss, f, grid, x, y + 1, edgeSize, gridSize);
1112                         }
1113                         else {
1114                                 med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSize, gridSize);
1115                                 med->v2 = getFaceIndex(ss, f, grid, y + 1, x, edgeSize, gridSize);
1116                         }
1117                 }
1118         }
1119         else {
1120                 /* this vert comes from edge data */
1121                 CCGEdge *e;
1122                 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1123                 int x;
1124                 short *edgeFlag;
1125                 unsigned int flags = 0;
1126
1127                 i = (edgeNum - ccgdm->edgeMap[0].startEdge) / (edgeSize - 1);
1128
1129                 e = ccgdm->edgeMap[i].edge;
1130
1131                 if (!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
1132
1133                 x = edgeNum - ccgdm->edgeMap[i].startEdge;
1134
1135                 med->v1 = getEdgeIndex(ss, e, x, edgeSize);
1136                 med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
1137
1138                 edgeFlag = (ccgdm->edgeFlags) ? &ccgdm->edgeFlags[i] : NULL;
1139                 if (edgeFlag)
1140                         flags |= (*edgeFlag & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER;
1141                 else
1142                         flags |= ME_EDGEDRAW | ME_EDGERENDER;
1143
1144                 med->flag = flags;
1145         }
1146 }
1147
1148 static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
1149 {
1150         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1151         CCGSubSurf *ss = ccgdm->ss;
1152         int gridSize = ccgSubSurf_getGridSize(ss);
1153         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1154         int gridSideEdges = gridSize - 1;
1155         int gridFaces = gridSideEdges * gridSideEdges;
1156         int i;
1157         CCGFace *f;
1158         /*int numVerts;*/
1159         int offset;
1160         int grid;
1161         int x, y;
1162         /*int lastface = ccgSubSurf_getNumFaces(ss) - 1;*/ /*UNUSED*/
1163         DMFlagMat *faceFlags = ccgdm->faceFlags;
1164
1165         memset(mf, 0, sizeof(*mf));
1166         if (faceNum >= ccgdm->dm.numTessFaceData)
1167                 return;
1168
1169         i = ccgdm->reverseFaceMap[faceNum];
1170
1171         f = ccgdm->faceMap[i].face;
1172         /*numVerts = ccgSubSurf_getFaceNumVerts(f);*/ /*UNUSED*/
1173
1174         offset = faceNum - ccgdm->faceMap[i].startFace;
1175         grid = offset / gridFaces;
1176         offset %= gridFaces;
1177         y = offset / gridSideEdges;
1178         x = offset % gridSideEdges;
1179
1180         mf->v1 = getFaceIndex(ss, f, grid, x + 0, y + 0, edgeSize, gridSize);
1181         mf->v2 = getFaceIndex(ss, f, grid, x + 0, y + 1, edgeSize, gridSize);
1182         mf->v3 = getFaceIndex(ss, f, grid, x + 1, y + 1, edgeSize, gridSize);
1183         mf->v4 = getFaceIndex(ss, f, grid, x + 1, y + 0, edgeSize, gridSize);
1184
1185         if (faceFlags) {
1186                 mf->flag = faceFlags[i].flag;
1187                 mf->mat_nr = faceFlags[i].mat_nr;
1188         }
1189         else {
1190                 mf->flag = ME_SMOOTH;
1191         }
1192
1193         mf->edcode = 0;
1194 }
1195
1196 /* Translate GridHidden into the ME_HIDE flag for MVerts. Assumes
1197  * vertices are in the order output by ccgDM_copyFinalVertArray. */
1198 void subsurf_copy_grid_hidden(DerivedMesh *dm, const MPoly *mpoly,
1199                               MVert *mvert, const MDisps *mdisps)
1200 {
1201         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1202         CCGSubSurf *ss = ccgdm->ss;
1203         int level = ccgSubSurf_getSubdivisionLevels(ss);
1204         int gridSize = ccgSubSurf_getGridSize(ss);
1205         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1206         int totface = ccgSubSurf_getNumFaces(ss);
1207         int i, j, x, y;
1208         
1209         for (i = 0; i < totface; i++) {
1210                 CCGFace *f = ccgdm->faceMap[i].face;
1211
1212                 for (j = 0; j < mpoly[i].totloop; j++) {
1213                         const MDisps *md = &mdisps[mpoly[i].loopstart + j];
1214                         int hidden_gridsize = BKE_ccg_gridsize(md->level);
1215                         int factor = BKE_ccg_factor(level, md->level);
1216                         BLI_bitmap *hidden = md->hidden;
1217                         
1218                         if (!hidden)
1219                                 continue;
1220                         
1221                         for (y = 0; y < gridSize; y++) {
1222                                 for (x = 0; x < gridSize; x++) {
1223                                         int vndx, offset;
1224                                         
1225                                         vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
1226                                         offset = (y * factor) * hidden_gridsize + (x * factor);
1227                                         if (BLI_BITMAP_TEST(hidden, offset))
1228                                                 mvert[vndx].flag |= ME_HIDE;
1229                                 }
1230                         }
1231                 }
1232         }
1233 }
1234
1235 /* Translate GridPaintMask into vertex paint masks. Assumes vertices
1236  * are in the order output by ccgDM_copyFinalVertArray. */
1237 void subsurf_copy_grid_paint_mask(DerivedMesh *dm, const MPoly *mpoly,
1238                                   float *paint_mask,
1239                                   const GridPaintMask *grid_paint_mask)
1240 {
1241         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1242         CCGSubSurf *ss = ccgdm->ss;
1243         int level = ccgSubSurf_getSubdivisionLevels(ss);
1244         int gridSize = ccgSubSurf_getGridSize(ss);
1245         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1246         int totface = ccgSubSurf_getNumFaces(ss);
1247         int i, j, x, y, factor, gpm_gridsize;
1248         
1249         for (i = 0; i < totface; i++) {
1250                 CCGFace *f = ccgdm->faceMap[i].face;
1251                 const MPoly *p = &mpoly[i];
1252                 
1253                 for (j = 0; j < p->totloop; j++) {
1254                         const GridPaintMask *gpm = &grid_paint_mask[p->loopstart + j];
1255                         if (!gpm->data)
1256                                 continue;
1257
1258                         factor = BKE_ccg_factor(level, gpm->level);
1259                         gpm_gridsize = BKE_ccg_gridsize(gpm->level);
1260                         
1261                         for (y = 0; y < gridSize; y++) {
1262                                 for (x = 0; x < gridSize; x++) {
1263                                         int vndx, offset;
1264                                         
1265                                         vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
1266                                         offset = y * factor * gpm_gridsize + x * factor;
1267                                         paint_mask[vndx] = gpm->data[offset];
1268                                 }
1269                         }
1270                 }
1271         }
1272 }
1273
1274 /* utility functon */
1275 BLI_INLINE void ccgDM_to_MVert(MVert *mv, const CCGKey *key, CCGElem *elem)
1276 {
1277         copy_v3_v3(mv->co, CCG_elem_co(key, elem));
1278         normal_float_to_short_v3(mv->no, CCG_elem_no(key, elem));
1279         mv->flag = mv->bweight = 0;
1280 }
1281
1282 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
1283 {
1284         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1285         CCGSubSurf *ss = ccgdm->ss;
1286         CCGElem *vd;
1287         CCGKey key;
1288         int index;
1289         int totvert, totedge, totface;
1290         int gridSize = ccgSubSurf_getGridSize(ss);
1291         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1292         unsigned int i = 0;
1293
1294         CCG_key_top_level(&key, ss);
1295
1296         totface = ccgSubSurf_getNumFaces(ss);
1297         for (index = 0; index < totface; index++) {
1298                 CCGFace *f = ccgdm->faceMap[index].face;
1299                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1300
1301                 vd = ccgSubSurf_getFaceCenterData(f);
1302                 ccgDM_to_MVert(&mvert[i++], &key, vd);
1303                 
1304                 for (S = 0; S < numVerts; S++) {
1305                         for (x = 1; x < gridSize - 1; x++) {
1306                                 vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
1307                                 ccgDM_to_MVert(&mvert[i++], &key, vd);
1308                         }
1309                 }
1310
1311                 for (S = 0; S < numVerts; S++) {
1312                         for (y = 1; y < gridSize - 1; y++) {
1313                                 for (x = 1; x < gridSize - 1; x++) {
1314                                         vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y);
1315                                         ccgDM_to_MVert(&mvert[i++], &key, vd);
1316                                 }
1317                         }
1318                 }
1319         }
1320
1321         totedge = ccgSubSurf_getNumEdges(ss);
1322         for (index = 0; index < totedge; index++) {
1323                 CCGEdge *e = ccgdm->edgeMap[index].edge;
1324                 int x;
1325
1326                 for (x = 1; x < edgeSize - 1; x++) {
1327                         /* This gives errors with -debug-fpe
1328                          * the normals don't seem to be unit length.
1329                          * this is most likely caused by edges with no
1330                          * faces which are now zerod out, see comment in:
1331                          * ccgSubSurf__calcVertNormals(), - campbell */
1332                         vd = ccgSubSurf_getEdgeData(ss, e, x);
1333                         ccgDM_to_MVert(&mvert[i++], &key, vd);
1334                 }
1335         }
1336
1337         totvert = ccgSubSurf_getNumVerts(ss);
1338         for (index = 0; index < totvert; index++) {
1339                 CCGVert *v = ccgdm->vertMap[index].vert;
1340
1341                 vd = ccgSubSurf_getVertData(ss, v);
1342                 ccgDM_to_MVert(&mvert[i++], &key, vd);
1343         }
1344 }
1345
1346
1347 /* utility functon */
1348 BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2, const short flag)
1349 {
1350         med->v1 = v1;
1351         med->v2 = v2;
1352         med->crease = med->bweight = 0;
1353         med->flag = flag;
1354 }
1355
1356 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
1357 {
1358         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1359         CCGSubSurf *ss = ccgdm->ss;
1360         int index;
1361         int totedge, totface;
1362         int gridSize = ccgSubSurf_getGridSize(ss);
1363         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1364         unsigned int i = 0;
1365         short *edgeFlags = ccgdm->edgeFlags;
1366         const short ed_interior_flag = ccgdm->drawInteriorEdges ? (ME_EDGEDRAW | ME_EDGERENDER) : 0;
1367
1368         totface = ccgSubSurf_getNumFaces(ss);
1369         for (index = 0; index < totface; index++) {
1370                 CCGFace *f = ccgdm->faceMap[index].face;
1371                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1372
1373                 for (S = 0; S < numVerts; S++) {
1374                         for (x = 0; x < gridSize - 1; x++) {
1375                                 ccgDM_to_MEdge(&medge[i++],
1376                                                getFaceIndex(ss, f, S, x,     0, edgeSize, gridSize),
1377                                                getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize),
1378                                                ed_interior_flag);
1379                         }
1380
1381                         for (x = 1; x < gridSize - 1; x++) {
1382                                 for (y = 0; y < gridSize - 1; y++) {
1383                                         ccgDM_to_MEdge(&medge[i++],
1384                                                        getFaceIndex(ss, f, S, x, y,    edgeSize, gridSize),
1385                                                        getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize),
1386                                                        ed_interior_flag);
1387                                         ccgDM_to_MEdge(&medge[i++],
1388                                                        getFaceIndex(ss, f, S, y, x,     edgeSize, gridSize),
1389                                                        getFaceIndex(ss, f, S, y + 1, x, edgeSize, gridSize),
1390                                                        ed_interior_flag);
1391                                 }
1392                         }
1393                 }
1394         }
1395
1396         totedge = ccgSubSurf_getNumEdges(ss);
1397         for (index = 0; index < totedge; index++) {
1398                 CCGEdge *e = ccgdm->edgeMap[index].edge;
1399                 short ed_flag = 0;
1400                 int x;
1401                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
1402
1403                 if (!ccgSubSurf_getEdgeNumFaces(e)) {
1404                         ed_flag |= ME_LOOSEEDGE;
1405                 }
1406
1407                 if (edgeFlags) {
1408                         if (edgeIdx != -1) {
1409                                 ed_flag |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER);
1410                         }
1411                 }
1412                 else {
1413                         ed_flag |= ME_EDGEDRAW | ME_EDGERENDER;
1414                 }
1415
1416                 for (x = 0; x < edgeSize - 1; x++) {
1417                         ccgDM_to_MEdge(&medge[i++],
1418                                        getEdgeIndex(ss, e, x, edgeSize),
1419                                        getEdgeIndex(ss, e, x + 1, edgeSize),
1420                                        ed_flag);
1421                 }
1422         }
1423 }
1424
1425 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
1426 {
1427         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1428         CCGSubSurf *ss = ccgdm->ss;
1429         int index;
1430         int totface;
1431         int gridSize = ccgSubSurf_getGridSize(ss);
1432         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1433         int i = 0;
1434         DMFlagMat *faceFlags = ccgdm->faceFlags;
1435
1436         totface = ccgSubSurf_getNumFaces(ss);
1437         for (index = 0; index < totface; index++) {
1438                 CCGFace *f = ccgdm->faceMap[index].face;
1439                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1440                 /* keep types in sync with MFace, avoid many conversions */
1441                 char flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH;
1442                 short mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0;
1443
1444                 for (S = 0; S < numVerts; S++) {
1445                         for (y = 0; y < gridSize - 1; y++) {
1446                                 for (x = 0; x < gridSize - 1; x++) {
1447                                         MFace *mf = &mface[i];
1448                                         mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1449                                                               edgeSize, gridSize);
1450                                         mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1451                                                               edgeSize, gridSize);
1452                                         mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1453                                                               edgeSize, gridSize);
1454                                         mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1455                                                               edgeSize, gridSize);
1456                                         mf->mat_nr = mat_nr;
1457                                         mf->flag = flag;
1458                                         mf->edcode = 0;
1459
1460                                         i++;
1461                                 }
1462                         }
1463                 }
1464         }
1465 }
1466
1467 static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
1468 {
1469         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1470         CCGSubSurf *ss = ccgdm->ss;
1471         int index;
1472         int totface;
1473         int gridSize = ccgSubSurf_getGridSize(ss);
1474         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1475         int i = 0;
1476         MLoop *mv;
1477         /* DMFlagMat *faceFlags = ccgdm->faceFlags; */ /* UNUSED */
1478
1479         if (!ccgdm->ehash) {
1480                 BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE);
1481                 if (!ccgdm->ehash) {
1482                         MEdge *medge;
1483
1484                         ccgdm->ehash = BLI_edgehash_new_ex(__func__, ccgdm->dm.numEdgeData);
1485                         medge = ccgdm->dm.getEdgeArray((DerivedMesh *)ccgdm);
1486
1487                         for (i = 0; i < ccgdm->dm.numEdgeData; i++) {
1488                                 BLI_edgehash_insert(ccgdm->ehash, medge[i].v1, medge[i].v2, SET_INT_IN_POINTER(i));
1489                         }
1490                 }
1491                 BLI_rw_mutex_unlock(&loops_cache_rwlock);
1492         }
1493
1494         BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_READ);
1495         totface = ccgSubSurf_getNumFaces(ss);
1496         mv = mloop;
1497         for (index = 0; index < totface; index++) {
1498                 CCGFace *f = ccgdm->faceMap[index].face;
1499                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1500                 /* int flag = (faceFlags) ? faceFlags[index * 2]: ME_SMOOTH; */ /* UNUSED */
1501                 /* int mat_nr = (faceFlags) ? faceFlags[index * 2 + 1]: 0; */ /* UNUSED */
1502
1503                 for (S = 0; S < numVerts; S++) {
1504                         for (y = 0; y < gridSize - 1; y++) {
1505                                 for (x = 0; x < gridSize - 1; x++) {
1506                                         unsigned int v1, v2, v3, v4;
1507
1508                                         v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1509                                                           edgeSize, gridSize);
1510
1511                                         v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1512                                                           edgeSize, gridSize);
1513                                         v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1514                                                           edgeSize, gridSize);
1515                                         v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1516                                                           edgeSize, gridSize);
1517
1518                                         mv->v = v1;
1519                                         mv->e = GET_UINT_FROM_POINTER(BLI_edgehash_lookup(ccgdm->ehash, v1, v2));
1520                                         mv++, i++;
1521
1522                                         mv->v = v2;
1523                                         mv->e = GET_UINT_FROM_POINTER(BLI_edgehash_lookup(ccgdm->ehash, v2, v3));
1524                                         mv++, i++;
1525
1526                                         mv->v = v3;
1527                                         mv->e = GET_UINT_FROM_POINTER(BLI_edgehash_lookup(ccgdm->ehash, v3, v4));
1528                                         mv++, i++;
1529
1530                                         mv->v = v4;
1531                                         mv->e = GET_UINT_FROM_POINTER(BLI_edgehash_lookup(ccgdm->ehash, v4, v1));
1532                                         mv++, i++;
1533                                 }
1534                         }
1535                 }
1536         }
1537         BLI_rw_mutex_unlock(&loops_cache_rwlock);
1538 }
1539
1540 static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mpoly)
1541 {
1542         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1543         CCGSubSurf *ss = ccgdm->ss;
1544         int index;
1545         int totface;
1546         int gridSize = ccgSubSurf_getGridSize(ss);
1547         /* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */
1548         int i = 0, k = 0;
1549         DMFlagMat *faceFlags = ccgdm->faceFlags;
1550
1551         totface = ccgSubSurf_getNumFaces(ss);
1552         for (index = 0; index < totface; index++) {
1553                 CCGFace *f = ccgdm->faceMap[index].face;
1554                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1555                 int flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH;
1556                 int mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0;
1557
1558                 for (S = 0; S < numVerts; S++) {
1559                         for (y = 0; y < gridSize - 1; y++) {
1560                                 for (x = 0; x < gridSize - 1; x++) {
1561                                         MPoly *mp = &mpoly[i];
1562
1563                                         mp->mat_nr = mat_nr;
1564                                         mp->flag = flag;
1565                                         mp->loopstart = k;
1566                                         mp->totloop = 4;
1567
1568                                         k += 4;
1569                                         i++;
1570                                 }
1571                         }
1572                 }
1573         }
1574 }
1575
1576 static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3])
1577 {
1578         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1579         CCGSubSurf *ss = ccgdm->ss;
1580         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1581         int gridSize = ccgSubSurf_getGridSize(ss);
1582         int i;
1583         CCGVertIterator vi;
1584         CCGEdgeIterator ei;
1585         CCGFaceIterator fi;
1586         CCGFace **faceMap2;
1587         CCGEdge **edgeMap2;
1588         CCGVert **vertMap2;
1589         int index, totvert, totedge, totface;
1590         
1591         totvert = ccgSubSurf_getNumVerts(ss);
1592         vertMap2 = MEM_mallocN(totvert * sizeof(*vertMap2), "vertmap");
1593         for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
1594                 CCGVert *v = ccgVertIterator_getCurrent(&vi);
1595
1596                 vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v;
1597         }
1598
1599         totedge = ccgSubSurf_getNumEdges(ss);
1600         edgeMap2 = MEM_mallocN(totedge * sizeof(*edgeMap2), "edgemap");
1601         for (ccgSubSurf_initEdgeIterator(ss, &ei), i = 0; !ccgEdgeIterator_isStopped(&ei); i++, ccgEdgeIterator_next(&ei)) {
1602                 CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
1603
1604                 edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
1605         }
1606
1607         totface = ccgSubSurf_getNumFaces(ss);
1608         faceMap2 = MEM_mallocN(totface * sizeof(*faceMap2), "facemap");
1609         for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
1610                 CCGFace *f = ccgFaceIterator_getCurrent(&fi);
1611
1612                 faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))] = f;
1613         }
1614
1615         i = 0;
1616         for (index = 0; index < totface; index++) {
1617                 CCGFace *f = faceMap2[index];
1618                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1619
1620                 copy_v3_v3(cos[i++], ccgSubSurf_getFaceCenterData(f));
1621                 
1622                 for (S = 0; S < numVerts; S++) {
1623                         for (x = 1; x < gridSize - 1; x++) {
1624                                 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1625                         }
1626                 }
1627
1628                 for (S = 0; S < numVerts; S++) {
1629                         for (y = 1; y < gridSize - 1; y++) {
1630                                 for (x = 1; x < gridSize - 1; x++) {
1631                                         copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1632                                 }
1633                         }
1634                 }
1635         }
1636
1637         for (index = 0; index < totedge; index++) {
1638                 CCGEdge *e = edgeMap2[index];
1639                 int x;
1640
1641                 for (x = 1; x < edgeSize - 1; x++) {
1642                         copy_v3_v3(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
1643                 }
1644         }
1645
1646         for (index = 0; index < totvert; index++) {
1647                 CCGVert *v = vertMap2[index];
1648                 copy_v3_v3(cos[i++], ccgSubSurf_getVertData(ss, v));
1649         }
1650
1651         MEM_freeN(vertMap2);
1652         MEM_freeN(edgeMap2);
1653         MEM_freeN(faceMap2);
1654 }
1655
1656 static void ccgDM_foreachMappedVert(
1657         DerivedMesh *dm,
1658         void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
1659         void *userData,
1660         DMForeachFlag flag)
1661 {
1662         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1663         CCGVertIterator vi;
1664         CCGKey key;
1665         CCG_key_top_level(&key, ccgdm->ss);
1666
1667         for (ccgSubSurf_initVertIterator(ccgdm->ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
1668                 CCGVert *v = ccgVertIterator_getCurrent(&vi);
1669                 const int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
1670
1671                 if (index != -1) {
1672                         CCGElem *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
1673                         const float *no = (flag & DM_FOREACH_USE_NORMAL) ? CCG_elem_no(&key, vd) : NULL;
1674                         func(userData, index, CCG_elem_co(&key, vd), no, NULL);
1675                 }
1676         }
1677 }
1678
1679 static void ccgDM_foreachMappedEdge(
1680         DerivedMesh *dm,
1681         void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
1682         void *userData)
1683 {
1684         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1685         CCGSubSurf *ss = ccgdm->ss;
1686         CCGEdgeIterator ei;
1687         CCGKey key;
1688         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1689
1690         CCG_key_top_level(&key, ss);
1691
1692         for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
1693                 CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
1694                 const int index = ccgDM_getEdgeMapIndex(ss, e);
1695
1696                 if (index != -1) {
1697                         CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1698                         for (i = 0; i < edgeSize - 1; i++) {
1699                                 func(userData, index, CCG_elem_offset_co(&key, edgeData, i), CCG_elem_offset_co(&key, edgeData, i + 1));
1700                         }
1701                 }
1702         }
1703 }
1704
1705 static void ccgDM_foreachMappedLoop(
1706         DerivedMesh *dm,
1707         void (*func)(void *userData, int vertex_index, int face_index, const float co[3], const float no[3]),
1708         void *userData,
1709         DMForeachFlag flag)
1710 {
1711         /* We can't use dm->getLoopDataLayout(dm) here, we want to always access dm->loopData, EditDerivedBMesh would
1712          * return loop data from bmesh itself. */
1713         const float (*lnors)[3] = (flag & DM_FOREACH_USE_NORMAL) ? DM_get_loop_data_layer(dm, CD_NORMAL) : NULL;
1714
1715         MVert *mv = dm->getVertArray(dm);
1716         MLoop *ml = dm->getLoopArray(dm);
1717         MPoly *mp = dm->getPolyArray(dm);
1718         const int *v_index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1719         const int *f_index = dm->getPolyDataArray(dm, CD_ORIGINDEX);
1720         int p_idx, i;
1721
1722         for (p_idx = 0; p_idx < dm->numPolyData; ++p_idx, ++mp) {
1723                 for (i = 0; i < mp->totloop; ++i, ++ml) {
1724                         const int v_idx = v_index ? v_index[ml->v] : ml->v;
1725                         const int f_idx = f_index ? f_index[p_idx] : p_idx;
1726                         const float *no = lnors ? *lnors++ : NULL;
1727                         if (!ELEM(ORIGINDEX_NONE, v_idx, f_idx)) {
1728                                 func(userData, v_idx, f_idx, mv[ml->v].co, no);
1729                         }
1730                 }
1731         }
1732 }
1733
1734 static void ccgDM_drawVerts(DerivedMesh *dm)
1735 {
1736         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1737         CCGSubSurf *ss = ccgdm->ss;
1738         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1739         int gridSize = ccgSubSurf_getGridSize(ss);
1740         CCGVertIterator vi;
1741         CCGEdgeIterator ei;
1742         CCGFaceIterator fi;
1743
1744         glBegin(GL_POINTS);
1745         for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
1746                 CCGVert *v = ccgVertIterator_getCurrent(&vi);
1747                 glVertex3fv(ccgSubSurf_getVertData(ss, v));
1748         }
1749
1750         for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
1751                 CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
1752                 int x;
1753
1754                 for (x = 1; x < edgeSize - 1; x++)
1755                         glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
1756         }
1757
1758         for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
1759                 CCGFace *f = ccgFaceIterator_getCurrent(&fi);
1760                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1761
1762                 glVertex3fv(ccgSubSurf_getFaceCenterData(f));
1763                 for (S = 0; S < numVerts; S++)
1764                         for (x = 1; x < gridSize - 1; x++)
1765                                 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1766                 for (S = 0; S < numVerts; S++)
1767                         for (y = 1; y < gridSize - 1; y++)
1768                                 for (x = 1; x < gridSize - 1; x++)
1769                                         glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1770         }
1771         glEnd();
1772 }
1773
1774 static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
1775 {
1776         if (ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
1777                 CCGFace **faces;
1778                 int totface;
1779
1780                 BKE_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void ***)&faces, &totface);
1781                 if (totface) {
1782                         ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface);
1783                         ccgSubSurf_updateNormals(ccgdm->ss, faces, totface);
1784                         MEM_freeN(faces);
1785                 }
1786         }
1787 }
1788
1789 static void ccgDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges)
1790 {
1791         GPUDrawObject *gdo;
1792         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1793
1794 #ifdef WITH_OPENSUBDIV
1795         if (ccgdm->useGpuBackend) {
1796                 /* TODO(sergey): We currently only support all edges drawing. */
1797                 if (ccgSubSurf_prepareGLMesh(ccgdm->ss, true)) {
1798                         ccgSubSurf_drawGLMesh(ccgdm->ss, false, -1, -1);
1799                 }
1800                 return;
1801         }
1802 #endif
1803
1804         ccgdm_pbvh_update(ccgdm);
1805
1806 /* old debug feature for edges, unsupported for now */
1807 #if 0
1808         int useAging = 0;
1809
1810         if (!(G.f & G_BACKBUFSEL)) {
1811                 CCGSubSurf *ss = ccgdm->ss;
1812                 ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1813
1814                 /* it needs some way to upload this to VBO now */
1815                 if (useAging) {
1816                         int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e) * 4;
1817                         glColor3ub(0, ageCol > 0 ? ageCol : 0, 0);
1818                 }
1819         }
1820 #endif
1821
1822         GPU_edge_setup(dm);
1823         gdo = dm->drawObject;
1824         if (gdo->edges && gdo->points) {
1825                 if (drawAllEdges && drawLooseEdges) {
1826                         GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, (gdo->totedge - gdo->totinterior) * 2);
1827                 }
1828                 else if (drawAllEdges) {
1829                         GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, gdo->loose_edge_offset * 2);
1830                 }
1831                 else {
1832                         GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, gdo->tot_edge_drawn * 2);
1833                         GPU_buffer_draw_elements(gdo->edges, GL_LINES, gdo->loose_edge_offset * 2, gdo->tot_loose_edge_drawn * 2);
1834                 }
1835         }
1836
1837         if (ccgdm->drawInteriorEdges) {
1838                 GPU_buffer_draw_elements(gdo->edges, GL_LINES, gdo->interior_offset * 2, gdo->totinterior * 2);
1839         }
1840         GPU_buffers_unbind();
1841 }
1842
1843 static void ccgDM_drawLooseEdges(DerivedMesh *dm)
1844 {
1845         int start;
1846         int count;
1847
1848 #ifdef WITH_OPENSUBDIV
1849         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1850         if (ccgdm->useGpuBackend) {
1851                 /* TODO(sergey): Needs implementation. */
1852                 return;
1853         }
1854 #endif
1855
1856         GPU_edge_setup(dm);
1857
1858         start = (dm->drawObject->loose_edge_offset * 2);
1859         count = (dm->drawObject->interior_offset - dm->drawObject->loose_edge_offset) * 2;
1860
1861         if (count) {
1862                 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, start, count);
1863         }
1864
1865         GPU_buffers_unbind();
1866 }
1867
1868 static void ccgDM_NormalFast(float *a, float *b, float *c, float *d, float no[3])
1869 {
1870         float a_cX = c[0] - a[0], a_cY = c[1] - a[1], a_cZ = c[2] - a[2];
1871         float b_dX = d[0] - b[0], b_dY = d[1] - b[1], b_dZ = d[2] - b[2];
1872
1873         no[0] = b_dY * a_cZ - b_dZ * a_cY;
1874         no[1] = b_dZ * a_cX - b_dX * a_cZ;
1875         no[2] = b_dX * a_cY - b_dY * a_cX;
1876         
1877         normalize_v3(no);
1878 }
1879
1880
1881 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
1882 {
1883         float a_cX = c[0] - a[0], a_cY = c[1] - a[1], a_cZ = c[2] - a[2];
1884         float b_dX = d[0] - b[0], b_dY = d[1] - b[1], b_dZ = d[2] - b[2];
1885         float no[3];
1886         
1887         no[0] = b_dY * a_cZ - b_dZ * a_cY;
1888         no[1] = b_dZ * a_cX - b_dX * a_cZ;
1889         no[2] = b_dX * a_cY - b_dY * a_cX;
1890
1891         /* don't normalize, GL_NORMALIZE is enabled */
1892         glNormal3fv(no);
1893 }
1894
1895 /* Only used by non-editmesh types */
1896 static void ccgDM_buffer_copy_normal(
1897         DerivedMesh *dm, short *varray)
1898 {
1899         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1900         CCGSubSurf *ss = ccgdm->ss;
1901         CCGKey key;
1902         const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
1903         int gridSize = ccgSubSurf_getGridSize(ss);
1904         int gridFaces = gridSize - 1;
1905         DMFlagMat *faceFlags = ccgdm->faceFlags;
1906         int i, totface = ccgSubSurf_getNumFaces(ss);
1907         int shademodel;
1908         int start = 0;
1909
1910         CCG_key_top_level(&key, ss);
1911         ccgdm_pbvh_update(ccgdm);
1912
1913         for (i = 0; i < totface; i++) {
1914                 CCGFace *f = ccgdm->faceMap[i].face;
1915                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1916                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
1917                 const float (*ln)[3] = NULL;
1918
1919                 if (faceFlags) {
1920                         shademodel = (lnors || (faceFlags[index].flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT;
1921                 }
1922                 else {
1923                         shademodel = GL_SMOOTH;
1924                 }
1925
1926                 if (lnors) {
1927                         ln = lnors;
1928                         lnors += gridFaces * gridFaces * numVerts * 4;
1929                 }
1930
1931                 for (S = 0; S < numVerts; S++) {
1932                         CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1933
1934                         if (ln) {
1935                                 /* Can't use quad strips here... */
1936                                 for (y = 0; y < gridFaces; y ++) {
1937                                         for (x = 0; x < gridFaces; x ++) {
1938                                                 normal_float_to_short_v3(&varray[start + 0],  ln[0]);
1939                                                 normal_float_to_short_v3(&varray[start + 4],  ln[3]);
1940                                                 normal_float_to_short_v3(&varray[start + 8],  ln[2]);
1941                                                 normal_float_to_short_v3(&varray[start + 12], ln[1]);
1942
1943                                                 start += 16;
1944                                                 ln += 4;
1945                                         }
1946                                 }
1947                         }
1948                         else if (shademodel == GL_SMOOTH) {
1949                                 for (y = 0; y < gridFaces; y ++) {
1950                                         for (x = 0; x < gridFaces; x ++) {
1951                                                 float *a = CCG_grid_elem_no(&key, faceGridData, x, y );
1952                                                 float *b = CCG_grid_elem_no(&key, faceGridData, x + 1, y);
1953                                                 float *c = CCG_grid_elem_no(&key, faceGridData, x + 1, y + 1);
1954                                                 float *d = CCG_grid_elem_no(&key, faceGridData, x, y + 1);
1955
1956                                                 normal_float_to_short_v3(&varray[start], a);
1957                                                 normal_float_to_short_v3(&varray[start + 4], b);
1958                                                 normal_float_to_short_v3(&varray[start + 8], c);
1959                                                 normal_float_to_short_v3(&varray[start + 12], d);
1960
1961                                                 start += 16;
1962                                         }
1963                                 }
1964                         }
1965                         else {
1966                                 for (y = 0; y < gridFaces; y ++) {
1967                                         for (x = 0; x < gridFaces; x ++) {
1968                                                 float f_no[3];
1969                                                 short f_no_s[3];
1970
1971                                                 float *a = CCG_grid_elem_co(&key, faceGridData, x, y );
1972                                                 float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y );
1973                                                 float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
1974                                                 float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
1975
1976                                                 ccgDM_NormalFast(a, b, c, d, f_no);
1977                                                 normal_float_to_short_v3(f_no_s, f_no);
1978         
1979                                                 copy_v3_v3_short(&varray[start], f_no_s);
1980                                                 copy_v3_v3_short(&varray[start + 4], f_no_s);
1981                                                 copy_v3_v3_short(&varray[start + 8], f_no_s);
1982                                                 copy_v3_v3_short(&varray[start + 12], f_no_s);
1983
1984                                                 start += 16;
1985                                         }
1986                                 }
1987                         }
1988                 }
1989         }
1990 }
1991
1992 typedef struct FaceCount {
1993         unsigned int i_visible;
1994         unsigned int i_hidden;
1995         unsigned int i_tri_visible;
1996         unsigned int i_tri_hidden;
1997 } FaceCount;
1998
1999
2000 /* Only used by non-editmesh types */
2001 static void ccgDM_buffer_copy_triangles(
2002         DerivedMesh *dm, unsigned int *varray,
2003         const int *mat_orig_to_new)
2004 {
2005         GPUBufferMaterial *gpumat, *gpumaterials = dm->drawObject->materials;
2006         const int totmat = dm->drawObject->totmaterial;
2007         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2008         CCGSubSurf *ss = ccgdm->ss;
2009         CCGKey key;
2010         int gridSize = ccgSubSurf_getGridSize(ss);
2011         int gridFaces = gridSize - 1;
2012         DMFlagMat *faceFlags = ccgdm->faceFlags;
2013         int i, totface = ccgSubSurf_getNumFaces(ss);
2014         int matnr = -1, start;
2015         int totloops = 0;
2016         FaceCount *fc = MEM_mallocN(sizeof(*fc) * totmat, "gpumaterial.facecount");
2017
2018         CCG_key_top_level(&key, ss);
2019
2020         for (i = 0; i < totmat; i++) {
2021                 fc[i].i_visible = 0;
2022                 fc[i].i_tri_visible = 0;
2023                 fc[i].i_hidden = gpumaterials[i].totpolys - 1;
2024                 fc[i].i_tri_hidden = gpumaterials[i].totelements - 1;
2025         }
2026
2027         for (i = 0; i < totface; i++) {
2028                 CCGFace *f = ccgdm->faceMap[i].face;
2029                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2030                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
2031                 bool is_hidden;
2032                 int mati;
2033
2034                 if (faceFlags) {
2035                         matnr = faceFlags[index].mat_nr;
2036                         is_hidden = (faceFlags[index].flag & ME_HIDE) != 0;
2037                 }
2038                 else {
2039                         matnr = 0;
2040                         is_hidden = false;
2041                 }
2042                 mati = mat_orig_to_new[matnr];
2043                 gpumat = dm->drawObject->materials + mati;
2044
2045                 if (is_hidden) {
2046                         for (S = 0; S < numVerts; S++) {
2047                                 for (y = 0; y < gridFaces; y++) {
2048                                         for (x = 0; x < gridFaces; x++) {
2049                                                 start = gpumat->start + fc[mati].i_tri_hidden;
2050
2051                                                 varray[start--] = totloops + 1;
2052                                                 varray[start--] = totloops + 2;
2053                                                 varray[start--] = totloops + 3;
2054
2055                                                 varray[start--] = totloops;
2056                                                 varray[start--] = totloops + 1;
2057                                                 varray[start--] = totloops + 3;
2058
2059                                                 fc[mati].i_tri_hidden -= 6;
2060
2061                                                 totloops += 4;
2062                                         }
2063                                 }
2064                         }
2065                         gpumat->polys[fc[mati].i_hidden--] = i;
2066                 }
2067                 else {
2068                         for (S = 0; S < numVerts; S++) {
2069                                 for (y = 0; y < gridFaces; y++) {
2070                                         for (x = 0; x < gridFaces; x++) {
2071                                                 start = gpumat->start + fc[mati].i_tri_visible;
2072
2073                                                 varray[start++] = totloops + 3;
2074                                                 varray[start++] = totloops + 2;
2075                                                 varray[start++] = totloops + 1;
2076
2077                                                 varray[start++] = totloops + 3;
2078                                                 varray[start++] = totloops + 1;
2079                                                 varray[start++] = totloops;
2080
2081                                                 fc[mati].i_tri_visible += 6;
2082
2083                                                 totloops += 4;
2084                                         }
2085                                 }
2086                         }
2087                         gpumat->polys[fc[mati].i_visible++] = i;
2088                 }
2089         }
2090
2091         /* set the visible polygons */
2092         for (i = 0; i < totmat; i++) {
2093                 gpumaterials[i].totvisiblepolys = fc[i].i_visible;
2094         }
2095
2096         MEM_freeN(fc);
2097 }
2098
2099
2100 /* Only used by non-editmesh types */
2101 static void ccgDM_buffer_copy_vertex(
2102         DerivedMesh *dm, void *varray_p)
2103 {
2104         float *varray = varray_p;
2105         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2106         CCGSubSurf *ss = ccgdm->ss;
2107         CCGKey key;
2108         int gridSize = ccgSubSurf_getGridSize(ss);
2109         int gridFaces = gridSize - 1;
2110         int i, totface = ccgSubSurf_getNumFaces(ss);
2111         int totedge = ccgSubSurf_getNumEdges(ss);
2112         int start = 0;
2113         int edgeSize = ccgSubSurf_getEdgeSize(ss);
2114         
2115         CCG_key_top_level(&key, ss);
2116         ccgdm_pbvh_update(ccgdm);
2117         
2118         for (i = 0; i < totface; i++) {
2119                 CCGFace *f = ccgdm->faceMap[i].face;
2120                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2121                 
2122                 for (S = 0; S < numVerts; S++) {
2123                         CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2124                         for (y = 0; y < gridFaces; y++) {
2125                                 for (x = 0; x < gridFaces; x++) {
2126                                         float *a = CCG_grid_elem_co(&key, faceGridData, x, y);
2127                                         float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y);
2128                                         float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
2129                                         float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
2130
2131                                         copy_v3_v3(&varray[start], a);
2132                                         copy_v3_v3(&varray[start + 3], b);
2133                                         copy_v3_v3(&varray[start + 6], c);
2134                                         copy_v3_v3(&varray[start + 9], d);
2135
2136                                         start += 12;
2137                                 }
2138                         }
2139                 }
2140         }
2141
2142         /* upload loose points */
2143         for (i = 0; i < totedge; i++) {
2144                 CCGEdge *e = ccgdm->edgeMap[i].edge;
2145                 CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2146
2147                 if (!ccgSubSurf_getEdgeNumFaces(e)) {
2148                         int j = 0;
2149                         for (j = 0; j < edgeSize; j++) {
2150                                 copy_v3_v3(&varray[start], CCG_elem_offset_co(&key, edgeData, j));
2151                                 start += 3;
2152                         }
2153                 }
2154         }
2155 }
2156
2157 /* Only used by non-editmesh types */
2158 static void ccgDM_buffer_copy_color(
2159         DerivedMesh *dm, unsigned char *varray,
2160         const void *user_data)
2161 {
2162         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2163         CCGSubSurf *ss = ccgdm->ss;
2164         CCGKey key;
2165         const char *mloopcol = user_data;
2166         int gridSize = ccgSubSurf_getGridSize(ss);
2167         int gridFaces = gridSize - 1;
2168         int i, totface = ccgSubSurf_getNumFaces(ss);
2169         int start = 0;
2170         int iface = 0;
2171
2172         CCG_key_top_level(&key, ss);
2173
2174
2175         for (i = 0; i < totface; i++) {
2176                 CCGFace *f = ccgdm->faceMap[i].face;
2177                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2178
2179                 for (S = 0; S < numVerts; S++) {
2180                         for (y = 0; y < gridFaces; y++) {
2181                                 for (x = 0; x < gridFaces; x++) {
2182                                         copy_v3_v3_char((char *)&varray[start + 0], &mloopcol[iface * 16 + 0]);
2183                                         copy_v3_v3_char((char *)&varray[start + 3], &mloopcol[iface * 16 + 12]);
2184                                         copy_v3_v3_char((char *)&varray[start + 6], &mloopcol[iface * 16 + 8]);
2185                                         copy_v3_v3_char((char *)&varray[start + 9], &mloopcol[iface * 16 + 4]);
2186
2187                                         start += 12;
2188                                         iface++;
2189                                 }
2190                         }
2191                 }
2192         }
2193 }
2194
2195 static void ccgDM_buffer_copy_uv(
2196         DerivedMesh *dm, void *varray_p)
2197 {
2198         float *varray = varray_p;
2199         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2200         CCGSubSurf *ss = ccgdm->ss;
2201         CCGKey key;
2202         MLoopUV *mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV);
2203         int gridSize = ccgSubSurf_getGridSize(ss);
2204         int gridFaces = gridSize - 1;
2205         int i, totface = ccgSubSurf_getNumFaces(ss);
2206         int start = 0;
2207
2208         CCG_key_top_level(&key, ss);
2209
2210         for (i = 0; i < totface; i++) {
2211                 CCGFace *f = ccgdm->faceMap[i].face;
2212                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2213
2214                 for (S = 0; S < numVerts; S++) {
2215                         for (y = 0; y < gridFaces; y++) {
2216                                 for (x = 0; x < gridFaces; x++) {
2217                                         copy_v2_v2(&varray[start + 0], mloopuv[0].uv);
2218                                         copy_v2_v2(&varray[start + 2], mloopuv[3].uv);
2219                                         copy_v2_v2(&varray[start + 4], mloopuv[2].uv);
2220                                         copy_v2_v2(&varray[start + 6], mloopuv[1].uv);
2221
2222                                         mloopuv += 4;
2223                                         start += 8;
2224                                 }
2225                         }
2226                 }
2227         }
2228 }
2229
2230 static void ccgDM_buffer_copy_uv_texpaint(
2231         DerivedMesh *dm, float *varray)
2232 {
2233         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2234         CCGSubSurf *ss = ccgdm->ss;
2235         CCGKey key;
2236         int gridSize = ccgSubSurf_getGridSize(ss);
2237         int gridFaces = gridSize - 1;
2238         int i, totface = ccgSubSurf_getNumFaces(ss);
2239         int start = 0;
2240         DMFlagMat *faceFlags = ccgdm->faceFlags;
2241         int totmaterial = dm->totmat;
2242         MLoopUV **mloopuv_base;
2243         MLoopUV  *stencil_base;
2244         int stencil;
2245
2246         CCG_key_top_level(&key, ss);
2247
2248         /* should have been checked for before, reassert */
2249         BLI_assert(DM_get_loop_data_layer(dm, CD_MLOOPUV));
2250         mloopuv_base = MEM_mallocN(totmaterial * sizeof(*mloopuv_base), "texslots");
2251
2252         for (i = 0; i < totmaterial; i++) {
2253                 mloopuv_base[i] = DM_paint_uvlayer_active_get(dm, i);
2254         }
2255
2256         stencil = CustomData_get_stencil_layer(&dm->loopData, CD_MLOOPUV);
2257         stencil_base = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, stencil);
2258
2259         start = 0;
2260
2261         for (i = 0; i < totface; i++) {
2262                 CCGFace *f = ccgdm->faceMap[i].face;
2263                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2264                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
2265                 int matnr;
2266
2267                 if (faceFlags) {
2268                         matnr = faceFlags[index].mat_nr;
2269                 }
2270                 else {
2271                         matnr = 0;
2272                 }
2273
2274                 for (S = 0; S < numVerts; S++) {
2275                         for (y = 0; y < gridFaces; y++) {
2276                                 for (x = 0; x < gridFaces; x++) {
2277                                         /* divide by 4, gives us current loop-index */
2278                                         unsigned int i_ml = start / 4;
2279                                         copy_v2_v2(&varray[start + 0],  mloopuv_base[matnr][i_ml + 0].uv);
2280                                         copy_v2_v2(&varray[start + 2],         stencil_base[i_ml + 0].uv);
2281                                         copy_v2_v2(&varray[start + 4],  mloopuv_base[matnr][i_ml + 3].uv);
2282                                         copy_v2_v2(&varray[start + 6],         stencil_base[i_ml + 3].uv);
2283                                         copy_v2_v2(&varray[start + 8],  mloopuv_base[matnr][i_ml + 2].uv);
2284                                         copy_v2_v2(&varray[start + 10],        stencil_base[i_ml + 2].uv);
2285                                         copy_v2_v2(&varray[start + 12], mloopuv_base[matnr][i_ml + 1].uv);
2286                                         copy_v2_v2(&varray[start + 14],        stencil_base[i_ml + 1].uv);
2287                                         start += 16;
2288                                 }
2289                         }
2290                 }
2291         }
2292
2293         MEM_freeN(mloopuv_base);
2294 }
2295
2296 static void ccgDM_buffer_copy_uvedge(
2297         DerivedMesh *dm, float *varray)
2298 {
2299         int i, totpoly;
2300         int start;
2301         const MLoopUV *mloopuv;
2302 #ifndef USE_LOOP_LAYOUT_FAST
2303         const MPoly *mpoly = dm->getPolyArray(dm);
2304 #endif
2305
2306         if ((mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV)) == NULL) {
2307                 return;
2308         }
2309
2310         totpoly = dm->getNumPolys(dm);
2311         start = 0;
2312
2313 #ifndef USE_LOOP_LAYOUT_FAST
2314         for (i = 0; i < totpoly; i++, mpoly++) {
2315                 for (j = 0; j < mpoly->totloop; j++) {
2316                         copy_v2_v2(&varray[start], mloopuv[mpoly->loopstart + j].uv);
2317                         copy_v2_v2(&varray[start + 2], mloopuv[mpoly->loopstart + (j + 1) % mpoly->totloop].uv);
2318                         start += 4;
2319                 }
2320         }
2321 #else
2322         for (i = 0; i < totpoly; i++) {
2323                 copy_v2_v2(&varray[start +  0], mloopuv[(i * 4) + 0].uv);
2324                 copy_v2_v2(&varray[start +  2], mloopuv[(i * 4) + 1].uv);
2325
2326                 copy_v2_v2(&varray[start +  4], mloopuv[(i * 4) + 1].uv);
2327                 copy_v2_v2(&varray[start +  6], mloopuv[(i * 4) + 2].uv);
2328
2329                 copy_v2_v2(&varray[start +  8], mloopuv[(i * 4) + 2].uv);
2330                 copy_v2_v2(&varray[start + 10], mloopuv[(i * 4) + 3].uv);
2331
2332                 copy_v2_v2(&varray[start + 12], mloopuv[(i * 4) + 3].uv);
2333                 copy_v2_v2(&varray[start + 14], mloopuv[(i * 4) + 0].uv);
2334
2335                 start += 16;
2336         }
2337 #endif
2338 }
2339
2340 static void ccgDM_buffer_copy_edge(
2341         DerivedMesh *dm, unsigned int *varray)
2342 {
2343         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2344         CCGSubSurf *ss = ccgdm->ss;
2345         /* getEdgeSuze returns num of verts, edges is one less */
2346         int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss) - 1;
2347         int totedge = ccgSubSurf_getNumEdges(ss);
2348         int grid_face_side = ccgSubSurf_getGridSize(ss) - 1;
2349         int totface = ccgSubSurf_getNumFaces(ss);
2350         unsigned int index_start;
2351         unsigned int tot_interior = 0;
2352         unsigned int grid_tot_face = grid_face_side * grid_face_side;
2353
2354         unsigned int iloose, inorm, iloosehidden, inormhidden;
2355         unsigned int tot_loose_hidden = 0, tot_loose = 0;
2356         unsigned int tot_hidden = 0, tot = 0;
2357         unsigned int iloosevert;
2358         /* int tot_interior = 0; */
2359
2360         /* first, handle hidden/loose existing edges, then interior edges */
2361         for (j = 0; j < totedge; j++) {
2362                 CCGEdge *e = ccgdm->edgeMap[j].edge;
2363
2364                 if (ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW)) {
2365                         if (!ccgSubSurf_getEdgeNumFaces(e)) tot_loose_hidden++;
2366                         else tot_hidden++;
2367                 }
2368                 else {
2369                         if (!ccgSubSurf_getEdgeNumFaces(e)) tot_loose++;
2370                         else tot++;
2371                 }
2372         }
2373
2374         inorm = 0;
2375         inormhidden = tot * edgeSize;
2376         iloose = (tot + tot_hidden) * edgeSize;
2377         iloosehidden = (tot + tot_hidden + tot_loose) * edgeSize;
2378         iloosevert = dm->drawObject->tot_loop_verts;
2379
2380         /* part one, handle all normal edges */
2381         for (j = 0; j < totedge; j++) {
2382                 CCGFace *f;
2383                 int fhandle;
2384                 int totvert;
2385                 unsigned int S;
2386                 CCGEdge *e = ccgdm->edgeMap[j].edge;
2387                 bool isloose = !ccgSubSurf_getEdgeNumFaces(e);
2388
2389                 if (!isloose) {
2390                         CCGVert *v1, *v2;
2391                         CCGVert *ev1 = ccgSubSurf_getEdgeVert0(e);
2392                         CCGVert *ev2 = ccgSubSurf_getEdgeVert1(e);
2393
2394                         f = ccgSubSurf_getEdgeFace(e, 0);
2395                         fhandle = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
2396                         totvert = ccgSubSurf_getFaceNumVerts(f);
2397
2398                         /* find the index of vertices in the face */
2399                         for (i = 0; i < totvert; i++) {
2400                                 v1 = ccgSubSurf_getFaceVert(f, i);
2401                                 v2 = ccgSubSurf_getFaceVert(f, (i + 1) % totvert);
2402
2403                                 if ((ev1 == v1 && ev2 == v2) || (ev1 == v2 && ev2 == v1)) {
2404                                         S = i;
2405                                         break;
2406                                 }
2407                         }
2408                 }
2409
2410                 if (ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW)) {
2411                         if (isloose) {
2412                                 for (i = 0; i < edgeSize; i++) {
2413                                         varray[iloosehidden * 2] = iloosevert;
2414                                         varray[iloosehidden * 2 + 1] = iloosevert + 1;
2415                                         iloosehidden++;
2416                                         iloosevert++;
2417                                 }
2418                                 /* we are through with this loose edge and moving to the next, so increase by one */
2419                                 iloosevert++;
2420                         }
2421                         else {
2422                                 index_start = ccgdm->faceMap[fhandle].startFace;
2423
2424                                 for (i = 0; i < grid_face_side; i++) {
2425                                         varray[inormhidden * 2] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 1;
2426                                         varray[inormhidden * 2 + 1] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 2;
2427                                         varray[inormhidden * 2 + 2] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 2;
2428                                         varray[inormhidden * 2 + 3] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 3;
2429                                         inormhidden += 2;
2430                                 }
2431                         }
2432                 }
2433                 else {
2434                         if (isloose) {
2435                                 for (i = 0; i < edgeSize; i++) {
2436                                         varray[iloose * 2] = iloosevert;
2437                                         varray[iloose * 2 + 1] = iloosevert + 1;
2438                                         iloose++;
2439                                         iloosevert++;
2440                                 }
2441                                 /* we are through with this loose edge and moving to the next, so increase by one */
2442                                 iloosevert++;
2443                         }
2444                         else {
2445                                 index_start = ccgdm->faceMap[fhandle].startFace;
2446
2447                                 for (i = 0; i < grid_face_side; i++) {
2448                                         varray[inorm * 2] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 1;
2449                                         varray[inorm * 2 + 1] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 2;
2450                                         varray[inorm * 2 + 2] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 2;
2451                                         varray[inorm * 2 + 3] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 3;
2452                                         inorm += 2;
2453                                 }
2454                         }
2455                 }
2456         }
2457
2458         /* part two, handle interior edges */
2459         inorm = totedge * grid_face_side * 2;
2460
2461         index_start = 0;
2462         for (i = 0; i < totface; i++) {
2463                 CCGFace *f = ccgdm->faceMap[i].face;
2464                 unsigned int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2465
2466                 for (S = 0; S < numVerts; S++) {
2467                         for (x = 1; x < grid_face_side; x++) {
2468                                 for (y = 0; y < grid_face_side; y++) {
2469                                         unsigned int tmp = (index_start + x * grid_face_side + y) * 4;
2470                                         varray[inorm * 2] = tmp;
2471                                         varray[inorm * 2 + 1] = tmp + 1;
2472                                         inorm++;
2473                                 }
2474                         }
2475                         for (x = 0; x < grid_face_side; x++) {
2476                                 for (y = 0; y < grid_face_side; y++) {
2477                                         unsigned int tmp = (index_start + x * grid_face_side + y) * 4;
2478                                         varray[inorm * 2] = tmp + 3;
2479                                         varray[inorm * 2 + 1] = tmp;
2480                                         inorm++;
2481                                 }
2482                         }
2483
2484                         tot_interior += grid_face_side * (2 * grid_face_side - 1);
2485                         index_start += grid_tot_face;
2486                 }
2487         }
2488
2489         dm->drawObject->tot_loose_edge_drawn = tot_loose * edgeSize;
2490         dm->drawObject->loose_edge_offset = (tot + tot_hidden) * edgeSize;
2491         dm->drawObject->tot_edge_drawn = tot * edgeSize;
2492
2493         dm->drawObject->interior_offset = totedge * edgeSize;
2494         dm->drawObject->totinterior = tot_interior;
2495 }
2496
2497 static void ccgDM_copy_gpu_data(
2498         DerivedMesh *dm, int type, void *varray_p,
2499         const int *mat_orig_to_new, const void *user_data)
2500 {
2501         /* 'varray_p' cast is redundant but include for self-documentation */
2502         switch (type) {
2503                 case GPU_BUFFER_VERTEX:
2504                         ccgDM_buffer_copy_vertex(dm, (float *)varray_p);
2505                         break;
2506                 case GPU_BUFFER_NORMAL:
2507                         ccgDM_buffer_copy_normal(dm, (short *)varray_p);
2508                         break;
2509                 case GPU_BUFFER_UV:
2510                         ccgDM_buffer_copy_uv(dm, (float *)varray_p);
2511                         break;
2512                 case GPU_BUFFER_UV_TEXPAINT:
2513                         ccgDM_buffer_copy_uv_texpaint(dm, (float *)varray_p);
2514                         break;
2515                 case GPU_BUFFER_COLOR:
2516                         ccgDM_buffer_copy_color(dm, (unsigned char *)varray_p, user_data);
2517                         break;
2518                 case GPU_BUFFER_UVEDGE:
2519                         ccgDM_buffer_copy_uvedge(dm, (float *)varray_p);
2520                         break;
2521                 case GPU_BUFFER_EDGE:
2522                         ccgDM_buffer_copy_edge(dm, (unsigned int *)varray_p);
2523                         break;
2524                 case GPU_BUFFER_TRIANGLES:
2525                         ccgDM_buffer_copy_triangles(dm, (unsigned int *)varray_p, mat_orig_to_new);
2526                         break;
2527                 default:
2528                         break;
2529         }
2530 }
2531
2532 static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm)
2533 {
2534         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2535         CCGSubSurf *ss = ccgdm->ss;
2536         GPUDrawObject *gdo;
2537         DMFlagMat *faceFlags = ccgdm->faceFlags;
2538         int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
2539         int totmat = (faceFlags) ? dm->totmat : 1;
2540         GPUBufferMaterial *matinfo;
2541         int i;
2542         unsigned int tot_internal_edges = 0;
2543         int edgeVerts = ccgSubSurf_getEdgeSize(ss);
2544         int edgeSize = edgeVerts - 1;
2545
2546         int totedge = ccgSubSurf_getNumEdges(ss);
2547         int totface = ccgSubSurf_getNumFaces(ss);
2548
2549         /* object contains at least one material (default included) so zero means uninitialized dm */
2550         BLI_assert(totmat != 0);
2551
2552         matinfo = MEM_callocN(sizeof(*matinfo) * totmat, "GPU_drawobject_new.mat_orig_to_new");
2553         
2554         if (faceFlags) {
2555                 for (i = 0; i < totface; i++) {
2556                         CCGFace *f = ccgdm->faceMap[i].face;
2557                         int numVerts = ccgSubSurf_getFaceNumVerts(f);
2558                         int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
2559                         int new_matnr = faceFlags[index].mat_nr;
2560                         matinfo[new_matnr].totelements += numVerts * gridFaces * gridFaces * 6;
2561                         matinfo[new_matnr].totloops += numVerts * gridFaces * gridFaces * 4;
2562                         matinfo[new_matnr].totpolys++;
2563                         tot_internal_edges += numVerts * gridFaces * (2 * gridFaces - 1);
2564                 }
2565         }
2566         else {
2567                 for (i = 0; i < totface; i++) {
2568                         CCGFace *f = ccgdm->faceMap[i].face;
2569                         int numVerts = ccgSubSurf_getFaceNumVerts(f);
2570                         matinfo[0].totelements += numVerts * gridFaces * gridFaces * 6;
2571                         matinfo[0].totloops += numVerts * gridFaces * gridFaces * 4;
2572                         matinfo[0].totpolys++;
2573                         tot_internal_edges += numVerts * gridFaces * (2 * gridFaces - 1);
2574                 }
2575         }
2576         
2577         /* create the GPUDrawObject */
2578         gdo = MEM_callocN(sizeof(GPUDrawObject), "GPUDrawObject");
2579         gdo->totvert = 0; /* used to count indices, doesn't really matter for ccgsubsurf */
2580         gdo->totedge = (totedge * edgeSize + tot_internal_edges);
2581
2582         GPU_buffer_material_finalize(gdo, matinfo, totmat);
2583
2584         /* store total number of points used for triangles */
2585         gdo->tot_triangle_point = ccgSubSurf_getNumFinalFaces(ss) * 6;
2586         gdo->tot_loop_verts = ccgSubSurf_getNumFinalFaces(ss) * 4;
2587
2588         /* finally, count loose points */
2589         for (i = 0; i < totedge; i++) {
2590                 CCGEdge *e = ccgdm->edgeMap[i].edge;
2591
2592                 if (!ccgSubSurf_getEdgeNumFaces(e))
2593                         gdo->tot_loose_point += edgeVerts;
2594         }
2595
2596         return gdo;
2597 }
2598
2599 /* Only used by non-editmesh types */
2600 static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], bool fast, DMSetMaterial setMaterial)
2601 {
2602         int a;
2603         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2604
2605         ccgdm_pbvh_update(ccgdm);
2606
2607         if (ccgdm->pbvh && ccgdm->multires.mmd) {
2608                 if (BKE_pbvh_has_faces(ccgdm->pbvh)) {
2609                         BKE_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL,
2610                                       setMaterial, false, fast);
2611                         glShadeModel(GL_FLAT);
2612                 }
2613
2614                 return;
2615         }
2616
2617 #ifdef WITH_OPENSUBDIV
2618         if (ccgdm->useGpuBackend) {
2619                 CCGSubSurf *ss = ccgdm->ss;
2620                 DMFlagMat *faceFlags = ccgdm->faceFlags;
2621                 int new_matnr;
2622                 bool draw_smooth;
2623                 if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, setMaterial != NULL) == false)) {
2624                         return;
2625                 }
2626                 /* TODO(sergey): Single matierial currently. */
2627                 if (faceFlags) {
2628                         draw_smooth = (faceFlags[0].flag & ME_SMOOTH);
2629                         new_matnr = (faceFlags[0].mat_nr + 1);
2630                 }
2631                 else {
2632                         draw_smooth = true;
2633                         new_matnr = 1;
2634                 }
2635                 if (setMaterial) {
2636                         setMaterial(new_matnr, NULL);
2637                 }
2638                 glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
2639                 ccgSubSurf_drawGLMesh(ss, true, -1, -1);
2640                 return;
2641         }
2642 #endif
2643
2644         GPU_vertex_setup(dm);
2645         GPU_normal_setup(dm);
2646         GPU_triangle_setup(dm);
2647         glShadeModel(GL_SMOOTH);
2648         for (a = 0; a < dm->drawObject->totmaterial; a++) {
2649                 if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
2650                         GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, dm->drawObject->materials[a].start,
2651                                                  dm->drawObject->materials[a].totelements);
2652                 }
2653         }
2654         GPU_buffers_unbind();
2655 }
2656
2657 /* Only used by non-editmesh types */
2658 static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
2659                                       DMSetMaterial setMaterial,
2660                                       DMSetDrawOptions setDrawOptions,
2661                                       void *userData)
2662 {
2663         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2664         CCGSubSurf *ss = ccgdm->ss;
2665         CCGKey key;
2666         GPUVertexAttribs gattribs;
2667         DMVertexAttribs attribs = {{{NULL}}};
2668         /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
2669         int gridSize = ccgSubSurf_getGridSize(ss);
2670         int gridFaces = gridSize - 1;
2671         int edgeSize = ccgSubSurf_getEdgeSize(ss);
2672         DMFlagMat *faceFlags = ccgdm->faceFlags;
2673         short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
2674         int a, i, do_draw, numVerts, matnr, new_matnr, totface;
2675
2676 #ifdef WITH_OPENSUBDIV
2677         if (ccgdm->useGpuBackend) {
2678                 int new_matnr;
2679                 bool draw_smooth;
2680                 GPU_draw_update_fvar_offset(dm);
2681                 if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, false) == false)) {
2682                         return;
2683                 }
2684                 /* TODO(sergey): Single matierial currently. */
2685                 if (faceFlags) {
2686                         draw_smooth = (faceFlags[0].flag & ME_SMOOTH);
2687                         new_matnr = (faceFlags[0].mat_nr + 1);
2688                 }
2689                 else {
2690                         draw_smooth = true;
2691                         new_matnr = 1;
2692                 }
2693                 glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
2694                 setMaterial(new_matnr, &gattribs);
2695                 ccgSubSurf_drawGLMesh(ss, true, -1, -1);
2696                 return;
2697         }
2698 #endif
2699
2700         CCG_key_top_level(&key, ss);
2701         ccgdm_pbvh_update(ccgdm);
2702
2703         do_draw = 0;
2704         matnr = -1;
2705
2706 #define PASSATTRIB(dx, dy, vert) {                                            \
2707         if (attribs.totorco)                                                      \
2708                 index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize);   \
2709         else                                                                      \
2710                 index = 0;                                                            \
2711         DM_draw_attrib_vertex(&attribs, a, index, vert, ((a) * 4) + vert);          \
2712 } (void)0
2713
2714         totface = ccgSubSurf_getNumFaces(ss);
2715         for (a = 0, i = 0; i < totface; i++) {
2716                 CCGFace *f = ccgdm->faceMap[i].face;
2717                 short (*ln)[4][3] = NULL;
2718                 int S, x, y, drawSmooth;
2719                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
2720                 int origIndex = ccgDM_getFaceMapIndex(ss, f);
2721                 
2722                 numVerts = ccgSubSurf_getFaceNumVerts(f);
2723
2724                 if (faceFlags) {
2725                         drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH));
2726                         new_matnr = faceFlags[index].mat_nr + 1;
2727                 }
2728                 else {
2729                         drawSmooth = 1;
2730                         new_matnr = 1;
2731                 }
2732
2733                 if (lnors) {
2734                         ln = lnors;
2735                         lnors += gridFaces * gridFaces * numVerts;
2736                 }
2737
2738                 if (new_matnr != matnr) {
2739                         do_draw = setMaterial(matnr = new_matnr, &gattribs);
2740                         if (do_draw)
2741                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
2742                 }
2743
2744                 if (!do_draw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) &&
2745                                 (setDrawOptions(userData, origIndex) == DM_DRAW_OPTION_SKIP)))
2746                 {
2747                         a += gridFaces * gridFaces * numVerts;
2748                         continue;
2749                 }
2750
2751                 glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT);
2752                 for (S = 0; S < numVerts; S++) {
2753                         CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2754                         CCGElem *vda, *vdb;
2755
2756                         if (ln) {
2757                                 glBegin(GL_QUADS);
2758                                 for (y = 0; y < gridFaces; y++) {
2759                                         for (x = 0; x < gridFaces; x++) {
2760                                                 float *aco = CCG_grid_elem_co(&key, faceGridData, x, y);
2761                                                 float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y);
2762                                                 float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
2763                                                 float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
2764
2765                                                 PASSATTRIB(0, 1, 1);
2766                                                 glNormal3sv(ln[0][1]);
2767                                                 glVertex3fv(dco);
2768                                                 PASSATTRIB(1, 1, 2);
2769                                                 glNormal3sv(ln[0][2]);
2770                                                 glVertex3fv(cco);
2771                                                 PASSATTRIB(1, 0, 3);
2772                                                 glNormal3sv(ln[0][3]);
2773                                                 glVertex3fv(bco);
2774                                                 PASSATTRIB(0, 0, 0);
2775                                                 glNormal3sv(ln[0][0]);
2776                                                 glVertex3fv(aco);
2777
2778                                                 ln++;
2779                                                 a++;
2780                                         }
2781                                 }
2782                                 glEnd();
2783                         }
2784                         else if (drawSmooth) {
2785                                 for (y = 0; y < gridFaces; y++) {
2786                                         glBegin(GL_QUAD_STRIP);
2787                                         for (x = 0; x < gridFaces; x++) {
2788                                                 vda = CCG_grid_elem(&key, faceGridData, x, y + 0);
2789                                                 vdb = CCG_grid_elem(&key, faceGridData, x, y + 1);
2790                                                 
2791                                                 PASSATTRIB(0, 0, 0);
2792                                                 glNormal3fv(CCG_elem_no(&key, vda));
2793                                                 glVertex3fv(CCG_elem_co(&key, vda));
2794
2795                                                 PASSATTRIB(0, 1, 1);
2796                                                 glNormal3fv(CCG_elem_no(&key, vdb));
2797                                                 glVertex3fv(CCG_elem_co(&key, vdb));
2798
2799                                                 if (x != gridFaces - 1)
2800                                                         a++;
2801                                         }
2802
2803                                         vda = CCG_grid_elem(&key, faceGridData, x, y + 0);
2804                                         vdb = CCG_grid_elem(&key, faceGridData, x, y + 1);
2805
2806                                         PASSATTRIB(0, 0, 3);
2807                                         glNormal3fv(CCG_elem_no(&key, vda));
2808                                         glVertex3fv(CCG_elem_co(&key, vda));
2809
2810                                         PASSATTRIB(0, 1, 2);
2811                                         glNormal3fv(CCG_elem_no(&key, vdb));
2812                                         glVertex3fv(CCG_elem_co(&key, vdb));
2813
2814                                         glEnd();
2815
2816                                         a++;
2817                                 }
2818                         }
2819                         else {
2820                                 glBegin(GL_QUADS);
2821                                 for (y = 0; y < gridFaces; y++) {
2822                                         for (x = 0; x < gridFaces; x++) {
2823                                                 float *aco = CCG_grid_elem_co(&key, faceGridData, x, y);
2824                                                 float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y);
2825                                                 float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
2826                                                 float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
2827
2828                                                 ccgDM_glNormalFast(aco, bco, cco, dco);
2829
2830                                                 PASSATTRIB(0, 1, 1);
2831                                                 glVertex3fv(dco);
2832                                                 PASSATTRIB(1, 1, 2);
2833                                                 glVertex3fv(cco);
2834                                                 PASSATTRIB(1, 0, 3);
2835                                                 glVertex3fv(bco);
2836                                                 PASSATTRIB(0, 0, 0);
2837                                                 glVertex3fv(aco);
2838                                                 
2839                                                 a++;
2840                                         }
2841                                 }
2842                                 glEnd();
2843                         }
2844                 }
2845         }
2846
2847 #undef PASSATTRIB
2848 }
2849
2850 static void ccgDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial)
2851 {
2852         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
2853 }
2854
2855 /* Only used by non-editmesh types */
2856 static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
2857                                      void (*setMaterial)(void *userData, int matnr, void *attribs),
2858                                      bool (*setFace)(void *userData, int index), void *userData)
2859 {
2860         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2861         CCGSubSurf *ss = ccgdm->ss;
2862         CCGKey key;
2863         GPUVertexAttribs gattribs;
2864         DMVertexAttribs attribs = {{{NULL}}};
2865         int gridSize = ccgSubSurf_getGridSize(ss);
2866         int gridFaces = gridSize - 1;
2867         int edgeSize = ccgSubSurf_getEdgeSize(ss);
2868         DMFlagMat *faceFlags = ccgdm->faceFlags;
2869         short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
2870         int a, i, numVerts, matnr, new_matnr, totface;
2871
2872 #ifdef WITH_OPENSUBDIV
2873         if (ccgdm->useGpuBackend) {
2874                 BLI_assert(!"Not currently supported");
2875                 return;
2876         }
2877 #endif
2878
2879         CCG_key_top_level(&key, ss);
2880         ccgdm_pbvh_update(ccgdm);
2881
2882         matnr = -1;
2883
2884 #define PASSATTRIB(dx, dy, vert) {                                            \
2885         if (attribs.totorco)                                                      \
2886                 index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize);   \
2887         else                                                                      \
2888                 index = 0;                                                            \
2889         DM_draw_attrib_vertex(&attribs, a, index, vert, ((a) * 4) + vert);          \
2890 } (void)0
2891
2892         totface = ccgSubSurf_getNumFaces(ss);
2893         for (a = 0, i = 0; i < totface; i++) {
2894                 CCGFace *f = ccgdm->faceMap[i].face;
2895                 short (*ln)[4][3] = NULL;
2896                 int S, x, y, drawSmooth;
2897                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
2898                 int origIndex = ccgDM_getFaceMapIndex(ss, f);
2899                 
2900                 numVerts = ccgSubSurf_getFaceNumVerts(f);
2901
2902                 /* get flags */
2903                 if (faceFlags) {
2904                         drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH));
2905                         new_matnr = faceFlags[index].mat_nr + 1;
2906                 }
2907                 else {
2908                         drawSmooth = 1;
2909                         new_matnr = 1;
2910                 }
2911
2912                 if (lnors) {
2913                         ln = lnors;
2914                         lnors += gridFaces * gridFaces * numVerts;
2915                 }
2916
2917                 /* material */
2918                 if (new_matnr != matnr) {
2919                         setMaterial(userData, matnr = new_matnr, &gattribs);
2920                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
2921                 }
2922
2923                 /* face hiding */
2924                 if ((setFace && (origIndex != ORIGINDEX_NONE) && !setFace(userData, origIndex))) {
2925                         a += gridFaces * gridFaces * numVerts;
2926                         continue;
2927                 }
2928
2929                 /* draw face*/
2930                 glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT);
2931                 for (S = 0; S < numVerts; S++) {
2932                         CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2933                         CCGElem *vda, *vdb;
2934
2935                         if (ln) {
2936                                 glBegin(GL_QUADS);
2937                                 for (y = 0; y < gridFaces; y++) {
2938                                         for (x = 0; x < gridFaces; x++) {
2939                                                 float *aco = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
2940                                                 float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
2941                                                 float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
2942                                                 float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
2943
2944                                                 PASSATTRIB(0, 1, 1);
2945                                                 glNormal3sv(ln[0][1]);
2946                                                 glVertex3fv(dco);
2947                                                 PASSATTRIB(1, 1, 2);
2948                                                 glNormal3sv(ln[0][2]);
2949                                                 glVertex3fv(cco);
2950                                                 PASSATTRIB(1, 0, 3);
2951                                                 glNormal3sv(ln[0][3]);
2952                                                 glVertex3fv(bco);
2953                                                 PASSATTRIB(0, 0, 0);
2954                                                 glNormal3sv(ln[0][0]);
2955                                                 glVertex3fv(aco);
2956
2957                                                 ln++;
2958                                                 a++;
2959                                         }
2960                                 }
2961                                 glEnd();
2962                         }
2963                         else if (drawSmooth) {
2964                                 for (y = 0; y < gridFaces; y++) {
2965                                         glBegin(GL_QUAD_STRIP);
2966