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