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