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