c777fcd5e7b5aa31c2d710730ab73cb6adcfb916
[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                         
1063                         if (!md->hidden)
1064                                 continue;
1065                         
1066                         for (y = 0; y < gridSize; y++) {
1067                                 for (x = 0; x < gridSize; x++) {
1068                                         int vndx, offset;
1069                                         
1070                                         vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
1071                                         offset = (y * factor) * hidden_gridsize + (x * factor);
1072                                         if (BLI_BITMAP_TEST(md->hidden, offset))
1073                                                 mvert[vndx].flag |= ME_HIDE;
1074                                 }
1075                         }
1076                 }
1077         }
1078 }
1079
1080 /* Translate GridPaintMask into vertex paint masks. Assumes vertices
1081  * are in the order output by ccgDM_copyFinalVertArray. */
1082 void subsurf_copy_grid_paint_mask(DerivedMesh *dm, const MPoly *mpoly,
1083                                   float *paint_mask,
1084                                   const GridPaintMask *grid_paint_mask)
1085 {
1086         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1087         CCGSubSurf *ss = ccgdm->ss;
1088         int level = ccgSubSurf_getSubdivisionLevels(ss);
1089         int gridSize = ccgSubSurf_getGridSize(ss);
1090         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1091         int totface = ccgSubSurf_getNumFaces(ss);
1092         int i, j, x, y, factor, gpm_gridsize;
1093         
1094         for (i = 0; i < totface; i++) {
1095                 CCGFace *f = ccgdm->faceMap[i].face;
1096                 const MPoly *p = &mpoly[i];
1097                 
1098                 for (j = 0; j < p->totloop; j++) {
1099                         const GridPaintMask *gpm = &grid_paint_mask[p->loopstart + j];
1100                         if (!gpm->data)
1101                                 continue;
1102
1103                         factor = BKE_ccg_factor(level, gpm->level);
1104                         gpm_gridsize = BKE_ccg_gridsize(gpm->level);
1105                         
1106                         for (y = 0; y < gridSize; y++) {
1107                                 for (x = 0; x < gridSize; x++) {
1108                                         int vndx, offset;
1109                                         
1110                                         vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
1111                                         offset = y * factor * gpm_gridsize + x * factor;
1112                                         paint_mask[vndx] = gpm->data[offset];
1113                                 }
1114                         }
1115                 }
1116         }
1117 }
1118
1119 /* utility functon */
1120 BLI_INLINE void ccgDM_to_MVert(MVert *mv, const CCGKey *key, CCGElem *elem)
1121 {
1122         copy_v3_v3(mv->co, CCG_elem_co(key, elem));
1123         normal_float_to_short_v3(mv->no, CCG_elem_no(key, elem));
1124         mv->flag = mv->bweight = 0;
1125 }
1126
1127 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
1128 {
1129         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1130         CCGSubSurf *ss = ccgdm->ss;
1131         CCGElem *vd;
1132         CCGKey key;
1133         int index;
1134         int totvert, totedge, totface;
1135         int gridSize = ccgSubSurf_getGridSize(ss);
1136         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1137         unsigned int i = 0;
1138
1139         CCG_key_top_level(&key, ss);
1140
1141         totface = ccgSubSurf_getNumFaces(ss);
1142         for (index = 0; index < totface; index++) {
1143                 CCGFace *f = ccgdm->faceMap[index].face;
1144                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1145
1146                 vd = ccgSubSurf_getFaceCenterData(f);
1147                 ccgDM_to_MVert(&mvert[i++], &key, vd);
1148                 
1149                 for (S = 0; S < numVerts; S++) {
1150                         for (x = 1; x < gridSize - 1; x++) {
1151                                 vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
1152                                 ccgDM_to_MVert(&mvert[i++], &key, vd);
1153                         }
1154                 }
1155
1156                 for (S = 0; S < numVerts; S++) {
1157                         for (y = 1; y < gridSize - 1; y++) {
1158                                 for (x = 1; x < gridSize - 1; x++) {
1159                                         vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y);
1160                                         ccgDM_to_MVert(&mvert[i++], &key, vd);
1161                                 }
1162                         }
1163                 }
1164         }
1165
1166         totedge = ccgSubSurf_getNumEdges(ss);
1167         for (index = 0; index < totedge; index++) {
1168                 CCGEdge *e = ccgdm->edgeMap[index].edge;
1169                 int x;
1170
1171                 for (x = 1; x < edgeSize - 1; x++) {
1172                         /* This gives errors with -debug-fpe
1173                          * the normals don't seem to be unit length.
1174                          * this is most likely caused by edges with no
1175                          * faces which are now zerod out, see comment in:
1176                          * ccgSubSurf__calcVertNormals(), - campbell */
1177                         vd = ccgSubSurf_getEdgeData(ss, e, x);
1178                         ccgDM_to_MVert(&mvert[i++], &key, vd);
1179                 }
1180         }
1181
1182         totvert = ccgSubSurf_getNumVerts(ss);
1183         for (index = 0; index < totvert; index++) {
1184                 CCGVert *v = ccgdm->vertMap[index].vert;
1185
1186                 vd = ccgSubSurf_getVertData(ss, v);
1187                 ccgDM_to_MVert(&mvert[i++], &key, vd);
1188         }
1189 }
1190
1191
1192 /* utility functon */
1193 BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2, const short flag)
1194 {
1195         med->v1 = v1;
1196         med->v2 = v2;
1197         med->crease = med->bweight = 0;
1198         med->flag = flag;
1199 }
1200
1201 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
1202 {
1203         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1204         CCGSubSurf *ss = ccgdm->ss;
1205         int index;
1206         int totedge, totface;
1207         int gridSize = ccgSubSurf_getGridSize(ss);
1208         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1209         unsigned int i = 0;
1210         short *edgeFlags = ccgdm->edgeFlags;
1211         const short ed_interior_flag = ccgdm->drawInteriorEdges ? (ME_EDGEDRAW | ME_EDGERENDER) : 0;
1212
1213         totface = ccgSubSurf_getNumFaces(ss);
1214         for (index = 0; index < totface; index++) {
1215                 CCGFace *f = ccgdm->faceMap[index].face;
1216                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1217
1218                 for (S = 0; S < numVerts; S++) {
1219                         for (x = 0; x < gridSize - 1; x++) {
1220                                 ccgDM_to_MEdge(&medge[i++],
1221                                                getFaceIndex(ss, f, S, x,     0, edgeSize, gridSize),
1222                                                getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize),
1223                                                ed_interior_flag);
1224                         }
1225
1226                         for (x = 1; x < gridSize - 1; x++) {
1227                                 for (y = 0; y < gridSize - 1; y++) {
1228                                         ccgDM_to_MEdge(&medge[i++],
1229                                                        getFaceIndex(ss, f, S, x, y,    edgeSize, gridSize),
1230                                                        getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize),
1231                                                        ed_interior_flag);
1232                                         ccgDM_to_MEdge(&medge[i++],
1233                                                        getFaceIndex(ss, f, S, y, x,     edgeSize, gridSize),
1234                                                        getFaceIndex(ss, f, S, y + 1, x, edgeSize, gridSize),
1235                                                        ed_interior_flag);
1236                                 }
1237                         }
1238                 }
1239         }
1240
1241         totedge = ccgSubSurf_getNumEdges(ss);
1242         for (index = 0; index < totedge; index++) {
1243                 CCGEdge *e = ccgdm->edgeMap[index].edge;
1244                 short ed_flag = 0;
1245                 int x;
1246                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
1247
1248                 if (!ccgSubSurf_getEdgeNumFaces(e)) {
1249                         ed_flag |= ME_LOOSEEDGE;
1250                 }
1251
1252                 if (edgeFlags) {
1253                         if (edgeIdx != -1) {
1254                                 ed_flag |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER);
1255                         }
1256                 }
1257                 else {
1258                         ed_flag |= ME_EDGEDRAW | ME_EDGERENDER;
1259                 }
1260
1261                 for (x = 0; x < edgeSize - 1; x++) {
1262                         ccgDM_to_MEdge(&medge[i++],
1263                                        getEdgeIndex(ss, e, x, edgeSize),
1264                                        getEdgeIndex(ss, e, x + 1, edgeSize),
1265                                        ed_flag);
1266                 }
1267         }
1268 }
1269
1270 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
1271 {
1272         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1273         CCGSubSurf *ss = ccgdm->ss;
1274         int index;
1275         int totface;
1276         int gridSize = ccgSubSurf_getGridSize(ss);
1277         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1278         int i = 0;
1279         DMFlagMat *faceFlags = ccgdm->faceFlags;
1280
1281         totface = ccgSubSurf_getNumFaces(ss);
1282         for (index = 0; index < totface; index++) {
1283                 CCGFace *f = ccgdm->faceMap[index].face;
1284                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1285                 /* keep types in sync with MFace, avoid many conversions */
1286                 char flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH;
1287                 short mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0;
1288
1289                 for (S = 0; S < numVerts; S++) {
1290                         for (y = 0; y < gridSize - 1; y++) {
1291                                 for (x = 0; x < gridSize - 1; x++) {
1292                                         MFace *mf = &mface[i];
1293                                         mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1294                                                               edgeSize, gridSize);
1295                                         mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1296                                                               edgeSize, gridSize);
1297                                         mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1298                                                               edgeSize, gridSize);
1299                                         mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1300                                                               edgeSize, gridSize);
1301                                         mf->mat_nr = mat_nr;
1302                                         mf->flag = flag;
1303                                         mf->edcode = 0;
1304
1305                                         i++;
1306                                 }
1307                         }
1308                 }
1309         }
1310 }
1311
1312 static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
1313 {
1314         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1315         CCGSubSurf *ss = ccgdm->ss;
1316         int index;
1317         int totface;
1318         int gridSize = ccgSubSurf_getGridSize(ss);
1319         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1320         int i = 0;
1321         MLoop *mv;
1322         /* DMFlagMat *faceFlags = ccgdm->faceFlags; */ /* UNUSED */
1323
1324         if (!ccgdm->ehash) {
1325                 BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE);
1326                 if (!ccgdm->ehash) {
1327                         MEdge *medge;
1328
1329                         ccgdm->ehash = BLI_edgehash_new_ex(__func__, ccgdm->dm.numEdgeData);
1330                         medge = ccgdm->dm.getEdgeArray((DerivedMesh *)ccgdm);
1331
1332                         for (i = 0; i < ccgdm->dm.numEdgeData; i++) {
1333                                 BLI_edgehash_insert(ccgdm->ehash, medge[i].v1, medge[i].v2, SET_INT_IN_POINTER(i));
1334                         }
1335                 }
1336                 BLI_rw_mutex_unlock(&loops_cache_rwlock);
1337         }
1338
1339         BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_READ);
1340         totface = ccgSubSurf_getNumFaces(ss);
1341         mv = mloop;
1342         for (index = 0; index < totface; index++) {
1343                 CCGFace *f = ccgdm->faceMap[index].face;
1344                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1345                 /* int flag = (faceFlags) ? faceFlags[index * 2]: ME_SMOOTH; */ /* UNUSED */
1346                 /* int mat_nr = (faceFlags) ? faceFlags[index * 2 + 1]: 0; */ /* UNUSED */
1347
1348                 for (S = 0; S < numVerts; S++) {
1349                         for (y = 0; y < gridSize - 1; y++) {
1350                                 for (x = 0; x < gridSize - 1; x++) {
1351                                         unsigned int v1, v2, v3, v4;
1352
1353                                         v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1354                                                           edgeSize, gridSize);
1355
1356                                         v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1357                                                           edgeSize, gridSize);
1358                                         v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1359                                                           edgeSize, gridSize);
1360                                         v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1361                                                           edgeSize, gridSize);
1362
1363                                         mv->v = v1;
1364                                         mv->e = GET_UINT_FROM_POINTER(BLI_edgehash_lookup(ccgdm->ehash, v1, v2));
1365                                         mv++, i++;
1366
1367                                         mv->v = v2;
1368                                         mv->e = GET_UINT_FROM_POINTER(BLI_edgehash_lookup(ccgdm->ehash, v2, v3));
1369                                         mv++, i++;
1370
1371                                         mv->v = v3;
1372                                         mv->e = GET_UINT_FROM_POINTER(BLI_edgehash_lookup(ccgdm->ehash, v3, v4));
1373                                         mv++, i++;
1374
1375                                         mv->v = v4;
1376                                         mv->e = GET_UINT_FROM_POINTER(BLI_edgehash_lookup(ccgdm->ehash, v4, v1));
1377                                         mv++, i++;
1378                                 }
1379                         }
1380                 }
1381         }
1382         BLI_rw_mutex_unlock(&loops_cache_rwlock);
1383 }
1384
1385 static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mpoly)
1386 {
1387         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1388         CCGSubSurf *ss = ccgdm->ss;
1389         int index;
1390         int totface;
1391         int gridSize = ccgSubSurf_getGridSize(ss);
1392         /* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */
1393         int i = 0, k = 0;
1394         DMFlagMat *faceFlags = ccgdm->faceFlags;
1395
1396         totface = ccgSubSurf_getNumFaces(ss);
1397         for (index = 0; index < totface; index++) {
1398                 CCGFace *f = ccgdm->faceMap[index].face;
1399                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1400                 int flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH;
1401                 int mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0;
1402
1403                 for (S = 0; S < numVerts; S++) {
1404                         for (y = 0; y < gridSize - 1; y++) {
1405                                 for (x = 0; x < gridSize - 1; x++) {
1406                                         MPoly *mp = &mpoly[i];
1407
1408                                         mp->mat_nr = mat_nr;
1409                                         mp->flag = flag;
1410                                         mp->loopstart = k;
1411                                         mp->totloop = 4;
1412
1413                                         k += 4;
1414                                         i++;
1415                                 }
1416                         }
1417                 }
1418         }
1419 }
1420
1421 static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3])
1422 {
1423         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1424         CCGSubSurf *ss = ccgdm->ss;
1425         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1426         int gridSize = ccgSubSurf_getGridSize(ss);
1427         int i;
1428         CCGVertIterator vi;
1429         CCGEdgeIterator ei;
1430         CCGFaceIterator fi;
1431         CCGFace **faceMap2;
1432         CCGEdge **edgeMap2;
1433         CCGVert **vertMap2;
1434         int index, totvert, totedge, totface;
1435         
1436         totvert = ccgSubSurf_getNumVerts(ss);
1437         vertMap2 = MEM_mallocN(totvert * sizeof(*vertMap2), "vertmap");
1438         for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
1439                 CCGVert *v = ccgVertIterator_getCurrent(&vi);
1440
1441                 vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v;
1442         }
1443
1444         totedge = ccgSubSurf_getNumEdges(ss);
1445         edgeMap2 = MEM_mallocN(totedge * sizeof(*edgeMap2), "edgemap");
1446         for (ccgSubSurf_initEdgeIterator(ss, &ei), i = 0; !ccgEdgeIterator_isStopped(&ei); i++, ccgEdgeIterator_next(&ei)) {
1447                 CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
1448
1449                 edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
1450         }
1451
1452         totface = ccgSubSurf_getNumFaces(ss);
1453         faceMap2 = MEM_mallocN(totface * sizeof(*faceMap2), "facemap");
1454         for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
1455                 CCGFace *f = ccgFaceIterator_getCurrent(&fi);
1456
1457                 faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))] = f;
1458         }
1459
1460         i = 0;
1461         for (index = 0; index < totface; index++) {
1462                 CCGFace *f = faceMap2[index];
1463                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1464
1465                 copy_v3_v3(cos[i++], ccgSubSurf_getFaceCenterData(f));
1466                 
1467                 for (S = 0; S < numVerts; S++) {
1468                         for (x = 1; x < gridSize - 1; x++) {
1469                                 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1470                         }
1471                 }
1472
1473                 for (S = 0; S < numVerts; S++) {
1474                         for (y = 1; y < gridSize - 1; y++) {
1475                                 for (x = 1; x < gridSize - 1; x++) {
1476                                         copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1477                                 }
1478                         }
1479                 }
1480         }
1481
1482         for (index = 0; index < totedge; index++) {
1483                 CCGEdge *e = edgeMap2[index];
1484                 int x;
1485
1486                 for (x = 1; x < edgeSize - 1; x++) {
1487                         copy_v3_v3(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
1488                 }
1489         }
1490
1491         for (index = 0; index < totvert; index++) {
1492                 CCGVert *v = vertMap2[index];
1493                 copy_v3_v3(cos[i++], ccgSubSurf_getVertData(ss, v));
1494         }
1495
1496         MEM_freeN(vertMap2);
1497         MEM_freeN(edgeMap2);
1498         MEM_freeN(faceMap2);
1499 }
1500
1501 static void ccgDM_foreachMappedVert(
1502         DerivedMesh *dm,
1503         void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
1504         void *userData,
1505         DMForeachFlag flag)
1506 {
1507         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1508         CCGVertIterator vi;
1509         CCGKey key;
1510         CCG_key_top_level(&key, ccgdm->ss);
1511
1512         for (ccgSubSurf_initVertIterator(ccgdm->ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
1513                 CCGVert *v = ccgVertIterator_getCurrent(&vi);
1514                 const int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
1515
1516                 if (index != -1) {
1517                         CCGElem *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
1518                         const float *no = (flag & DM_FOREACH_USE_NORMAL) ? CCG_elem_no(&key, vd) : NULL;
1519                         func(userData, index, CCG_elem_co(&key, vd), no, NULL);
1520                 }
1521         }
1522 }
1523
1524 static void ccgDM_foreachMappedEdge(
1525         DerivedMesh *dm,
1526         void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
1527         void *userData)
1528 {
1529         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1530         CCGSubSurf *ss = ccgdm->ss;
1531         CCGEdgeIterator ei;
1532         CCGKey key;
1533         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1534
1535         CCG_key_top_level(&key, ss);
1536
1537         for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
1538                 CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
1539                 const int index = ccgDM_getEdgeMapIndex(ss, e);
1540
1541                 if (index != -1) {
1542                         CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1543                         for (i = 0; i < edgeSize - 1; i++) {
1544                                 func(userData, index, CCG_elem_offset_co(&key, edgeData, i), CCG_elem_offset_co(&key, edgeData, i + 1));
1545                         }
1546                 }
1547         }
1548 }
1549
1550 static void ccgDM_foreachMappedLoop(
1551         DerivedMesh *dm,
1552         void (*func)(void *userData, int vertex_index, int face_index, const float co[3], const float no[3]),
1553         void *userData,
1554         DMForeachFlag flag)
1555 {
1556         /* We can't use dm->getLoopDataLayout(dm) here, we want to always access dm->loopData, EditDerivedBMesh would
1557          * return loop data from bmesh itself. */
1558         const float (*lnors)[3] = (flag & DM_FOREACH_USE_NORMAL) ? DM_get_loop_data_layer(dm, CD_NORMAL) : NULL;
1559
1560         MVert *mv = dm->getVertArray(dm);
1561         MLoop *ml = dm->getLoopArray(dm);
1562         MPoly *mp = dm->getPolyArray(dm);
1563         const int *v_index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1564         const int *f_index = dm->getPolyDataArray(dm, CD_ORIGINDEX);
1565         int p_idx, i;
1566
1567         for (p_idx = 0; p_idx < dm->numPolyData; ++p_idx, ++mp) {
1568                 for (i = 0; i < mp->totloop; ++i, ++ml) {
1569                         const int v_idx = v_index ? v_index[ml->v] : ml->v;
1570                         const int f_idx = f_index ? f_index[p_idx] : p_idx;
1571                         const float *no = lnors ? *lnors++ : NULL;
1572                         if (!ELEM(ORIGINDEX_NONE, v_idx, f_idx)) {
1573                                 func(userData, v_idx, f_idx, mv[ml->v].co, no);
1574                         }
1575                 }
1576         }
1577 }
1578
1579 static void ccgDM_drawVerts(DerivedMesh *dm)
1580 {
1581         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1582         CCGSubSurf *ss = ccgdm->ss;
1583         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1584         int gridSize = ccgSubSurf_getGridSize(ss);
1585         CCGVertIterator vi;
1586         CCGEdgeIterator ei;
1587         CCGFaceIterator fi;
1588
1589         glBegin(GL_POINTS);
1590         for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
1591                 CCGVert *v = ccgVertIterator_getCurrent(&vi);
1592                 glVertex3fv(ccgSubSurf_getVertData(ss, v));
1593         }
1594
1595         for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
1596                 CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
1597                 int x;
1598
1599                 for (x = 1; x < edgeSize - 1; x++)
1600                         glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
1601         }
1602
1603         for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
1604                 CCGFace *f = ccgFaceIterator_getCurrent(&fi);
1605                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1606
1607                 glVertex3fv(ccgSubSurf_getFaceCenterData(f));
1608                 for (S = 0; S < numVerts; S++)
1609                         for (x = 1; x < gridSize - 1; x++)
1610                                 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1611                 for (S = 0; S < numVerts; S++)
1612                         for (y = 1; y < gridSize - 1; y++)
1613                                 for (x = 1; x < gridSize - 1; x++)
1614                                         glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1615         }
1616         glEnd();
1617 }
1618
1619 static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
1620 {
1621         if (ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
1622                 CCGFace **faces;
1623                 int totface;
1624
1625                 BKE_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void ***)&faces, &totface);
1626                 if (totface) {
1627                         ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface);
1628                         ccgSubSurf_updateNormals(ccgdm->ss, faces, totface);
1629                         MEM_freeN(faces);
1630                 }
1631         }
1632 }
1633
1634 static void ccgDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges)
1635 {
1636         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1637         CCGSubSurf *ss = ccgdm->ss;
1638         CCGKey key;
1639         int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1640         int totedge = ccgSubSurf_getNumEdges(ss);
1641         int gridSize = ccgSubSurf_getGridSize(ss);
1642         int useAging;
1643
1644         CCG_key_top_level(&key, ss);
1645         ccgdm_pbvh_update(ccgdm);
1646
1647         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1648
1649         for (j = 0; j < totedge; j++) {
1650                 CCGEdge *e = ccgdm->edgeMap[j].edge;
1651                 CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1652
1653                 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e))
1654                         continue;
1655
1656                 if (!drawAllEdges && ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW))
1657                         continue;
1658
1659                 if (useAging && !(G.f & G_BACKBUFSEL)) {
1660                         int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e) * 4;
1661                         glColor3ub(0, ageCol > 0 ? ageCol : 0, 0);
1662                 }
1663
1664                 glBegin(GL_LINE_STRIP);
1665                 for (i = 0; i < edgeSize - 1; i++) {
1666                         glVertex3fv(CCG_elem_offset_co(&key, edgeData, i));
1667                         glVertex3fv(CCG_elem_offset_co(&key, edgeData, i + 1));
1668                 }
1669                 glEnd();
1670         }
1671
1672         if (useAging && !(G.f & G_BACKBUFSEL)) {
1673                 glColor3ub(0, 0, 0);
1674         }
1675
1676         if (ccgdm->drawInteriorEdges) {
1677                 int totface = ccgSubSurf_getNumFaces(ss);
1678
1679                 for (j = 0; j < totface; j++) {
1680                         CCGFace *f = ccgdm->faceMap[j].face;
1681                         int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1682
1683                         for (S = 0; S < numVerts; S++) {
1684                                 CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1685
1686                                 glBegin(GL_LINE_STRIP);
1687                                 for (x = 0; x < gridSize; x++)
1688                                         glVertex3fv(CCG_elem_offset_co(&key, faceGridData, x));
1689                                 glEnd();
1690                                 for (y = 1; y < gridSize - 1; y++) {
1691                                         glBegin(GL_LINE_STRIP);
1692                                         for (x = 0; x < gridSize; x++)
1693                                                 glVertex3fv(CCG_grid_elem_co(&key, faceGridData, x, y));
1694                                         glEnd();
1695                                 }
1696                                 for (x = 1; x < gridSize - 1; x++) {
1697                                         glBegin(GL_LINE_STRIP);
1698                                         for (y = 0; y < gridSize; y++)
1699                                                 glVertex3fv(CCG_grid_elem_co(&key, faceGridData, x, y));
1700                                         glEnd();
1701                                 }
1702                         }
1703                 }
1704         }
1705 }
1706
1707 static void ccgDM_drawLooseEdges(DerivedMesh *dm)
1708 {
1709         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1710         CCGSubSurf *ss = ccgdm->ss;
1711         CCGKey key;
1712         int totedge = ccgSubSurf_getNumEdges(ss);
1713         int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1714
1715         CCG_key_top_level(&key, ss);
1716
1717         for (j = 0; j < totedge; j++) {
1718                 CCGEdge *e = ccgdm->edgeMap[j].edge;
1719                 CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1720
1721                 if (!ccgSubSurf_getEdgeNumFaces(e)) {
1722                         glBegin(GL_LINE_STRIP);
1723                         for (i = 0; i < edgeSize - 1; i++) {
1724                                 glVertex3fv(CCG_elem_offset_co(&key, edgeData, i));
1725                                 glVertex3fv(CCG_elem_offset_co(&key, edgeData, i + 1));
1726                         }
1727                         glEnd();
1728                 }
1729         }
1730 }
1731
1732 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
1733 {
1734         float a_cX = c[0] - a[0], a_cY = c[1] - a[1], a_cZ = c[2] - a[2];
1735         float b_dX = d[0] - b[0], b_dY = d[1] - b[1], b_dZ = d[2] - b[2];
1736         float no[3];
1737
1738         no[0] = b_dY * a_cZ - b_dZ * a_cY;
1739         no[1] = b_dZ * a_cX - b_dX * a_cZ;
1740         no[2] = b_dX * a_cY - b_dY * a_cX;
1741
1742         /* don't normalize, GL_NORMALIZE is enabled */
1743         glNormal3fv(no);
1744 }
1745
1746 /* Only used by non-editmesh types */
1747 static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], bool fast, DMSetMaterial setMaterial)
1748 {
1749         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1750         CCGSubSurf *ss = ccgdm->ss;
1751         CCGKey key;
1752         short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
1753         int gridSize = ccgSubSurf_getGridSize(ss);
1754         int gridFaces = gridSize - 1;
1755         DMFlagMat *faceFlags = ccgdm->faceFlags;
1756         int step = (fast) ? gridSize - 1 : 1;
1757         int i, totface = ccgSubSurf_getNumFaces(ss);
1758         int drawcurrent = 0, matnr = -1, shademodel = -1;
1759
1760         CCG_key_top_level(&key, ss);
1761         ccgdm_pbvh_update(ccgdm);
1762
1763         if (ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
1764                 if (dm->numTessFaceData) {
1765                         BKE_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL,
1766                                       setMaterial, false);
1767                         glShadeModel(GL_FLAT);
1768                 }
1769
1770                 return;
1771         }
1772
1773         for (i = 0; i < totface; i++) {
1774                 CCGFace *f = ccgdm->faceMap[i].face;
1775                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1776                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
1777                 int new_matnr, new_shademodel;
1778                 short (*ln)[4][3] = NULL;
1779
1780                 if (faceFlags) {
1781                         new_shademodel = (lnors || (faceFlags[index].flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT;
1782                         new_matnr = faceFlags[index].mat_nr;
1783                 }
1784                 else {
1785                         new_shademodel = GL_SMOOTH;
1786                         new_matnr = 0;
1787                 }
1788
1789                 if (lnors) {
1790                         ln = lnors;
1791                         lnors += gridFaces * gridFaces * numVerts;
1792                 }
1793
1794                 if (shademodel != new_shademodel || matnr != new_matnr) {
1795                         matnr = new_matnr;
1796                         shademodel = new_shademodel;
1797
1798                         if (setMaterial)
1799                                 drawcurrent = setMaterial(matnr + 1, NULL);
1800                         else
1801                                 drawcurrent = 1;
1802
1803                         glShadeModel(shademodel);
1804                 }
1805
1806                 if (!drawcurrent)
1807                         continue;
1808
1809                 for (S = 0; S < numVerts; S++) {
1810                         CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1811
1812                         if (ln) {
1813                                 /* Can't use quad strips here... */
1814                                 glBegin(GL_QUADS);
1815                                 for (y = 0; y < gridFaces; y += step) {
1816                                         for (x = 0; x < gridFaces; x += step) {
1817                                                 float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
1818                                                 float *b = CCG_grid_elem_co(&key, faceGridData, x + step, y + 0);
1819                                                 float *c = CCG_grid_elem_co(&key, faceGridData, x + step, y + step);
1820                                                 float *d = CCG_grid_elem_co(&key, faceGridData, x, y + step);
1821
1822                                                 glNormal3sv(ln[0][1]);
1823                                                 glVertex3fv(d);
1824                                                 glNormal3sv(ln[0][2]);
1825                                                 glVertex3fv(c);
1826                                                 glNormal3sv(ln[0][3]);
1827                                                 glVertex3fv(b);
1828                                                 glNormal3sv(ln[0][0]);
1829                                                 glVertex3fv(a);
1830                                                 ln += step;
1831                                         }
1832                                 }
1833                                 glEnd();
1834                         }
1835                         else if (shademodel == GL_SMOOTH) {
1836                                 for (y = 0; y < gridFaces; y += step) {
1837                                         glBegin(GL_QUAD_STRIP);
1838                                         for (x = 0; x < gridSize; x += step) {
1839                                                 CCGElem *a = CCG_grid_elem(&key, faceGridData, x, y + 0);
1840                                                 CCGElem *b = CCG_grid_elem(&key, faceGridData, x, y + step);
1841
1842                                                 glNormal3fv(CCG_elem_no(&key, a));
1843                                                 glVertex3fv(CCG_elem_co(&key, a));
1844                                                 glNormal3fv(CCG_elem_no(&key, b));
1845                                                 glVertex3fv(CCG_elem_co(&key, b));
1846                                         }
1847                                         glEnd();
1848                                 }
1849                         }
1850                         else {
1851                                 glBegin(GL_QUADS);
1852                                 for (y = 0; y < gridFaces; y += step) {
1853                                         for (x = 0; x < gridFaces; x += step) {
1854                                                 float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
1855                                                 float *b = CCG_grid_elem_co(&key, faceGridData, x + step, y + 0);
1856                                                 float *c = CCG_grid_elem_co(&key, faceGridData, x + step, y + step);
1857                                                 float *d = CCG_grid_elem_co(&key, faceGridData, x, y + step);
1858
1859                                                 ccgDM_glNormalFast(a, b, c, d);
1860
1861                                                 glVertex3fv(d);
1862                                                 glVertex3fv(c);
1863                                                 glVertex3fv(b);
1864                                                 glVertex3fv(a);
1865                                         }
1866                                 }
1867                                 glEnd();
1868                         }
1869                 }
1870         }
1871 }
1872
1873 static void ccgdm_draw_attrib_vertex(DMVertexAttribs *attribs, int a, int index, int vert)
1874 {
1875         const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1876         int b;
1877
1878         /* orco texture coordinates */
1879         if (attribs->totorco) {
1880                 /*const*/ float (*array)[3] = attribs->orco.array;
1881                 const float *orco = (array) ? array[index] : zero;
1882
1883                 if (attribs->orco.gl_texco)
1884                         glTexCoord3fv(orco);
1885                 else
1886                         glVertexAttrib3fvARB(attribs->orco.gl_index, orco);
1887         }
1888
1889         /* uv texture coordinates */
1890         for (b = 0; b < attribs->tottface; b++) {
1891                 const float *uv;
1892
1893                 if (attribs->tface[b].array) {
1894                         MTFace *tf = &attribs->tface[b].array[a];
1895                         uv = tf->uv[vert];
1896                 }
1897                 else {
1898                         uv = zero;
1899                 }
1900
1901                 if (attribs->tface[b].gl_texco)
1902                         glTexCoord2fv(uv);
1903                 else
1904                         glVertexAttrib2fvARB(attribs->tface[b].gl_index, uv);
1905         }
1906
1907         /* vertex colors */
1908         for (b = 0; b < attribs->totmcol; b++) {
1909                 GLubyte col[4];
1910
1911                 if (attribs->mcol[b].array) {
1912                         MCol *cp = &attribs->mcol[b].array[a * 4 + vert];
1913                         col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1914                 }
1915                 else {
1916                         col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0;
1917                 }
1918
1919                 glVertexAttrib4ubvARB(attribs->mcol[b].gl_index, col);
1920         }
1921
1922         /* tangent for normal mapping */
1923         if (attribs->tottang) {
1924                 /*const*/ float (*array)[4] = attribs->tang.array;
1925                 const float *tang = (array) ? array[a * 4 + vert] : zero;
1926
1927                 glVertexAttrib4fvARB(attribs->tang.gl_index, tang);
1928         }
1929 }
1930
1931 /* Only used by non-editmesh types */
1932 static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
1933                                       DMSetMaterial setMaterial,
1934                                       DMSetDrawOptions setDrawOptions,
1935                                       void *userData)
1936 {
1937         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
1938         CCGSubSurf *ss = ccgdm->ss;
1939         CCGKey key;
1940         GPUVertexAttribs gattribs;
1941         DMVertexAttribs attribs = {{{NULL}}};
1942         /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1943         int gridSize = ccgSubSurf_getGridSize(ss);
1944         int gridFaces = gridSize - 1;
1945         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1946         DMFlagMat *faceFlags = ccgdm->faceFlags;
1947         short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
1948         int a, i, do_draw, numVerts, matnr, new_matnr, totface;
1949
1950         CCG_key_top_level(&key, ss);
1951         ccgdm_pbvh_update(ccgdm);
1952
1953         do_draw = 0;
1954         matnr = -1;
1955
1956 #define PASSATTRIB(dx, dy, vert) {                                            \
1957         if (attribs.totorco)                                                      \
1958                 index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize);   \
1959         else                                                                      \
1960                 index = 0;                                                            \
1961         ccgdm_draw_attrib_vertex(&attribs, a, index, vert);                       \
1962 } (void)0
1963
1964         totface = ccgSubSurf_getNumFaces(ss);
1965         for (a = 0, i = 0; i < totface; i++) {
1966                 CCGFace *f = ccgdm->faceMap[i].face;
1967                 short (*ln)[4][3] = NULL;
1968                 int S, x, y, drawSmooth;
1969                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
1970                 int origIndex = ccgDM_getFaceMapIndex(ss, f);
1971                 
1972                 numVerts = ccgSubSurf_getFaceNumVerts(f);
1973
1974                 if (faceFlags) {
1975                         drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH));
1976                         new_matnr = faceFlags[index].mat_nr + 1;
1977                 }
1978                 else {
1979                         drawSmooth = 1;
1980                         new_matnr = 1;
1981                 }
1982
1983                 if (lnors) {
1984                         ln = lnors;
1985                         lnors += gridFaces * gridFaces * numVerts;
1986                 }
1987
1988                 if (new_matnr != matnr) {
1989                         do_draw = setMaterial(matnr = new_matnr, &gattribs);
1990                         if (do_draw)
1991                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1992                 }
1993
1994                 if (!do_draw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) &&
1995                                 (setDrawOptions(userData, origIndex) == DM_DRAW_OPTION_SKIP)))
1996                 {
1997                         a += gridFaces * gridFaces * numVerts;
1998                         continue;
1999                 }
2000
2001                 glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT);
2002                 for (S = 0; S < numVerts; S++) {
2003                         CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2004                         CCGElem *vda, *vdb;
2005
2006                         if (ln) {
2007                                 glBegin(GL_QUADS);
2008                                 for (y = 0; y < gridFaces; y++) {
2009                                         for (x = 0; x < gridFaces; x++) {
2010                                                 float *aco = CCG_grid_elem_co(&key, faceGridData, x, y);
2011                                                 float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y);
2012                                                 float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
2013                                                 float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
2014
2015                                                 PASSATTRIB(0, 1, 1);
2016                                                 glNormal3sv(ln[0][1]);
2017                                                 glVertex3fv(dco);
2018                                                 PASSATTRIB(1, 1, 2);
2019                                                 glNormal3sv(ln[0][2]);
2020                                                 glVertex3fv(cco);
2021                                                 PASSATTRIB(1, 0, 3);
2022                                                 glNormal3sv(ln[0][3]);
2023                                                 glVertex3fv(bco);
2024                                                 PASSATTRIB(0, 0, 0);
2025                                                 glNormal3sv(ln[0][0]);
2026                                                 glVertex3fv(aco);
2027
2028                                                 ln++;
2029                                                 a++;
2030                                         }
2031                                 }
2032                                 glEnd();
2033                         }
2034                         else if (drawSmooth) {
2035                                 for (y = 0; y < gridFaces; y++) {
2036                                         glBegin(GL_QUAD_STRIP);
2037                                         for (x = 0; x < gridFaces; x++) {
2038                                                 vda = CCG_grid_elem(&key, faceGridData, x, y + 0);
2039                                                 vdb = CCG_grid_elem(&key, faceGridData, x, y + 1);
2040                                                 
2041                                                 PASSATTRIB(0, 0, 0);
2042                                                 glNormal3fv(CCG_elem_no(&key, vda));
2043                                                 glVertex3fv(CCG_elem_co(&key, vda));
2044
2045                                                 PASSATTRIB(0, 1, 1);
2046                                                 glNormal3fv(CCG_elem_no(&key, vdb));
2047                                                 glVertex3fv(CCG_elem_co(&key, vdb));
2048
2049                                                 if (x != gridFaces - 1)
2050                                                         a++;
2051                                         }
2052
2053                                         vda = CCG_grid_elem(&key, faceGridData, x, y + 0);
2054                                         vdb = CCG_grid_elem(&key, faceGridData, x, y + 1);
2055
2056                                         PASSATTRIB(0, 0, 3);
2057                                         glNormal3fv(CCG_elem_no(&key, vda));
2058                                         glVertex3fv(CCG_elem_co(&key, vda));
2059
2060                                         PASSATTRIB(0, 1, 2);
2061                                         glNormal3fv(CCG_elem_no(&key, vdb));
2062                                         glVertex3fv(CCG_elem_co(&key, vdb));
2063
2064                                         glEnd();
2065
2066                                         a++;
2067                                 }
2068                         }
2069                         else {
2070                                 glBegin(GL_QUADS);
2071                                 for (y = 0; y < gridFaces; y++) {
2072                                         for (x = 0; x < gridFaces; x++) {
2073                                                 float *aco = CCG_grid_elem_co(&key, faceGridData, x, y);
2074                                                 float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y);
2075                                                 float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
2076                                                 float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
2077
2078                                                 ccgDM_glNormalFast(aco, bco, cco, dco);
2079
2080                                                 PASSATTRIB(0, 1, 1);
2081                                                 glVertex3fv(dco);
2082                                                 PASSATTRIB(1, 1, 2);
2083                                                 glVertex3fv(cco);
2084                                                 PASSATTRIB(1, 0, 3);
2085                                                 glVertex3fv(bco);
2086                                                 PASSATTRIB(0, 0, 0);
2087                                                 glVertex3fv(aco);
2088                                                 
2089                                                 a++;
2090                                         }
2091                                 }
2092                                 glEnd();
2093                         }
2094                 }
2095         }
2096
2097 #undef PASSATTRIB
2098 }
2099
2100 static void ccgDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial)
2101 {
2102         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
2103 }
2104
2105 /* Only used by non-editmesh types */
2106 static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
2107                                      void (*setMaterial)(void *userData, int matnr, void *attribs),
2108                                      bool (*setFace)(void *userData, int index), void *userData)
2109 {
2110         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2111         CCGSubSurf *ss = ccgdm->ss;
2112         CCGKey key;
2113         GPUVertexAttribs gattribs;
2114         DMVertexAttribs attribs = {{{NULL}}};
2115         int gridSize = ccgSubSurf_getGridSize(ss);
2116         int gridFaces = gridSize - 1;
2117         int edgeSize = ccgSubSurf_getEdgeSize(ss);
2118         DMFlagMat *faceFlags = ccgdm->faceFlags;
2119         short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
2120         int a, i, numVerts, matnr, new_matnr, totface;
2121
2122         CCG_key_top_level(&key, ss);
2123         ccgdm_pbvh_update(ccgdm);
2124
2125         matnr = -1;
2126
2127 #define PASSATTRIB(dx, dy, vert) {                                            \
2128         if (attribs.totorco)                                                      \
2129                 index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize);   \
2130         else                                                                      \
2131                 index = 0;                                                            \
2132         ccgdm_draw_attrib_vertex(&attribs, a, index, vert);                       \
2133 } (void)0
2134
2135         totface = ccgSubSurf_getNumFaces(ss);
2136         for (a = 0, i = 0; i < totface; i++) {
2137                 CCGFace *f = ccgdm->faceMap[i].face;
2138                 short (*ln)[4][3] = NULL;
2139                 int S, x, y, drawSmooth;
2140                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
2141                 int origIndex = ccgDM_getFaceMapIndex(ss, f);
2142                 
2143                 numVerts = ccgSubSurf_getFaceNumVerts(f);
2144
2145                 /* get flags */
2146                 if (faceFlags) {
2147                         drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH));
2148                         new_matnr = faceFlags[index].mat_nr + 1;
2149                 }
2150                 else {
2151                         drawSmooth = 1;
2152                         new_matnr = 1;
2153                 }
2154
2155                 if (lnors) {
2156                         ln = lnors;
2157                         lnors += gridFaces * gridFaces * numVerts;
2158                 }
2159
2160                 /* material */
2161                 if (new_matnr != matnr) {
2162                         setMaterial(userData, matnr = new_matnr, &gattribs);
2163                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
2164                 }
2165
2166                 /* face hiding */
2167                 if ((setFace && (origIndex != ORIGINDEX_NONE) && !setFace(userData, origIndex))) {
2168                         a += gridFaces * gridFaces * numVerts;
2169                         continue;
2170                 }
2171
2172                 /* draw face*/
2173                 glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT);
2174                 for (S = 0; S < numVerts; S++) {
2175                         CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2176                         CCGElem *vda, *vdb;
2177
2178                         if (ln) {
2179                                 glBegin(GL_QUADS);
2180                                 for (y = 0; y < gridFaces; y++) {
2181                                         for (x = 0; x < gridFaces; x++) {
2182                                                 float *aco = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
2183                                                 float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
2184                                                 float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
2185                                                 float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
2186
2187                                                 PASSATTRIB(0, 1, 1);
2188                                                 glNormal3sv(ln[0][1]);
2189                                                 glVertex3fv(dco);
2190                                                 PASSATTRIB(1, 1, 2);
2191                                                 glNormal3sv(ln[0][2]);
2192                                                 glVertex3fv(cco);
2193                                                 PASSATTRIB(1, 0, 3);
2194                                                 glNormal3sv(ln[0][3]);
2195                                                 glVertex3fv(bco);
2196                                                 PASSATTRIB(0, 0, 0);
2197                                                 glNormal3sv(ln[0][0]);
2198                                                 glVertex3fv(aco);
2199
2200                                                 ln++;
2201                                                 a++;
2202                                         }
2203                                 }
2204                                 glEnd();
2205                         }
2206                         else if (drawSmooth) {
2207                                 for (y = 0; y < gridFaces; y++) {
2208                                         glBegin(GL_QUAD_STRIP);
2209                                         for (x = 0; x < gridFaces; x++) {
2210                                                 vda = CCG_grid_elem(&key, faceGridData, x, y);
2211                                                 vdb = CCG_grid_elem(&key, faceGridData, x, y + 1);
2212                                                 
2213                                                 PASSATTRIB(0, 0, 0);
2214                                                 glNormal3fv(CCG_elem_no(&key, vda));
2215                                                 glVertex3fv(CCG_elem_co(&key, vda));
2216
2217                                                 PASSATTRIB(0, 1, 1);
2218                                                 glNormal3fv(CCG_elem_no(&key, vdb));
2219                                                 glVertex3fv(CCG_elem_co(&key, vdb));
2220
2221                                                 if (x != gridFaces - 1)
2222                                                         a++;
2223                                         }
2224
2225                                         vda = CCG_grid_elem(&key, faceGridData, x, y + 0);
2226                                         vdb = CCG_grid_elem(&key, faceGridData, x, y + 1);
2227
2228                                         PASSATTRIB(0, 0, 3);
2229                                         glNormal3fv(CCG_elem_no(&key, vda));
2230                                         glVertex3fv(CCG_elem_co(&key, vda));
2231
2232                                         PASSATTRIB(0, 1, 2);
2233                                         glNormal3fv(CCG_elem_no(&key, vdb));
2234                                         glVertex3fv(CCG_elem_co(&key, vdb));
2235
2236                                         glEnd();
2237
2238                                         a++;
2239                                 }
2240                         }
2241                         else {
2242                                 glBegin(GL_QUADS);
2243                                 for (y = 0; y < gridFaces; y++) {
2244                                         for (x = 0; x < gridFaces; x++) {
2245                                                 float *aco = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
2246                                                 float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
2247                                                 float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
2248                                                 float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
2249
2250                                                 ccgDM_glNormalFast(aco, bco, cco, dco);
2251
2252                                                 PASSATTRIB(0, 1, 1);
2253                                                 glVertex3fv(dco);
2254                                                 PASSATTRIB(1, 1, 2);
2255                                                 glVertex3fv(cco);
2256                                                 PASSATTRIB(1, 0, 3);
2257                                                 glVertex3fv(bco);
2258                                                 PASSATTRIB(0, 0, 0);
2259                                                 glVertex3fv(aco);
2260                                                 
2261                                                 a++;
2262                                         }
2263                                 }
2264                                 glEnd();
2265                         }
2266                 }
2267         }
2268
2269 #undef PASSATTRIB
2270 }
2271
2272 static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
2273                                       DMSetDrawOptionsTex drawParams,
2274                                       DMSetDrawOptionsMappedTex drawParamsMapped,
2275                                       DMCompareDrawOptions compareDrawOptions,
2276                                       void *userData, DMDrawFlag flag)
2277 {
2278         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2279         CCGSubSurf *ss = ccgdm->ss;
2280         CCGKey key;
2281         MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
2282         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
2283         MTFace *tf_stencil_base = NULL;
2284         MTFace *tf_stencil = NULL;
2285         MTFace *tf_base;
2286         short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
2287         DMFlagMat *faceFlags = ccgdm->faceFlags;
2288         DMDrawOption draw_option;
2289         int i, totface, gridSize = ccgSubSurf_getGridSize(ss);
2290         int gridFaces = gridSize - 1;
2291         int gridOffset = 0;
2292         int mat_nr_cache = -1;
2293
2294         (void) compareDrawOptions;
2295
2296         CCG_key_top_level(&key, ss);
2297         ccgdm_pbvh_update(ccgdm);
2298
2299         if (!mcol)
2300                 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
2301
2302         if (!mcol)
2303                 mcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL);
2304
2305         totface = ccgSubSurf_getNumFaces(ss);
2306
2307         if (flag & DM_DRAW_USE_TEXPAINT_UV) {
2308                 int stencil = CustomData_get_stencil_layer(&dm->faceData, CD_MTFACE);
2309                 tf_stencil_base = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, stencil);
2310         }
2311
2312         for (i = 0; i < totface; i++) {
2313                 CCGFace *f = ccgdm->faceMap[i].face;
2314                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2315                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
2316                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
2317                 unsigned char *cp = NULL;
2318                 short (*ln)[4][3] = NULL;
2319                 int mat_nr;
2320
2321                 if (faceFlags) {
2322                         drawSmooth = (lnors || (faceFlags[origIndex].flag & ME_SMOOTH));
2323                         mat_nr = faceFlags[origIndex].mat_nr;
2324                 }
2325                 else {
2326                         drawSmooth = 1;
2327                         mat_nr = 0;
2328                 }
2329
2330                 /* texture painting, handle the correct uv layer here */
2331                 if (flag & DM_DRAW_USE_TEXPAINT_UV) {
2332                         if (mat_nr != mat_nr_cache) {
2333                                 tf_base = DM_paint_uvlayer_active_get(dm, mat_nr);
2334
2335                                 mat_nr_cache = mat_nr;
2336                         }
2337
2338                         tf = tf_base ? tf_base + gridOffset : NULL;
2339                         tf_stencil = tf_stencil_base ? tf_stencil_base + gridOffset : NULL;
2340                         gridOffset += gridFaces * gridFaces * numVerts;
2341                 }
2342
2343                 if (drawParams)
2344                         draw_option = drawParams(tf, (mcol != NULL), mat_nr);
2345                 else if (index != ORIGINDEX_NONE)
2346                         draw_option = (drawParamsMapped) ? drawParamsMapped(userData, index, mat_nr) : DM_DRAW_OPTION_NORMAL;
2347                 else
2348                         draw_option = GPU_enable_material(mat_nr, NULL) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP;
2349
2350                 if (lnors) {
2351                         ln = lnors;
2352                         lnors += gridFaces * gridFaces * numVerts;
2353                 }
2354
2355                 if (draw_option == DM_DRAW_OPTION_SKIP) {
2356                         if (tf) tf += gridFaces * gridFaces * numVerts;
2357                         if (mcol) mcol += gridFaces * gridFaces * numVerts * 4;
2358                         continue;
2359                 }
2360
2361                 /* flag 1 == use vertex colors */
2362                 if (mcol) {
2363                         if (draw_option != DM_DRAW_OPTION_NO_MCOL)
2364                                 cp = (unsigned char *)mcol;
2365                         mcol += gridFaces * gridFaces * numVerts * 4;
2366                 }
2367
2368                 for (S = 0; S < numVerts; S++) {
2369                         CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2370                         CCGElem *a, *b;
2371
2372                         if (ln) {
2373                                 glShadeModel(GL_SMOOTH);
2374                                 glBegin(GL_QUADS);
2375                                 for (y = 0; y < gridFaces; y++) {
2376                                         for (x = 0; x < gridFaces; x++) {
2377                                                 float *a_co = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
2378                                                 float *b_co = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
2379                                                 float *c_co = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
2380                                                 float *d_co = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
2381
2382                                                 if (tf) glTexCoord2fv(tf->uv[1]);
2383                                                 if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[1]);
2384                                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
2385                                                 glNormal3sv(ln[0][1]);
2386                                                 glVertex3fv(d_co);
2387
2388                                                 if (tf) glTexCoord2fv(tf->uv[2]);
2389                                                 if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[2]);
2390                                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
2391                                                 glNormal3sv(ln[0][2]);
2392                                                 glVertex3fv(c_co);
2393
2394                                                 if (tf) glTexCoord2fv(tf->uv[3]);
2395                                                 if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[3]);
2396                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
2397                                                 glNormal3sv(ln[0][3]);
2398                                                 glVertex3fv(b_co);
2399
2400                                                 if (tf) glTexCoord2fv(tf->uv[0]);
2401                                                 if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[0]);
2402                                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
2403                                                 glNormal3sv(ln[0][0]);
2404                                                 glVertex3fv(a_co);
2405
2406                                                 if (tf) tf++;
2407                                                 if (tf_stencil) tf_stencil++;
2408                                                 if (cp) cp += 16;
2409                                                 ln++;
2410                                         }
2411                                 }
2412                                 glEnd();
2413                         }
2414                         else if (drawSmooth) {
2415                                 glShadeModel(GL_SMOOTH);
2416                                 for (y = 0; y < gridFaces; y++) {
2417                                         glBegin(GL_QUAD_STRIP);
2418                                         for (x = 0; x < gridFaces; x++) {
2419                                                 a = CCG_grid_elem(&key, faceGridData, x, y + 0);
2420                                                 b = CCG_grid_elem(&key, faceGridData, x, y + 1);
2421
2422                                                 if (tf) glTexCoord2fv(tf->uv[0]);
2423                                                 if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[0]);
2424                                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
2425                                                 glNormal3fv(CCG_elem_no(&key, a));
2426                                                 glVertex3fv(CCG_elem_co(&key, a));
2427
2428                                                 if (tf) glTexCoord2fv(tf->uv[1]);
2429                                                 if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[1]);
2430                                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
2431                                                 glNormal3fv(CCG_elem_no(&key, b));
2432                                                 glVertex3fv(CCG_elem_co(&key, b));
2433                                                 
2434                                                 if (x != gridFaces - 1) {
2435                                                         if (tf) tf++;
2436                                                         if (tf_stencil) tf_stencil++;
2437                                                         if (cp) cp += 16;
2438                                                 }
2439                                         }
2440
2441                                         a = CCG_grid_elem(&key, faceGridData, x, y + 0);
2442                                         b = CCG_grid_elem(&key, faceGridData, x, y + 1);
2443
2444                                         if (tf) glTexCoord2fv(tf->uv[3]);
2445                                         if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[3]);
2446                                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
2447                                         glNormal3fv(CCG_elem_no(&key, a));
2448                                         glVertex3fv(CCG_elem_co(&key, a));
2449
2450                                         if (tf) glTexCoord2fv(tf->uv[2]);
2451                                         if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[2]);
2452                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
2453                                         glNormal3fv(CCG_elem_no(&key, b));
2454                                         glVertex3fv(CCG_elem_co(&key, b));
2455
2456                                         if (tf) tf++;
2457                                         if (tf_stencil) tf_stencil++;
2458                                         if (cp) cp += 16;
2459
2460                                         glEnd();
2461                                 }
2462                         }
2463                         else {
2464                                 glShadeModel((cp) ? GL_SMOOTH : GL_FLAT);
2465                                 glBegin(GL_QUADS);
2466                                 for (y = 0; y < gridFaces; y++) {
2467                                         for (x = 0; x < gridFaces; x++) {
2468                                                 float *a_co = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
2469                                                 float *b_co = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
2470                                                 float *c_co = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
2471                                                 float *d_co = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
2472
2473                                                 ccgDM_glNormalFast(a_co, b_co, c_co, d_co);
2474
2475                                                 if (tf) glTexCoord2fv(tf->uv[1]);
2476                                                 if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[1]);
2477                                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
2478                                                 glVertex3fv(d_co);
2479
2480                                                 if (tf) glTexCoord2fv(tf->uv[2]);
2481                                                 if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[2]);
2482                                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
2483                                                 glVertex3fv(c_co);
2484
2485                                                 if (tf) glTexCoord2fv(tf->uv[3]);
2486                                                 if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[3]);
2487                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
2488                                                 glVertex3fv(b_co);
2489
2490                                                 if (tf) glTexCoord2fv(tf->uv[0]);
2491                                                 if (tf_stencil) glMultiTexCoord2fv(GL_TEXTURE2, tf_stencil->uv[0]);
2492                                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
2493                                                 glVertex3fv(a_co);
2494
2495                                                 if (tf) tf++;
2496                                                 if (tf_stencil) tf_stencil++;
2497                                                 if (cp) cp += 16;
2498                                         }
2499                                 }
2500                                 glEnd();
2501                         }
2502                 }
2503         }
2504 }
2505
2506 static void ccgDM_drawFacesTex(DerivedMesh *dm,
2507                                DMSetDrawOptionsTex setDrawOptions,
2508                                DMCompareDrawOptions compareDrawOptions,
2509                                void *userData, DMDrawFlag flag)
2510 {
2511         ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData, flag);
2512 }
2513
2514 static void ccgDM_drawMappedFacesTex(DerivedMesh *dm,
2515                                      DMSetDrawOptionsMappedTex setDrawOptions,
2516                                      DMCompareDrawOptions compareDrawOptions,
2517                                      void *userData, DMDrawFlag flag)
2518 {
2519         ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData, flag);
2520 }
2521
2522 static void ccgDM_drawUVEdges(DerivedMesh *dm)
2523 {
2524
2525         MFace *mf = dm->getTessFaceArray(dm);
2526         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
2527         int i;
2528         
2529         if (tf) {
2530                 glBegin(GL_LINES);
2531                 for (i = 0; i < dm->numTessFaceData; i++, mf++, tf++) {
2532                         if (!(mf->flag & ME_HIDE)) {
2533                                 glVertex2fv(tf->uv[0]);
2534                                 glVertex2fv(tf->uv[1]);
2535         
2536                                 glVertex2fv(tf->uv[1]);
2537                                 glVertex2fv(tf->uv[2]);
2538         
2539                                 if (!mf->v4) {
2540                                         glVertex2fv(tf->uv[2]);
2541                                         glVertex2fv(tf->uv[0]);
2542                                 }
2543                                 else {
2544                                         glVertex2fv(tf->uv[2]);
2545                                         glVertex2fv(tf->uv[3]);
2546         
2547                                         glVertex2fv(tf->uv[3]);
2548                                         glVertex2fv(tf->uv[0]);
2549                                 }
2550                         }
2551                 }
2552                 glEnd();
2553         }
2554 }
2555
2556 static void ccgDM_drawMappedFaces(DerivedMesh *dm,
2557                                   DMSetDrawOptions setDrawOptions,
2558                                   DMSetMaterial setMaterial,
2559                                   DMCompareDrawOptions compareDrawOptions,
2560                                   void *userData, DMDrawFlag flag)
2561 {
2562         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2563         CCGSubSurf *ss = ccgdm->ss;
2564         CCGKey key;
2565         MCol *mcol = NULL;
2566         short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
2567         int i, gridSize = ccgSubSurf_getGridSize(ss);
2568         DMFlagMat *faceFlags = ccgdm->faceFlags;
2569         int useColors = flag & DM_DRAW_USE_COLORS;
2570         int gridFaces = gridSize - 1, totface;
2571         int prev_mat_nr = -1;
2572
2573         CCG_key_top_level(&key, ss);
2574
2575         /* currently unused -- each original face is handled separately */
2576         (void)compareDrawOptions;
2577
2578         if (useColors) {
2579                 mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
2580                 if (!mcol)
2581                         mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
2582         }
2583
2584         totface = ccgSubSurf_getNumFaces(ss);
2585         for (i = 0; i < totface; i++) {
2586                 CCGFace *f = ccgdm->faceMap[i].face;
2587                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2588                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
2589                 int origIndex;
2590                 unsigned char *cp = NULL;
2591                 short (*ln)[4][3] = NULL;
2592
2593                 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
2594
2595                 if (flag & DM_DRAW_ALWAYS_SMOOTH) drawSmooth = 1;
2596                 else if (faceFlags) drawSmooth = (lnors || (faceFlags[origIndex].flag & ME_SMOOTH));
2597                 else drawSmooth = 1;
2598
2599                 if (mcol) {
2600                         cp = (unsigned char *)mcol;
2601                         mcol += gridFaces * gridFaces * numVerts * 4;
2602                 }
2603
2604                 if (lnors) {
2605                         ln = lnors;
2606                         lnors += gridFaces * gridFaces * numVerts;
2607                 }
2608
2609                 {
2610                         DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
2611
2612                         if (setMaterial) {
2613                                 int mat_nr = faceFlags ? faceFlags[origIndex].mat_nr + 1 : 1;
2614                                 
2615                                 if (mat_nr != prev_mat_nr) {
2616                                         setMaterial(mat_nr, NULL);  /* XXX, no faceFlags no material */
2617                                         prev_mat_nr = mat_nr;
2618                                 }
2619                         }
2620                         
2621                         if (setDrawOptions && (index != ORIGINDEX_NONE))
2622                                 draw_option = setDrawOptions(userData, index);
2623
2624                         if (draw_option != DM_DRAW_OPTION_SKIP) {
2625                                 if (draw_option == DM_DRAW_OPTION_STIPPLE) {
2626                                         glEnable(GL_POLYGON_STIPPLE);
2627                                         glPolygonStipple(stipple_quarttone);
2628                                 }
2629
2630                                 /* no need to set shading mode to flat because
2631                                  *  normals are already used to change shading */
2632                                 glShadeModel(GL_SMOOTH);
2633                                 
2634                                 for (S = 0; S < numVerts; S++) {
2635                                         CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2636                                         if (ln) {
2637                                                 glBegin(GL_QUADS);
2638                                                 for (y = 0; y < gridFaces; y++) {
2639                                                         for (x = 0; x < gridFaces; x++) {
2640                                                                 float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
2641                                                                 float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
2642                                                                 float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
2643                                                                 float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
2644
2645                                                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
2646                                                                 glNormal3sv(ln[0][1]);
2647                                                                 glVertex3fv(d);
2648                                                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
2649                                                                 glNormal3sv(ln[0][2]);
2650                                                                 glVertex3fv(c);
2651                                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
2652                                                                 glNormal3sv(ln[0][3]);
2653                                                                 glVertex3fv(b);
2654                                                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
2655                                                                 glNormal3sv(ln[0][0]);
2656                                                                 glVertex3fv(a);
2657
2658                                                                 if (cp) cp += 16;
2659                                                                 ln++;
2660                                                         }
2661                                                 }
2662                                                 glEnd();
2663                                         }
2664                                         else if (drawSmooth) {
2665                                                 for (y = 0; y < gridFaces; y++) {
2666                                                         CCGElem *a, *b;
2667                                                         glBegin(GL_QUAD_STRIP);
2668                                                         for (x = 0; x < gridFaces; x++) {
2669                                                                 a = CCG_grid_elem(&key, faceGridData, x, y + 0);
2670                                                                 b = CCG_grid_elem(&key, faceGridData, x, y + 1);
2671         
2672                                                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
2673                                                                 glNormal3fv(CCG_elem_no(&key, a));
2674                                                                 glVertex3fv(CCG_elem_co(&key, a));
2675                                                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
2676                                                                 glNormal3fv(CCG_elem_no(&key, b));
2677                                                                 glVertex3fv(CCG_elem_co(&key, b));
2678
2679                                                                 if (x != gridFaces - 1) {
2680                                                                         if (cp) cp += 16;
2681                                                                 }
2682                                                         }
2683
2684                                                         a = CCG_grid_elem(&key, faceGridData, x, y + 0);
2685                                                         b = CCG_grid_elem(&key, faceGridData, x, y + 1);
2686
2687                                                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
2688                                                         glNormal3fv(CCG_elem_no(&key, a));
2689                                                         glVertex3fv(CCG_elem_co(&key, a));
2690                                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
2691                                                         glNormal3fv(CCG_elem_no(&key, b));
2692                                                         glVertex3fv(CCG_elem_co(&key, b));
2693
2694                                                         if (cp) cp += 16;
2695
2696                                                         glEnd();
2697                                                 }
2698                                         }
2699                                         else {
2700                                                 glBegin(GL_QUADS);
2701                                                 for (y = 0; y < gridFaces; y++) {
2702                                                         for (x = 0; x < gridFaces; x++) {
2703                                                                 float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
2704                                                                 float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
2705                                                                 float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
2706                                                                 float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
2707
2708                                                                 ccgDM_glNormalFast(a, b, c, d);
2709         
2710                                                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
2711                                                                 glVertex3fv(d);
2712                                                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
2713                                                                 glVertex3fv(c);
2714                                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
2715                                                                 glVertex3fv(b);
2716                                                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
2717                                                                 glVertex3fv(a);
2718
2719                                                                 if (cp) cp += 16;
2720                                                         }
2721                                                 }
2722                                                 glEnd();
2723                                         }
2724                                 }
2725                                 if (draw_option == DM_DRAW_OPTION_STIPPLE)
2726                                         glDisable(GL_POLYGON_STIPPLE);
2727                         }
2728                 }
2729         }
2730 }
2731
2732 static void ccgDM_drawMappedEdges(DerivedMesh *dm,
2733                                   DMSetDrawOptions setDrawOptions,
2734                                   void *userData)
2735 {
2736         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2737         CCGSubSurf *ss = ccgdm->ss;
2738         CCGEdgeIterator ei;
2739         CCGKey key;
2740         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2741
2742         CCG_key_top_level(&key, ss);
2743         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2744
2745         for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
2746                 CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
2747                 CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2748                 int index = ccgDM_getEdgeMapIndex(ss, e);
2749
2750                 glBegin(GL_LINE_STRIP);
2751                 if (index != -1 && (!setDrawOptions || (setDrawOptions(userData, index) != DM_DRAW_OPTION_SKIP))) {
2752                         if (useAging && !(G.f & G_BACKBUFSEL)) {
2753                                 int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e) * 4;
2754                                 glColor3ub(0, ageCol > 0 ? ageCol : 0, 0);
2755                         }
2756
2757                         for (i = 0; i < edgeSize - 1; i++) {
2758                                 glVertex3fv(CCG_elem_offset_co(&key, edgeData, i));
2759                                 glVertex3fv(CCG_elem_offset_co(&key, edgeData, i + 1));
2760                         }
2761                 }
2762                 glEnd();
2763         }
2764 }
2765
2766 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm,
2767                                         DMSetDrawOptions setDrawOptions,
2768                                         DMSetDrawInterpOptions setDrawInterpOptions,
2769                                         void *userData)
2770 {
2771         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2772         CCGSubSurf *ss = ccgdm->ss;
2773         CCGKey key;
2774         CCGEdgeIterator ei;
2775         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2776
2777         CCG_key_top_level(&key, ss);
2778         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2779
2780         for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) {
2781                 CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
2782                 CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2783                 int index = ccgDM_getEdgeMapIndex(ss, e);
2784
2785                 glBegin(GL_LINE_STRIP);
2786                 if (index != -1 && (!setDrawOptions || (setDrawOptions(userData, index) != DM_DRAW_OPTION_SKIP))) {
2787                         for (i = 0; i < edgeSize; i++) {
2788                                 setDrawInterpOptions(userData, index, (float) i / (edgeSize - 1));
2789
2790                                 if (useAging && !(G.f & G_BACKBUFSEL)) {
2791                                         int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e) * 4;
2792                                         glColor3ub(0, ageCol > 0 ? ageCol : 0, 0);
2793                                 }
2794
2795                                 glVertex3fv(CCG_elem_offset_co(&key, edgeData, i));
2796                         }
2797                 }
2798                 glEnd();
2799         }
2800 }
2801
2802 static void ccgDM_foreachMappedFaceCenter(
2803         DerivedMesh *dm,
2804         void (*func)(void *userData, int index, const float co[3], const float no[3]),
2805         void *userData,
2806         DMForeachFlag flag)
2807 {
2808         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2809         CCGSubSurf *ss = ccgdm->ss;
2810         CCGKey key;
2811         CCGFaceIterator fi;
2812
2813         CCG_key_top_level(&key, ss);
2814
2815         for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) {
2816                 CCGFace *f = ccgFaceIterator_getCurrent(&fi);
2817                 const int index = ccgDM_getFaceMapIndex(ss, f);
2818
2819                 if (index != -1) {
2820                         /* Face center data normal isn't updated atm. */
2821                         CCGElem *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
2822                         const float *no = (flag & DM_FOREACH_USE_NORMAL) ? CCG_elem_no(&key, vd) : NULL;
2823                         func(userData, index, CCG_elem_co(&key, vd), no);
2824                 }
2825         }
2826 }
2827
2828 static void ccgDM_release(DerivedMesh *dm)
2829 {
2830         CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
2831
2832         if (DM_release(dm)) {
2833                 /* Before freeing, need to update the displacement map */
2834                 if (ccgdm->multires.modified_flags) {
2835                         /* Check that mmd still exists */
2836                         if (!ccgdm->multires.local_mmd &&
2837                             BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
2838                         {
2839                                 ccgdm->multires.mmd = NULL;
2840                         }
2841                         
2842                         if (ccgdm->multires.mmd) {
2843                                 if (ccgdm->multires.modified_flags & MULTIRES_COORDS_MODIFIED)
2844                                         multires_modifier_update_mdisps(dm);
2845                                 if (ccgdm->multires.modified_flags & MULTIRES_HIDDEN_MODIFIED)
2846                                         multires_modifier_update_hidden(dm);
2847                         }
2848                 }
2849
2850                 if (ccgdm->ehash)
2851                         BLI_edgehash_free(ccgdm->ehash, NULL);
2852
2853                 if (ccgdm->reverseFaceMap) MEM_freeN(ccgdm->reverseFaceMap);