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