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