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