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