fixed crash on loop cut of wire edge
[blender-staging.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.0f / (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.0f - fy + -fac2*fy*fac);
440                                         
441                                         fac2 = 1.0f - (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         MVert *mvert = dm->getVertArray(dm);
501         MEdge *medge = dm->getEdgeArray(dm);
502         /* MFace *mface = dm->getTessFaceArray(dm); */ /* UNUSED */
503         MVert *mv;
504         MEdge *me;
505         MLoop *mloop = dm->getLoopArray(dm), *ml;
506         MPoly *mpoly = dm->getPolyArray(dm), *mp;
507         /*MFace *mf;*/ /*UNUSED*/
508         int totvert = dm->getNumVerts(dm);
509         int totedge = dm->getNumEdges(dm);
510         /*int totface = dm->getNumTessFaces(dm);*/ /*UNUSED*/
511         /*int totpoly = dm->getNumFaces(dm);*/ /*UNUSED*/
512         int i, j;
513         int *index;
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         mp = mpoly;
547         index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
548         for (i=0; i<dm->numPolyData; i++, mp++) {
549                 CCGFace *f=NULL;
550
551                 BLI_array_empty(fVerts);
552
553                 ml = mloop + mp->loopstart;
554                 for (j=0; j<mp->totloop; j++, ml++) {
555                         BLI_array_append(fVerts, SET_INT_IN_POINTER(ml->v));
556                 }
557
558                 /* this is very bad, means mesh is internally inconsistent.
559                  * it is not really possible to continue without modifying
560                  * other parts of code significantly to handle missing faces.
561                  * since this really shouldn't even be possible we just bail.*/
562                 if(ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), mp->totloop,
563                                                            fVerts, &f) == eCCGError_InvalidValue) {
564                         static int hasGivenError = 0;
565
566                         if(!hasGivenError) {
567                                 printf("Unrecoverable error in SubSurf calculation,"
568                                            " mesh is inconsistent.\n");
569
570                                 hasGivenError = 1;
571                         }
572
573                         return 0;
574                 }
575
576                 ((int*)ccgSubSurf_getFaceUserData(ss, f))[1] = index ? *index++: i;
577         }
578
579         ccgSubSurf_processSync(ss);
580
581         BLI_array_free(fVerts);
582         return 1;
583 }
584
585 /***/
586
587 static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v) {
588         return ((int*) ccgSubSurf_getVertUserData(ss, v))[1];
589 }
590
591 static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e) {
592         return ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1];
593 }
594
595 static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f) {
596         return ((int*) ccgSubSurf_getFaceUserData(ss, f))[1];
597 }
598
599 static void cgdm_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
600         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
601         CCGSubSurf *ss = cgdm->ss;
602         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
603         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
604         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
605         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
606         int gridSize = ccgSubSurf_getGridSize(ss);
607
608         if (!ccgSubSurf_getNumVerts(ss))
609                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
610
611         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
612                 CCGVert *v = ccgVertIterator_getCurrent(vi);
613                 float *co = ccgSubSurf_getVertData(ss, v);
614
615                 DO_MINMAX(co, min_r, max_r);
616         }
617
618         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
619                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
620                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
621
622                 for (i=0; i<edgeSize; i++)
623                         DO_MINMAX(edgeData[i].co, min_r, max_r);
624         }
625
626         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
627                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
628                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
629
630                 for (S=0; S<numVerts; S++) {
631                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
632
633                         for (y=0; y<gridSize; y++)
634                                 for (x=0; x<gridSize; x++)
635                                         DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r);
636                 }
637         }
638
639         ccgFaceIterator_free(fi);
640         ccgEdgeIterator_free(ei);
641         ccgVertIterator_free(vi);
642 }
643 static int cgdm_getNumVerts(DerivedMesh *dm) {
644         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
645
646         return ccgSubSurf_getNumFinalVerts(cgdm->ss);
647 }
648 static int cgdm_getNumEdges(DerivedMesh *dm) {
649         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
650
651         return ccgSubSurf_getNumFinalEdges(cgdm->ss);
652 }
653 static int cgdm_getNumTessFaces(DerivedMesh *dm) {
654         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
655
656         return ccgSubSurf_getNumFinalFaces(cgdm->ss);
657 }
658
659 static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
660 {
661         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
662         CCGSubSurf *ss = cgdm->ss;
663         DMGridData *vd;
664         int i;
665
666         memset(mv, 0, sizeof(*mv));
667
668         if((vertNum < cgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) {
669                 /* this vert comes from face data */
670                 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
671                 CCGFace *f;
672                 int x, y, grid, numVerts;
673                 int offset;
674                 int gridSize = ccgSubSurf_getGridSize(ss);
675                 int gridSideVerts;
676                 int gridInternalVerts;
677                 int gridSideEnd;
678                 int gridInternalEnd;
679
680                 i = 0;
681                 while(i < lastface && vertNum >= cgdm->faceMap[i + 1].startVert)
682                         ++i;
683
684                 f = cgdm->faceMap[i].face;
685                 numVerts = ccgSubSurf_getFaceNumVerts(f);
686
687                 gridSideVerts = gridSize - 2;
688                 gridInternalVerts = gridSideVerts * gridSideVerts;
689
690                 gridSideEnd = 1 + numVerts * gridSideVerts;
691                 gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
692
693                 offset = vertNum - cgdm->faceMap[i].startVert;
694                 if(offset < 1) {
695                         vd = ccgSubSurf_getFaceCenterData(f);
696                         copy_v3_v3(mv->co, vd->co);
697                         normal_float_to_short_v3(mv->no, vd->no);
698                 } else if(offset < gridSideEnd) {
699                         offset -= 1;
700                         grid = offset / gridSideVerts;
701                         x = offset % gridSideVerts + 1;
702                         vd = ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x);
703                         copy_v3_v3(mv->co, vd->co);
704                         normal_float_to_short_v3(mv->no, vd->no);
705                 } else if(offset < gridInternalEnd) {
706                         offset -= gridSideEnd;
707                         grid = offset / gridInternalVerts;
708                         offset %= gridInternalVerts;
709                         y = offset / gridSideVerts + 1;
710                         x = offset % gridSideVerts + 1;
711                         vd = ccgSubSurf_getFaceGridData(ss, f, grid, x, y);
712                         copy_v3_v3(mv->co, vd->co);
713                         normal_float_to_short_v3(mv->no, vd->no);
714                 }
715         } else if((vertNum < cgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
716                 /* this vert comes from edge data */
717                 CCGEdge *e;
718                 int lastedge = ccgSubSurf_getNumEdges(ss) - 1;
719                 int x;
720
721                 i = 0;
722                 while(i < lastedge && vertNum >= cgdm->edgeMap[i + 1].startVert)
723                         ++i;
724
725                 e = cgdm->edgeMap[i].edge;
726
727                 x = vertNum - cgdm->edgeMap[i].startVert + 1;
728                 vd = ccgSubSurf_getEdgeData(ss, e, x);
729                 copy_v3_v3(mv->co, vd->co);
730                 normal_float_to_short_v3(mv->no, vd->no);
731         } else {
732                 /* this vert comes from vert data */
733                 CCGVert *v;
734                 i = vertNum - cgdm->vertMap[0].startVert;
735
736                 v = cgdm->vertMap[i].vert;
737                 vd = ccgSubSurf_getVertData(ss, v);
738                 copy_v3_v3(mv->co, vd->co);
739                 normal_float_to_short_v3(mv->no, vd->no);
740         }
741 }
742
743 static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float co_r[3])
744 {
745         MVert mvert;
746
747         ccgDM_getFinalVert(dm, vertNum, &mvert);
748         VECCOPY(co_r, mvert.co);
749 }
750
751 static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float no_r[3])
752 {
753         MVert mvert;
754
755         ccgDM_getFinalVert(dm, vertNum, &mvert);
756         normal_short_to_float_v3(no_r, mvert.no);
757 }
758
759 static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
760 {
761         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
762         CCGSubSurf *ss = cgdm->ss;
763         int i;
764
765         memset(med, 0, sizeof(*med));
766
767         if(edgeNum < cgdm->edgeMap[0].startEdge) {
768                 /* this edge comes from face data */
769                 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
770                 CCGFace *f;
771                 int x, y, grid /*, numVerts*/;
772                 int offset;
773                 int gridSize = ccgSubSurf_getGridSize(ss);
774                 int edgeSize = ccgSubSurf_getEdgeSize(ss);
775                 int gridSideEdges;
776                 int gridInternalEdges;
777                                 int lasti, previ;
778
779                                 i = lastface;
780                                 lasti = 0;
781                                 while (1) {
782                                         previ = i;
783                                         if (cgdm->faceMap[i].startEdge >= edgeNum) {
784                                                 i -= fabsf(i-lasti)/2.0f;
785                                         } else if (cgdm->faceMap[i].startEdge < edgeNum) {
786                                                 i += fabsf(i-lasti)/2.0f;
787                                         } else {
788                                                 break;
789                                         }
790
791                                         if (i < 0) {
792                                                 i = 0;
793                                                 break;
794                                         }
795
796                                         if (i > lastface) {
797                                                 i = lastface;
798                                                 break;
799
800                                         }
801
802                                         if (i == lasti)
803                                            break;
804
805                                         lasti = previ;
806                                 }
807
808                                 i = i > 0 ? i - 1 : i;
809                 while(i < lastface && edgeNum >= cgdm->faceMap[i + 1].startEdge)
810                         ++i;
811
812                 f = cgdm->faceMap[i].face;
813                 /* numVerts = ccgSubSurf_getFaceNumVerts(f); */ /*UNUSED*/
814
815                 gridSideEdges = gridSize - 1;
816                 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
817
818                 offset = edgeNum - cgdm->faceMap[i].startEdge;
819                 grid = offset / (gridSideEdges + gridInternalEdges);
820                 offset %= (gridSideEdges + gridInternalEdges);
821
822                 if(offset < gridSideEdges) {
823                         x = offset;
824                         med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, gridSize);
825                         med->v2 = getFaceIndex(ss, f, grid, x+1, 0, edgeSize, gridSize);
826                 } else {
827                         offset -= gridSideEdges;
828                         x = (offset / 2) / gridSideEdges + 1;
829                         y = (offset / 2) % gridSideEdges;
830                         if(offset % 2 == 0) {
831                                 med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSize, gridSize);
832                                 med->v2 = getFaceIndex(ss, f, grid, x, y+1, edgeSize, gridSize);
833                         } else {
834                                 med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSize, gridSize);
835                                 med->v2 = getFaceIndex(ss, f, grid, y+1, x, edgeSize, gridSize);
836                         }
837                 }
838         } else {
839                 /* this vert comes from edge data */
840                 CCGEdge *e;
841                 int edgeSize = ccgSubSurf_getEdgeSize(ss);
842                 int x;
843                 short *edgeFlag;
844                 unsigned int flags = 0;
845
846                 i = (edgeNum - cgdm->edgeMap[0].startEdge) / (edgeSize - 1);
847
848                 e = cgdm->edgeMap[i].edge;
849
850                 if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
851
852                 x = edgeNum - cgdm->edgeMap[i].startEdge;
853
854                 med->v1 = getEdgeIndex(ss, e, x, edgeSize);
855                 med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
856
857                 edgeFlag = (cgdm->edgeFlags)? &cgdm->edgeFlags[i]: NULL;
858                 if(edgeFlag)
859                         flags |= (*edgeFlag & (ME_SEAM | ME_SHARP))
860                                          | ME_EDGEDRAW | ME_EDGERENDER;
861                 else
862                         flags |= ME_EDGEDRAW | ME_EDGERENDER;
863
864                 med->flag = flags;
865         }
866 }
867
868 static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
869 {
870         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
871         CCGSubSurf *ss = cgdm->ss;
872         int gridSize = ccgSubSurf_getGridSize(ss);
873         int edgeSize = ccgSubSurf_getEdgeSize(ss);
874         int gridSideEdges = gridSize - 1;
875         int gridFaces = gridSideEdges * gridSideEdges;
876         int i;
877         CCGFace *f;
878         /*int numVerts;*/
879         int offset;
880         int grid;
881         int x, y;
882         /*int lastface = ccgSubSurf_getNumFaces(ss) - 1;*/ /*UNUSED*/
883         char *faceFlags = cgdm->faceFlags;
884
885         memset(mf, 0, sizeof(*mf));
886         if (faceNum >= cgdm->dm.numFaceData)
887                 return;
888
889         i = cgdm->reverseFaceMap[faceNum];
890
891         f = cgdm->faceMap[i].face;
892         /*numVerts = ccgSubSurf_getFaceNumVerts(f);*/ /*UNUSED*/
893
894         offset = faceNum - cgdm->faceMap[i].startFace;
895         grid = offset / gridFaces;
896         offset %= gridFaces;
897         y = offset / gridSideEdges;
898         x = offset % gridSideEdges;
899
900         mf->v1 = getFaceIndex(ss, f, grid, x+0, y+0, edgeSize, gridSize);
901         mf->v2 = getFaceIndex(ss, f, grid, x+0, y+1, edgeSize, gridSize);
902         mf->v3 = getFaceIndex(ss, f, grid, x+1, y+1, edgeSize, gridSize);
903         mf->v4 = getFaceIndex(ss, f, grid, x+1, y+0, edgeSize, gridSize);
904
905         if(faceFlags) {
906                 mf->flag = faceFlags[i*2];
907                 mf->mat_nr = faceFlags[i*2+1];
908         }
909         else mf->flag = ME_SMOOTH;
910 }
911
912 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
913 {
914         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
915         CCGSubSurf *ss = cgdm->ss;
916         DMGridData *vd;
917         int index;
918         int totvert, totedge, totface;
919         int gridSize = ccgSubSurf_getGridSize(ss);
920         int edgeSize = ccgSubSurf_getEdgeSize(ss);
921         int i = 0;
922
923         totface = ccgSubSurf_getNumFaces(ss);
924         for(index = 0; index < totface; index++) {
925                 CCGFace *f = cgdm->faceMap[index].face;
926                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
927
928                 vd= ccgSubSurf_getFaceCenterData(f);
929                 copy_v3_v3(mvert[i].co, vd->co);
930                 normal_float_to_short_v3(mvert[i].no, vd->no);
931                 i++;
932                 
933                 for(S = 0; S < numVerts; S++) {
934                         for(x = 1; x < gridSize - 1; x++, i++) {
935                                 vd= ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
936                                 copy_v3_v3(mvert[i].co, vd->co);
937                                 normal_float_to_short_v3(mvert[i].no, vd->no);
938                         }
939                 }
940
941                 for(S = 0; S < numVerts; S++) {
942                         for(y = 1; y < gridSize - 1; y++) {
943                                 for(x = 1; x < gridSize - 1; x++, i++) {
944                                         vd= ccgSubSurf_getFaceGridData(ss, f, S, x, y);
945                                         copy_v3_v3(mvert[i].co, vd->co);
946                                         normal_float_to_short_v3(mvert[i].no, vd->no);
947                                 }
948                         }
949                 }
950         }
951
952         totedge = ccgSubSurf_getNumEdges(ss);
953         for(index = 0; index < totedge; index++) {
954                 CCGEdge *e = cgdm->edgeMap[index].edge;
955                 int x;
956
957                 for(x = 1; x < edgeSize - 1; x++, i++) {
958                         vd= ccgSubSurf_getEdgeData(ss, e, x);
959                         copy_v3_v3(mvert[i].co, vd->co);
960                         /* This gives errors with -debug-fpe
961                          * the normals dont seem to be unit length.
962                          * this is most likely caused by edges with no
963                          * faces which are now zerod out, see comment in:
964                          * ccgSubSurf__calcVertNormals(), - campbell */
965                         normal_float_to_short_v3(mvert[i].no, vd->no);
966                 }
967         }
968
969         totvert = ccgSubSurf_getNumVerts(ss);
970         for(index = 0; index < totvert; index++) {
971                 CCGVert *v = cgdm->vertMap[index].vert;
972
973                 vd= ccgSubSurf_getVertData(ss, v);
974                 copy_v3_v3(mvert[i].co, vd->co);
975                 normal_float_to_short_v3(mvert[i].no, vd->no);
976                 i++;
977         }
978 }
979
980 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
981 {
982         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
983         CCGSubSurf *ss = cgdm->ss;
984         int index;
985         int totedge, totface;
986         int gridSize = ccgSubSurf_getGridSize(ss);
987         int edgeSize = ccgSubSurf_getEdgeSize(ss);
988         int i = 0;
989         short *edgeFlags = cgdm->edgeFlags;
990
991         totface = ccgSubSurf_getNumFaces(ss);
992         for(index = 0; index < totface; index++) {
993                 CCGFace *f = cgdm->faceMap[index].face;
994                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
995
996                 for(S = 0; S < numVerts; S++) {
997                         for(x = 0; x < gridSize - 1; x++) {
998                                 MEdge *med = &medge[i];
999
1000                                 if(cgdm->drawInteriorEdges)
1001                                         med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1002                                 med->v1 = getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize);
1003                                 med->v2 = getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize);
1004                                 i++;
1005                         }
1006
1007                         for(x = 1; x < gridSize - 1; x++) {
1008                                 for(y = 0; y < gridSize - 1; y++) {
1009                                         MEdge *med;
1010
1011                                         med = &medge[i];
1012                                         if(cgdm->drawInteriorEdges)
1013                                                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1014                                         med->v1 = getFaceIndex(ss, f, S, x, y,
1015                                                                                    edgeSize, gridSize);
1016                                         med->v2 = getFaceIndex(ss, f, S, x, y + 1,
1017                                                                                    edgeSize, gridSize);
1018                                         i++;
1019
1020                                         med = &medge[i];
1021                                         if(cgdm->drawInteriorEdges)
1022                                                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1023                                         med->v1 = getFaceIndex(ss, f, S, y, x,
1024                                                                                    edgeSize, gridSize);
1025                                         med->v2 = getFaceIndex(ss, f, S, y + 1, x,
1026                                                                                    edgeSize, gridSize);
1027                                         i++;
1028                                 }
1029                         }
1030                 }
1031         }
1032
1033         totedge = ccgSubSurf_getNumEdges(ss);
1034         for(index = 0; index < totedge; index++) {
1035                 CCGEdge *e = cgdm->edgeMap[index].edge;
1036                 unsigned int flags = 0;
1037                 int x;
1038                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
1039
1040                 if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
1041
1042                 if(edgeFlags) {
1043                         if(edgeIdx != -1) {
1044                                 flags |= (edgeFlags[index] & (ME_SEAM | ME_SHARP))
1045                                                  | ME_EDGEDRAW | ME_EDGERENDER;
1046                         }
1047                 } else {
1048                         flags |= ME_EDGEDRAW | ME_EDGERENDER;
1049                 }
1050
1051                 for(x = 0; x < edgeSize - 1; x++) {
1052                         MEdge *med = &medge[i];
1053                         med->v1 = getEdgeIndex(ss, e, x, edgeSize);
1054                         med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
1055                         med->flag = flags;
1056                         i++;
1057                 }
1058         }
1059 }
1060
1061 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
1062 {
1063         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1064         CCGSubSurf *ss = cgdm->ss;
1065         int index;
1066         int totface;
1067         int gridSize = ccgSubSurf_getGridSize(ss);
1068         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1069         int i = 0;
1070         char *faceFlags = cgdm->faceFlags;
1071
1072         totface = ccgSubSurf_getNumFaces(ss);
1073         for(index = 0; index < totface; index++) {
1074                 CCGFace *f = cgdm->faceMap[index].face;
1075                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1076                 int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH;
1077                 int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0;
1078
1079                 for(S = 0; S < numVerts; S++) {
1080                         for(y = 0; y < gridSize - 1; y++) {
1081                                 for(x = 0; x < gridSize - 1; x++) {
1082                                         MFace *mf = &mface[i];
1083                                         mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1084                                                                                   edgeSize, gridSize);
1085                                         mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1086                                                                                   edgeSize, gridSize);
1087                                         mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1088                                                                                   edgeSize, gridSize);
1089                                         mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1090                                                                                   edgeSize, gridSize);
1091                                         if (faceFlags) {
1092                                                 mat_nr = faceFlags[index*2+1];
1093                                                 mf->flag = faceFlags[index*2];
1094                                         } else mf->flag = flag;
1095
1096                                         mf->mat_nr = mat_nr;
1097                                         mf->flag = flag;
1098
1099                                         i++;
1100                                 }
1101                         }
1102                 }
1103         }
1104 }
1105
1106 static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
1107 {
1108         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1109         CCGSubSurf *ss = cgdm->ss;
1110         int index;
1111         int totface;
1112         int gridSize = ccgSubSurf_getGridSize(ss);
1113         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1114         int i = 0;
1115         MLoop *mv;
1116         /* char *faceFlags = cgdm->faceFlags; */ /* UNUSED */
1117
1118         if (!cgdm->ehash) {
1119                 MEdge *medge;
1120
1121                 cgdm->ehash = BLI_edgehash_new();
1122                 medge = cgdm->dm.getEdgeArray((DerivedMesh*)cgdm);
1123
1124                 for (i=0; i<cgdm->dm.numEdgeData; i++) {
1125                         BLI_edgehash_insert(cgdm->ehash, medge[i].v1, medge[i].v2, SET_INT_IN_POINTER(i));
1126                 }
1127         }
1128
1129         totface = ccgSubSurf_getNumFaces(ss);
1130         mv = mloop;
1131         for(index = 0; index < totface; index++) {
1132                 CCGFace *f = cgdm->faceMap[index].face;
1133                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1134                 /* int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; */ /* UNUSED */
1135                 /* int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; */ /* UNUSED */
1136
1137                 for(S = 0; S < numVerts; S++) {
1138                         for(y = 0; y < gridSize - 1; y++) {
1139                                 for(x = 0; x < gridSize - 1; x++) {
1140                                         int v1, v2, v3, v4;
1141
1142                                         v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1143                                                                                   edgeSize, gridSize);
1144
1145                                         v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1146                                                                                   edgeSize, gridSize);
1147                                         v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1148                                                                                   edgeSize, gridSize);
1149                                         v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1150                                                                                   edgeSize, gridSize);
1151
1152                                         mv->v = v1;
1153                                         mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v1, v2));
1154                                         mv++, i++;
1155
1156                                         mv->v = v2;
1157                                         mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v2, v3));
1158                                         mv++, i++;
1159
1160                                         mv->v = v3;
1161                                         mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v3, v4));
1162                                         mv++, i++;
1163
1164                                         mv->v = v4;
1165                                         mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(cgdm->ehash, v4, v1));
1166                                         mv++, i++;
1167                                 }
1168                         }
1169                 }
1170         }
1171 }
1172
1173
1174 static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mface)
1175 {
1176         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1177         CCGSubSurf *ss = cgdm->ss;
1178         int index;
1179         int totface;
1180         int gridSize = ccgSubSurf_getGridSize(ss);
1181         /* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */
1182         int i = 0, k = 0;
1183         char *faceFlags = cgdm->faceFlags;
1184
1185         totface = ccgSubSurf_getNumFaces(ss);
1186         for(index = 0; index < totface; index++) {
1187                 CCGFace *f = cgdm->faceMap[index].face;
1188                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1189                 int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH;
1190                 int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0;
1191
1192                 for(S = 0; S < numVerts; S++) {
1193                         for(y = 0; y < gridSize - 1; y++) {
1194                                 for(x = 0; x < gridSize - 1; x++) {
1195                                         MPoly *mf = &mface[i];
1196
1197                                         if (faceFlags) {
1198                                                 mat_nr = faceFlags[index*2+1];
1199                                                 mf->flag = faceFlags[index*2];
1200                                         } else mf->flag = flag;
1201
1202                                         mf->mat_nr = mat_nr;
1203                                         mf->flag = flag;
1204                                         mf->loopstart = k;
1205                                         mf->totloop = 4;
1206
1207                                         k += 4;
1208                                         i++;
1209                                 }
1210                         }
1211                 }
1212         }
1213 }
1214
1215 static void cgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
1216         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1217         CCGSubSurf *ss = cgdm->ss;
1218         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1219         int gridSize = ccgSubSurf_getGridSize(ss);
1220         int i;
1221         CCGVertIterator *vi;
1222         CCGEdgeIterator *ei;
1223         CCGFaceIterator *fi;
1224         CCGFace **faceMap2;
1225         CCGEdge **edgeMap2;
1226         CCGVert **vertMap2;
1227         int index, totvert, totedge, totface;
1228         
1229         totvert = ccgSubSurf_getNumVerts(ss);
1230         vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
1231         vi = ccgSubSurf_getVertIterator(ss);
1232         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1233                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1234
1235                 vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v;
1236         }
1237         ccgVertIterator_free(vi);
1238
1239         totedge = ccgSubSurf_getNumEdges(ss);
1240         edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
1241         ei = ccgSubSurf_getEdgeIterator(ss);
1242         for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
1243                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1244
1245                 edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
1246         }
1247
1248         totface = ccgSubSurf_getNumFaces(ss);
1249         faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
1250         fi = ccgSubSurf_getFaceIterator(ss);
1251         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1252                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1253
1254                 faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f;
1255         }
1256         ccgFaceIterator_free(fi);
1257
1258         i = 0;
1259         for (index=0; index<totface; index++) {
1260                 CCGFace *f = faceMap2[index];
1261                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1262
1263                 copy_v3_v3(cos[i++], ccgSubSurf_getFaceCenterData(f));
1264                 
1265                 for (S=0; S<numVerts; S++) {
1266                         for (x=1; x<gridSize-1; x++) {
1267                                 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1268                         }
1269                 }
1270
1271                 for (S=0; S<numVerts; S++) {
1272                         for (y=1; y<gridSize-1; y++) {
1273                                 for (x=1; x<gridSize-1; x++) {
1274                                         copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1275                                 }
1276                         }
1277                 }
1278         }
1279
1280         for (index=0; index<totedge; index++) {
1281                 CCGEdge *e= edgeMap2[index];
1282                 int x;
1283
1284                 for (x=1; x<edgeSize-1; x++) {
1285                         copy_v3_v3(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
1286                 }
1287         }
1288
1289         for (index=0; index<totvert; index++) {
1290                 CCGVert *v = vertMap2[index];
1291                 copy_v3_v3(cos[i++], ccgSubSurf_getVertData(ss, v));
1292         }
1293
1294         MEM_freeN(vertMap2);
1295         MEM_freeN(edgeMap2);
1296         MEM_freeN(faceMap2);
1297 }
1298 static void cgdm_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
1299         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1300         CCGVertIterator *vi = ccgSubSurf_getVertIterator(cgdm->ss);
1301
1302         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1303                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1304                 DMGridData *vd = ccgSubSurf_getVertData(cgdm->ss, v);
1305                 int index = ccgDM_getVertMapIndex(cgdm->ss, v);
1306
1307                 if (index!=-1)
1308                         func(userData, index, vd->co, vd->no, NULL);
1309         }
1310
1311         ccgVertIterator_free(vi);
1312 }
1313 static void cgdm_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
1314         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1315         CCGSubSurf *ss = cgdm->ss;
1316         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1317         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1318
1319         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1320                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1321                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1322                 int index = ccgDM_getEdgeMapIndex(ss, e);
1323
1324                 if (index!=-1) {
1325                         for (i=0; i<edgeSize-1; i++)
1326                                 func(userData, index, edgeData[i].co, edgeData[i+1].co);
1327                 }
1328         }
1329
1330         ccgEdgeIterator_free(ei);
1331 }
1332
1333 static void ccgDM_drawVerts(DerivedMesh *dm) {
1334         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1335         CCGSubSurf *ss = cgdm->ss;
1336         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1337         int gridSize = ccgSubSurf_getGridSize(ss);
1338         CCGVertIterator *vi;
1339         CCGEdgeIterator *ei;
1340         CCGFaceIterator *fi;
1341
1342         glBegin(GL_POINTS);
1343         vi = ccgSubSurf_getVertIterator(ss);
1344         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1345                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1346                 glVertex3fv(ccgSubSurf_getVertData(ss, v));
1347         }
1348         ccgVertIterator_free(vi);
1349
1350         ei = ccgSubSurf_getEdgeIterator(ss);
1351         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1352                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1353                 int x;
1354
1355                 for (x=1; x<edgeSize-1; x++)
1356                         glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
1357         }
1358         ccgEdgeIterator_free(ei);
1359
1360         fi = ccgSubSurf_getFaceIterator(ss);
1361         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1362                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1363                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1364
1365                 glVertex3fv(ccgSubSurf_getFaceCenterData(f));
1366                 for (S=0; S<numVerts; S++)
1367                         for (x=1; x<gridSize-1; x++)
1368                                 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1369                 for (S=0; S<numVerts; S++)
1370                         for (y=1; y<gridSize-1; y++)
1371                                 for (x=1; x<gridSize-1; x++)
1372                                         glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1373         }
1374         ccgFaceIterator_free(fi);
1375         glEnd();
1376 }
1377
1378 static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
1379 {
1380         if(ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
1381                 CCGFace **faces;
1382                 int totface;
1383
1384                 BLI_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void***)&faces, &totface);
1385                 if(totface) {
1386                         ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface);
1387                         ccgSubSurf_updateNormals(ccgdm->ss, faces, totface);
1388                         MEM_freeN(faces);
1389                 }
1390         }
1391 }
1392
1393 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int UNUSED(drawAllEdges)) {
1394         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1395         CCGSubSurf *ss = ccgdm->ss;
1396         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1397         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1398         int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1399         int totedge = ccgSubSurf_getNumEdges(ss);
1400         int gridSize = ccgSubSurf_getGridSize(ss);
1401         int useAging;
1402
1403         ccgdm_pbvh_update(ccgdm);
1404
1405         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1406
1407         for (j=0; j< totedge; j++) {
1408                 CCGEdge *e = ccgdm->edgeMap[j].edge;
1409                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1410
1411                 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e))
1412                         continue;
1413
1414                 if(ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW))
1415                         continue;
1416
1417                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1418                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1419                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1420                 }
1421
1422                 glBegin(GL_LINE_STRIP);
1423                 for (i=0; i<edgeSize-1; i++) {
1424                         glVertex3fv(edgeData[i].co);
1425                         glVertex3fv(edgeData[i+1].co);
1426                 }
1427                 glEnd();
1428         }
1429
1430         if (useAging && !(G.f&G_BACKBUFSEL)) {
1431                 glColor3ub(0, 0, 0);
1432         }
1433
1434         if (ccgdm->drawInteriorEdges) {
1435                 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1436                         CCGFace *f = ccgFaceIterator_getCurrent(fi);
1437                         int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1438
1439                         for (S=0; S<numVerts; S++) {
1440                                 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1441
1442                                 glBegin(GL_LINE_STRIP);
1443                                 for (x=0; x<gridSize; x++)
1444                                         glVertex3fv(faceGridData[x].co);
1445                                 glEnd();
1446                                 for (y=1; y<gridSize-1; y++) {
1447                                         glBegin(GL_LINE_STRIP);
1448                                         for (x=0; x<gridSize; x++)
1449                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1450                                         glEnd();
1451                                 }
1452                                 for (x=1; x<gridSize-1; x++) {
1453                                         glBegin(GL_LINE_STRIP);
1454                                         for (y=0; y<gridSize; y++)
1455                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1456                                         glEnd();
1457                                 }
1458                         }
1459                 }
1460         }
1461
1462         ccgFaceIterator_free(fi);
1463         ccgEdgeIterator_free(ei);
1464 }
1465 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
1466         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1467         CCGSubSurf *ss = cgdm->ss;
1468         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1469         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1470
1471         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1472                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1473                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1474
1475                 if (!ccgSubSurf_getEdgeNumFaces(e)) {
1476                         glBegin(GL_LINE_STRIP);
1477                         for (i=0; i<edgeSize-1; i++) {
1478                                 glVertex3fv(edgeData[i].co);
1479                                 glVertex3fv(edgeData[i+1].co);
1480                         }
1481                         glEnd();
1482                 }
1483         }
1484
1485         ccgEdgeIterator_free(ei);
1486 }
1487
1488 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
1489 {
1490         float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1491         float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1492         float no[3];
1493
1494         no[0] = b_dY*a_cZ - b_dZ*a_cY;
1495         no[1] = b_dZ*a_cX - b_dX*a_cZ;
1496         no[2] = b_dX*a_cY - b_dY*a_cX;
1497
1498         /* don't normalize, GL_NORMALIZE is enabled */
1499         glNormal3fv(no);
1500 }
1501
1502         /* Only used by non-editmesh types */
1503 static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int fast, int (*setMaterial)(int, void *attribs)) {
1504         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1505         CCGSubSurf *ss = ccgdm->ss;
1506         CCGFaceIterator *fi;
1507         int gridSize = ccgSubSurf_getGridSize(ss);
1508         char *faceFlags = ccgdm->faceFlags;
1509         int step = (fast)? gridSize-1: 1;
1510
1511         ccgdm_pbvh_update(ccgdm);
1512
1513         if(ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
1514                 if(dm->numFaceData) {
1515                         /* should be per face */
1516                         if(!setMaterial(faceFlags[1]+1, NULL))
1517                                 return;
1518
1519                         glShadeModel((faceFlags[0] & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
1520                         BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, (faceFlags[0] & ME_SMOOTH));
1521                         glShadeModel(GL_FLAT);
1522                 }
1523
1524                 return;
1525         }
1526
1527         fi = ccgSubSurf_getFaceIterator(ss);
1528         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1529                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1530                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1531                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1532                 int drawSmooth, mat_nr;
1533
1534                 if(faceFlags) {
1535                         drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1536                         mat_nr= faceFlags[index*2 + 1];
1537                 }
1538                 else {
1539                         drawSmooth = 1;
1540                         mat_nr= 0;
1541                 }
1542                 
1543                 if (!setMaterial(mat_nr+1, NULL))
1544                         continue;
1545
1546                 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1547                 for (S=0; S<numVerts; S++) {
1548                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1549
1550                         if (drawSmooth) {
1551                                 for (y=0; y<gridSize-1; y+=step) {
1552                                         glBegin(GL_QUAD_STRIP);
1553                                         for (x=0; x<gridSize; x+=step) {
1554                                                 DMGridData *a = &faceGridData[(y+0)*gridSize + x];
1555                                                 DMGridData *b = &faceGridData[(y+step)*gridSize + x];
1556
1557                                                 glNormal3fv(a->no);
1558                                                 glVertex3fv(a->co);
1559                                                 glNormal3fv(b->no);
1560                                                 glVertex3fv(b->co);
1561                                         }
1562                                         glEnd();
1563                                 }
1564                         } else {
1565                                 glBegin(GL_QUADS);
1566                                 for (y=0; y<gridSize-1; y+=step) {
1567                                         for (x=0; x<gridSize-1; x+=step) {
1568                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
1569                                                 float *b = faceGridData[(y+0)*gridSize + x + step].co;
1570                                                 float *c = faceGridData[(y+step)*gridSize + x + step].co;
1571                                                 float *d = faceGridData[(y+step)*gridSize + x].co;
1572
1573                                                 ccgDM_glNormalFast(a, b, c, d);
1574
1575                                                 glVertex3fv(d);
1576                                                 glVertex3fv(c);
1577                                                 glVertex3fv(b);
1578                                                 glVertex3fv(a);
1579                                         }
1580                                 }
1581                                 glEnd();
1582                         }
1583                 }
1584         }
1585
1586         ccgFaceIterator_free(fi);
1587 }
1588
1589         /* Only used by non-editmesh types */
1590 static void cgdm_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) {
1591         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1592         CCGSubSurf *ss = cgdm->ss;
1593         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1594         GPUVertexAttribs gattribs;
1595         DMVertexAttribs attribs= {{{NULL}}};
1596         MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE);
1597         int gridSize = ccgSubSurf_getGridSize(ss);
1598         int gridFaces = gridSize - 1;
1599         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1600         int transp, orig_transp, new_transp;
1601         char *faceFlags = cgdm->faceFlags;
1602         int a, b, i, doDraw, numVerts, matnr, new_matnr, totface;
1603
1604         ccgdm_pbvh_update(cgdm);
1605
1606         doDraw = 0;
1607         matnr = -1;
1608         transp = GPU_get_material_blend_mode();
1609         orig_transp = transp;
1610
1611 #define PASSATTRIB(dx, dy, vert) {                                                                                              \
1612         if(attribs.totorco) {                                                                                                           \
1613                 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize);                 \
1614                 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
1615         }                                                                                                                                                       \
1616         for(b = 0; b < attribs.tottface; b++) {                                                                         \
1617                 MTFace *tf = &attribs.tface[b].array[a];                                                                \
1618                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);                   \
1619         }                                                                                                                                                       \
1620         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
1621                 MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
1622                 GLubyte col[4];                                                                                                                 \
1623                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
1624                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
1625         }                                                                                                                                                       \
1626         if(attribs.tottang) {                                                                                                           \
1627                 float *tang = attribs.tang.array[a*4 + vert];                                                   \
1628                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
1629         }                                                                                                                                                       \
1630 }
1631
1632         totface = ccgSubSurf_getNumFaces(ss);
1633         for(a = 0, i = 0; i < totface; i++) {
1634                 CCGFace *f = cgdm->faceMap[i].face;
1635                 int S, x, y, drawSmooth;
1636                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1637                 int origIndex = ccgDM_getFaceMapIndex(ss, f);
1638                 
1639                 numVerts = ccgSubSurf_getFaceNumVerts(f);
1640
1641                 if(faceFlags) {
1642                         drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1643                         new_matnr= faceFlags[index*2 + 1] + 1;
1644                 }
1645                 else {
1646                         drawSmooth = 1;
1647                         new_matnr= 1;
1648                 }
1649
1650                 if(new_matnr != matnr) {
1651                         doDraw = setMaterial(matnr = new_matnr, &gattribs);
1652                         if(doDraw)
1653                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1654                 }
1655
1656                 if(!doDraw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) && !setDrawOptions(userData, origIndex))) {
1657                         a += gridFaces*gridFaces*numVerts;
1658                         continue;
1659                 }
1660
1661                 if(tf) {
1662                         new_transp = tf[i].transp;
1663
1664                         if(new_transp != transp) {
1665                                 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
1666                                         GPU_set_material_blend_mode(orig_transp);
1667                                 else
1668                                         GPU_set_material_blend_mode(new_transp);
1669                                 transp = new_transp;
1670                         }
1671                 }
1672
1673                 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1674                 for (S=0; S<numVerts; S++) {
1675                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1676                         DMGridData *vda, *vdb;
1677
1678                         if (drawSmooth) {
1679                                 for (y=0; y<gridFaces; y++) {
1680                                         glBegin(GL_QUAD_STRIP);
1681                                         for (x=0; x<gridFaces; x++) {
1682                                                 vda = &faceGridData[(y+0)*gridSize + x];
1683                                                 vdb = &faceGridData[(y+1)*gridSize + x];
1684                                                 
1685                                                 PASSATTRIB(0, 0, 0);
1686                                                 glNormal3fv(vda->no);
1687                                                 glVertex3fv(vda->co);
1688
1689                                                 PASSATTRIB(0, 1, 1);
1690                                                 glNormal3fv(vdb->no);
1691                                                 glVertex3fv(vdb->co);
1692
1693                                                 if(x != gridFaces-1)
1694                                                         a++;
1695                                         }
1696
1697                                         vda = &faceGridData[(y+0)*gridSize + x];
1698                                         vdb = &faceGridData[(y+1)*gridSize + x];
1699
1700                                         PASSATTRIB(0, 0, 3);
1701                                         glNormal3fv(vda->no);
1702                                         glVertex3fv(vda->co);
1703
1704                                         PASSATTRIB(0, 1, 2);
1705                                         glNormal3fv(vdb->no);
1706                                         glVertex3fv(vdb->co);
1707
1708                                         glEnd();
1709
1710                                         a++;
1711                                 }
1712                         } else {
1713                                 glBegin(GL_QUADS);
1714                                 for (y=0; y<gridFaces; y++) {
1715                                         for (x=0; x<gridFaces; x++) {
1716                                                 float *aco = faceGridData[(y+0)*gridSize + x].co;
1717                                                 float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
1718                                                 float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
1719                                                 float *dco = faceGridData[(y+1)*gridSize + x].co;
1720
1721                                                 ccgDM_glNormalFast(aco, bco, cco, dco);
1722
1723                                                 PASSATTRIB(0, 1, 1);
1724                                                 glVertex3fv(dco);
1725                                                 PASSATTRIB(1, 1, 2);
1726                                                 glVertex3fv(cco);
1727                                                 PASSATTRIB(1, 0, 3);
1728                                                 glVertex3fv(bco);
1729                                                 PASSATTRIB(0, 0, 0);
1730                                                 glVertex3fv(aco);
1731                                                 
1732                                                 a++;
1733                                         }
1734                                 }
1735                                 glEnd();
1736                         }
1737                 }
1738         }
1739
1740 #undef PASSATTRIB
1741
1742         ccgFaceIterator_free(fi);
1743 }
1744
1745 static void cgdm_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
1746         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1747 }
1748
1749 static void cgdm_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) {
1750         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1751         CCGSubSurf *ss = cgdm->ss;
1752         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1753         int gridSize = ccgSubSurf_getGridSize(ss);
1754         unsigned char *cp1, *cp2;
1755         int useTwoSide=1;
1756
1757         ccgdm_pbvh_update(cgdm);
1758
1759         cp1= col1;
1760         if(col2) {
1761                 cp2= col2;
1762         } else {
1763                 cp2= NULL;
1764                 useTwoSide= 0;
1765         }
1766
1767         glShadeModel(GL_SMOOTH);
1768
1769         if(col2) {
1770                 glEnable(GL_CULL_FACE);
1771         }
1772
1773         glBegin(GL_QUADS);
1774         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1775                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1776                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1777
1778                 for (S=0; S<numVerts; S++) {
1779                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1780                         for (y=0; y<gridSize-1; y++) {
1781                                 for (x=0; x<gridSize-1; x++) {
1782                                         float *a = faceGridData[(y+0)*gridSize + x].co;
1783                                         float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1784                                         float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1785                                         float *d = faceGridData[(y+1)*gridSize + x].co;
1786
1787                                         glColor3ub(cp1[3], cp1[2], cp1[1]);
1788                                         glVertex3fv(d);
1789                                         glColor3ub(cp1[7], cp1[6], cp1[5]);
1790                                         glVertex3fv(c);
1791                                         glColor3ub(cp1[11], cp1[10], cp1[9]);
1792                                         glVertex3fv(b);
1793                                         glColor3ub(cp1[15], cp1[14], cp1[13]);
1794                                         glVertex3fv(a);
1795
1796                                         if (useTwoSide) {
1797                                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
1798                                                 glVertex3fv(a);
1799                                                 glColor3ub(cp2[11], cp2[10], cp2[9]);
1800                                                 glVertex3fv(b);
1801                                                 glColor3ub(cp2[7], cp2[6], cp2[5]);
1802                                                 glVertex3fv(c);
1803                                                 glColor3ub(cp2[3], cp2[2], cp2[1]);
1804                                                 glVertex3fv(d);
1805                                         }
1806
1807                                         if (cp2) cp2+=16;
1808                                         cp1+=16;
1809                                 }
1810                         }
1811                 }
1812         }
1813         glEnd();
1814
1815         ccgFaceIterator_free(fi);
1816 }
1817
1818 static void cgdm_drawFacesTex_common(DerivedMesh *dm,
1819         int (*drawParams)(MTFace *tface, int has_vcol, int matnr),
1820         int (*drawParamsMapped)(void *userData, int index),
1821         void *userData) 
1822 {
1823         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1824         CCGSubSurf *ss = cgdm->ss;
1825         MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
1826         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
1827         char *faceFlags = cgdm->faceFlags;
1828         int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss);
1829         int gridFaces = gridSize - 1;
1830
1831         ccgdm_pbvh_update(cgdm);
1832
1833         if(!mcol)
1834                 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
1835
1836         totface = ccgSubSurf_getNumFaces(ss);
1837         for(i = 0; i < totface; i++) {
1838                 CCGFace *f = cgdm->faceMap[i].face;
1839                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1840                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
1841                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1842                 unsigned char *cp= NULL;
1843                 int mat_nr;
1844
1845                 if(faceFlags) {
1846                         drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
1847                         mat_nr= faceFlags[origIndex*2 + 1];
1848                 }
1849                 else {
1850                         drawSmooth = 1;
1851                         mat_nr= 0;
1852                 }
1853
1854                 if(drawParams)
1855                         flag = drawParams(tf, mcol!=NULL, mat_nr);
1856                 else if (index != ORIGINDEX_NONE)
1857                         flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1;
1858                 else
1859                         flag= GPU_enable_material(mat_nr, NULL) ? 1:0;
1860
1861
1862                 if (flag == 0) { /* flag 0 == the face is hidden or invisible */
1863                         if(tf) tf += gridFaces*gridFaces*numVerts;
1864                         if(mcol) mcol += gridFaces*gridFaces*numVerts*4;
1865                         continue;
1866                 }
1867
1868                 /* flag 1 == use vertex colors */
1869                 if(mcol) {
1870                         if(flag==1) cp= (unsigned char*)mcol;
1871                         mcol += gridFaces*gridFaces*numVerts*4;
1872                 }
1873
1874                 for (S=0; S<numVerts; S++) {
1875                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1876                         DMGridData *a, *b;
1877
1878                         if (drawSmooth) {
1879                                 glShadeModel(GL_SMOOTH);
1880                                 for (y=0; y<gridFaces; y++) {
1881                                         glBegin(GL_QUAD_STRIP);
1882                                         for (x=0; x<gridFaces; x++) {
1883                                                 a = &faceGridData[(y+0)*gridSize + x];
1884                                                 b = &faceGridData[(y+1)*gridSize + x];
1885
1886                                                 if(tf) glTexCoord2fv(tf->uv[0]);
1887                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1888                                                 glNormal3fv(a->no);
1889                                                 glVertex3fv(a->co);
1890
1891                                                 if(tf) glTexCoord2fv(tf->uv[1]);
1892                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1893                                                 glNormal3fv(b->no);
1894                                                 glVertex3fv(b->co);
1895                                                 
1896                                                 if(x != gridFaces-1) {
1897                                                         if(tf) tf++;
1898                                                         if(cp) cp += 16;
1899                                                 }
1900                                         }
1901
1902                                         a = &faceGridData[(y+0)*gridSize + x];
1903                                         b = &faceGridData[(y+1)*gridSize + x];
1904
1905                                         if(tf) glTexCoord2fv(tf->uv[3]);
1906                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1907                                         glNormal3fv(a->no);
1908                                         glVertex3fv(a->co);
1909
1910                                         if(tf) glTexCoord2fv(tf->uv[2]);
1911                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1912                                         glNormal3fv(b->no);
1913                                         glVertex3fv(b->co);
1914
1915                                         if(tf) tf++;
1916                                         if(cp) cp += 16;
1917
1918                                         glEnd();
1919                                 }
1920                         } else {
1921                                 glShadeModel(GL_FLAT);
1922                                 glBegin(GL_QUADS);
1923                                 for (y=0; y<gridFaces; y++) {
1924                                         for (x=0; x<gridFaces; x++) {
1925                                                 float *a_co = faceGridData[(y+0)*gridSize + x].co;
1926                                                 float *b_co = faceGridData[(y+0)*gridSize + x + 1].co;
1927                                                 float *c_co = faceGridData[(y+1)*gridSize + x + 1].co;
1928                                                 float *d_co = faceGridData[(y+1)*gridSize + x].co;
1929
1930                                                 ccgDM_glNormalFast(a_co, b_co, c_co, d_co);
1931
1932                                                 if(tf) glTexCoord2fv(tf->uv[1]);
1933                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1934                                                 glVertex3fv(d_co);
1935
1936                                                 if(tf) glTexCoord2fv(tf->uv[2]);
1937                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1938                                                 glVertex3fv(c_co);
1939
1940                                                 if(tf) glTexCoord2fv(tf->uv[3]);
1941                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1942                                                 glVertex3fv(b_co);
1943
1944                                                 if(tf) glTexCoord2fv(tf->uv[0]);
1945                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1946                                                 glVertex3fv(a_co);
1947
1948                                                 if(tf) tf++;
1949                                                 if(cp) cp += 16;
1950                                         }
1951                                 }
1952                                 glEnd();
1953                         }
1954                 }
1955         }
1956 }
1957
1958 static void cgdm_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr))
1959 {
1960         cgdm_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
1961 }
1962
1963 static void cgdm_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1964 {
1965         cgdm_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
1966 }
1967
1968 static void cgdm_drawUVEdges(DerivedMesh *dm)
1969 {
1970
1971         MFace *mf = dm->getTessFaceArray(dm);
1972         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
1973         int i;
1974         
1975         if (tf) {
1976                 glBegin(GL_LINES);
1977                 for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
1978                         if(!(mf->flag&ME_HIDE)) {
1979                                 glVertex2fv(tf->uv[0]);
1980                                 glVertex2fv(tf->uv[1]);
1981         
1982                                 glVertex2fv(tf->uv[1]);
1983                                 glVertex2fv(tf->uv[2]);
1984         
1985                                 if(!mf->v4) {
1986                                         glVertex2fv(tf->uv[2]);
1987                                         glVertex2fv(tf->uv[0]);
1988                                 } else {
1989                                         glVertex2fv(tf->uv[2]);
1990                                         glVertex2fv(tf->uv[3]);
1991         
1992                                         glVertex2fv(tf->uv[3]);
1993                                         glVertex2fv(tf->uv[0]);
1994                                 }
1995                         }
1996                 }
1997                 glEnd();
1998         }
1999 }
2000
2001 static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs)) {
2002         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2003         CCGSubSurf *ss = cgdm->ss;
2004         MCol *mcol= NULL;
2005         int i, gridSize = ccgSubSurf_getGridSize(ss);
2006         char *faceFlags = cgdm->faceFlags;
2007         int gridFaces = gridSize - 1, totface;
2008
2009         if(useColors) {
2010                 mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
2011                 if(!mcol)
2012                         mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
2013         }
2014
2015         totface = ccgSubSurf_getNumFaces(ss);
2016         for(i = 0; i < totface; i++) {
2017                 CCGFace *f = cgdm->faceMap[i].face;
2018                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2019                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
2020                 int origIndex;
2021                 unsigned char *cp= NULL;
2022
2023                 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2024
2025                 if(faceFlags) drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
2026                 else drawSmooth = 1;
2027
2028                 if(mcol) {
2029                         cp= (unsigned char*)mcol;
2030                         mcol += gridFaces*gridFaces*numVerts*4;
2031                 }
2032
2033                 {
2034                         int draw= 1;
2035
2036                         if(index == ORIGINDEX_NONE)
2037                                 draw= setMaterial(faceFlags ? faceFlags[origIndex*2 + 1] + 1: 1, NULL); /* XXX, no faceFlags no material */
2038                         else if (setDrawOptions)
2039                                 draw= setDrawOptions(userData, index, &drawSmooth);
2040
2041                         if (draw) {
2042                                 if (draw==2) {
2043                                           glEnable(GL_POLYGON_STIPPLE);
2044                                           glPolygonStipple(stipple_quarttone);
2045                                 }
2046                                 
2047                                 for (S=0; S<numVerts; S++) {
2048                                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2049                                         if (drawSmooth) {
2050                                                 glShadeModel(GL_SMOOTH);
2051                                                 for (y=0; y<gridFaces; y++) {
2052                                                         DMGridData *a, *b;
2053                                                         glBegin(GL_QUAD_STRIP);
2054                                                         for (x=0; x<gridFaces; x++) {
2055                                                                 a = &faceGridData[(y+0)*gridSize + x];
2056                                                                 b = &faceGridData[(y+1)*gridSize + x];
2057         
2058                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2059                                                                 glNormal3fv(a->no);
2060                                                                 glVertex3fv(a->co);
2061                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2062                                                                 glNormal3fv(b->no);
2063                                                                 glVertex3fv(b->co);
2064
2065                                                                 if(x != gridFaces-1) {
2066                                                                         if(cp) cp += 16;
2067                                                                 }
2068                                                         }
2069
2070                                                         a = &faceGridData[(y+0)*gridSize + x];
2071                                                         b = &faceGridData[(y+1)*gridSize + x];
2072
2073                                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2074                                                         glNormal3fv(a->no);
2075                                                         glVertex3fv(a->co);
2076                                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2077                                                         glNormal3fv(b->no);
2078                                                         glVertex3fv(b->co);
2079
2080                                                         if(cp) cp += 16;
2081
2082                                                         glEnd();
2083                                                 }
2084                                         } else {
2085                                                 glShadeModel(GL_FLAT);
2086                                                 glBegin(GL_QUADS);
2087                                                 for (y=0; y<gridFaces; y++) {
2088                                                         for (x=0; x<gridFaces; x++) {
2089                                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
2090                                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
2091                                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
2092                                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
2093
2094                                                                 ccgDM_glNormalFast(a, b, c, d);
2095         
2096                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2097                                                                 glVertex3fv(d);
2098                                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2099                                                                 glVertex3fv(c);
2100                                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2101                                                                 glVertex3fv(b);
2102                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2103                                                                 glVertex3fv(a);
2104
2105                                                                 if(cp) cp += 16;
2106                                                         }
2107                                                 }
2108                                                 glEnd();
2109                                         }
2110                                 }
2111                                 if (draw==2)
2112                                         glDisable(GL_POLYGON_STIPPLE);
2113                         }
2114                 }
2115         }
2116 }
2117 static void cgdm_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
2118         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2119         CCGSubSurf *ss = cgdm->ss;
2120         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2121         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2122
2123         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2124
2125         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2126                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2127                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2128                 int index = ccgDM_getEdgeMapIndex(ss, e);
2129
2130                 glBegin(GL_LINE_STRIP);
2131                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2132                         if (useAging && !(G.f&G_BACKBUFSEL)) {
2133                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2134                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
2135                         }
2136
2137                         for (i=0; i<edgeSize-1; i++) {
2138                                 glVertex3fv(edgeData[i].co);
2139                                 glVertex3fv(edgeData[i+1].co);
2140                         }
2141                 }
2142                 glEnd();
2143         }
2144
2145         ccgEdgeIterator_free(ei);
2146 }
2147 static void cgdm_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
2148         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2149         CCGSubSurf *ss = cgdm->ss;
2150         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2151         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2152
2153         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2154
2155         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2156                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2157                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2158                 int index = ccgDM_getEdgeMapIndex(ss, e);
2159
2160                 glBegin(GL_LINE_STRIP);
2161                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2162                         for (i=0; i<edgeSize; i++) {
2163                                 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
2164
2165                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
2166                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2167                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
2168                                 }
2169
2170                                 glVertex3fv(edgeData[i].co);
2171                         }
2172                 }
2173                 glEnd();
2174         }
2175
2176         ccgEdgeIterator_free(ei);
2177 }
2178 static void cgdm_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
2179         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2180         CCGSubSurf *ss = cgdm->ss;
2181         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
2182
2183         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2184                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2185                 int index = ccgDM_getFaceMapIndex(ss, f);
2186
2187                 if (index!=-1) {
2188                                 /* Face center data normal isn't updated atm. */
2189                         DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
2190
2191                         func(userData, index, vd->co, vd->no);
2192                 }
2193         }
2194
2195         ccgFaceIterator_free(fi);
2196 }
2197
2198 static void cgdm_release(DerivedMesh *dm) {
2199         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2200
2201         if (DM_release(dm)) {
2202                 /* Before freeing, need to update the displacement map */
2203                 if(ccgdm->multires.modified) {
2204                         /* Check that mmd still exists */
2205                         if(!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
2206                                 ccgdm->multires.mmd = NULL;
2207                         if(ccgdm->multires.mmd)
2208                                 ccgdm->multires.update(dm);
2209                 }
2210
2211                 if (ccgdm->ehash)
2212                         BLI_edgehash_free(ccgdm->ehash, NULL);
2213
2214                 if(ccgdm->reverseFaceMap) MEM_freeN(ccgdm->reverseFaceMap);
2215                 if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
2216                 if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
2217                 if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
2218                 if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
2219                 if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
2220                 if(ccgdm->fmap) MEM_freeN(ccgdm->fmap);
2221                 if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem);
2222                 MEM_freeN(ccgdm->edgeFlags);
2223                 MEM_freeN(ccgdm->faceFlags);
2224                 MEM_freeN(ccgdm->vertMap);
2225                 MEM_freeN(ccgdm->edgeMap);
2226                 MEM_freeN(ccgdm->faceMap);
2227                 MEM_freeN(ccgdm);
2228         }
2229 }
2230
2231 static void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata, 
2232                           CustomData *pdata, int loopstart, int findex, 
2233                           int polyindex, int numTex, int numCol) 
2234 {
2235         MTFace *texface;
2236         MTexPoly *texpoly;
2237         MCol *mcol;
2238         MLoopCol *mloopcol;
2239         MLoopUV *mloopuv;
2240         int i, j, hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL);
2241
2242         for(i=0; i < numTex; i++){
2243                 texface = CustomData_get_n(fdata, CD_MTFACE, findex, i);
2244                 texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i);
2245                 
2246                 texface->tpage = texpoly->tpage;
2247                 texface->flag = texpoly->flag;
2248                 texface->transp = texpoly->transp;
2249                 texface->mode = texpoly->mode;
2250                 texface->tile = texpoly->tile;
2251                 texface->unwrap = texpoly->unwrap;
2252
2253                 mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i);
2254                 for (j=0; j<4; j++, mloopuv++) {
2255                         texface->uv[j][0] = mloopuv->uv[0];
2256                         texface->uv[j][1] = mloopuv->uv[1];
2257                 }
2258         }
2259
2260         for(i=0; i < numCol; i++){
2261                 mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i);
2262                 mcol = CustomData_get_n(fdata, CD_MCOL, findex, i);
2263
2264                 for (j=0; j<4; j++, mloopcol++) {
2265                         mcol[j].r = mloopcol->r;
2266                         mcol[j].g = mloopcol->g;
2267                         mcol[j].b = mloopcol->b;
2268                         mcol[j].a = mloopcol->a;
2269                 }
2270         }
2271         
2272         if (hasWCol) {
2273                 mloopcol = CustomData_get(ldata, loopstart, CD_WEIGHT_MLOOPCOL);
2274                 mcol = CustomData_get(fdata, findex, CD_WEIGHT_MCOL);
2275
2276                 for (j=0; j<4; j++, mloopcol++) {
2277                         mcol[j].r = mloopcol->r;
2278                         mcol[j].g = mloopcol->g;
2279                         mcol[j].b = mloopcol->b;
2280                         mcol[j].a = mloopcol->a;
2281                 }
2282         }
2283 }
2284
2285 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
2286 {
2287         if(type == CD_ORIGINDEX) {
2288                 /* create origindex on demand to save memory */
2289                 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2290                 CCGSubSurf *ss= cgdm->ss;
2291                 int *origindex;
2292                 int a, index, totnone, totorig;
2293
2294                 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2295                 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
2296
2297                 totorig = ccgSubSurf_getNumVerts(ss);
2298                 totnone= dm->numVertData - totorig;
2299
2300                 /* original vertices are at the end */
2301                 for(a=0; a<totnone; a++)
2302                         origindex[a]= ORIGINDEX_NONE;
2303
2304                 for(index=0; index<totorig; index++, a++) {
2305                         CCGVert *v = cgdm->vertMap[index].vert;
2306                         origindex[a] = ccgDM_getVertMapIndex(cgdm->ss, v);
2307                 }
2308
2309                 return origindex;
2310         }
2311
2312         return DM_get_vert_data_layer(dm, type);
2313 }
2314
2315 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
2316 {
2317         if(type == CD_ORIGINDEX) {
2318                 /* create origindex on demand to save memory */
2319                 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2320                 CCGSubSurf *ss= cgdm->ss;
2321                 int *origindex;
2322                 int a, i, index, totnone, totorig, totedge;
2323                 int edgeSize= ccgSubSurf_getEdgeSize(ss);
2324
2325                 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2326                 origindex= DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2327
2328                 totedge= ccgSubSurf_getNumEdges(ss);
2329                 totorig= totedge*(edgeSize - 1);
2330                 totnone= dm->numEdgeData - totorig;
2331
2332                 /* original edges are at the end */
2333                 for(a=0; a<totnone; a++)
2334                         origindex[a]= ORIGINDEX_NONE;
2335
2336                 for(index=0; index<totedge; index++) {
2337                         CCGEdge *e= cgdm->edgeMap[index].edge;
2338                         int mapIndex= ccgDM_getEdgeMapIndex(ss, e);
2339
2340                         for(i = 0; i < edgeSize - 1; i++, a++)
2341                                 origindex[a]= mapIndex;
2342                 }
2343
2344                 return origindex;
2345         }
2346
2347         return DM_get_edge_data_layer(dm, type);
2348 }
2349
2350 static void *ccgDM_get_face_data_layer(DerivedMesh *dm, int type)
2351 {
2352         if(type == CD_ORIGINDEX) {
2353                 /* create origindex on demand to save memory */
2354                 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2355                 CCGSubSurf *ss= cgdm->ss;
2356                 int *origindex;
2357                 int a, i, index, totface;
2358                 int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
2359
2360                 DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2361                 origindex= DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
2362
2363                 totface= ccgSubSurf_getNumFaces(ss);
2364
2365                 for(a=0, index=0; index<totface; index++) {
2366                         CCGFace *f = cgdm->faceMap[index].face;
2367                         int numVerts = ccgSubSurf_getFaceNumVerts(f);
2368                         int mapIndex = ccgDM_getFaceMapIndex(ss, f);
2369
2370                         for(i=0; i<gridFaces*gridFaces*numVerts; i++, a++)
2371                                 origindex[a]= mapIndex;
2372                 }
2373
2374                 return origindex;
2375         }
2376
2377         return DM_get_tessface_data_layer(dm, type);
2378 }
2379
2380 static int ccgDM_getNumGrids(DerivedMesh *dm)
2381 {
2382         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2383         int index, numFaces, numGrids;
2384
2385         numFaces= ccgSubSurf_getNumFaces(cgdm->ss);
2386         numGrids= 0;
2387
2388         for(index=0; index<numFaces; index++) {
2389                 CCGFace *f = cgdm->faceMap[index].face;
2390                 numGrids += ccgSubSurf_getFaceNumVerts(f);
2391         }
2392
2393         return numGrids;
2394 }
2395
2396 static int ccgDM_getGridSize(DerivedMesh *dm)
2397 {
2398         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2399         return ccgSubSurf_getGridSize(cgdm->ss);
2400 }
2401
2402 static int cgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset)
2403 {
2404         CCGFace *adjf;
2405         CCGEdge *e;
2406         int i, j= 0, numFaces, fIndex, numEdges= 0;
2407
2408         e = ccgSubSurf_getFaceEdge(ss, f, S);
2409         numFaces = ccgSubSurf_getEdgeNumFaces(e);
2410
2411         if(numFaces != 2)
2412                 return -1;
2413
2414         for(i = 0; i < numFaces; i++) {
2415                 adjf = ccgSubSurf_getEdgeFace(e, i);
2416
2417                 if(adjf != f) {
2418                         numEdges = ccgSubSurf_getFaceNumVerts(adjf);
2419                         for(j = 0; j < numEdges; j++)
2420                                 if(ccgSubSurf_getFaceEdge(ss, adjf, j) == e)
2421                                         break;
2422
2423                         if(j != numEdges)
2424                                 break;
2425                 }
2426         }
2427         
2428         fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, adjf));
2429
2430         return gridOffset[fIndex] + (j + offset)%numEdges;
2431 }
2432
2433 static void ccgdm_create_grids(DerivedMesh *dm)
2434 {
2435         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2436         CCGSubSurf *ss= cgdm->ss;
2437         DMGridData **gridData;
2438         DMGridAdjacency *gridAdjacency, *adj;
2439         CCGFace **gridFaces;
2440         int *gridOffset;
2441         int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
2442
2443         if(cgdm->gridData)
2444                 return;
2445         
2446         numGrids = ccgDM_getNumGrids(dm);
2447         numFaces = ccgSubSurf_getNumFaces(ss);
2448         /*gridSize = ccgDM_getGridSize(dm);*/  /*UNUSED*/
2449
2450         /* compute offset into grid array for each face */
2451         gridOffset = MEM_mallocN(sizeof(int)*numFaces, "cgdm.gridOffset");
2452
2453         for(gIndex = 0, index = 0; index < numFaces; index++) {
2454                 CCGFace *f = cgdm->faceMap[index].face;
2455                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2456
2457                 gridOffset[index] = gIndex;
2458                 gIndex += numVerts;
2459         }
2460
2461         /* compute grid data */
2462         gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "cgdm.gridData");
2463         gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "cgdm.gridAdjacency");
2464         gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "cgdm.gridFaces");
2465
2466         for(gIndex = 0, index = 0; index < numFaces; index++) {
2467                 CCGFace *f = cgdm->faceMap[index].face;
2468                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2469
2470                 for(S = 0; S < numVerts; S++, gIndex++) {
2471                         int prevS = (S - 1 + numVerts) % numVerts;
2472                         int nextS = (S + 1 + numVerts) % numVerts;
2473
2474                         gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2475                         gridFaces[gIndex] = f;
2476
2477                         adj = &gridAdjacency[gIndex];
2478
2479                         adj->index[0] = gIndex - S + nextS;
2480                         adj->rotation[0] = 3;
2481                         adj->index[1] = cgdm_adjacent_grid(ss, gridOffset, f, prevS, 0);
2482                         adj->rotation[1] = 1;
2483                         adj->index[2] = cgdm_adjacent_grid(ss, gridOffset, f, S, 1);
2484                         adj->rotation[2] = 3;
2485                         adj->index[3] = gIndex - S + prevS;
2486                         adj->rotation[3] = 1;
2487                 }
2488         }
2489
2490         cgdm->gridData = gridData;
2491         cgdm->gridFaces = gridFaces;
2492         cgdm->gridAdjacency = gridAdjacency;
2493         cgdm->gridOffset = gridOffset;
2494 }
2495
2496 static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
2497 {
2498         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2499
2500         ccgdm_create_grids(dm);
2501         return cgdm->gridData;
2502 }
2503
2504 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm)
2505 {
2506         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2507
2508         ccgdm_create_grids(dm);
2509         return cgdm->gridAdjacency;
2510 }
2511
2512 static int *ccgDM_getGridOffset(DerivedMesh *dm)
2513 {
2514         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2515
2516         ccgdm_create_grids(dm);
2517         return cgdm->gridOffset;
2518 }
2519
2520 static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
2521 {
2522         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2523
2524         if(!ccgdm->multires.mmd && !ccgdm->fmap && ob->type == OB_MESH) {
2525                 Mesh *me= ob->data;
2526
2527                 create_vert_face_map(&ccgdm->fmap, &ccgdm->fmap_mem, me->mface,
2528                                      me->totvert, me->totface);
2529         }
2530
2531         return ccgdm->fmap;
2532 }
2533
2534 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
2535 {
2536         MultiresModifierData *mmd= ccgdm->multires.mmd;
2537
2538         /* both of multires and subsurm modifiers are CCG, but
2539            grids should only be used when sculpting on multires */
2540         if(!mmd)
2541                 return 0;
2542
2543         return 1;
2544 }
2545
2546 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
2547 {
2548         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2549         int gridSize, numGrids, grid_pbvh;
2550
2551         if(!ob) {
2552                 ccgdm->pbvh= NULL;
2553                 return NULL;
2554         }
2555
2556         if(!ob->sculpt)
2557                 return NULL;
2558
2559         grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
2560
2561         if(ob->sculpt->pbvh) {
2562                 if(grid_pbvh) {
2563                         /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
2564                            but this can be freed on ccgdm release, this updates the pointers
2565                            when the ccgdm gets remade, the assumption is that the topology
2566                            does not change. */
2567                         ccgdm_create_grids(dm);
2568                         BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
2569                 }
2570
2571                 ccgdm->pbvh = ob->sculpt->pbvh;
2572         }
2573
2574         if(ccgdm->pbvh)
2575                 return ccgdm->pbvh;
2576
2577         /* no pbvh exists yet, we need to create one. only in case of multires
2578            we build a pbvh over the modified mesh, in other cases the base mesh
2579            is being sculpted, so we build a pbvh from that. */
2580         if(grid_pbvh) {
2581                 ccgdm_create_grids(dm);
2582
2583                 gridSize = ccgDM_getGridSize(dm);
2584                 numGrids = ccgDM_getNumGrids(dm);
2585
2586                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2587                 BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
2588                         numGrids, gridSize, (void**)ccgdm->gridFaces);
2589         } else if(ob->type == OB_MESH) {
2590                 Mesh *me= ob->data;
2591                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2592                 BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
2593                                    me->totface, me->totvert);
2594         }
2595
2596         return ccgdm->pbvh;
2597 }
2598
2599 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2600                                                                                  int drawInteriorEdges,
2601                                                                                  int useSubsurfUv,
2602                                                                                  DerivedMesh *dm)
2603 {
2604         CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "cgdm");
2605         CCGVertIterator *vi;
2606         CCGEdgeIterator *ei;
2607         CCGFaceIterator *fi;
2608         int index, totvert, totedge, totface;
2609         int i;
2610         int vertNum, edgeNum, faceNum;
2611         int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex; /* *edgeOrigIndex - as yet, unused  */
2612         short *edgeFlags;
2613         char *faceFlags;
2614         int *loopidx = NULL, *vertidx = NULL;
2615         BLI_array_declare(loopidx);
2616         BLI_array_declare(vertidx);
2617         int loopindex, loopindex2;
2618         int edgeSize, has_edge_origindex;
2619         int gridSize;
2620         int gridFaces, gridCuts;
2621         /*int gridSideVerts;*/
2622         int gridSideEdges;
2623         int numTex, numCol;
2624         int gridInternalEdges;
2625         float *w = NULL;
2626         WeightTable wtable = {0};
2627         MCol *mcol;
2628         MEdge *medge = NULL;
2629         MFace *mface = NULL;
2630         MPoly *mpoly = NULL;
2631
2632         DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
2633                                          ccgSubSurf_getNumFinalVerts(ss),
2634                                          ccgSubSurf_getNumFinalEdges(ss),
2635                                          ccgSubSurf_getNumFinalFaces(ss),
2636                                          ccgSubSurf_getNumFinalFaces(ss)*4, 
2637                                          ccgSubSurf_getNumFinalFaces(ss));
2638         
2639         numTex = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPUV);
2640         numCol = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPCOL);
2641         
2642         if (numTex && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MTFACE) != numTex)
2643                 CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
2644         else if (numCol && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MCOL) != numCol)
2645                 CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
2646
2647         ccgdm->dm.getMinMax = cgdm_getMinMax;
2648         ccgdm->dm.getNumVerts = cgdm_getNumVerts;
2649         ccgdm->dm.getNumEdges = cgdm_getNumEdges;
2650         ccgdm->dm.getNumTessFaces = cgdm_getNumTessFaces;
2651         ccgdm->dm.getNumFaces = cgdm_getNumTessFaces;
2652
2653         ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
2654         ccgdm->dm.getPBVH = ccgDM_getPBVH;
2655
2656         ccgdm->dm.getVert = ccgDM_getFinalVert;
2657         ccgdm->dm.getEdge = ccgDM_getFinalEdge;
2658         ccgdm->dm.getTessFace = ccgDM_getFinalFace;
2659         ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
2660         ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
2661         ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2662         ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2663         ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
2664         ccgdm->dm.copyLoopArray = ccgDM_copyFinalLoopArray;
2665         ccgdm->dm.copyPolyArray = ccgDM_copyFinalPolyArray;
2666         ccgdm->dm.getVertData = DM_get_vert_data;
2667         ccgdm->dm.getEdgeData = DM_get_edge_data;
2668         ccgdm->dm.getTessFaceData = DM_get_face_data;
2669         ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
2670         ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
2671         ccgdm->dm.getTessFaceDataArray = ccgDM_get_face_data_layer;
2672         ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
2673         ccgdm->dm.getGridSize = ccgDM_getGridSize;
2674         ccgdm->dm.getGridData = ccgDM_getGridData;
2675         ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency;
2676         ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
2677         ccgdm->dm.getFaceMap = ccgDM_getFaceMap;
2678         ccgdm->dm.getPBVH = ccgDM_getPBVH;
2679
2680         ccgdm->dm.getTessFace = ccgDM_getFinalFace;
2681         ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2682         ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2683         ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
2684         ccgdm->dm.getVertData = DM_get_vert_data;
2685         ccgdm->dm.getEdgeData = DM_get_edge_data;
2686         ccgdm->dm.getTessFaceData = DM_get_face_data;
2687         ccgdm->dm.getVertDataArray = DM_get_vert_data_layer;
2688         ccgdm->dm.getEdgeDataArray = DM_get_edge_data_layer;
2689         ccgdm->dm.getTessFaceDataArray = DM_get_tessface_data_layer;
2690
2691         ccgdm->dm.getVertCos = cgdm_getVertCos;
2692         ccgdm->dm.foreachMappedVert = cgdm_foreachMappedVert;
2693         ccgdm->dm.foreachMappedEdge = cgdm_foreachMappedEdge;
2694         ccgdm->dm.foreachMappedFaceCenter = cgdm_foreachMappedFaceCenter;
2695         
2696         ccgdm->dm.drawVerts = ccgDM_drawVerts;
2697         ccgdm->dm.drawEdges = ccgDM_drawEdges;
2698         ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
2699         ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
2700         ccgdm->dm.drawFacesColored = cgdm_drawFacesColored;
2701         ccgdm->dm.drawFacesTex = cgdm_drawFacesTex;
2702         ccgdm->dm.drawFacesGLSL = cgdm_drawFacesGLSL;
2703         ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
2704         ccgdm->dm.drawMappedFacesTex = cgdm_drawMappedFacesTex;
2705         ccgdm->dm.drawMappedFacesGLSL = cgdm_drawMappedFacesGLSL;
2706         ccgdm->dm.drawUVEdges = cgdm_drawUVEdges;
2707
2708         ccgdm->dm.drawMappedEdgesInterp = cgdm_drawMappedEdgesInterp;
2709         ccgdm->dm.drawMappedEdges = cgdm_drawMappedEdges;
2710         
2711         ccgdm->dm.release = cgdm_release;
2712         
2713         ccgdm->ss = ss;
2714         ccgdm->drawInteriorEdges = drawInteriorEdges;
2715         ccgdm->useSubsurfUv = useSubsurfUv;
2716
2717         totvert = ccgSubSurf_getNumVerts(ss);
2718         ccgdm->vertMap = MEM_callocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
2719         vi = ccgSubSurf_getVertIterator(ss);
2720         for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2721                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2722
2723                 ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
2724         }
2725         ccgVertIterator_free(vi);
2726
2727         totedge = ccgSubSurf_getNumEdges(ss);
2728         ccgdm->edgeMap = MEM_callocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
2729         ei = ccgSubSurf_getEdgeIterator(ss);
2730         for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2731                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2732
2733                 ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
2734         }
2735
2736         totface = ccgSubSurf_getNumFaces(ss);
2737         ccgdm->faceMap = MEM_callocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
2738         fi = ccgSubSurf_getFaceIterator(ss);
2739         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2740                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2741
2742                 ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
2743         }
2744         ccgFaceIterator_free(fi);
2745
2746         ccgdm->reverseFaceMap = MEM_callocN(sizeof(int)*ccgSubSurf_getNumFinalFaces(ss), "reverseFaceMap");
2747
2748         edgeSize = ccgSubSurf_getEdgeSize(ss);
2749         gridSize = ccgSubSurf_getGridSize(ss);
2750         gridFaces = gridSize - 1;
2751         gridCuts = gridSize - 2;
2752         /*gridInternalVerts = gridSideVerts * gridSideVerts; - as yet, unused */
2753         gridSideEdges = gridSize - 1;
2754         gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
2755
2756         vertNum = 0;
2757         edgeNum = 0;
2758         faceNum = 0;
2759
2760         /* mvert = dm->getVertArray(dm); - as yet unused */
2761         medge = dm->getEdgeArray(dm);
2762         mface = dm->getTessFaceArray(dm);
2763
2764         mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2765         base_polyOrigIndex = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
2766         
2767         /*CDDM hack*/
2768         edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "faceFlags");
2769         faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags");
2770
2771         vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2772         /*edgeOrigIndex = DM_get_edge_data_layer(&cgdm->dm, CD_ORIGINDEX);*/
2773         faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2774
2775         polyOrigIndex = DM_get_face_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2776
2777         if (!CustomData_has_layer(&ccgdm->dm.faceData, CD_MCOL))
2778                 DM_add_tessface_layer(&ccgdm->dm, CD_MCOL, CD_CALLOC, NULL);
2779
2780         mcol = DM_get_tessface_data_layer(&ccgdm->dm, CD_MCOL);
2781         has_edge_origindex = CustomData_has_layer(&ccgdm->dm.edgeData, CD_ORIGINDEX);
2782
2783         faceNum = 0;
2784         loopindex = loopindex2 = 0; //current loop index
2785         for (index = 0; index < totface; index++) {
2786                 CCGFace *f = ccgdm->faceMap[index].face;
2787                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2788                 int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
2789                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2790                 int g2_wid = gridCuts+2;
2791                 float *w2;
2792                 int s, x, y;
2793                 
2794                 origIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
2795                 
2796                 w = get_ss_weights(&wtable, gridCuts, numVerts);
2797
2798                 ccgdm->faceMap[index].startVert = vertNum;
2799                 ccgdm->faceMap[index].startEdge = edgeNum;
2800                 ccgdm->faceMap[index].startFace = faceNum;
2801                 
2802                 faceFlags[0] = mpoly ?  mpoly[origIndex].flag : 0;
2803                 faceFlags[1] = mpoly ? mpoly[origIndex].mat_nr : 0;
2804                 faceFlags += 2;
2805
2806                 /* set the face base vert */
2807                 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
2808
2809                 BLI_array_empty(loopidx);               
2810                 for (s=0; s<numVerts; s++) {
2811                         BLI_array_growone(loopidx);
2812                         loopidx[s] = loopindex++;
2813                 }
2814                 
2815                 BLI_array_empty(vertidx);
2816                                 for(s = 0; s < numVerts; s++) {
2817                         CCGVert *v = ccgSubSurf_getFaceVert(ss, f, s);
2818                         
2819                         BLI_array_growone(vertidx);
2820                         vertidx[s] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2821                 }
2822                 
2823
2824                 /*I think this is for interpolating the center vert?*/
2825                 w2 = w; // + numVerts*(g2_wid-1)*(g2_wid-1); //numVerts*((g2_wid-1)*g2_wid+g2_wid-1);
2826                 DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
2827                                     numVerts, vertNum);
2828                 if (vertOrigIndex) {
2829                         *vertOrigIndex = ORIGINDEX_NONE;
2830                         ++vertOrigIndex;
2831                 }
2832
2833                 ++vertNum;
2834
2835                 /*interpolate per-vert data*/
2836                 for(s = 0; s < numVerts; s++) {
2837                         for(x = 1; x < gridFaces; x++) {
2838                                 w2 = w + s*numVerts*g2_wid*g2_wid + x*numVerts;
2839                                 DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
2840                                                     numVerts, vertNum);
2841
2842                                 if (vertOrigIndex) {
2843                                         *vertOrigIndex = ORIGINDEX_NONE;
2844                                         ++vertOrigIndex;
2845                                 }
2846
2847                                 ++vertNum;
2848                         }
2849                 }
2850
2851                 /*interpolate per-vert data*/
2852                 for(s = 0; s < numVerts; s++) {
2853                         for(y = 1; y < gridFaces; y++) {
2854                                 for(x = 1; x < gridFaces; x++) {
2855                                         w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts;
2856                                         DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
2857                                                             numVerts, vertNum);
2858
2859                                         if (vertOrigIndex) {
2860                                                 *vertOrigIndex = ORIGINDEX_NONE;
2861                                                 ++vertOrigIndex;
2862                                         }
2863
2864                                         ++vertNum;
2865                                 }
2866                         }
2867                 }
2868
2869                 if (has_edge_origindex) {
2870                         for(i = 0; i < numFinalEdges; ++i)
2871                                 *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i,
2872                                                          CD_ORIGINDEX) = ORIGINDEX_NONE;
2873                 }
2874
2875                 for (s=0; s<numVerts; s++) {
2876                         /*interpolate per-face data*/
2877                         for (y=0; y<gridFaces; y++) {
2878                                 for (x=0; x<gridFaces; x++) {
2879                                         w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts;
2880                                         CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
2881                                                           loopidx, w2, NULL, numVerts, loopindex2);
2882                                         loopindex2++;