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