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