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