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