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