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