svn merge -r39765:39781 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / source / blender / blenkernel / intern / subsurf_ccg.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2005 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /** \file blender/blenkernel/intern/subsurf_ccg.c
31  *  \ingroup bke
32  */
33
34
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdio.h>
38 #include <math.h>
39 #include <float.h>
40
41 #include "MEM_guardedalloc.h"
42
43 #include "DNA_mesh_types.h"
44 #include "DNA_meshdata_types.h"
45 #include "DNA_modifier_types.h"
46 #include "DNA_object_types.h"
47 #include "DNA_scene_types.h"
48
49 #include "BLI_utildefines.h"
50 #include "BLI_blenlib.h"
51 #include "BLI_edgehash.h"
52 #include "BLI_math.h"
53 #include "BLI_memarena.h"
54 #include "BLI_pbvh.h"
55
56 #include "BKE_cdderivedmesh.h"
57 #include "BKE_global.h"
58 #include "BKE_mesh.h"
59 #include "BKE_modifier.h"
60 #include "BKE_paint.h"
61 #include "BKE_scene.h"
62 #include "BKE_subsurf.h"
63 #include "BKE_tessmesh.h"
64
65 #include "PIL_time.h"
66 #include "BLI_array.h"
67
68 #include "BIF_gl.h"
69 #include "BIF_glutil.h"
70
71 #include "GPU_draw.h"
72 #include "GPU_extensions.h"
73 #include "GPU_material.h"
74
75 #include "CCGSubSurf.h"
76
77 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
78                                          int drawInteriorEdges,
79                                          int useSubsurfUv,
80                                          DerivedMesh *dm);
81 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm);
82
83 ///
84
85 static void *arena_alloc(CCGAllocatorHDL a, int numBytes) {
86         return BLI_memarena_alloc(a, numBytes);
87 }
88 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) {
89         void *p2 = BLI_memarena_alloc(a, newSize);
90         if (ptr) {
91                 memcpy(p2, ptr, oldSize);
92         }
93         return p2;
94 }
95 static void arena_free(CCGAllocatorHDL UNUSED(a), void *UNUSED(ptr)) {
96 }
97 static void arena_release(CCGAllocatorHDL a) {
98         BLI_memarena_free(a);
99 }
100
101 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int UNUSED(useFlatSubdiv)) {
102         CCGMeshIFC ifc;
103         CCGSubSurf *ccgSS;
104
105                 /* subdivLevels==0 is not allowed */
106         subdivLevels = MAX2(subdivLevels, 1);
107
108         if (prevSS) {
109                 int oldUseAging;
110
111                 useAging = !!useAging;
112                 ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
113
114                 if (oldUseAging!=useAging) {
115                         ccgSubSurf_free(prevSS);
116                 } else {
117                         ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
118
119                         return prevSS;
120                 }
121         }
122
123         if (useAging) {
124                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
125         } else {
126                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
127         }
128         ifc.vertDataSize = sizeof(DMGridData);
129
130         if (useArena) {
131                 CCGAllocatorIFC allocatorIFC;
132                 CCGAllocatorHDL allocator = BLI_memarena_new((1<<16), "subsurf arena");
133
134                 allocatorIFC.alloc = arena_alloc;
135                 allocatorIFC.realloc = arena_realloc;
136                 allocatorIFC.free = arena_free;
137                 allocatorIFC.release = arena_release;
138
139                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
140         } else {
141                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
142         }
143
144         if (useAging) {
145                 ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
146         }
147
148         ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(DMGridData, no));
149
150         return ccgSS;
151 }
152
153 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
154         CCGVert *v0 = ccgSubSurf_getEdgeVert0(e);
155         CCGVert *v1 = ccgSubSurf_getEdgeVert1(e);
156         int v0idx = *((int*) ccgSubSurf_getVertUserData(ss, v0));
157         int v1idx = *((int*) ccgSubSurf_getVertUserData(ss, v1));
158         int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
159
160         if (x==0) {
161                 return v0idx;
162         } else if (x==edgeSize-1) {
163                 return v1idx;
164         } else {
165                 return edgeBase + x-1;
166         }
167 }
168
169 BM_INLINE int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) {
170         int faceBase = *((int*) ccgSubSurf_getFaceUserData(ss, f));
171         int numVerts = ccgSubSurf_getFaceNumVerts(f);
172
173         if (x==gridSize-1 && y==gridSize-1) {
174                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
175                 return *((int*) ccgSubSurf_getVertUserData(ss, v));
176         } else if (x==gridSize-1) {
177                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
178                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S);
179                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
180                 if (v==ccgSubSurf_getEdgeVert0(e)) {
181                         return edgeBase + (gridSize-1-y)-1;
182                 } else {
183                         return edgeBase + (edgeSize-2-1)-((gridSize-1-y)-1);
184                 }
185         } else if (y==gridSize-1) {
186                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
187                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts);
188                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
189                 if (v==ccgSubSurf_getEdgeVert0(e)) {
190                         return edgeBase + (gridSize-1-x)-1;
191                 } else {
192                         return edgeBase + (edgeSize-2-1)-((gridSize-1-x)-1);
193                 }
194         } else if (x==0 && y==0) {
195                 return faceBase;
196         } else if (x==0) {
197                 S = (S+numVerts-1)%numVerts;
198                 return faceBase + 1 + (gridSize-2)*S + (y-1);
199         } else if (y==0) {
200                 return faceBase + 1 + (gridSize-2)*S + (x-1);
201         } else {
202                 return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1);
203         }
204 }
205
206 static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCGVertHDL *fverts) {
207         unsigned int *fv = &mf->v1;
208         UvMapVert *v, *nv;
209         int j, nverts= mf->v4? 4: 3;
210
211         for (j=0; j<nverts; j++, fv++) {
212                 for (nv=v=get_uv_map_vert(vmap, *fv); v; v=v->next) {
213                         if (v->separate)
214                                 nv= v;
215                         if (v->f == fi)
216                                 break;
217                 }
218
219                 fverts[j]= SET_INT_IN_POINTER(nv->f*4 + nv->tfindex);
220         }
221 }
222
223 static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MTFace *tface) {
224 #if 1 /*BMESH_TODO*/
225         (void)ss;
226         (void)origss;
227         (void)dm;
228         (void)tface;
229 #else
230         MFace *mface = dm->getTessFaceArray(dm);
231         MVert *mvert = dm->getVertArray(dm);
232         int totvert = dm->getNumVerts(dm);
233         int totface = dm->getNumTessFaces(dm);
234         int i, j, seam;
235         UvMapVert *v;
236         UvVertMap *vmap;
237         float limit[2];
238         CCGVertHDL fverts[4];
239         EdgeHash *ehash;
240         float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
241
242         limit[0]= limit[1]= STD_UV_CONNECT_LIMIT;
243         vmap= make_uv_vert_map(mface, tface, totface, totvert, 0, limit);
244         if (!vmap)
245                 return 0;
246         
247         ccgSubSurf_initFullSync(ss);
248
249         /* create vertices */
250         for (i=0; i<totvert; i++) {
251                 if (!get_uv_map_vert(vmap, i))
252                         continue;
253
254                 for (v=get_uv_map_vert(vmap, i)->next; v; v=v->next)
255                         if (v->separate)
256                                 break;
257
258                 seam = (v != NULL) || ((mvert+i)->flag & ME_VERT_MERGED);
259
260                 for (v=get_uv_map_vert(vmap, i); v; v=v->next) {
261                         if (v->separate) {
262                                 CCGVert *ssv;
263                                 CCGVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex);
264                                 float uv[3];
265
266                                 uv[0]= (tface+v->f)->uv[v->tfindex][0];
267                                 uv[1]= (tface+v->f)->uv[v->tfindex][1];
268                                 uv[2]= 0.0f;
269
270                                 ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
271                         }
272                 }
273         }
274
275         /* create edges */
276         ehash = BLI_edgehash_new();
277
278         for (i=0; i<totface; i++) {
279                 MFace *mf = &((MFace*) mface)[i];
280                 int nverts= mf->v4? 4: 3;
281                 CCGFace *origf= ccgSubSurf_getFace(origss, SET_INT_IN_POINTER(i));
282                 unsigned int *fv = &mf->v1;
283
284                 get_face_uv_map_vert(vmap, mf, i, fverts);
285
286                 for (j=0; j<nverts; j++) {
287                         int v0 = GET_INT_FROM_POINTER(fverts[j]);
288                         int v1 = GET_INT_FROM_POINTER(fverts[(j+1)%nverts]);
289                         MVert *mv0 = mvert + *(fv+j);
290                         MVert *mv1 = mvert + *(fv+((j+1)%nverts));
291
292                         if (!BLI_edgehash_haskey(ehash, v0, v1)) {
293                                 CCGEdge *e, *orige= ccgSubSurf_getFaceEdge(origss, origf, j);
294                                 CCGEdgeHDL ehdl= SET_INT_IN_POINTER(i*4 + j);
295                                 float crease;
296
297                                 if ((mv0->flag&mv1->flag) & ME_VERT_MERGED)
298                                         crease = creaseFactor;
299                                 else
300                                         crease = ccgSubSurf_getEdgeCrease(orige);
301
302                                 ccgSubSurf_syncEdge(ss, ehdl, fverts[j], fverts[(j+1)%nverts], crease, &e);
303                                 BLI_edgehash_insert(ehash, v0, v1, NULL);
304                         }
305                 }
306         }
307
308         BLI_edgehash_free(ehash, NULL);
309
310         /* create faces */
311         for (i=0; i<totface; i++) {
312                 MFace *mf = &((MFace*) mface)[i];
313                 int nverts= mf->v4? 4: 3;
314                 CCGFace *f;
315
316                 get_face_uv_map_vert(vmap, mf, i, fverts);
317                 ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), nverts, fverts, &f);
318         }
319
320         free_uv_vert_map(vmap);
321         ccgSubSurf_processSync(ss);
322
323 #endif
324         return 1;
325 }
326
327 static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
328 {
329         CCGSubSurf *uvss;
330         CCGFace **faceMap;
331         MTFace *tf;
332         CCGFaceIterator *fi;
333         int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S;
334         MTFace *dmtface = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, n);
335         MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
336
337         if(!dmtface || !tface)
338                 return;
339
340         /* create a CCGSubSurf from uv's */
341         uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0);
342
343         if(!ss_sync_from_uv(uvss, ss, dm, dmtface)) {
344                 ccgSubSurf_free(uvss);
345                 return;
346         }
347
348         /* get some info from CCGSubSurf */
349         totface = ccgSubSurf_getNumFaces(uvss);
350         /* edgeSize = ccgSubSurf_getEdgeSize(uvss); */ /*UNUSED*/
351         gridSize = ccgSubSurf_getGridSize(uvss);
352         gridFaces = gridSize - 1;
353
354         /* make a map from original faces to CCGFaces */
355         faceMap = MEM_mallocN(totface*sizeof(*faceMap), "facemapuv");
356
357         fi = ccgSubSurf_getFaceIterator(uvss);
358         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
359                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
360                 faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(uvss, f))] = f;
361         }
362         ccgFaceIterator_free(fi);
363
364         /* load coordinates from uvss into tface */
365         tf= tface;
366
367         for(index = 0; index < totface; index++) {
368                 CCGFace *f = faceMap[index];
369                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
370
371                 for (S=0; S<numVerts; S++) {
372                         DMGridData *faceGridData= ccgSubSurf_getFaceGridDataArray(uvss, f, S);
373
374                         for(y = 0; y < gridFaces; y++) {
375                                 for(x = 0; x < gridFaces; x++) {
376                                         float *a = faceGridData[(y + 0)*gridSize + x + 0].co;
377                                         float *b = faceGridData[(y + 0)*gridSize + x + 1].co;
378                                         float *c = faceGridData[(y + 1)*gridSize + x + 1].co;
379                                         float *d = faceGridData[(y + 1)*gridSize + x + 0].co;
380
381                                         tf->uv[0][0] = a[0]; tf->uv[0][1] = a[1];
382                                         tf->uv[1][0] = d[0]; tf->uv[1][1] = d[1];
383                                         tf->uv[2][0] = c[0]; tf->uv[2][1] = c[1];
384                                         tf->uv[3][0] = b[0]; tf->uv[3][1] = b[1];
385
386                                         tf++;
387                                 }
388                         }
389                 }
390         }
391
392         ccgSubSurf_free(uvss);
393         MEM_freeN(faceMap);
394 }
395
396 /* face weighting */
397 typedef struct FaceVertWeightEntry {
398         FaceVertWeight *weight;
399         float *w;
400         int valid;
401 } FaceVertWeightEntry;
402
403 typedef struct WeightTable {
404         FaceVertWeightEntry *weight_table;
405         int len;
406 } WeightTable;
407
408 static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen)
409 {
410         int x, y, i, j;
411         float *w, w1, w2, w4, fac, fac2, fx, fy;
412
413         if (wtable->len <= faceLen) {
414                 void *tmp = MEM_callocN(sizeof(FaceVertWeightEntry)*(faceLen+1), "weight table alloc 2");
415                 
416                 if (wtable->len) {
417                         memcpy(tmp, wtable->weight_table, sizeof(FaceVertWeightEntry)*wtable->len);
418                         MEM_freeN(wtable->weight_table);
419                 }
420                 
421                 wtable->weight_table = tmp;
422                 wtable->len = faceLen+1;
423         }
424
425         if (!wtable->weight_table[faceLen].valid) {
426                 wtable->weight_table[faceLen].valid = 1;
427                 wtable->weight_table[faceLen].w = w = MEM_callocN(sizeof(float)*faceLen*faceLen*(gridCuts+2)*(gridCuts+2), "weight table alloc");
428                 fac = 1.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                         int (*compareDrawOptions)(void *userData, int cur_index, int next_index)) {
2003         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2004         CCGSubSurf *ss = cgdm->ss;
2005         MCol *mcol= NULL;
2006         int i, gridSize = ccgSubSurf_getGridSize(ss);
2007         char *faceFlags = cgdm->faceFlags;
2008         int gridFaces = gridSize - 1, totface;
2009
2010         /* currently unused -- each original face is handled separately */
2011         (void)compareDrawOptions;
2012
2013         if(useColors) {
2014                 mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
2015                 if(!mcol)
2016                         mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
2017         }
2018
2019         totface = ccgSubSurf_getNumFaces(ss);
2020         for(i = 0; i < totface; i++) {
2021                 CCGFace *f = cgdm->faceMap[i].face;
2022                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2023                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
2024                 int origIndex;
2025                 unsigned char *cp= NULL;
2026
2027                 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2028
2029                 if(faceFlags) drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
2030                 else drawSmooth = 1;
2031
2032                 if(mcol) {
2033                         cp= (unsigned char*)mcol;
2034                         mcol += gridFaces*gridFaces*numVerts*4;
2035                 }
2036
2037                 {
2038                         int draw= 1;
2039
2040                         if(index == ORIGINDEX_NONE)
2041                                 draw= setMaterial(faceFlags ? faceFlags[origIndex*2 + 1] + 1: 1, NULL); /* XXX, no faceFlags no material */
2042                         else if (setDrawOptions)
2043                                 draw= setDrawOptions(userData, index, &drawSmooth);
2044
2045                         if (draw) {
2046                                 if (draw==2) {
2047                                           glEnable(GL_POLYGON_STIPPLE);
2048                                           glPolygonStipple(stipple_quarttone);
2049                                 }
2050                                 
2051                                 for (S=0; S<numVerts; S++) {
2052                                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2053                                         if (drawSmooth) {
2054                                                 glShadeModel(GL_SMOOTH);
2055                                                 for (y=0; y<gridFaces; y++) {
2056                                                         DMGridData *a, *b;
2057                                                         glBegin(GL_QUAD_STRIP);
2058                                                         for (x=0; x<gridFaces; x++) {
2059                                                                 a = &faceGridData[(y+0)*gridSize + x];
2060                                                                 b = &faceGridData[(y+1)*gridSize + x];
2061         
2062                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2063                                                                 glNormal3fv(a->no);
2064                                                                 glVertex3fv(a->co);
2065                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2066                                                                 glNormal3fv(b->no);
2067                                                                 glVertex3fv(b->co);
2068
2069                                                                 if(x != gridFaces-1) {
2070                                                                         if(cp) cp += 16;
2071                                                                 }
2072                                                         }
2073
2074                                                         a = &faceGridData[(y+0)*gridSize + x];
2075                                                         b = &faceGridData[(y+1)*gridSize + x];
2076
2077                                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2078                                                         glNormal3fv(a->no);
2079                                                         glVertex3fv(a->co);
2080                                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2081                                                         glNormal3fv(b->no);
2082                                                         glVertex3fv(b->co);
2083
2084                                                         if(cp) cp += 16;
2085
2086                                                         glEnd();
2087                                                 }
2088                                         } else {
2089                                                 glShadeModel(GL_FLAT);
2090                                                 glBegin(GL_QUADS);
2091                                                 for (y=0; y<gridFaces; y++) {
2092                                                         for (x=0; x<gridFaces; x++) {
2093                                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
2094                                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
2095                                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
2096                                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
2097
2098                                                                 ccgDM_glNormalFast(a, b, c, d);
2099         
2100                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2101                                                                 glVertex3fv(d);
2102                                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2103                                                                 glVertex3fv(c);
2104                                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2105                                                                 glVertex3fv(b);
2106                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2107                                                                 glVertex3fv(a);
2108
2109                                                                 if(cp) cp += 16;
2110                                                         }
2111                                                 }
2112                                                 glEnd();
2113                                         }
2114                                 }
2115                                 if (draw==2)
2116                                         glDisable(GL_POLYGON_STIPPLE);
2117                         }
2118                 }
2119         }
2120 }
2121 static void cgdm_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
2122         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2123         CCGSubSurf *ss = cgdm->ss;
2124         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2125         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2126
2127         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2128
2129         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2130                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2131                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2132                 int index = ccgDM_getEdgeMapIndex(ss, e);
2133
2134                 glBegin(GL_LINE_STRIP);
2135                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2136                         if (useAging && !(G.f&G_BACKBUFSEL)) {
2137                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2138                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
2139                         }
2140
2141                         for (i=0; i<edgeSize-1; i++) {
2142                                 glVertex3fv(edgeData[i].co);
2143                                 glVertex3fv(edgeData[i+1].co);
2144                         }
2145                 }
2146                 glEnd();
2147         }
2148
2149         ccgEdgeIterator_free(ei);
2150 }
2151 static void cgdm_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
2152         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2153         CCGSubSurf *ss = cgdm->ss;
2154         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2155         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2156
2157         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2158
2159         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2160                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2161                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2162                 int index = ccgDM_getEdgeMapIndex(ss, e);
2163
2164                 glBegin(GL_LINE_STRIP);
2165                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2166                         for (i=0; i<edgeSize; i++) {
2167                                 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
2168
2169                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
2170                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2171                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
2172                                 }
2173
2174                                 glVertex3fv(edgeData[i].co);
2175                         }
2176                 }
2177                 glEnd();
2178         }
2179
2180         ccgEdgeIterator_free(ei);
2181 }
2182 static void cgdm_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
2183         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2184         CCGSubSurf *ss = cgdm->ss;
2185         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
2186
2187         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2188                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2189                 int index = ccgDM_getFaceMapIndex(ss, f);
2190
2191                 if (index!=-1) {
2192                                 /* Face center data normal isn't updated atm. */
2193                         DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
2194
2195                         func(userData, index, vd->co, vd->no);
2196                 }
2197         }
2198
2199         ccgFaceIterator_free(fi);
2200 }
2201
2202 static void cgdm_release(DerivedMesh *dm) {
2203         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2204
2205         if (DM_release(dm)) {
2206                 /* Before freeing, need to update the displacement map */
2207                 if(ccgdm->multires.modified) {
2208                         /* Check that mmd still exists */
2209                         if(!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
2210                                 ccgdm->multires.mmd = NULL;
2211                         if(ccgdm->multires.mmd)
2212                                 ccgdm->multires.update(dm);
2213                 }
2214
2215                 if (ccgdm->ehash)
2216                         BLI_edgehash_free(ccgdm->ehash, NULL);
2217
2218                 if(ccgdm->reverseFaceMap) MEM_freeN(ccgdm->reverseFaceMap);
2219                 if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
2220                 if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
2221                 if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
2222                 if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
2223                 if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
2224                 if(ccgdm->fmap) MEM_freeN(ccgdm->fmap);
2225                 if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem);
2226                 MEM_freeN(ccgdm->edgeFlags);
2227                 MEM_freeN(ccgdm->faceFlags);
2228                 MEM_freeN(ccgdm->vertMap);
2229                 MEM_freeN(ccgdm->edgeMap);
2230                 MEM_freeN(ccgdm->faceMap);
2231                 MEM_freeN(ccgdm);
2232         }
2233 }
2234
2235 static void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata, 
2236                           CustomData *pdata, int loopstart, int findex, 
2237                           int polyindex, int numTex, int numCol) 
2238 {
2239         MTFace *texface;
2240         MTexPoly *texpoly;
2241         MCol *mcol;
2242         MLoopCol *mloopcol;
2243         MLoopUV *mloopuv;
2244         int i, j, hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL);
2245
2246         for(i=0; i < numTex; i++){
2247                 texface = CustomData_get_n(fdata, CD_MTFACE, findex, i);
2248                 texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i);
2249                 
2250                 texface->tpage = texpoly->tpage;
2251                 texface->flag = texpoly->flag;
2252                 texface->transp = texpoly->transp;
2253                 texface->mode = texpoly->mode;
2254                 texface->tile = texpoly->tile;
2255                 texface->unwrap = texpoly->unwrap;
2256
2257                 mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i);
2258                 for (j=0; j<4; j++, mloopuv++) {
2259                         texface->uv[j][0] = mloopuv->uv[0];
2260                         texface->uv[j][1] = mloopuv->uv[1];
2261                 }
2262         }
2263
2264         for(i=0; i < numCol; i++){
2265                 mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i);
2266                 mcol = CustomData_get_n(fdata, CD_MCOL, findex, i);
2267
2268                 for (j=0; j<4; j++, mloopcol++) {
2269                         mcol[j].r = mloopcol->r;
2270                         mcol[j].g = mloopcol->g;
2271                         mcol[j].b = mloopcol->b;
2272                         mcol[j].a = mloopcol->a;
2273                 }
2274         }
2275         
2276         if (hasWCol) {
2277                 mloopcol = CustomData_get(ldata, loopstart, CD_WEIGHT_MLOOPCOL);
2278                 mcol = CustomData_get(fdata, findex, CD_WEIGHT_MCOL);
2279
2280                 for (j=0; j<4; j++, mloopcol++) {
2281                         mcol[j].r = mloopcol->r;
2282                         mcol[j].g = mloopcol->g;
2283                         mcol[j].b = mloopcol->b;
2284                         mcol[j].a = mloopcol->a;
2285                 }
2286         }
2287 }
2288
2289 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
2290 {
2291         if(type == CD_ORIGINDEX) {
2292                 /* create origindex on demand to save memory */
2293                 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2294                 CCGSubSurf *ss= cgdm->ss;
2295                 int *origindex;
2296                 int a, index, totnone, totorig;
2297
2298                 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2299                 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
2300
2301                 totorig = ccgSubSurf_getNumVerts(ss);
2302                 totnone= dm->numVertData - totorig;
2303
2304                 /* original vertices are at the end */
2305                 for(a=0; a<totnone; a++)
2306                         origindex[a]= ORIGINDEX_NONE;
2307
2308                 for(index=0; index<totorig; index++, a++) {
2309                         CCGVert *v = cgdm->vertMap[index].vert;
2310                         origindex[a] = ccgDM_getVertMapIndex(cgdm->ss, v);
2311                 }
2312
2313                 return origindex;
2314         }
2315
2316         return DM_get_vert_data_layer(dm, type);
2317 }
2318
2319 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
2320 {
2321         if(type == CD_ORIGINDEX) {
2322                 /* create origindex on demand to save memory */
2323                 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2324                 CCGSubSurf *ss= cgdm->ss;
2325                 int *origindex;
2326                 int a, i, index, totnone, totorig, totedge;
2327                 int edgeSize= ccgSubSurf_getEdgeSize(ss);
2328
2329                 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2330                 origindex= DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2331
2332                 totedge= ccgSubSurf_getNumEdges(ss);
2333                 totorig= totedge*(edgeSize - 1);
2334                 totnone= dm->numEdgeData - totorig;
2335
2336                 /* original edges are at the end */
2337                 for(a=0; a<totnone; a++)
2338                         origindex[a]= ORIGINDEX_NONE;
2339
2340                 for(index=0; index<totedge; index++) {
2341                         CCGEdge *e= cgdm->edgeMap[index].edge;
2342                         int mapIndex= ccgDM_getEdgeMapIndex(ss, e);
2343
2344                         for(i = 0; i < edgeSize - 1; i++, a++)
2345                                 origindex[a]= mapIndex;
2346                 }
2347
2348                 return origindex;
2349         }
2350
2351         return DM_get_edge_data_layer(dm, type);
2352 }
2353
2354 static void *ccgDM_get_face_data_layer(DerivedMesh *dm, int type)
2355 {
2356         if(type == CD_ORIGINDEX) {
2357                 /* create origindex on demand to save memory */
2358                 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2359                 CCGSubSurf *ss= cgdm->ss;
2360                 int *origindex;
2361                 int a, i, index, totface;
2362                 int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
2363
2364                 DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2365                 origindex= DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
2366
2367                 totface= ccgSubSurf_getNumFaces(ss);
2368
2369                 for(a=0, index=0; index<totface; index++) {
2370                         CCGFace *f = cgdm->faceMap[index].face;
2371                         int numVerts = ccgSubSurf_getFaceNumVerts(f);
2372                         int mapIndex = ccgDM_getFaceMapIndex(ss, f);
2373
2374                         for(i=0; i<gridFaces*gridFaces*numVerts; i++, a++)
2375                                 origindex[a]= mapIndex;
2376                 }
2377
2378                 return origindex;
2379         }
2380
2381         return DM_get_tessface_data_layer(dm, type);
2382 }
2383
2384 static int ccgDM_getNumGrids(DerivedMesh *dm)
2385 {
2386         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2387         int index, numFaces, numGrids;
2388
2389         numFaces= ccgSubSurf_getNumFaces(cgdm->ss);
2390         numGrids= 0;
2391
2392         for(index=0; index<numFaces; index++) {
2393                 CCGFace *f = cgdm->faceMap[index].face;
2394                 numGrids += ccgSubSurf_getFaceNumVerts(f);
2395         }
2396
2397         return numGrids;
2398 }
2399
2400 static int ccgDM_getGridSize(DerivedMesh *dm)
2401 {
2402         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2403         return ccgSubSurf_getGridSize(cgdm->ss);
2404 }
2405
2406 static int cgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset)
2407 {
2408         CCGFace *adjf;
2409         CCGEdge *e;
2410         int i, j= 0, numFaces, fIndex, numEdges= 0;
2411
2412         e = ccgSubSurf_getFaceEdge(ss, f, S);
2413         numFaces = ccgSubSurf_getEdgeNumFaces(e);
2414
2415         if(numFaces != 2)
2416                 return -1;
2417
2418         for(i = 0; i < numFaces; i++) {
2419                 adjf = ccgSubSurf_getEdgeFace(e, i);
2420
2421                 if(adjf != f) {
2422                         numEdges = ccgSubSurf_getFaceNumVerts(adjf);
2423                         for(j = 0; j < numEdges; j++)
2424                                 if(ccgSubSurf_getFaceEdge(ss, adjf, j) == e)
2425                                         break;
2426
2427                         if(j != numEdges)
2428                                 break;
2429                 }
2430         }
2431         
2432         fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, adjf));
2433
2434         return gridOffset[fIndex] + (j + offset)%numEdges;
2435 }
2436
2437 static void ccgdm_create_grids(DerivedMesh *dm)
2438 {
2439         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2440         CCGSubSurf *ss= cgdm->ss;
2441         DMGridData **gridData;
2442         DMGridAdjacency *gridAdjacency, *adj;
2443         CCGFace **gridFaces;
2444         int *gridOffset;
2445         int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
2446
2447         if(cgdm->gridData)
2448                 return;
2449         
2450         numGrids = ccgDM_getNumGrids(dm);
2451         numFaces = ccgSubSurf_getNumFaces(ss);
2452         /*gridSize = ccgDM_getGridSize(dm);*/  /*UNUSED*/
2453
2454         /* compute offset into grid array for each face */
2455         gridOffset = MEM_mallocN(sizeof(int)*numFaces, "cgdm.gridOffset");
2456
2457         for(gIndex = 0, index = 0; index < numFaces; index++) {
2458                 CCGFace *f = cgdm->faceMap[index].face;
2459                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2460
2461                 gridOffset[index] = gIndex;
2462                 gIndex += numVerts;
2463         }
2464
2465         /* compute grid data */
2466         gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "cgdm.gridData");
2467         gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "cgdm.gridAdjacency");
2468         gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "cgdm.gridFaces");
2469
2470         for(gIndex = 0, index = 0; index < numFaces; index++) {
2471                 CCGFace *f = cgdm->faceMap[index].face;
2472                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2473
2474                 for(S = 0; S < numVerts; S++, gIndex++) {
2475                         int prevS = (S - 1 + numVerts) % numVerts;
2476                         int nextS = (S + 1 + numVerts) % numVerts;
2477
2478                         gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2479                         gridFaces[gIndex] = f;
2480
2481                         adj = &gridAdjacency[gIndex];
2482
2483                         adj->index[0] = gIndex - S + nextS;
2484                         adj->rotation[0] = 3;
2485                         adj->index[1] = cgdm_adjacent_grid(ss, gridOffset, f, prevS, 0);
2486                         adj->rotation[1] = 1;
2487                         adj->index[2] = cgdm_adjacent_grid(ss, gridOffset, f, S, 1);
2488                         adj->rotation[2] = 3;
2489                         adj->index[3] = gIndex - S + prevS;
2490                         adj->rotation[3] = 1;
2491                 }
2492         }
2493
2494         cgdm->gridData = gridData;
2495         cgdm->gridFaces = gridFaces;
2496         cgdm->gridAdjacency = gridAdjacency;
2497         cgdm->gridOffset = gridOffset;
2498 }
2499
2500 static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
2501 {
2502         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2503
2504         ccgdm_create_grids(dm);
2505         return cgdm->gridData;
2506 }
2507
2508 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm)
2509 {
2510         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2511
2512         ccgdm_create_grids(dm);
2513         return cgdm->gridAdjacency;
2514 }
2515
2516 static int *ccgDM_getGridOffset(DerivedMesh *dm)
2517 {
2518         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2519
2520         ccgdm_create_grids(dm);
2521         return cgdm->gridOffset;
2522 }
2523
2524 static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
2525 {
2526         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2527
2528         if(!ccgdm->multires.mmd && !ccgdm->fmap && ob->type == OB_MESH) {
2529                 Mesh *me= ob->data;
2530
2531                 create_vert_face_map(&ccgdm->fmap, &ccgdm->fmap_mem, me->mface,
2532                                      me->totvert, me->totface);
2533         }
2534
2535         return ccgdm->fmap;
2536 }
2537
2538 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
2539 {
2540         MultiresModifierData *mmd= ccgdm->multires.mmd;
2541
2542         /* both of multires and subsurm modifiers are CCG, but
2543            grids should only be used when sculpting on multires */
2544         if(!mmd)
2545                 return 0;
2546
2547         return 1;
2548 }
2549
2550 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
2551 {
2552         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2553         int gridSize, numGrids, grid_pbvh;
2554
2555         if(!ob) {
2556                 ccgdm->pbvh= NULL;
2557                 return NULL;
2558         }
2559
2560         if(!ob->sculpt)
2561                 return NULL;
2562
2563         grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
2564
2565         if(ob->sculpt->pbvh) {
2566                 if(grid_pbvh) {
2567                         /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
2568                            but this can be freed on ccgdm release, this updates the pointers
2569                            when the ccgdm gets remade, the assumption is that the topology
2570                            does not change. */
2571                         ccgdm_create_grids(dm);
2572                         BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
2573                 }
2574
2575                 ccgdm->pbvh = ob->sculpt->pbvh;
2576         }
2577
2578         if(ccgdm->pbvh)
2579                 return ccgdm->pbvh;
2580
2581         /* no pbvh exists yet, we need to create one. only in case of multires
2582            we build a pbvh over the modified mesh, in other cases the base mesh
2583            is being sculpted, so we build a pbvh from that. */
2584         if(grid_pbvh) {
2585                 ccgdm_create_grids(dm);
2586
2587                 gridSize = ccgDM_getGridSize(dm);
2588                 numGrids = ccgDM_getNumGrids(dm);
2589
2590                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2591                 BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
2592                         numGrids, gridSize, (void**)ccgdm->gridFaces);
2593         } else if(ob->type == OB_MESH) {
2594                 Mesh *me= ob->data;
2595                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2596                 BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
2597                                    me->totface, me->totvert);
2598         }
2599
2600         return ccgdm->pbvh;
2601 }
2602
2603 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2604                                                                                  int drawInteriorEdges,
2605                                                                                  int useSubsurfUv,
2606                                                                                  DerivedMesh *dm)
2607 {
2608         CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "cgdm");
2609         CCGVertIterator *vi;
2610         CCGEdgeIterator *ei;
2611         CCGFaceIterator *fi;
2612         int index, totvert, totedge, totface;
2613         int i;
2614         int vertNum, edgeNum, faceNum;
2615         int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex; /* *edgeOrigIndex - as yet, unused  */
2616         short *edgeFlags;
2617         char *faceFlags;
2618         int *loopidx = NULL, *vertidx = NULL;
2619         BLI_array_declare(loopidx);
2620         BLI_array_declare(vertidx);
2621         int loopindex, loopindex2;
2622         int edgeSize, has_edge_origindex;
2623         int gridSize;
2624         int gridFaces, gridCuts;
2625         /*int gridSideVerts;*/
2626         int gridSideEdges;
2627         int numTex, numCol;
2628         int gridInternalEdges;
2629         float *w = NULL;
2630         WeightTable wtable = {0};
2631         MCol *mcol;
2632         MEdge *medge = NULL;
2633         MFace *mface = NULL;
2634         MPoly *mpoly = NULL;
2635
2636         DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
2637                                          ccgSubSurf_getNumFinalVerts(ss),
2638                                          ccgSubSurf_getNumFinalEdges(ss),
2639                                          ccgSubSurf_getNumFinalFaces(ss),
2640                                          ccgSubSurf_getNumFinalFaces(ss)*4, 
2641                                          ccgSubSurf_getNumFinalFaces(ss));
2642         
2643         numTex = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPUV);
2644         numCol = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPCOL);
2645         
2646         if (numTex && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MTFACE) != numTex)
2647                 CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
2648         else if (numCol && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MCOL) != numCol)
2649                 CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
2650
2651         ccgdm->dm.getMinMax = cgdm_getMinMax;
2652         ccgdm->dm.getNumVerts = cgdm_getNumVerts;
2653         ccgdm->dm.getNumEdges = cgdm_getNumEdges;
2654         ccgdm->dm.getNumTessFaces = cgdm_getNumTessFaces;
2655         ccgdm->dm.getNumFaces = cgdm_getNumTessFaces;
2656
2657         ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
2658         ccgdm->dm.getPBVH = ccgDM_getPBVH;
2659
2660         ccgdm->dm.getVert = ccgDM_getFinalVert;
2661         ccgdm->dm.getEdge = ccgDM_getFinalEdge;
2662         ccgdm->dm.getTessFace = ccgDM_getFinalFace;
2663         ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
2664         ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
2665         ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2666         ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2667         ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
2668         ccgdm->dm.copyLoopArray = ccgDM_copyFinalLoopArray;
2669         ccgdm->dm.copyPolyArray = ccgDM_copyFinalPolyArray;
2670         ccgdm->dm.getVertData = DM_get_vert_data;
2671         ccgdm->dm.getEdgeData = DM_get_edge_data;
2672         ccgdm->dm.getTessFaceData = DM_get_face_data;
2673         ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
2674         ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
2675         ccgdm->dm.getTessFaceDataArray = ccgDM_get_face_data_layer;
2676         ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
2677         ccgdm->dm.getGridSize = ccgDM_getGridSize;
2678         ccgdm->dm.getGridData = ccgDM_getGridData;
2679         ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency;
2680         ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
2681         ccgdm->dm.getFaceMap = ccgDM_getFaceMap;
2682         ccgdm->dm.getPBVH = ccgDM_getPBVH;
2683
2684         ccgdm->dm.getTessFace = ccgDM_getFinalFace;
2685         ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2686         ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2687         ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
2688         ccgdm->dm.getVertData = DM_get_vert_data;
2689         ccgdm->dm.getEdgeData = DM_get_edge_data;
2690         ccgdm->dm.getTessFaceData = DM_get_face_data;
2691         ccgdm->dm.getVertDataArray = DM_get_vert_data_layer;
2692         ccgdm->dm.getEdgeDataArray = DM_get_edge_data_layer;
2693         ccgdm->dm.getTessFaceDataArray = DM_get_tessface_data_layer;
2694
2695         ccgdm->dm.getVertCos = cgdm_getVertCos;
2696         ccgdm->dm.foreachMappedVert = cgdm_foreachMappedVert;
2697         ccgdm->dm.foreachMappedEdge = cgdm_foreachMappedEdge;
2698         ccgdm->dm.foreachMappedFaceCenter = cgdm_foreachMappedFaceCenter;
2699         
2700         ccgdm->dm.drawVerts = ccgDM_drawVerts;
2701         ccgdm->dm.drawEdges = ccgDM_drawEdges;
2702         ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
2703         ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
2704         ccgdm->dm.drawFacesColored = cgdm_drawFacesColored;
2705         ccgdm->dm.drawFacesTex = cgdm_drawFacesTex;
2706         ccgdm->dm.drawFacesGLSL = cgdm_drawFacesGLSL;
2707         ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
2708         ccgdm->dm.drawMappedFacesTex = cgdm_drawMappedFacesTex;
2709         ccgdm->dm.drawMappedFacesGLSL = cgdm_drawMappedFacesGLSL;
2710         ccgdm->dm.drawUVEdges = cgdm_drawUVEdges;
2711
2712         ccgdm->dm.drawMappedEdgesInterp = cgdm_drawMappedEdgesInterp;
2713         ccgdm->dm.drawMappedEdges = cgdm_drawMappedEdges;
2714         
2715         ccgdm->dm.release = cgdm_release;
2716         
2717         ccgdm->ss = ss;
2718         ccgdm->drawInteriorEdges = drawInteriorEdges;
2719         ccgdm->useSubsurfUv = useSubsurfUv;
2720
2721         totvert = ccgSubSurf_getNumVerts(ss);
2722         ccgdm->vertMap = MEM_callocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
2723         vi = ccgSubSurf_getVertIterator(ss);
2724         for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2725                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2726
2727                 ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
2728         }
2729         ccgVertIterator_free(vi);
2730
2731         totedge = ccgSubSurf_getNumEdges(ss);
2732         ccgdm->edgeMap = MEM_callocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
2733         ei = ccgSubSurf_getEdgeIterator(ss);
2734         for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2735                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2736
2737                 ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
2738         }
2739
2740         totface = ccgSubSurf_getNumFaces(ss);
2741         ccgdm->faceMap = MEM_callocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
2742         fi = ccgSubSurf_getFaceIterator(ss);
2743         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2744                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2745
2746                 ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
2747         }
2748         ccgFaceIterator_free(fi);
2749
2750         ccgdm->reverseFaceMap = MEM_callocN(sizeof(int)*ccgSubSurf_getNumFinalFaces(ss), "reverseFaceMap");
2751
2752         edgeSize = ccgSubSurf_getEdgeSize(ss);
2753         gridSize = ccgSubSurf_getGridSize(ss);
2754         gridFaces = gridSize - 1;
2755         gridCuts = gridSize - 2;
2756         /*gridInternalVerts = gridSideVerts * gridSideVerts; - as yet, unused */
2757         gridSideEdges = gridSize - 1;
2758         gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
2759
2760         vertNum = 0;
2761         edgeNum = 0;
2762         faceNum = 0;
2763
2764         /* mvert = dm->getVertArray(dm); - as yet unused */
2765         medge = dm->getEdgeArray(dm);
2766         mface = dm->getTessFaceArray(dm);
2767
2768         mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2769         base_polyOrigIndex = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
2770         
2771         /*CDDM hack*/
2772         edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "faceFlags");
2773         faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags");
2774
2775         vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2776         /*edgeOrigIndex = DM_get_edge_data_layer(&cgdm->dm, CD_ORIGINDEX);*/
2777         faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2778
2779         polyOrigIndex = DM_get_face_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2780
2781         if (!CustomData_has_layer(&ccgdm->dm.faceData, CD_MCOL))
2782                 DM_add_tessface_layer(&ccgdm->dm, CD_MCOL, CD_CALLOC, NULL);
2783
2784         mcol = DM_get_tessface_data_layer(&ccgdm->dm, CD_MCOL);
2785         has_edge_origindex = CustomData_has_layer(&ccgdm->dm.edgeData, CD_ORIGINDEX);
2786
2787         faceNum = 0;
2788         loopindex = loopindex2 = 0; //current loop index
2789         for (index = 0; index < totface; index++) {
2790                 CCGFace *f = ccgdm->faceMap[index].face;
2791                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2792                 int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
2793                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2794                 int g2_wid = gridCuts+2;
2795                 float *w2;
2796                 int s, x, y;
2797                 
2798                 origIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
2799                 
2800                 w = get_ss_weights(&wtable, gridCuts, numVerts);
2801
2802                 ccgdm->faceMap[index].startVert = vertNum;
2803                 ccgdm->faceMap[index].startEdge = edgeNum;
2804                 ccgdm->faceMap[index].startFace = faceNum;
2805                 
2806                 faceFlags[0] = mpoly ?  mpoly[origIndex].flag : 0;
2807                 faceFlags[1] = mpoly ? mpoly[origIndex].mat_nr : 0;
2808                 faceFlags += 2;
2809
2810                 /* set the face base vert */
2811                 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
2812
2813                 BLI_array_empty(loopidx);               
2814                 for (s=0; s<numVerts; s++) {
2815                         BLI_array_growone(loopidx);
2816                         loopidx[s] = loopindex++;
2817                 }
2818                 
2819                 BLI_array_empty(vertidx);
2820                                 for(s = 0; s < numVerts; s++) {
2821                         CCGVert *v = ccgSubSurf_getFaceVert(ss, f, s);
2822                         
2823                         BLI_array_growone(vertidx);
2824                         vertidx[s] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2825                 }
2826                 
2827
2828                 /*I think this is for interpolating the center vert?*/
2829                 w2 = w; // + numVerts*(g2_wid-1)*(g2_wid-1); //numVerts*((g2_wid-1)*g2_wid+g2_wid-1);
2830                 DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
2831                                     numVerts, vertNum);
2832                 if (vertOrigIndex) {
2833                         *vertOrigIndex = ORIGINDEX_NONE;
2834                         ++vertOrigIndex;
2835                 }
2836
2837                 ++vertNum;
2838
2839                 /*interpolate per-vert data*/
2840                 for(s = 0; s < numVerts; s++) {
2841                         for(x = 1; x < gridFaces; x++) {
2842                                 w2 = w + s*numVerts*g2_wid*g2_wid + x*numVerts;
2843                                 DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
2844                                                     numVerts, vertNum);
2845
2846                                 if (vertOrigIndex) {
2847                                         *vertOrigIndex = ORIGINDEX_NONE;
2848                                         ++vertOrigIndex;
2849                                 }
2850
2851                                 ++vertNum;
2852                         }
2853                 }
2854
2855                 /*interpolate per-vert data*/
2856                 for(s = 0; s < numVerts; s++) {
2857                         for(y = 1; y < gridFaces; y++) {
2858                                 for(x = 1; x < gridFaces; x++) {
2859                                         w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts;
2860                                         DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2,
2861                                                             numVerts, vertNum);
2862
2863                                         if (vertOrigIndex) {
2864                                                 *vertOrigIndex = ORIGINDEX_NONE;
2865                                                 ++vertOrigIndex;
2866                                         }
2867
2868                                         ++vertNum;
2869                                 }
2870                         }
2871                 }
2872
2873                 if (has_edge_origindex) {
2874                         for(i = 0; i < numFinalEdges; ++i)
2875                                 *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i,
2876                                                          CD_ORIGINDEX) = ORIGINDEX_NONE;
2877                 }
2878
2879                 for (s=0; s<numVerts; s++) {
2880                         /*interpolate per-face data*/
2881                         for (y=0; y<gridFaces; y++) {
2882                                 for (x=0; x<gridFaces; x++) {
2883                                         w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts;
2884                                         CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
2885                                                           loopidx, w2, NULL, numVerts, loopindex2);
2886                                         loopindex2++;
2887
2888                                         w2 = w + s*numVerts*g2_wid*g2_wid + ((y+1)*g2_wid+(x))*numVerts;
2889                                         CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
2890                                                           loopidx, w2, NULL, numVerts, loopindex2);
2891                                         loopindex2++;
2892
2893                                         w2 = w + s*numVerts*g2_wid*g2_wid + ((y+1)*g2_wid+(x+1))*numVerts;
2894                                         CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
2895                                                           loopidx, w2, NULL, numVerts, loopindex2);
2896                                         loopindex2++;
2897                                         
2898                                         w2 = w + s*numVerts*g2_wid*g2_wid + ((y)*g2_wid+(x+1))*numVerts;
2899                                         CustomData_interp(&dm->loopData, &ccgdm->dm.loopData,
2900                                                           loopidx, w2, NULL, numVerts, loopindex2);
2901                                         loopindex2++;
2902
2903                                         /*copy over poly data, e.g. mtexpoly*/
2904                                         CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, origIndex, faceNum, 1);
2905
2906                                         /*generate tesselated face data used for drawing*/
2907                                         ccg_loops_to_corners(&ccgdm->dm.faceData, &ccgdm->dm.loopData,
2908                                                 &ccgdm->dm.polyData, loopindex2-4, faceNum, faceNum, numTex, numCol);
2909                                         
2910                                         /*set original index data*/
2911                                         if (faceOrigIndex) {
2912                                                 *faceOrigIndex = origIndex;
2913                                                 faceOrigIndex++;
2914                                         }
2915                                         if (polyOrigIndex) {
2916                                                 *polyOrigIndex = origIndex;
2917                                                 polyOrigIndex++;
2918                                         }
2919
2920                                         ccgdm->reverseFaceMap[faceNum] = index;
2921
2922                                         faceNum++;
2923                                 }
2924                         }
2925                 }
2926
2927                 edgeNum += numFinalEdges;
2928         }
2929
2930         for(index = 0; index < totedge; ++index) {
2931                 CCGEdge *e = ccgdm->edgeMap[index].edge;
2932                 int numFinalEdges = edgeSize - 1;
2933                 int mapIndex = ccgDM_getEdgeMapIndex(ss, e);
2934                 int x;
2935                 int vertIdx[2];
2936                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));