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