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