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