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