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