Bone Heat Weighting
[blender-staging.git] / source / blender / blenkernel / intern / subsurf_ccg.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2005 Blender Foundation.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <stdlib.h>
34 #include <string.h>
35 #include <stdio.h>
36 #include <math.h>
37 #include <float.h>
38
39 #include "MEM_guardedalloc.h"
40
41 #include "DNA_mesh_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_modifier_types.h"
44 #include "DNA_object_types.h"
45
46 #include "BKE_bad_level_calls.h"
47 #include "BKE_cdderivedmesh.h"
48 #include "BKE_customdata.h"
49 #include "BKE_utildefines.h"
50 #include "BKE_global.h"
51 #include "BKE_mesh.h"
52 #include "BKE_subsurf.h"
53 #include "BKE_displist.h"
54 #include "BKE_DerivedMesh.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
63 #include "BIF_gl.h"
64
65 #include "CCGSubSurf.h"
66
67 typedef struct _VertData {
68         float co[3];
69         float no[3];
70 } VertData;
71
72 struct CCGDerivedMesh {
73         DerivedMesh dm;
74
75         CCGSubSurf *ss;
76         int drawInteriorEdges, useSubsurfUv;
77
78         Mesh *me;
79
80         struct {int startVert; CCGVert *vert;} *vertMap;
81         struct {int startVert; int startEdge; CCGEdge *edge;} *edgeMap;
82         struct {int startVert; int startEdge;
83                 int startFace; CCGFace *face;} *faceMap;
84 };
85
86 typedef struct CCGDerivedMesh CCGDerivedMesh;
87
88 static int ccgDM_getVertMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGVert *v);
89 static int ccgDM_getEdgeMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGEdge *e);
90 static int ccgDM_getFaceMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGFace *f);
91
92 ///
93
94 static void *arena_alloc(CCGAllocatorHDL a, int numBytes) {
95         return BLI_memarena_alloc(a, numBytes);
96 }
97 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) {
98         void *p2 = BLI_memarena_alloc(a, newSize);
99         if (ptr) {
100                 memcpy(p2, ptr, oldSize);
101         }
102         return p2;
103 }
104 static void arena_free(CCGAllocatorHDL a, void *ptr) {
105 }
106 static void arena_release(CCGAllocatorHDL a) {
107         BLI_memarena_free(a);
108 }
109
110 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int useFlatSubdiv) {
111         CCGMeshIFC ifc;
112         CCGSubSurf *ccgSS;
113
114                 /* subdivLevels==0 is not allowed */
115         subdivLevels = MAX2(subdivLevels, 1);
116
117         if (prevSS) {
118                 int oldUseAging;
119
120                 useAging = !!useAging;
121                 ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
122
123                 if (oldUseAging!=useAging) {
124                         ccgSubSurf_free(prevSS);
125                 } else {
126                         ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
127
128                         return prevSS;
129                 }
130         }
131
132         if (useAging) {
133                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
134         } else {
135                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
136         }
137         ifc.vertDataSize = sizeof(VertData);
138
139         if (useArena) {
140                 CCGAllocatorIFC allocatorIFC;
141                 CCGAllocatorHDL allocator = BLI_memarena_new((1<<16));
142
143                 allocatorIFC.alloc = arena_alloc;
144                 allocatorIFC.realloc = arena_realloc;
145                 allocatorIFC.free = arena_free;
146                 allocatorIFC.release = arena_release;
147
148                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
149         } else {
150                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
151         }
152
153         if (useAging) {
154                 ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
155         }
156
157         ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(VertData, no));
158
159         return ccgSS;
160 }
161
162 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
163         CCGVert *v0 = ccgSubSurf_getEdgeVert0(ss, e);
164         CCGVert *v1 = ccgSubSurf_getEdgeVert1(ss, e);
165         int v0idx = *((int*) ccgSubSurf_getVertUserData(ss, v0));
166         int v1idx = *((int*) ccgSubSurf_getVertUserData(ss, v1));
167         int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
168
169         if (x==0) {
170                 return v0idx;
171         } else if (x==edgeSize-1) {
172                 return v1idx;
173         } else {
174                 return edgeBase + x-1;
175         }
176 }
177 static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) {
178         int faceBase = *((int*) ccgSubSurf_getFaceUserData(ss, f));
179         int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
180
181         if (x==gridSize-1 && y==gridSize-1) {
182                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
183                 return *((int*) ccgSubSurf_getVertUserData(ss, v));
184         } else if (x==gridSize-1) {
185                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
186                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S);
187                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
188                 if (v==ccgSubSurf_getEdgeVert0(ss, e)) {
189                         return edgeBase + (gridSize-1-y)-1;
190                 } else {
191                         return edgeBase + (edgeSize-2-1)-((gridSize-1-y)-1);
192                 }
193         } else if (y==gridSize-1) {
194                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
195                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts);
196                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
197                 if (v==ccgSubSurf_getEdgeVert0(ss, e)) {
198                         return edgeBase + (gridSize-1-x)-1;
199                 } else {
200                         return edgeBase + (edgeSize-2-1)-((gridSize-1-x)-1);
201                 }
202         } else if (x==0 && y==0) {
203                 return faceBase;
204         } else if (x==0) {
205                 S = (S+numVerts-1)%numVerts;
206                 return faceBase + 1 + (gridSize-2)*S + (y-1);
207         } else if (y==0) {
208                 return faceBase + 1 + (gridSize-2)*S + (x-1);
209         } else {
210                 return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1);
211         }
212 }
213
214 static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCGVertHDL *fverts) {
215         unsigned int *fv = &mf->v1;
216         UvMapVert *v, *nv;
217         int j, nverts= mf->v4? 4: 3;
218
219         for (j=0; j<nverts; j++, fv++) {
220                 for (nv=v=get_uv_map_vert(vmap, *fv); v; v=v->next) {
221                         if (v->separate)
222                                 nv= v;
223                         if (v->f == fi)
224                                 break;
225                 }
226
227                 fverts[j]= (CCGVertHDL)(nv->f*4 + nv->tfindex);
228         }
229 }
230
231 static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MTFace *tface) {
232         MFace *mface = dm->getFaceArray(dm);
233         MVert *mvert = dm->getVertArray(dm);
234         int totvert = dm->getNumVerts(dm);
235         int totface = dm->getNumFaces(dm);
236         int i, j, seam;
237         UvMapVert *v;
238         UvVertMap *vmap;
239         float limit[2];
240         CCGVertHDL fverts[4];
241         EdgeHash *ehash;
242         float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
243
244         limit[0]= limit[1]= 0.0001f;
245         vmap= make_uv_vert_map(mface, tface, totface, totvert, 0, limit);
246         if (!vmap)
247                 return 0;
248         
249         ccgSubSurf_initFullSync(ss);
250
251         /* create vertices */
252         for (i=0; i<totvert; i++) {
253                 if (!get_uv_map_vert(vmap, i))
254                         continue;
255
256                 for (v=get_uv_map_vert(vmap, i)->next; v; v=v->next)
257                         if (v->separate)
258                                 break;
259
260                 seam = (v != NULL) || ((mvert+i)->flag & ME_VERT_MERGED);
261
262                 for (v=get_uv_map_vert(vmap, i); v; v=v->next) {
263                         if (v->separate) {
264                                 CCGVert *ssv;
265                                 CCGVertHDL vhdl = (CCGVertHDL)(v->f*4 + v->tfindex);
266                                 float uv[3];
267
268                                 uv[0]= (tface+v->f)->uv[v->tfindex][0];
269                                 uv[1]= (tface+v->f)->uv[v->tfindex][1];
270                                 uv[2]= 0.0f;
271
272                                 ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
273                         }
274                 }
275         }
276
277         /* create edges */
278         ehash = BLI_edgehash_new();
279
280         for (i=0; i<totface; i++) {
281                 MFace *mf = &((MFace*) mface)[i];
282                 int nverts= mf->v4? 4: 3;
283                 CCGFace *origf= ccgSubSurf_getFace(origss, (CCGFaceHDL)i);
284                 unsigned int *fv = &mf->v1;
285
286                 get_face_uv_map_vert(vmap, mf, i, fverts);
287
288                 for (j=0; j<nverts; j++) {
289                         int v0 = (int)fverts[j];
290                         int v1 = (int)fverts[(j+1)%nverts];
291                         MVert *mv0 = mvert + *(fv+j);
292                         MVert *mv1 = mvert + *(fv+((j+1)%nverts));
293
294                         if (!BLI_edgehash_haskey(ehash, v0, v1)) {
295                                 CCGEdge *e, *orige= ccgSubSurf_getFaceEdge(origss, origf, j);
296                                 CCGEdgeHDL ehdl= (CCGEdgeHDL)(i*4 + j);
297                                 float crease;
298
299                                 if ((mv0->flag&mv1->flag) & ME_VERT_MERGED)
300                                         crease = creaseFactor;
301                                 else
302                                         crease = ccgSubSurf_getEdgeCrease(origss, orige);
303
304                                 ccgSubSurf_syncEdge(ss, ehdl, fverts[j], fverts[(j+1)%nverts], crease, &e);
305                                 BLI_edgehash_insert(ehash, v0, v1, NULL);
306                         }
307                 }
308         }
309
310         BLI_edgehash_free(ehash, NULL);
311
312         /* create faces */
313         for (i=0; i<totface; i++) {
314                 MFace *mf = &((MFace*) mface)[i];
315                 int nverts= mf->v4? 4: 3;
316                 CCGFace *f;
317
318                 get_face_uv_map_vert(vmap, mf, i, fverts);
319                 ccgSubSurf_syncFace(ss, (CCGFaceHDL)i, nverts, fverts, &f);
320         }
321
322         free_uv_vert_map(vmap);
323         ccgSubSurf_processSync(ss);
324
325         return 1;
326 }
327
328 static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
329 {
330         CCGSubSurf *uvss;
331         CCGFace **faceMap;
332         MTFace *tf;
333         CCGFaceIterator *fi;
334         int index, gridSize, gridFaces, edgeSize, totface, x, y, S;
335         MTFace *dmtface = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, n);
336         MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
337
338
339         if(!dmtface || !tface)
340                 return;
341
342         /* create a CCGSubsurf from uv's */
343         uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0);
344
345         if(!ss_sync_from_uv(uvss, ss, dm, dmtface)) {
346                 ccgSubSurf_free(uvss);
347                 return;
348         }
349
350         /* get some info from CCGSubsurf */
351         totface = ccgSubSurf_getNumFaces(uvss);
352         edgeSize = ccgSubSurf_getEdgeSize(uvss);
353         gridSize = ccgSubSurf_getGridSize(uvss);
354         gridFaces = gridSize - 1;
355
356         /* make a map from original faces to CCGFaces */
357         faceMap = MEM_mallocN(totface*sizeof(*faceMap), "facemapuv");
358
359         fi = ccgSubSurf_getFaceIterator(uvss);
360         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
361                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
362                 faceMap[(int) ccgSubSurf_getFaceFaceHandle(uvss, f)] = f;
363         }
364         ccgFaceIterator_free(fi);
365
366         /* load coordinates from uvss into tface */
367         tf= tface;
368
369         for(index = 0; index < totface; index++) {
370                 CCGFace *f = faceMap[index];
371                 int numVerts = ccgSubSurf_getFaceNumVerts(uvss, f);
372
373                 for (S=0; S<numVerts; S++) {
374                         VertData *faceGridData= ccgSubSurf_getFaceGridDataArray(uvss, f, S);
375
376                         for(y = 0; y < gridFaces; y++) {
377                                 for(x = 0; x < gridFaces; x++) {
378                                         float *a = faceGridData[(y + 0)*gridSize + x + 0].co;
379                                         float *b = faceGridData[(y + 0)*gridSize + x + 1].co;
380                                         float *c = faceGridData[(y + 1)*gridSize + x + 1].co;
381                                         float *d = faceGridData[(y + 1)*gridSize + x + 0].co;
382
383                                         tf->uv[0][0] = a[0]; tf->uv[0][1] = a[1];
384                                         tf->uv[1][0] = d[0]; tf->uv[1][1] = d[1];
385                                         tf->uv[2][0] = c[0]; tf->uv[2][1] = c[1];
386                                         tf->uv[3][0] = b[0]; tf->uv[3][1] = b[1];
387
388                                         tf++;
389                                 }
390                         }
391                 }
392         }
393
394         ccgSubSurf_free(uvss);
395         MEM_freeN(faceMap);
396 }
397
398 #if 0
399 static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditmesh, DispListMesh *dlm, MEdge *medge, MTFace *tface)
400 {
401         unsigned int flags = 0;
402         int N = ccgSubSurf_getEdgeNumFaces(ss, e);
403
404         if (!N) flags |= ME_LOOSEEDGE;
405
406         if (ssFromEditmesh) {
407                 EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(ss, e);
408
409                 flags |= ME_EDGEDRAW|ME_EDGERENDER;
410                 if (eed->seam) {
411                         flags |= ME_SEAM;
412                 }
413         } else {
414                 if (edgeIdx!=-1) {
415                         MEdge *origMed = &medge[edgeIdx];
416
417                         if (dlm) {
418                                 flags |= origMed->flag&~ME_EDGE_STEPINDEX;
419                         } else {
420                                 flags |= (origMed->flag&ME_SEAM)|ME_EDGEDRAW|ME_EDGERENDER;
421                         }
422                 }
423         }
424
425         return flags;
426 }
427 #endif
428
429 /* face weighting */
430 static void calc_ss_weights(int gridFaces,
431                             FaceVertWeight **qweight, FaceVertWeight **tweight)
432 {
433         FaceVertWeight *qw, *tw;
434         int x, y, j;
435         int numWeights = gridFaces * gridFaces;
436
437         *tweight = MEM_mallocN(sizeof(**tweight) * numWeights, "ssTriWeight");
438         *qweight = MEM_mallocN(sizeof(**qweight) * numWeights, "ssQuadWeight");
439
440         qw = *qweight;
441         tw = *tweight;
442
443         for (y = 0; y < gridFaces; y++) {
444                 for (x = 0; x < gridFaces; x++) {
445                         for (j = 0; j < 4; j++) {
446                                 int fx = x + (j == 2 || j == 3);
447                                 int fy = y + (j == 1 || j == 2);
448                                 float x_v = (float) fx / gridFaces;
449                                 float y_v = (float) fy / gridFaces;
450                                 float tx_v = (1.0f - x_v), ty_v = (1.0f - y_v);
451                                 float center = (1.0f / 3.0f) * tx_v * ty_v;
452
453                                 (*tw)[j][0] = center + 0.5f * tx_v * y_v;
454                                 (*tw)[j][2] = center + 0.5f * x_v * ty_v;
455                                 (*tw)[j][1] = 1.0f - (*tw)[j][0] - (*tw)[j][2];
456                                 (*tw)[j][3] = 0.0f;
457
458                                 tx_v *= 0.5f;
459                                 ty_v *= 0.5f;
460
461                                 (*qw)[j][3] = tx_v * ty_v;
462                                 (*qw)[j][0] = (*qw)[j][3] + tx_v * y_v;
463                                 (*qw)[j][2] = (*qw)[j][3] + x_v * ty_v;
464                                 (*qw)[j][1] = 1.0f - (*qw)[j][0] - (*qw)[j][2] - (*qw)[j][3];
465
466                         }
467                         tw++;
468                         qw++;
469                 }
470         }
471 }
472
473 DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
474                                  int drawInteriorEdges, int useSubsurfUv,
475                                  DerivedMesh *dm)
476 {
477         DerivedMesh *result;
478         int edgeSize = ccgSubSurf_getEdgeSize(ss);
479         int gridSize = ccgSubSurf_getGridSize(ss);
480         int gridFaces = gridSize - 1;
481         int edgeBase, faceBase;
482         int i, j, k, S, x, y, index;
483         int vertBase = 0;
484         CCGVertIterator *vi;
485         CCGEdgeIterator *ei;
486         CCGFaceIterator *fi;
487         CCGFace **faceMap2;
488         CCGEdge **edgeMap2;
489         CCGVert **vertMap2;
490         int totvert, totedge, totface;
491         MVert *mvert;
492         MEdge *med;
493         MFace *mf;
494         int *origIndex;
495         FaceVertWeight *qweight, *tweight;
496
497         calc_ss_weights(gridFaces, &qweight, &tweight);
498
499         /* vert map */
500         totvert = ccgSubSurf_getNumVerts(ss);
501         vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
502         vi = ccgSubSurf_getVertIterator(ss);
503         for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
504                 CCGVert *v = ccgVertIterator_getCurrent(vi);
505
506                 vertMap2[(int) ccgSubSurf_getVertVertHandle(ss, v)] = v;
507         }
508         ccgVertIterator_free(vi);
509
510         totedge = ccgSubSurf_getNumEdges(ss);
511         edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
512         ei = ccgSubSurf_getEdgeIterator(ss);
513         for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
514                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
515
516                 edgeMap2[(int) ccgSubSurf_getEdgeEdgeHandle(ss, e)] = e;
517         }
518
519         totface = ccgSubSurf_getNumFaces(ss);
520         faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
521         fi = ccgSubSurf_getFaceIterator(ss);
522         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
523                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
524
525                 faceMap2[(int) ccgSubSurf_getFaceFaceHandle(ss, f)] = f;
526         }
527         ccgFaceIterator_free(fi);
528
529         if(dm) {
530                 result = CDDM_from_template(dm, ccgSubSurf_getNumFinalVerts(ss),
531                                             ccgSubSurf_getNumFinalEdges(ss),
532                                             ccgSubSurf_getNumFinalFaces(ss));
533         } else {
534                 result = CDDM_new(ccgSubSurf_getNumFinalVerts(ss),
535                                   ccgSubSurf_getNumFinalEdges(ss),
536                                   ccgSubSurf_getNumFinalFaces(ss));
537         }
538
539         // load verts
540         faceBase = i = 0;
541         mvert = CDDM_get_verts(result);
542         origIndex = result->getVertData(result, 0, CD_ORIGINDEX);
543
544         for(index = 0; index < totface; index++) {
545                 CCGFace *f = faceMap2[index];
546                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
547                 FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
548                 int vertIdx[4];
549
550                 for(S = 0; S < numVerts; S++) {
551                         CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
552
553                         vertIdx[S] = (int)ccgSubSurf_getVertVertHandle(ss, v);
554                 }
555
556                 DM_interp_vert_data(dm, result, vertIdx, weight[0][0], numVerts, i);
557                 VecCopyf(mvert->co, ccgSubSurf_getFaceCenterData(ss, f));
558                 *origIndex = ORIGINDEX_NONE;
559                 ++mvert;
560                 ++origIndex;
561                 i++;
562                 
563                 for(S = 0; S < numVerts; S++) {
564                         int prevS = (S - 1 + numVerts) % numVerts;
565                         int nextS = (S + 1) % numVerts;
566                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
567                         for(x = 1; x < gridFaces; x++) {
568                                 float w[4];
569                                 w[prevS]  = weight[x][0][0];
570                                 w[S]      = weight[x][0][1];
571                                 w[nextS]  = weight[x][0][2];
572                                 w[otherS] = weight[x][0][3];
573                                 DM_interp_vert_data(dm, result, vertIdx, w, numVerts, i);
574                                 VecCopyf(mvert->co,
575                                          ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
576                                 *origIndex = ORIGINDEX_NONE;
577                                 ++mvert;
578                                 ++origIndex;
579                                 i++;
580                         }
581                 }
582
583                 for(S = 0; S < numVerts; S++) {
584                         int prevS = (S - 1 + numVerts) % numVerts;
585                         int nextS = (S + 1) % numVerts;
586                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
587                         for(y = 1; y < gridFaces; y++) {
588                                 for(x = 1; x < gridFaces; x++) {
589                                         float w[4];
590                                         w[prevS]  = weight[y * gridFaces + x][0][0];
591                                         w[S]      = weight[y * gridFaces + x][0][1];
592                                         w[nextS]  = weight[y * gridFaces + x][0][2];
593                                         w[otherS] = weight[y * gridFaces + x][0][3];
594                                         DM_interp_vert_data(dm, result, vertIdx, w, numVerts, i);
595                                         VecCopyf(mvert->co,
596                                                  ccgSubSurf_getFaceGridData(ss, f, S, x, y));
597                                         *origIndex = ORIGINDEX_NONE;
598                                         ++mvert;
599                                         ++origIndex;
600                                         i++;
601                                 }
602                         }
603                 }
604
605                 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = faceBase;
606                 faceBase += 1 + numVerts * ((gridSize-2) + (gridSize-2) * (gridSize-2));
607         }
608
609         edgeBase = i;
610         for(index = 0; index < totedge; index++) {
611                 CCGEdge *e = edgeMap2[index];
612                 int x;
613                 int vertIdx[2];
614
615                 CCGVert *v;
616                 v = ccgSubSurf_getEdgeVert0(ss, e);
617                 vertIdx[0] = (int)ccgSubSurf_getVertVertHandle(ss, v);
618                 v = ccgSubSurf_getEdgeVert1(ss, e);
619                 vertIdx[1] = (int)ccgSubSurf_getVertVertHandle(ss, v);
620
621                 for(x = 1; x < edgeSize - 1; x++) {
622                         float w[2];
623                         w[1] = (float) x / (edgeSize - 1);
624                         w[0] = 1 - w[1];
625                         DM_interp_vert_data(dm, result, vertIdx, w, 2, i);
626                         VecCopyf(mvert->co, ccgSubSurf_getEdgeData(ss, e, x));
627                         *origIndex = ORIGINDEX_NONE;
628                         ++mvert;
629                         ++origIndex;
630                         i++;
631                 }
632
633                 *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = edgeBase;
634                 edgeBase += edgeSize-2;
635         }
636
637         vertBase = i;
638         for(index = 0; index < totvert; index++) {
639                 CCGVert *v = vertMap2[index];
640                 int vertIdx;
641
642                 vertIdx = (int)ccgSubSurf_getVertVertHandle(ss, v);
643
644                 DM_copy_vert_data(dm, result, vertIdx, i, 1);
645                 VecCopyf(mvert->co, ccgSubSurf_getVertData(ss, v));
646
647                 *((int*)ccgSubSurf_getVertUserData(ss, v)) = i;
648                 *origIndex = ccgDM_getVertMapIndex(NULL, ss, v);
649                 ++mvert;
650                 ++origIndex;
651                 i++;
652         }
653
654         // load edges
655         i = 0;
656         med = CDDM_get_edges(result);
657         origIndex = result->getEdgeData(result, 0, CD_ORIGINDEX);
658
659         for(index = 0; index < totface; index++) {
660                 CCGFace *f = faceMap2[index];
661                 int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
662
663                 for(k = 0; k < numVerts; k++) {
664                         for(x = 0; x < gridFaces; x++) {
665                                 if(drawInteriorEdges) med->flag = ME_EDGEDRAW | ME_EDGERENDER;
666                                 med->v1 = getFaceIndex(ss, f, k, x, 0, edgeSize, gridSize);
667                                 med->v2 = getFaceIndex(ss, f, k, x+1, 0, edgeSize, gridSize);
668                                 *origIndex = ORIGINDEX_NONE;
669                                 ++med;
670                                 ++origIndex;
671                                 i++;
672                         }
673
674                         for(x = 1; x < gridFaces; x++) {
675                                 for(y = 0; y < gridFaces; y++) {
676                                         if(drawInteriorEdges)
677                                                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
678                                         med->v1 = getFaceIndex(ss, f, k, x, y, edgeSize, gridSize);
679                                         med->v2 = getFaceIndex(ss, f, k, x, y + 1,
680                                                                edgeSize, gridSize);
681                                         *origIndex = ORIGINDEX_NONE;
682                                         ++med;
683                                         ++origIndex;
684                                         i++;
685
686                                         if(drawInteriorEdges)
687                                                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
688                                         med->v1 = getFaceIndex(ss, f, k, y, x, edgeSize, gridSize);
689                                         med->v2 = getFaceIndex(ss, f, k, y + 1, x,
690                                                                edgeSize, gridSize);
691                                         *origIndex = ORIGINDEX_NONE;
692                                         ++med;
693                                         ++origIndex;
694                                         i++;
695                                 }
696                         }
697                 }
698         }
699
700         for(index = 0; index < totedge; index++) {
701                 CCGEdge *e = edgeMap2[index];
702                 unsigned int flags = 0;
703                 int edgeIdx = (int)ccgSubSurf_getEdgeEdgeHandle(ss, e);
704
705                 if(!ccgSubSurf_getEdgeNumFaces(ss, e)) flags |= ME_LOOSEEDGE;
706
707
708                 if(edgeIdx != -1 && dm) {
709                         MEdge origMed;
710                         dm->getEdge(dm, edgeIdx, &origMed);
711
712                         flags |= origMed.flag;
713                 }
714
715                 for(x = 0; x < edgeSize - 1; x++) {
716                         med->v1 = getEdgeIndex(ss, e, x, edgeSize);
717                         med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
718                         med->flag = flags;
719                         *origIndex = ccgDM_getEdgeMapIndex(NULL, ss, e);
720                         ++med;
721                         ++origIndex;
722                         i++;
723                 }
724         }
725
726         // load faces
727         i = 0;
728         mf = CDDM_get_faces(result);
729         origIndex = result->getFaceData(result, 0, CD_ORIGINDEX);
730
731         for(index = 0; index < totface; index++) {
732                 CCGFace *f = faceMap2[index];
733                 int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
734                 int mat_nr;
735                 int flag;
736                 int mapIndex = ccgDM_getFaceMapIndex(NULL, ss, f);
737                 int faceIdx = (int)ccgSubSurf_getFaceFaceHandle(ss, f);
738
739                 if(!ssFromEditmesh) {
740                         MFace origMFace;
741                         dm->getFace(dm, faceIdx, &origMFace);
742                         
743                         mat_nr = origMFace.mat_nr;
744                         flag = origMFace.flag;
745                 } else {
746                         EditFace *ef = ccgSubSurf_getFaceFaceHandle(ss, f);
747                         mat_nr = ef->mat_nr;
748                         flag = ef->flag;
749                 }
750
751                 for(S = 0; S < numVerts; S++) {
752                         FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
753
754                         for(y = 0; y < gridFaces; y++) {
755                                 for(x = 0; x < gridFaces; x++) {
756                                         mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
757                                                               edgeSize, gridSize);
758                                         mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
759                                                               edgeSize, gridSize);
760                                         mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
761                                                               edgeSize, gridSize);
762                                         mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
763                                                               edgeSize, gridSize);
764                                         mf->mat_nr = mat_nr;
765                                         mf->flag = flag;
766
767                                         if(dm) {
768                                                 int prevS = (S - 1 + numVerts) % numVerts;
769                                                 int nextS = (S + 1) % numVerts;
770                                                 int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
771                                                 FaceVertWeight w;
772
773                                                 for(j = 0; j < 4; ++j) {
774                                                         w[j][prevS]  = (*weight)[j][0];
775                                                         w[j][S]      = (*weight)[j][1];
776                                                         w[j][nextS]  = (*weight)[j][2];
777                                                         w[j][otherS] = (*weight)[j][3];
778                                                 }
779
780                                                 DM_interp_face_data(dm, result, &faceIdx, NULL,
781                                                                     &w, 1, i);
782                                                 weight++;
783                                         }
784
785                                         *origIndex = mapIndex;
786                                         ++mf;
787                                         ++origIndex;
788                                         i++;
789                                 }
790                         }
791                 }
792         }
793
794         MEM_freeN(faceMap2);
795         MEM_freeN(edgeMap2);
796         MEM_freeN(vertMap2);
797
798         MEM_freeN(tweight);
799         MEM_freeN(qweight);
800
801         if(useSubsurfUv) {
802                 CustomData *fdata = &result->faceData;
803                 CustomData *dmfdata = &dm->faceData;
804                 int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
805                 int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
806                 
807                 for (i=0; i<numlayer && i<dmnumlayer; i++)
808                         set_subsurf_uv(ss, dm, result, i);
809         }
810
811         CDDM_calc_normals(result);
812
813         return result;
814 }
815
816 static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
817                                      float (*vertexCos)[3], int useFlatSubdiv)
818 {
819         float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
820         CCGVertHDL fVerts[4];
821         int totvert = dm->getNumVerts(dm);
822         int totedge = dm->getNumEdges(dm);
823         int totface = dm->getNumFaces(dm);
824         int i;
825         int *index;
826         MVert *mvert = dm->getVertArray(dm);
827         MEdge *medge = dm->getEdgeArray(dm);
828         MFace *mface = dm->getFaceArray(dm);
829         MVert *mv;
830         MEdge *me;
831         MFace *mf;
832
833         ccgSubSurf_initFullSync(ss);
834
835         mv = mvert;
836         index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
837         for(i = 0; i < totvert; i++, mv++, index++) {
838                 CCGVert *v;
839
840                 if(vertexCos) {
841                         ccgSubSurf_syncVert(ss, (CCGVertHDL)i, vertexCos[i], 0, &v);
842                 } else {
843                         ccgSubSurf_syncVert(ss, (CCGVertHDL)i, mv->co, 0, &v);
844                 }
845
846                 ((int*)ccgSubSurf_getVertUserData(ss, v))[1] = *index;
847         }
848
849         me = medge;
850         index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX);
851         for(i = 0; i < totedge; i++, me++, index++) {
852                 CCGEdge *e;
853                 float crease;
854
855                 crease = useFlatSubdiv ? creaseFactor :
856                                          me->crease * creaseFactor / 255.0f;
857
858                 ccgSubSurf_syncEdge(ss, (CCGEdgeHDL)i, (CCGVertHDL)me->v1,
859                                     (CCGVertHDL)me->v2, crease, &e);
860
861                 ((int*)ccgSubSurf_getEdgeUserData(ss, e))[1] = *index;
862         }
863
864         mf = mface;
865         index = (int *)dm->getFaceDataArray(dm, CD_ORIGINDEX);
866         for (i = 0; i < totface; i++, mf++, index++) {
867                 CCGFace *f;
868
869                 fVerts[0] = (CCGVertHDL) mf->v1;
870                 fVerts[1] = (CCGVertHDL) mf->v2;
871                 fVerts[2] = (CCGVertHDL) mf->v3;
872                 fVerts[3] = (CCGVertHDL) mf->v4;
873
874                 // this is very bad, means mesh is internally consistent.
875                 // it is not really possible to continue without modifying
876                 // other parts of code significantly to handle missing faces.
877                 // since this really shouldn't even be possible we just bail.
878                 if(ccgSubSurf_syncFace(ss, (CCGFaceHDL)i, fVerts[3] ? 4 : 3,
879                                        fVerts, &f) == eCCGError_InvalidValue) {
880                         static int hasGivenError = 0;
881
882                         if(!hasGivenError) {
883                                 error("Unrecoverable error in SubSurf calculation,"
884                                       " mesh is inconsistent.");
885
886                                 hasGivenError = 1;
887                         }
888
889                         return;
890                 }
891
892                 ((int*)ccgSubSurf_getFaceUserData(ss, f))[1] = *index;
893         }
894
895         ccgSubSurf_processSync(ss);
896 }
897
898 /***/
899
900 static int ccgDM_getVertMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGVert *v) {
901         return ((int*) ccgSubSurf_getVertUserData(ss, v))[1];
902 }
903
904 static int ccgDM_getEdgeMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGEdge *e) {
905         return ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1];
906 }
907
908 static int ccgDM_getFaceMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGFace *f) {
909         return ((int*) ccgSubSurf_getFaceUserData(ss, f))[1];
910 }
911
912 static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
913         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
914         CCGSubSurf *ss = ccgdm->ss;
915         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
916         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
917         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
918         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
919         int gridSize = ccgSubSurf_getGridSize(ss);
920
921         if (!ccgSubSurf_getNumVerts(ss))
922                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
923
924         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
925                 CCGVert *v = ccgVertIterator_getCurrent(vi);
926                 float *co = ccgSubSurf_getVertData(ss, v);
927
928                 DO_MINMAX(co, min_r, max_r);
929         }
930
931         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
932                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
933                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
934
935                 for (i=0; i<edgeSize; i++)
936                         DO_MINMAX(edgeData[i].co, min_r, max_r);
937         }
938
939         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
940                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
941                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
942
943                 for (S=0; S<numVerts; S++) {
944                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
945
946                         for (y=0; y<gridSize; y++)
947                                 for (x=0; x<gridSize; x++)
948                                         DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r);
949                 }
950         }
951
952         ccgFaceIterator_free(fi);
953         ccgEdgeIterator_free(ei);
954         ccgVertIterator_free(vi);
955 }
956 static int ccgDM_getNumVerts(DerivedMesh *dm) {
957         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
958
959         return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
960 }
961 static int ccgDM_getNumEdges(DerivedMesh *dm) {
962         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
963
964         return ccgSubSurf_getNumFinalEdges(ccgdm->ss);
965 }
966 static int ccgDM_getNumFaces(DerivedMesh *dm) {
967         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
968
969         return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
970 }
971
972 static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
973 {
974         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
975         CCGSubSurf *ss = ccgdm->ss;
976         int i;
977
978         memset(mv, 0, sizeof(*mv));
979
980         if(vertNum < ccgdm->edgeMap[0].startVert) {
981                 /* this vert comes from face data */
982                 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
983                 CCGFace *f;
984                 int x, y, grid, numVerts;
985                 int offset;
986                 int gridSize = ccgSubSurf_getGridSize(ss);
987                 int gridSideVerts;
988                 int gridInternalVerts;
989                 int gridSideEnd;
990                 int gridInternalEnd;
991
992                 i = 0;
993                 while(i < lastface && vertNum >= ccgdm->faceMap[i + 1].startVert)
994                         ++i;
995
996                 f = ccgdm->faceMap[i].face;
997                 numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
998
999                 gridSideVerts = gridSize - 2;
1000                 gridInternalVerts = gridSideVerts * gridSideVerts;
1001
1002                 gridSideEnd = 1 + numVerts * gridSideVerts;
1003                 gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
1004
1005                 offset = vertNum - ccgdm->faceMap[i].startVert;
1006                 if(offset < 1) {
1007                         VecCopyf(mv->co, ccgSubSurf_getFaceCenterData(ss, f));
1008                 } else if(offset < gridSideEnd) {
1009                         offset -= 1;
1010                         grid = offset / gridSideVerts;
1011                         x = offset % gridSideVerts + 1;
1012                         VecCopyf(mv->co, ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x));
1013                 } else if(offset < gridInternalEnd) {
1014                         offset -= gridSideEnd;
1015                         grid = offset / gridInternalVerts;
1016                         offset %= gridInternalVerts;
1017                         y = offset / gridSideVerts + 1;
1018                         x = offset % gridSideVerts + 1;
1019                         VecCopyf(mv->co, ccgSubSurf_getFaceGridData(ss, f, grid, x, y));
1020                 }
1021         } else if(vertNum < ccgdm->vertMap[0].startVert) {
1022                 /* this vert comes from edge data */
1023                 CCGEdge *e;
1024                 int lastedge = ccgSubSurf_getNumEdges(ss) - 1;
1025                 int x;
1026
1027                 i = 0;
1028                 while(i < lastedge && vertNum >= ccgdm->edgeMap[i + 1].startVert)
1029                         ++i;
1030
1031                 e = ccgdm->edgeMap[i].edge;
1032
1033                 x = vertNum - ccgdm->edgeMap[i].startVert + 1;
1034                 VecCopyf(mv->co, ccgSubSurf_getEdgeData(ss, e, x));
1035         } else {
1036                 /* this vert comes from vert data */
1037                 CCGVert *v;
1038                 i = vertNum - ccgdm->vertMap[0].startVert;
1039
1040                 v = ccgdm->vertMap[i].vert;
1041                 VecCopyf(mv->co, ccgSubSurf_getVertData(ss, v));
1042         }
1043 }
1044
1045 static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
1046 {
1047         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1048         CCGSubSurf *ss = ccgdm->ss;
1049         int i;
1050
1051         memset(med, 0, sizeof(*med));
1052
1053         if(edgeNum < ccgdm->edgeMap[0].startEdge) {
1054                 /* this edge comes from face data */
1055                 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
1056                 CCGFace *f;
1057                 int x, y, grid, numVerts;
1058                 int offset;
1059                 int gridSize = ccgSubSurf_getGridSize(ss);
1060                 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1061                 int gridSideEdges;
1062                 int gridInternalEdges;
1063
1064                 i = 0;
1065                 while(i < lastface && edgeNum >= ccgdm->faceMap[i + 1].startEdge)
1066                         ++i;
1067
1068                 f = ccgdm->faceMap[i].face;
1069                 numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1070
1071                 gridSideEdges = gridSize - 1;
1072                 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
1073
1074                 offset = edgeNum - ccgdm->faceMap[i].startEdge;
1075                 grid = offset / (gridSideEdges + gridInternalEdges);
1076                 offset %= (gridSideEdges + gridInternalEdges);
1077
1078                 if(offset < gridSideEdges) {
1079                         x = offset;
1080                         med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, gridSize);
1081                         med->v2 = getFaceIndex(ss, f, grid, x+1, 0, edgeSize, gridSize);
1082                 } else {
1083                         offset -= gridSideEdges;
1084                         x = (offset / 2) / gridSideEdges + 1;
1085                         y = (offset / 2) % gridSideEdges;
1086                         if(offset % 2 == 0) {
1087                                 med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSize, gridSize);
1088                                 med->v2 = getFaceIndex(ss, f, grid, x, y+1, edgeSize, gridSize);
1089                         } else {
1090                                 med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSize, gridSize);
1091                                 med->v2 = getFaceIndex(ss, f, grid, y+1, x, edgeSize, gridSize);
1092                         }
1093                 }
1094         } else {
1095                 /* this vert comes from edge data */
1096                 CCGEdge *e;
1097                 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1098                 int x;
1099                 unsigned int flags = 0;
1100
1101                 i = (edgeNum - ccgdm->edgeMap[0].startEdge) / (edgeSize - 1);
1102
1103                 e = ccgdm->edgeMap[i].edge;
1104
1105                 if(!ccgSubSurf_getEdgeNumFaces(ss, e)) flags |= ME_LOOSEEDGE;
1106
1107                 x = edgeNum - ccgdm->edgeMap[i].startEdge;
1108
1109                 med->v1 = getEdgeIndex(ss, e, x, edgeSize);
1110                 med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
1111
1112                 if(ccgdm->me) {
1113                         int edgeIdx = (int) ccgSubSurf_getEdgeEdgeHandle(ss, e);
1114
1115                         if(edgeIdx!=-1) {
1116                                 MEdge *medge = ccgdm->me->medge;
1117                                 MEdge *origMed = &medge[edgeIdx];
1118
1119                                 flags |= (origMed->flag & (ME_SEAM | ME_SHARP))
1120                                          | ME_EDGEDRAW | ME_EDGERENDER;
1121                         }
1122                 } else {
1123                         int *edgeFlag = dm->getEdgeData(dm, edgeNum, CD_FLAGS);
1124                         if(edgeFlag)
1125                                 flags |= (*edgeFlag & (ME_SEAM | ME_SHARP))
1126                                          | ME_EDGEDRAW | ME_EDGERENDER;
1127                         else
1128                                 flags |= ME_EDGEDRAW | ME_EDGERENDER;
1129                 }
1130
1131                 med->flag = flags;
1132         }
1133 }
1134
1135 static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
1136 {
1137         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1138         CCGSubSurf *ss = ccgdm->ss;
1139         int gridSize = ccgSubSurf_getGridSize(ss);
1140         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1141         int gridSideEdges = gridSize - 1;
1142         int gridFaces = gridSideEdges * gridSideEdges;
1143         int i;
1144         CCGFace *f;
1145         int numVerts;
1146         int offset;
1147         int grid;
1148         int x, y;
1149         int lastface = ccgSubSurf_getNumFaces(ss) - 1;
1150         int *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
1151
1152         memset(mf, 0, sizeof(*mf));
1153
1154         i = 0;
1155         while(i < lastface && faceNum >= ccgdm->faceMap[i + 1].startFace)
1156                 ++i;
1157
1158         f = ccgdm->faceMap[i].face;
1159         numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1160
1161         offset = faceNum - ccgdm->faceMap[i].startFace;
1162         grid = offset / gridFaces;
1163         offset %= gridFaces;
1164         y = offset / gridSideEdges;
1165         x = offset % gridSideEdges;
1166
1167         mf->v1 = getFaceIndex(ss, f, grid, x+0, y+0, edgeSize, gridSize);
1168         mf->v2 = getFaceIndex(ss, f, grid, x+0, y+1, edgeSize, gridSize);
1169         mf->v3 = getFaceIndex(ss, f, grid, x+1, y+1, edgeSize, gridSize);
1170         mf->v4 = getFaceIndex(ss, f, grid, x+1, y+0, edgeSize, gridSize);
1171
1172         if(faceFlags) mf->flag = faceFlags[i];
1173         else mf->flag = ME_SMOOTH;
1174 }
1175
1176 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
1177 {
1178         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1179         CCGSubSurf *ss = ccgdm->ss;
1180         int index;
1181         int totvert, totedge, totface;
1182         int gridSize = ccgSubSurf_getGridSize(ss);
1183         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1184         int i = 0;
1185
1186         totface = ccgSubSurf_getNumFaces(ss);
1187         for(index = 0; index < totface; index++) {
1188                 CCGFace *f = ccgdm->faceMap[index].face;
1189                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1190
1191                 VecCopyf(mvert[i++].co, ccgSubSurf_getFaceCenterData(ss, f));
1192                 
1193                 for(S = 0; S < numVerts; S++) {
1194                         for(x = 1; x < gridSize - 1; x++) {
1195                                 VecCopyf(mvert[i++].co,
1196                                          ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1197                         }
1198                 }
1199
1200                 for(S = 0; S < numVerts; S++) {
1201                         for(y = 1; y < gridSize - 1; y++) {
1202                                 for(x = 1; x < gridSize - 1; x++) {
1203                                         VecCopyf(mvert[i++].co,
1204                                                  ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1205                                 }
1206                         }
1207                 }
1208         }
1209
1210         totedge = ccgSubSurf_getNumEdges(ss);
1211         for(index = 0; index < totedge; index++) {
1212                 CCGEdge *e = ccgdm->edgeMap[index].edge;
1213                 int x;
1214
1215                 for(x = 1; x < edgeSize - 1; x++) {
1216                         VecCopyf(mvert[i++].co, ccgSubSurf_getEdgeData(ss, e, x));
1217                 }
1218         }
1219
1220         totvert = ccgSubSurf_getNumVerts(ss);
1221         for(index = 0; index < totvert; index++) {
1222                 CCGVert *v = ccgdm->vertMap[index].vert;
1223
1224                 VecCopyf(mvert[i].co, ccgSubSurf_getVertData(ss, v));
1225
1226                 i++;
1227         }
1228 }
1229
1230 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
1231 {
1232         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1233         CCGSubSurf *ss = ccgdm->ss;
1234         int index;
1235         int totedge, totface;
1236         int gridSize = ccgSubSurf_getGridSize(ss);
1237         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1238         int i = 0;
1239         MEdge *origEdges = NULL;
1240         int *edgeFlags = dm->getEdgeDataArray(dm, CD_FLAGS);
1241
1242         if(ccgdm->me) origEdges = ccgdm->me->medge;
1243
1244         totface = ccgSubSurf_getNumFaces(ss);
1245         for(index = 0; index < totface; index++) {
1246                 CCGFace *f = ccgdm->faceMap[index].face;
1247                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1248
1249                 for(S = 0; S < numVerts; S++) {
1250                         for(x = 0; x < gridSize - 1; x++) {
1251                                 MEdge *med = &medge[i];
1252
1253                                 if(ccgdm->drawInteriorEdges)
1254                                     med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1255                                 med->v1 = getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize);
1256                                 med->v2 = getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize);
1257                                 i++;
1258                         }
1259
1260                         for(x = 1; x < gridSize - 1; x++) {
1261                                 for(y = 0; y < gridSize - 1; y++) {
1262                                         MEdge *med;
1263
1264                                         med = &medge[i];
1265                                         if(ccgdm->drawInteriorEdges)
1266                                             med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1267                                         med->v1 = getFaceIndex(ss, f, S, x, y,
1268                                                                edgeSize, gridSize);
1269                                         med->v2 = getFaceIndex(ss, f, S, x, y + 1,
1270                                                                edgeSize, gridSize);
1271                                         i++;
1272
1273                                         med = &medge[i];
1274                                         if(ccgdm->drawInteriorEdges)
1275                                             med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1276                                         med->v1 = getFaceIndex(ss, f, S, y, x,
1277                                                                edgeSize, gridSize);
1278                                         med->v2 = getFaceIndex(ss, f, S, y + 1, x,
1279                                                                edgeSize, gridSize);
1280                                         i++;
1281                                 }
1282                         }
1283                 }
1284         }
1285
1286         totedge = ccgSubSurf_getNumEdges(ss);
1287         for(index = 0; index < totedge; index++) {
1288                 CCGEdge *e = ccgdm->edgeMap[index].edge;
1289                 unsigned int flags = 0;
1290                 int x;
1291                 int edgeIdx = (int)ccgSubSurf_getEdgeEdgeHandle(ss, e);
1292
1293                 if(!ccgSubSurf_getEdgeNumFaces(ss, e)) flags |= ME_LOOSEEDGE;
1294
1295                 if(origEdges){
1296                         if(edgeIdx != -1) {
1297                                 MEdge *origMed = &origEdges[edgeIdx];
1298
1299                                 flags |= (origMed->flag & (ME_SEAM | ME_SHARP))
1300                                          | ME_EDGEDRAW | ME_EDGERENDER;
1301                         }
1302                 } else if(edgeFlags) {
1303                         if(edgeIdx != -1) {
1304                                 flags |= (edgeFlags[i] & (ME_SEAM | ME_SHARP))
1305                                          | ME_EDGEDRAW | ME_EDGERENDER;
1306                         }
1307                 } else {
1308                         flags |= ME_EDGEDRAW | ME_EDGERENDER;
1309                 }
1310
1311                 for(x = 0; x < edgeSize - 1; x++) {
1312                         MEdge *med = &medge[i];
1313                         med->v1 = getEdgeIndex(ss, e, x, edgeSize);
1314                         med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
1315                         med->flag = flags;
1316                         i++;
1317                 }
1318         }
1319 }
1320
1321 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
1322 {
1323         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1324         CCGSubSurf *ss = ccgdm->ss;
1325         int index;
1326         int totface;
1327         int gridSize = ccgSubSurf_getGridSize(ss);
1328         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1329         int i = 0;
1330         MFace *origFaces = NULL;
1331         int *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
1332
1333         if(ccgdm->me) origFaces = ccgdm->me->mface;
1334
1335         totface = ccgSubSurf_getNumFaces(ss);
1336         for(index = 0; index < totface; index++) {
1337                 CCGFace *f = ccgdm->faceMap[index].face;
1338                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1339                 int mat_nr = 0;
1340                 int flag = ME_SMOOTH; /* assume face is smooth by default */
1341
1342                 if(!faceFlags) {
1343                         if(origFaces) {
1344                                 int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
1345                                 MFace *origMFace = &origFaces[origIdx];
1346
1347                                 mat_nr = origMFace->mat_nr;
1348                                 flag = origMFace->flag;
1349                         }
1350                 }
1351
1352                 for(S = 0; S < numVerts; S++) {
1353                         for(y = 0; y < gridSize - 1; y++) {
1354                                 for(x = 0; x < gridSize - 1; x++) {
1355                                         MFace *mf = &mface[i];
1356                                         mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1357                                                               edgeSize, gridSize);
1358                                         mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1359                                                               edgeSize, gridSize);
1360                                         mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1361                                                               edgeSize, gridSize);
1362                                         mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1363                                                               edgeSize, gridSize);
1364                                         mf->mat_nr = mat_nr;
1365                                         if(faceFlags) mf->flag = faceFlags[index];
1366                                         else mf->flag = flag;
1367
1368                                         i++;
1369                                 }
1370                         }
1371                 }
1372         }
1373 }
1374
1375 static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
1376         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1377         CCGSubSurf *ss = ccgdm->ss;
1378         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1379         int gridSize = ccgSubSurf_getGridSize(ss);
1380         int i;
1381         CCGVertIterator *vi;
1382         CCGEdgeIterator *ei;
1383         CCGFaceIterator *fi;
1384         CCGFace **faceMap2;
1385         CCGEdge **edgeMap2;
1386         CCGVert **vertMap2;
1387         int index, totvert, totedge, totface;
1388         
1389         totvert = ccgSubSurf_getNumVerts(ss);
1390         vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
1391         vi = ccgSubSurf_getVertIterator(ss);
1392         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1393                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1394
1395                 vertMap2[(int) ccgSubSurf_getVertVertHandle(ss, v)] = v;
1396         }
1397         ccgVertIterator_free(vi);
1398
1399         totedge = ccgSubSurf_getNumEdges(ss);
1400         edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
1401         ei = ccgSubSurf_getEdgeIterator(ss);
1402         for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
1403                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1404
1405                 edgeMap2[(int) ccgSubSurf_getEdgeEdgeHandle(ss, e)] = e;
1406         }
1407
1408         totface = ccgSubSurf_getNumFaces(ss);
1409         faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
1410         fi = ccgSubSurf_getFaceIterator(ss);
1411         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1412                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1413
1414                 faceMap2[(int) ccgSubSurf_getFaceFaceHandle(ss, f)] = f;
1415         }
1416         ccgFaceIterator_free(fi);
1417
1418         i = 0;
1419         for (index=0; index<totface; index++) {
1420                 CCGFace *f = faceMap2[index];
1421                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1422
1423                 VecCopyf(cos[i++], ccgSubSurf_getFaceCenterData(ss, f));
1424                 
1425                 for (S=0; S<numVerts; S++) {
1426                         for (x=1; x<gridSize-1; x++) {
1427                                 VecCopyf(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1428                         }
1429                 }
1430
1431                 for (S=0; S<numVerts; S++) {
1432                         for (y=1; y<gridSize-1; y++) {
1433                                 for (x=1; x<gridSize-1; x++) {
1434                                         VecCopyf(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1435                                 }
1436                         }
1437                 }
1438         }
1439
1440         for (index=0; index<totedge; index++) {
1441                 CCGEdge *e= edgeMap2[index];
1442                 int x;
1443
1444                 for (x=1; x<edgeSize-1; x++) {
1445                         VecCopyf(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
1446                 }
1447         }
1448
1449         for (index=0; index<totvert; index++) {
1450                 CCGVert *v = vertMap2[index];
1451                 VecCopyf(cos[i++], ccgSubSurf_getVertData(ss, v));
1452         }
1453
1454         MEM_freeN(vertMap2);
1455         MEM_freeN(edgeMap2);
1456         MEM_freeN(faceMap2);
1457 }
1458 static void ccgDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
1459         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1460         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
1461
1462         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1463                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1464                 VertData *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
1465                 int index = ccgDM_getVertMapIndex(ccgdm, ccgdm->ss, v);
1466
1467                 if (index!=-1)
1468                         func(userData, index, vd->co, vd->no, NULL);
1469         }
1470
1471         ccgVertIterator_free(vi);
1472 }
1473 static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
1474         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1475         CCGSubSurf *ss = ccgdm->ss;
1476         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1477         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1478
1479         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1480                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1481                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1482                 int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
1483
1484                 if (index!=-1) {
1485                         for (i=0; i<edgeSize-1; i++)
1486                                 func(userData, index, edgeData[i].co, edgeData[i+1].co);
1487                 }
1488         }
1489
1490         ccgEdgeIterator_free(ei);
1491 }
1492
1493 static void ccgDM_drawVerts(DerivedMesh *dm) {
1494         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1495         CCGSubSurf *ss = ccgdm->ss;
1496         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1497         int gridSize = ccgSubSurf_getGridSize(ss);
1498         CCGVertIterator *vi;
1499         CCGEdgeIterator *ei;
1500         CCGFaceIterator *fi;
1501
1502         glBegin(GL_POINTS);
1503         vi = ccgSubSurf_getVertIterator(ss);
1504         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1505                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1506                 glVertex3fv(ccgSubSurf_getVertData(ss, v));
1507         }
1508         ccgVertIterator_free(vi);
1509
1510         ei = ccgSubSurf_getEdgeIterator(ss);
1511         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1512                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1513                 int x;
1514
1515                 for (x=1; x<edgeSize-1; x++)
1516                         glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
1517         }
1518         ccgEdgeIterator_free(ei);
1519
1520         fi = ccgSubSurf_getFaceIterator(ss);
1521         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1522                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1523                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1524
1525                 glVertex3fv(ccgSubSurf_getFaceCenterData(ss, f));
1526                 for (S=0; S<numVerts; S++)
1527                         for (x=1; x<gridSize-1; x++)
1528                                 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1529                 for (S=0; S<numVerts; S++)
1530                         for (y=1; y<gridSize-1; y++)
1531                                 for (x=1; x<gridSize-1; x++)
1532                                         glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1533         }
1534         ccgFaceIterator_free(fi);
1535         glEnd();
1536 }
1537 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) {
1538         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1539         CCGSubSurf *ss = ccgdm->ss;
1540         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1541         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1542         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1543         int gridSize = ccgSubSurf_getGridSize(ss);
1544         int useAging;
1545
1546         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1547
1548         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1549                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1550                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1551
1552                 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(ss, e))
1553                         continue;
1554
1555                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1556                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1557                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1558                 }
1559
1560                 glBegin(GL_LINE_STRIP);
1561                 for (i=0; i<edgeSize-1; i++) {
1562                         glVertex3fv(edgeData[i].co);
1563                         glVertex3fv(edgeData[i+1].co);
1564                 }
1565                 glEnd();
1566         }
1567
1568         if (useAging && !(G.f&G_BACKBUFSEL)) {
1569                 glColor3ub(0, 0, 0);
1570         }
1571
1572         if (ccgdm->drawInteriorEdges) {
1573                 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1574                         CCGFace *f = ccgFaceIterator_getCurrent(fi);
1575                         int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1576
1577                         for (S=0; S<numVerts; S++) {
1578                                 VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1579
1580                                 glBegin(GL_LINE_STRIP);
1581                                 for (x=0; x<gridSize; x++)
1582                                         glVertex3fv(faceGridData[x].co);
1583                                 glEnd();
1584                                 for (y=1; y<gridSize-1; y++) {
1585                                         glBegin(GL_LINE_STRIP);
1586                                         for (x=0; x<gridSize; x++)
1587                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1588                                         glEnd();
1589                                 }
1590                                 for (x=1; x<gridSize-1; x++) {
1591                                         glBegin(GL_LINE_STRIP);
1592                                         for (y=0; y<gridSize; y++)
1593                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1594                                         glEnd();
1595                                 }
1596                         }
1597                 }
1598         }
1599
1600         ccgFaceIterator_free(fi);
1601         ccgEdgeIterator_free(ei);
1602 }
1603 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
1604         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1605         CCGSubSurf *ss = ccgdm->ss;
1606         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1607         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1608
1609         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1610                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1611                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1612
1613                 if (!ccgSubSurf_getEdgeNumFaces(ss, e)) {
1614                         glBegin(GL_LINE_STRIP);
1615                         for (i=0; i<edgeSize-1; i++) {
1616                                 glVertex3fv(edgeData[i].co);
1617                                 glVertex3fv(edgeData[i+1].co);
1618                         }
1619                         glEnd();
1620                 }
1621         }
1622
1623         ccgEdgeIterator_free(ei);
1624 }
1625
1626         /* Only used by non-editmesh types */
1627 static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
1628         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1629         CCGSubSurf *ss = ccgdm->ss;
1630         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1631         int gridSize = ccgSubSurf_getGridSize(ss);
1632         MFace *mface = ccgdm->me->mface;
1633
1634         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1635                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1636                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1637                 int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
1638                 MFace *mf = &mface[index];
1639                 
1640                 if (!setMaterial(mf->mat_nr+1))
1641                         continue;
1642
1643                 glShadeModel((mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT);
1644                 for (S=0; S<numVerts; S++) {
1645                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1646
1647                         if (mf->flag&ME_SMOOTH) {
1648                                 for (y=0; y<gridSize-1; y++) {
1649                                         glBegin(GL_QUAD_STRIP);
1650                                         for (x=0; x<gridSize; x++) {
1651                                                 VertData *a = &faceGridData[(y+0)*gridSize + x];
1652                                                 VertData *b = &faceGridData[(y+1)*gridSize + x];
1653
1654                                                 glNormal3fv(a->no);
1655                                                 glVertex3fv(a->co);
1656                                                 glNormal3fv(b->no);
1657                                                 glVertex3fv(b->co);
1658                                         }
1659                                         glEnd();
1660                                 }
1661                         } else {
1662                                 glBegin(GL_QUADS);
1663                                 for (y=0; y<gridSize-1; y++) {
1664                                         for (x=0; x<gridSize-1; x++) {
1665                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
1666                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1667                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1668                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
1669                                                 float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1670                                                 float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1671                                                 float no[3];
1672
1673                                                 no[0] = b_dY*a_cZ - b_dZ*a_cY;
1674                                                 no[1] = b_dZ*a_cX - b_dX*a_cZ;
1675                                                 no[2] = b_dX*a_cY - b_dY*a_cX;
1676                                                 glNormal3fv(no);
1677
1678                                                 glVertex3fv(d);
1679                                                 glVertex3fv(c);
1680                                                 glVertex3fv(b);
1681                                                 glVertex3fv(a);
1682                                         }
1683                                 }
1684                                 glEnd();
1685                         }
1686                 }
1687         }
1688
1689         ccgFaceIterator_free(fi);
1690 }
1691 static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2) {
1692         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1693         CCGSubSurf *ss = ccgdm->ss;
1694         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1695         int gridSize = ccgSubSurf_getGridSize(ss);
1696         unsigned char *cp1, *cp2;
1697         int useTwoSide=1;
1698
1699         cp1= col1;
1700         if(col2) {
1701                 cp2= col2;
1702         } else {
1703                 cp2= NULL;
1704                 useTwoSide= 0;
1705         }
1706
1707         glShadeModel(GL_SMOOTH);
1708         if(col1 && col2)
1709                 glEnable(GL_CULL_FACE);
1710
1711         glBegin(GL_QUADS);
1712         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1713                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1714                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1715
1716                 for (S=0; S<numVerts; S++) {
1717                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1718                         for (y=0; y<gridSize-1; y++) {
1719                                 for (x=0; x<gridSize-1; x++) {
1720                                         float *a = faceGridData[(y+0)*gridSize + x].co;
1721                                         float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1722                                         float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1723                                         float *d = faceGridData[(y+1)*gridSize + x].co;
1724
1725                                         glColor3ub(cp1[3], cp1[2], cp1[1]);
1726                                         glVertex3fv(d);
1727                                         glColor3ub(cp1[7], cp1[6], cp1[5]);
1728                                         glVertex3fv(c);
1729                                         glColor3ub(cp1[11], cp1[10], cp1[9]);
1730                                         glVertex3fv(b);
1731                                         glColor3ub(cp1[15], cp1[14], cp1[13]);
1732                                         glVertex3fv(a);
1733
1734                                         if (useTwoSide) {
1735                                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
1736                                                 glVertex3fv(a);
1737                                                 glColor3ub(cp2[11], cp2[10], cp2[9]);
1738                                                 glVertex3fv(b);
1739                                                 glColor3ub(cp2[7], cp2[6], cp2[5]);
1740                                                 glVertex3fv(c);
1741                                                 glColor3ub(cp2[3], cp2[2], cp2[1]);
1742                                                 glVertex3fv(d);
1743                                         }
1744
1745                                         if (cp2) cp2+=16;
1746                                         cp1+=16;
1747                                 }
1748                         }
1749                 }
1750         }
1751         glEnd();
1752
1753         ccgFaceIterator_free(fi);
1754 }
1755
1756 static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(MTFace *tface, MCol *mcol, int matnr))
1757 {
1758         /* unimplemented, no textures in editmode anyway */
1759 }
1760 static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index), void *userData)
1761 {
1762         /* unfinished code, no textures in editmode anyway */
1763
1764         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1765         CCGSubSurf *ss = ccgdm->ss;
1766         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1767         int gridSize = ccgSubSurf_getGridSize(ss);
1768         MFace *mface = ccgdm->me->mface;
1769         MCol *mcol = ccgdm->me->mcol;
1770 //      float uv[4][2];
1771 //      float col[4][3];
1772
1773         glBegin(GL_QUADS);
1774         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1775                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1776                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1777                 int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
1778                 MFace *mf = &mface[index];
1779                 unsigned char *cp= NULL;
1780                 int findex = ccgDM_getFaceMapIndex(ccgdm, ss, f); 
1781                 int flag = (findex == -1)? 0: setDrawParams(userData, findex);
1782
1783                 if (flag==0)
1784                         continue;
1785                 else if (flag==1 && mcol)
1786                         cp= (unsigned char*) &mcol[index*4];
1787
1788                 for (S=0; S<numVerts; S++) {
1789                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1790                         for (y=0; y<gridSize-1; y++) {
1791                                 for (x=0; x<gridSize-1; x++) {
1792                                         VertData *a = &faceGridData[(y+0)*gridSize + x + 0];
1793                                         VertData *b = &faceGridData[(y+0)*gridSize + x + 1];
1794                                         VertData *c = &faceGridData[(y+1)*gridSize + x + 1];
1795                                         VertData *d = &faceGridData[(y+1)*gridSize + x + 0];
1796
1797                                         if (!(mf->flag&ME_SMOOTH)) {
1798                                                 float a_cX = c->co[0]-a->co[0], a_cY = c->co[1]-a->co[1], a_cZ = c->co[2]-a->co[2];
1799                                                 float b_dX = d->co[0]-b->co[0], b_dY = d->co[1]-b->co[1], b_dZ = d->co[2]-b->co[2];
1800                                                 float no[3];
1801
1802                                                 no[0] = b_dY*a_cZ - b_dZ*a_cY;
1803                                                 no[1] = b_dZ*a_cX - b_dX*a_cZ;
1804                                                 no[2] = b_dX*a_cY - b_dY*a_cX;
1805
1806                                                 glNormal3fv(no);
1807                                         }
1808
1809 //                                      if (tf) glTexCoord2fv(tf->uv[0]);
1810 //                                      if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1811 //                                      if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no);
1812 //                                      glVertex3fv(mvert[mf->v1].co);
1813
1814 /*
1815                                         {
1816                                                 float x_v = (float) fx/(gridSize-1);
1817                                                 float y_v = (float) fy/(gridSize-1);
1818                                                 float data[6];
1819
1820                                                 for (k=0; k<numDataComponents; k++) {
1821                                                         data[k] = (center_data[k]*(1.0f-x_v) + edge_data[S][k]*x_v)*(1.0f-y_v) + 
1822                                                                         (edge_data[prevS][k]*(1.0f-x_v) + corner_data[S][k]*x_v)*y_v;
1823                                         }
1824 */
1825
1826 //                                      if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1827                                         if (mf->flag&ME_SMOOTH) glNormal3fv(d->no);
1828                                         glVertex3fv(d->co);
1829 //                                      if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1830                                         if (mf->flag&ME_SMOOTH) glNormal3fv(c->no);
1831                                         glVertex3fv(c->co);
1832 //                                      if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1833                                         if (mf->flag&ME_SMOOTH) glNormal3fv(b->no);
1834                                         glVertex3fv(b->co);
1835 //                                      if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1836                                         if (mf->flag&ME_SMOOTH) glNormal3fv(a->no);
1837                                         glVertex3fv(a->co);
1838                                 }
1839                         }
1840                 }
1841         }
1842         glEnd();
1843
1844         ccgFaceIterator_free(fi);
1845 /*
1846         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
1847         Mesh *me = mdm->me;
1848         MVert *mvert= mdm->verts;
1849         MFace *mface= me->mface;
1850         MTFace *tface = me->mtface;
1851         float *nors = mdm->nors;
1852         int a;
1853
1854         for (a=0; a<me->totface; a++) {
1855                 MFace *mf= &mface[a];
1856                 if (tf) glTexCoord2fv(tf->uv[1]);
1857                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1858                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no);
1859                 glVertex3fv(mvert[mf->v2].co);
1860
1861                 if (tf) glTexCoord2fv(tf->uv[2]);
1862                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1863                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no);
1864                 glVertex3fv(mvert[mf->v3].co);
1865
1866                 if(mf->v4) {
1867                         if (tf) glTexCoord2fv(tf->uv[3]);
1868                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1869                         if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no);
1870                         glVertex3fv(mvert[mf->v4].co);
1871                 }
1872                 glEnd();
1873         }
1874 */
1875 }
1876 static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) {
1877         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1878         CCGSubSurf *ss = ccgdm->ss;
1879         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1880         int i, gridSize = ccgSubSurf_getGridSize(ss);
1881         int *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
1882
1883         for (i=0; !ccgFaceIterator_isStopped(fi); i++,ccgFaceIterator_next(fi)) {
1884                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1885                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1886                 int drawSmooth, index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
1887                 int origIndex;
1888
1889                 origIndex = (int)ccgSubSurf_getFaceFaceHandle(ss, f);
1890
1891                 if(faceFlags) drawSmooth = (faceFlags[origIndex] & ME_SMOOTH);
1892                 else drawSmooth = 1;
1893
1894                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index, &drawSmooth))) {
1895                         for (S=0; S<numVerts; S++) {
1896                                 VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1897                                 if (drawSmooth) {
1898                                         glShadeModel(GL_SMOOTH);
1899                                         for (y=0; y<gridSize-1; y++) {
1900                                                 glBegin(GL_QUAD_STRIP);
1901                                                 for (x=0; x<gridSize; x++) {
1902                                                         VertData *a = &faceGridData[(y+0)*gridSize + x];
1903                                                         VertData *b = &faceGridData[(y+1)*gridSize + x];
1904
1905                                                         glNormal3fv(a->no);
1906                                                         glVertex3fv(a->co);
1907                                                         glNormal3fv(b->no);
1908                                                         glVertex3fv(b->co);
1909                                                 }
1910                                                 glEnd();
1911                                         }
1912                                 } else {
1913                                         glShadeModel(GL_FLAT);
1914                                         glBegin(GL_QUADS);
1915                                         for (y=0; y<gridSize-1; y++) {
1916                                                 for (x=0; x<gridSize-1; x++) {
1917                                                         float *a = faceGridData[(y+0)*gridSize + x].co;
1918                                                         float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1919                                                         float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1920                                                         float *d = faceGridData[(y+1)*gridSize + x].co;
1921                                                         float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1922                                                         float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1923                                                         float no[3];
1924
1925                                                         no[0] = b_dY*a_cZ - b_dZ*a_cY;
1926                                                         no[1] = b_dZ*a_cX - b_dX*a_cZ;
1927                                                         no[2] = b_dX*a_cY - b_dY*a_cX;
1928                                                         glNormal3fv(no);
1929
1930                                                         glVertex3fv(d);
1931                                                         glVertex3fv(c);
1932                                                         glVertex3fv(b);
1933                                                         glVertex3fv(a);
1934                                                 }
1935                                         }
1936                                         glEnd();
1937                                 }
1938                         }
1939                 }
1940         }
1941
1942         ccgFaceIterator_free(fi);
1943 }
1944 static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
1945         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1946         CCGSubSurf *ss = ccgdm->ss;
1947         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1948         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
1949
1950         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1951
1952         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1953                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1954                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1955                 int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
1956
1957                 glBegin(GL_LINE_STRIP);
1958                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
1959                         if (useAging && !(G.f&G_BACKBUFSEL)) {
1960                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1961                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
1962                         }
1963
1964                         for (i=0; i<edgeSize-1; i++) {
1965                                 glVertex3fv(edgeData[i].co);
1966                                 glVertex3fv(edgeData[i+1].co);
1967                         }
1968                 }
1969                 glEnd();
1970         }
1971
1972         ccgEdgeIterator_free(ei);
1973 }
1974 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
1975         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1976         CCGSubSurf *ss = ccgdm->ss;
1977         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1978         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
1979
1980         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1981
1982         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1983                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1984                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1985                 int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
1986
1987                 glBegin(GL_LINE_STRIP);
1988                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
1989                         for (i=0; i<edgeSize; i++) {
1990                                 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
1991
1992                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1993                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1994                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1995                                 }
1996
1997                                 glVertex3fv(edgeData[i].co);
1998                         }
1999                 }
2000                 glEnd();
2001         }
2002
2003         ccgEdgeIterator_free(ei);
2004 }
2005 static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
2006         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2007         CCGSubSurf *ss = ccgdm->ss;
2008         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
2009
2010         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2011                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2012                 int index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
2013
2014                 if (index!=-1) {
2015                                 /* Face center data normal isn't updated atm. */
2016                         VertData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
2017
2018                         func(userData, index, vd->co, vd->no);
2019                 }
2020         }
2021
2022         ccgFaceIterator_free(fi);
2023 }
2024
2025 static void ccgDM_release(DerivedMesh *dm) {
2026         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2027
2028         if (DM_release(dm)) {
2029                 MEM_freeN(ccgdm->vertMap);
2030                 MEM_freeN(ccgdm->edgeMap);
2031                 MEM_freeN(ccgdm->faceMap);
2032                 MEM_freeN(ccgdm);
2033         }
2034 }
2035
2036 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2037                                          int drawInteriorEdges,
2038                                          int useSubsurfUv, Mesh *me,
2039                                          DerivedMesh *dm)
2040 {
2041         CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
2042         CCGVertIterator *vi;
2043         CCGEdgeIterator *ei;
2044         CCGFaceIterator *fi;
2045         int index, totvert, totedge, totface;
2046         int i;
2047         int vertNum, edgeNum, faceNum;
2048         int *vertOrigIndex, *edgeOrigIndex, *faceOrigIndex;
2049         int *faceFlags, *edgeFlags;
2050         int edgeSize;
2051         int gridSize;
2052         int gridFaces;
2053         int gridSideVerts;
2054         int gridInternalVerts;
2055         int gridSideEdges;
2056         int gridInternalEdges;
2057         MVert *mvert = NULL;
2058         MEdge *medge = NULL;
2059         MFace *mface = NULL;
2060         FaceVertWeight *qweight, *tweight;
2061
2062         if(dm) {
2063                 DM_from_template(&ccgdm->dm, dm, ccgSubSurf_getNumFinalVerts(ss),
2064                                  ccgSubSurf_getNumFinalEdges(ss),
2065                                  ccgSubSurf_getNumFinalFaces(ss));
2066                 DM_add_face_layer(&ccgdm->dm, CD_FLAGS, CD_CALLOC, NULL);
2067                 DM_add_edge_layer(&ccgdm->dm, CD_FLAGS, CD_CALLOC, NULL);
2068
2069                 CustomData_set_layer_flag(&ccgdm->dm.faceData, CD_FLAGS, CD_FLAG_NOCOPY);
2070                 CustomData_set_layer_flag(&ccgdm->dm.edgeData, CD_FLAGS, CD_FLAG_NOCOPY);
2071         } else {
2072                 DM_init(&ccgdm->dm, ccgSubSurf_getNumFinalVerts(ss),
2073                         ccgSubSurf_getNumFinalEdges(ss),
2074                         ccgSubSurf_getNumFinalFaces(ss));
2075         }
2076
2077         ccgdm->dm.getMinMax = ccgDM_getMinMax;
2078         ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
2079         ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
2080
2081         ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
2082         ccgdm->dm.getVert = ccgDM_getFinalVert;
2083         ccgdm->dm.getEdge = ccgDM_getFinalEdge;
2084         ccgdm->dm.getFace = ccgDM_getFinalFace;
2085         ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2086         ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2087         ccgdm->dm.copyFaceArray = ccgDM_copyFinalFaceArray;
2088         ccgdm->dm.getVertData = DM_get_vert_data;
2089         ccgdm->dm.getEdgeData = DM_get_edge_data;
2090         ccgdm->dm.getFaceData = DM_get_face_data;
2091         ccgdm->dm.getVertDataArray = DM_get_vert_data_layer;
2092         ccgdm->dm.getEdgeDataArray = DM_get_edge_data_layer;
2093         ccgdm->dm.getFaceDataArray = DM_get_face_data_layer;
2094
2095         ccgdm->dm.getVertCos = ccgdm_getVertCos;
2096         ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
2097         ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
2098         ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
2099         
2100         ccgdm->dm.drawVerts = ccgDM_drawVerts;
2101         ccgdm->dm.drawEdges = ccgDM_drawEdges;
2102         ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
2103         ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
2104         ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
2105         ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
2106         ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
2107         ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
2108
2109         ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
2110         ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
2111         
2112         ccgdm->dm.release = ccgDM_release;
2113         
2114         ccgdm->ss = ss;
2115         ccgdm->drawInteriorEdges = drawInteriorEdges;
2116         ccgdm->useSubsurfUv = useSubsurfUv;
2117         ccgdm->me = me;
2118
2119         totvert = ccgSubSurf_getNumVerts(ss);
2120         ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
2121         vi = ccgSubSurf_getVertIterator(ss);
2122         for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2123                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2124
2125                 ccgdm->vertMap[(int) ccgSubSurf_getVertVertHandle(ss, v)].vert = v;
2126         }
2127         ccgVertIterator_free(vi);
2128
2129         totedge = ccgSubSurf_getNumEdges(ss);
2130         ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
2131         ei = ccgSubSurf_getEdgeIterator(ss);
2132         for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2133                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2134
2135                 ccgdm->edgeMap[(int) ccgSubSurf_getEdgeEdgeHandle(ss, e)].edge = e;
2136         }
2137
2138         totface = ccgSubSurf_getNumFaces(ss);
2139         ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
2140         fi = ccgSubSurf_getFaceIterator(ss);
2141         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2142                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2143
2144                 ccgdm->faceMap[(int) ccgSubSurf_getFaceFaceHandle(ss, f)].face = f;
2145         }
2146         ccgFaceIterator_free(fi);
2147
2148         edgeSize = ccgSubSurf_getEdgeSize(ss);
2149         gridSize = ccgSubSurf_getGridSize(ss);
2150         gridFaces = gridSize - 1;
2151         gridSideVerts = gridSize - 2;
2152         gridInternalVerts = gridSideVerts * gridSideVerts;
2153         gridSideEdges = gridSize - 1;
2154         gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
2155
2156         calc_ss_weights(gridFaces, &qweight, &tweight);
2157
2158         vertNum = 0;
2159         edgeNum = 0;
2160         faceNum = 0;
2161
2162         if(dm) {
2163                 mvert = dm->getVertArray(dm);
2164                 medge = dm->getEdgeArray(dm);
2165                 mface = dm->getFaceArray(dm);
2166         } else if(me) {
2167                 mvert = me->mvert;
2168                 medge = me->medge;
2169                 mface = me->mface;
2170         }
2171
2172         vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2173         edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2174         faceOrigIndex = DM_get_face_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2175
2176         faceFlags = DM_get_face_data_layer(&ccgdm->dm, CD_FLAGS);
2177
2178         for(index = 0; index < totface; ++index) {
2179                 CCGFace *f = ccgdm->faceMap[index].face;
2180                 int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
2181                 int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
2182                 int mapIndex = ccgDM_getFaceMapIndex(ccgdm, ss, f);
2183                 int origIndex = (int)ccgSubSurf_getFaceFaceHandle(ss, f);
2184                 FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
2185                 int S, x, y;
2186                 int vertIdx[4];
2187
2188                 ccgdm->faceMap[index].startVert = vertNum;
2189                 ccgdm->faceMap[index].startEdge = edgeNum;
2190                 ccgdm->faceMap[index].startFace = faceNum;
2191
2192                 /* set the face base vert */
2193                 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
2194
2195                 for(S = 0; S < numVerts; S++) {
2196                         CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
2197
2198                         vertIdx[S] = (int)ccgSubSurf_getVertVertHandle(ss, v);
2199                 }
2200
2201                 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, weight[0][0],
2202                                     numVerts, vertNum);
2203                 *vertOrigIndex = ORIGINDEX_NONE;
2204                 ++vertOrigIndex;
2205                 ++vertNum;
2206
2207                 for(S = 0; S < numVerts; S++) {
2208                         int prevS = (S - 1 + numVerts) % numVerts;
2209                         int nextS = (S + 1) % numVerts;
2210                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2211                         for(x = 1; x < gridFaces; x++) {
2212                                 float w[4];
2213                                 w[prevS]  = weight[x][0][0];
2214                                 w[S]      = weight[x][0][1];
2215                                 w[nextS]  = weight[x][0][2];
2216                                 w[otherS] = weight[x][0][3];
2217                                 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2218                                                     numVerts, vertNum);
2219                                 *vertOrigIndex = ORIGINDEX_NONE;
2220                                 ++vertOrigIndex;
2221                                 ++vertNum;
2222                         }
2223                 }
2224
2225                 for(S = 0; S < numVerts; S++) {
2226                         int prevS = (S - 1 + numVerts) % numVerts;
2227                         int nextS = (S + 1) % numVerts;
2228                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2229                         for(y = 1; y < gridFaces; y++) {
2230                                 for(x = 1; x < gridFaces; x++) {
2231                                         float w[4];
2232                                         w[prevS]  = weight[y * gridFaces + x][0][0];
2233                                         w[S]      = weight[y * gridFaces + x][0][1];
2234                                         w[nextS]  = weight[y * gridFaces + x][0][2];
2235                                         w[otherS] = weight[y * gridFaces + x][0][3];
2236                                         DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2237                                                             numVerts, vertNum);
2238                                         *vertOrigIndex = ORIGINDEX_NONE;
2239                                         ++vertOrigIndex;
2240                                         ++vertNum;
2241                                 }
2242                         }
2243                 }
2244
2245                 for(i = 0; i < numFinalEdges; ++i)
2246                         *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i,
2247                                                  CD_ORIGINDEX) = ORIGINDEX_NONE;
2248
2249                 for(S = 0; S < numVerts; S++) {
2250                         int prevS = (S - 1 + numVerts) % numVerts;
2251                         int nextS = (S + 1) % numVerts;
2252                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2253
2254                         weight = (numVerts == 4) ? qweight : tweight;
2255
2256                         for(y = 0; y < gridFaces; y++) {
2257                                 for(x = 0; x < gridFaces; x++) {
2258                                         FaceVertWeight w;
2259                                         int j;
2260
2261                                         for(j = 0; j < 4; ++j) {
2262                                                 w[j][prevS]  = (*weight)[j][0];
2263                                                 w[j][S]      = (*weight)[j][1];
2264                                                 w[j][nextS]  = (*weight)[j][2];
2265                                                 w[j][otherS] = (*weight)[j][3];
2266                                         }
2267
2268                                         DM_interp_face_data(dm, &ccgdm->dm, &origIndex, NULL,
2269                                                             &w, 1, faceNum);
2270                                         weight++;
2271
2272                                         *faceOrigIndex = mapIndex;
2273
2274                                         ++faceOrigIndex;
2275                                         ++faceNum;
2276                                 }
2277                         }
2278                 }
2279
2280                 faceFlags[index] = mface[origIndex].flag;
2281
2282                 edgeNum += numFinalEdges;
2283         }
2284
2285         if(useSubsurfUv) {
2286                 CustomData *fdata = &ccgdm->dm.faceData;
2287                 CustomData *dmfdata = &dm->faceData;
2288                 int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
2289                 int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
2290
2291                 for (i=0; i<numlayer && i<dmnumlayer; i++)
2292                         set_subsurf_uv(ss, dm, &ccgdm->dm, i);
2293         }
2294
2295         edgeFlags = DM_get_edge_data_layer(&ccgdm->dm, CD_FLAGS);
2296
2297         for(index = 0; index < totedge; ++index) {
2298                 CCGEdge *e = ccgdm->edgeMap[index].edge;
2299                 int numFinalEdges = edgeSize - 1;
2300                 int mapIndex = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
2301                 int x;
2302                 int vertIdx[2];
2303                 int edgeIdx = (int)ccgSubSurf_getEdgeEdgeHandle(ss, e);
2304
2305                 CCGVert *v;
2306                 v = ccgSubSurf_getEdgeVert0(ss, e);
2307                 vertIdx[0] = (int)ccgSubSurf_getVertVertHandle(ss, v);
2308                 v = ccgSubSurf_getEdgeVert1(ss, e);
2309                 vertIdx[1] = (int)ccgSubSurf_getVertVertHandle(ss, v);
2310
2311                 ccgdm->edgeMap[index].startVert = vertNum;
2312                 ccgdm->edgeMap[index].startEdge = edgeNum;
2313
2314                 /* set the edge base vert */
2315                 *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
2316
2317                 for(x = 1; x < edgeSize - 1; x++) {
2318                         float w[2];
2319                         w[1] = (float) x / (edgeSize - 1);
2320                         w[0] = 1 - w[1];
2321                         DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
2322                         *vertOrigIndex = ORIGINDEX_NONE;
2323                         ++vertOrigIndex;
2324                         ++vertNum;
2325                 }
2326
2327                 for(i = 0; i < numFinalEdges; ++i) {
2328                         if(edgeIdx >= 0 && edgeFlags)
2329                                         edgeFlags[edgeNum + i] = medge[edgeIdx].flag;
2330
2331                         *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i,
2332                                                  CD_ORIGINDEX) = mapIndex;
2333                 }
2334
2335                 edgeNum += numFinalEdges;
2336         }
2337
2338         for(index = 0; index < totvert; ++index) {
2339                 CCGVert *v = ccgdm->vertMap[index].vert;
2340                 int mapIndex = ccgDM_getVertMapIndex(ccgdm, ccgdm->ss, v);
2341                 int vertIdx;
2342
2343                 vertIdx = (int)ccgSubSurf_getVertVertHandle(ss, v);
2344
2345                 ccgdm->vertMap[index].startVert = vertNum;
2346
2347                 /* set the vert base vert */
2348                 *((int*) ccgSubSurf_getVertUserData(ss, v)) = vertNum;
2349
2350                 DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
2351
2352                 *vertOrigIndex = mapIndex;
2353                 ++vertOrigIndex;
2354                 ++vertNum;
2355         }
2356
2357         MEM_freeN(qweight);
2358         MEM_freeN(tweight);
2359
2360         return ccgdm;
2361 }
2362
2363 /***/
2364
2365 struct DerivedMesh *subsurf_make_derived_from_derived(
2366                         struct DerivedMesh *dm,
2367                         struct SubsurfModifierData *smd,
2368                         int useRenderParams, float (*vertCos)[3],
2369                         int isFinalCalc, int editMode)
2370 {
2371         int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF;
2372         int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2373         int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv;
2374         int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
2375         DerivedMesh *result;
2376
2377         if(editMode) {
2378                 smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0,
2379                                            useSimple);
2380                 ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
2381
2382                 return (DerivedMesh *)getCCGDerivedMesh(smd->emCache,
2383                                                         drawInteriorEdges,
2384                                                     useSubsurfUv, NULL, dm);
2385         } else if(useRenderParams) {
2386                 /* Do not use cache in render mode. */
2387                 CCGSubSurf *ss = _getSubSurf(NULL, smd->renderLevels, 0, 1, useSimple);
2388
2389                 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2390
2391                 result = ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
2392                                              useSubsurfUv, dm);
2393
2394                 ccgSubSurf_free(ss);
2395                 
2396                 return result;
2397         } else {
2398                 int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
2399                 int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2400                 CCGSubSurf *ss;
2401                 
2402                 /* It is quite possible there is a much better place to do this. It
2403                  * depends a bit on how rigourously we expect this function to never
2404                  * be called in editmode. In semi-theory we could share a single
2405                  * cache, but the handles used inside and outside editmode are not
2406                  * the same so we would need some way of converting them. Its probably
2407                  * not worth the effort. But then why am I even writing this long
2408                  * comment that no one will read? Hmmm. - zr
2409                  */
2410                 if(smd->emCache) {
2411                         ccgSubSurf_free(smd->emCache);
2412                         smd->emCache = NULL;
2413                 }
2414
2415                 if(useIncremental && isFinalCalc) {
2416                         smd->mCache = ss = _getSubSurf(smd->mCache, smd->levels,
2417                                                        useAging, 0, useSimple);
2418
2419                         ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2420
2421                         return ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
2422                                                useSubsurfUv, dm);
2423                 } else {
2424                         if (smd->mCache && isFinalCalc) {
2425                                 ccgSubSurf_free(smd->mCache);
2426                                 smd->mCache = NULL;
2427                         }
2428
2429                         ss = _getSubSurf(NULL, smd->levels, 0, 1, useSimple);
2430                         ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2431
2432                         result = ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
2433                                                      useSubsurfUv, dm);
2434
2435                         ccgSubSurf_free(ss);
2436
2437                         return result;
2438                 }
2439         }
2440 }
2441
2442 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 
2443 {
2444         /* Finds the subsurf limit positions for the verts in a mesh 
2445          * and puts them in an array of floats. Please note that the 
2446          * calculated vert positions is incorrect for the verts 
2447          * on the boundary of the mesh.
2448          */
2449         CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0);
2450         float edge_sum[3], face_sum[3];
2451         CCGVertIterator *vi;
2452         DerivedMesh *dm = CDDM_from_mesh(me, NULL);
2453
2454         ss_sync_from_derivedmesh(ss, dm, NULL, 0);
2455
2456         vi = ccgSubSurf_getVertIterator(ss);
2457         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2458                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2459                 int idx = (int) ccgSubSurf_getVertVertHandle(ss, v);
2460                 int N = ccgSubSurf_getVertNumEdges(ss, v);
2461                 int numFaces = ccgSubSurf_getVertNumFaces(ss, v);
2462                 float *co;
2463                 int i;
2464                 
2465                 edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0;
2466                 face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
2467
2468                 for (i=0; i<N; i++) {
2469                         CCGEdge *e = ccgSubSurf_getVertEdge(ss, v, i);
2470                         VecAddf(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
2471                 }
2472                 for (i=0; i<numFaces; i++) {
2473                         CCGFace *f = ccgSubSurf_getVertFace(ss, v, i);
2474                         VecAddf(face_sum, face_sum, ccgSubSurf_getFaceCenterData(ss, f));
2475                 }
2476
2477                 /* ad-hoc correction for boundary vertices, to at least avoid them
2478                    moving completely out of place (brecht) */
2479                 if(numFaces && numFaces != N)
2480                         VecMulf(face_sum, (float)N/(float)numFaces);
2481
2482                 co = ccgSubSurf_getVertData(ss, v);
2483                 positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
2484                 positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
2485                 positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
2486         }
2487         ccgVertIterator_free(vi);
2488
2489         ccgSubSurf_free(ss);
2490
2491         dm->release(dm);
2492 }
2493