Merge of first part of changes from the apricot branch, especially
[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                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e));
704
705                 if(!ccgSubSurf_getEdgeNumFaces(ss, e)) flags |= ME_LOOSEEDGE;
706
707
708                 if(edgeIdx != -1 && dm) {
709                         MEdge origMed;
710                         dm->getEdge(dm, edgeIdx, &origMed);
711
712                         flags |= origMed.flag;
713                 }
714
715                 for(x = 0; x < edgeSize - 1; x++) {
716                         med->v1 = getEdgeIndex(ss, e, x, edgeSize);
717                         med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
718                         med->flag = flags;
719                         *origIndex = ccgDM_getEdgeMapIndex(NULL, ss, e);
720                         ++med;
721                         ++origIndex;
722                         i++;
723                 }
724         }
725
726         // load faces
727         i = 0;
728         mf = CDDM_get_faces(result);
729         origIndex = result->getFaceData(result, 0, CD_ORIGINDEX);
730
731         for(index = 0; index < totface; index++) {
732                 CCGFace *f = faceMap2[index];
733                 int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
734                 int mat_nr;
735                 int flag;
736                 int mapIndex = ccgDM_getFaceMapIndex(NULL, ss, f);
737                 int faceIdx = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
738
739                 if(!ssFromEditmesh) {
740                         MFace origMFace;
741                         dm->getFace(dm, faceIdx, &origMFace);
742                         
743                         mat_nr = origMFace.mat_nr;
744                         flag = origMFace.flag;
745                 } else {
746                         EditFace *ef = ccgSubSurf_getFaceFaceHandle(ss, f);
747                         mat_nr = ef->mat_nr;
748                         flag = ef->flag;
749                 }
750
751                 for(S = 0; S < numVerts; S++) {
752                         FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
753
754                         for(y = 0; y < gridFaces; y++) {
755                                 for(x = 0; x < gridFaces; x++) {
756                                         mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
757                                                               edgeSize, gridSize);
758                                         mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
759                                                               edgeSize, gridSize);
760                                         mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
761                                                               edgeSize, gridSize);
762                                         mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
763                                                               edgeSize, gridSize);
764                                         mf->mat_nr = mat_nr;
765                                         mf->flag = flag;
766
767                                         if(dm) {
768                                                 int prevS = (S - 1 + numVerts) % numVerts;
769                                                 int nextS = (S + 1) % numVerts;
770                                                 int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
771                                                 FaceVertWeight w;
772
773                                                 for(j = 0; j < 4; ++j) {
774                                                         w[j][prevS]  = (*weight)[j][0];
775                                                         w[j][S]      = (*weight)[j][1];
776                                                         w[j][nextS]  = (*weight)[j][2];
777                                                         w[j][otherS] = (*weight)[j][3];
778                                                 }
779
780                                                 DM_interp_face_data(dm, result, &faceIdx, NULL,
781                                                                     &w, 1, i);
782                                                 weight++;
783                                         }
784
785                                         *origIndex = mapIndex;
786                                         ++mf;
787                                         ++origIndex;
788                                         i++;
789                                 }
790                         }
791                 }
792         }
793
794         MEM_freeN(faceMap2);
795         MEM_freeN(edgeMap2);
796         MEM_freeN(vertMap2);
797
798         MEM_freeN(tweight);
799         MEM_freeN(qweight);
800
801         if(useSubsurfUv) {
802                 CustomData *fdata = &result->faceData;
803                 CustomData *dmfdata = &dm->faceData;
804                 int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
805                 int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
806                 
807                 for (i=0; i<numlayer && i<dmnumlayer; i++)
808                         set_subsurf_uv(ss, dm, result, i);
809         }
810
811         CDDM_calc_normals(result);
812
813         return result;
814 }
815
816 static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
817                                      float (*vertexCos)[3], int useFlatSubdiv)
818 {
819         float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
820         CCGVertHDL fVerts[4];
821         int totvert = dm->getNumVerts(dm);
822         int totedge = dm->getNumEdges(dm);
823         int totface = dm->getNumFaces(dm);
824         int i;
825         int *index;
826         MVert *mvert = dm->getVertArray(dm);
827         MEdge *medge = dm->getEdgeArray(dm);
828         MFace *mface = dm->getFaceArray(dm);
829         MVert *mv;
830         MEdge *me;
831         MFace *mf;
832
833         ccgSubSurf_initFullSync(ss);
834
835         mv = mvert;
836         index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
837         for(i = 0; i < totvert; i++, mv++, index++) {
838                 CCGVert *v;
839
840                 if(vertexCos) {
841                         ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), vertexCos[i], 0, &v);
842                 } else {
843                         ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), mv->co, 0, &v);
844                 }
845
846                 ((int*)ccgSubSurf_getVertUserData(ss, v))[1] = *index;
847         }
848
849         me = medge;
850         index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX);
851         for(i = 0; i < totedge; i++, me++, index++) {
852                 CCGEdge *e;
853                 float crease;
854
855                 crease = useFlatSubdiv ? creaseFactor :
856                                          me->crease * creaseFactor / 255.0f;
857
858                 ccgSubSurf_syncEdge(ss, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(me->v1),
859                                     SET_INT_IN_POINTER(me->v2), crease, &e);
860
861                 ((int*)ccgSubSurf_getEdgeUserData(ss, e))[1] = *index;
862         }
863
864         mf = mface;
865         index = (int *)dm->getFaceDataArray(dm, CD_ORIGINDEX);
866         for (i = 0; i < totface; i++, mf++, index++) {
867                 CCGFace *f;
868
869                 fVerts[0] = SET_INT_IN_POINTER(mf->v1);
870                 fVerts[1] = SET_INT_IN_POINTER(mf->v2);
871                 fVerts[2] = SET_INT_IN_POINTER(mf->v3);
872                 fVerts[3] = SET_INT_IN_POINTER(mf->v4);
873
874                 // this is very bad, means mesh is internally consistent.
875                 // it is not really possible to continue without modifying
876                 // other parts of code significantly to handle missing faces.
877                 // since this really shouldn't even be possible we just bail.
878                 if(ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), fVerts[3] ? 4 : 3,
879                                        fVerts, &f) == eCCGError_InvalidValue) {
880                         static int hasGivenError = 0;
881
882                         if(!hasGivenError) {
883                                 error("Unrecoverable error in SubSurf calculation,"
884                                       " mesh is inconsistent.");
885
886                                 hasGivenError = 1;
887                         }
888
889                         return;
890                 }
891
892                 ((int*)ccgSubSurf_getFaceUserData(ss, f))[1] = *index;
893         }
894
895         ccgSubSurf_processSync(ss);
896 }
897
898 /***/
899
900 static int ccgDM_getVertMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGVert *v) {
901         return ((int*) ccgSubSurf_getVertUserData(ss, v))[1];
902 }
903
904 static int ccgDM_getEdgeMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGEdge *e) {
905         return ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1];
906 }
907
908 static int ccgDM_getFaceMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGFace *f) {
909         return ((int*) ccgSubSurf_getFaceUserData(ss, f))[1];
910 }
911
912 static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
913         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
914         CCGSubSurf *ss = ccgdm->ss;
915         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
916         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
917         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
918         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
919         int gridSize = ccgSubSurf_getGridSize(ss);
920
921         if (!ccgSubSurf_getNumVerts(ss))
922                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
923
924         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
925                 CCGVert *v = ccgVertIterator_getCurrent(vi);
926                 float *co = ccgSubSurf_getVertData(ss, v);
927
928                 DO_MINMAX(co, min_r, max_r);
929         }
930
931         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
932                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
933                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
934
935                 for (i=0; i<edgeSize; i++)
936                         DO_MINMAX(edgeData[i].co, min_r, max_r);
937         }
938
939         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
940                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
941                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
942
943                 for (S=0; S<numVerts; S++) {
944                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
945
946                         for (y=0; y<gridSize; y++)
947                                 for (x=0; x<gridSize; x++)
948                                         DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r);
949                 }
950         }
951
952         ccgFaceIterator_free(fi);
953         ccgEdgeIterator_free(ei);
954         ccgVertIterator_free(vi);
955 }
956 static int ccgDM_getNumVerts(DerivedMesh *dm) {
957         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
958
959         return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
960 }
961 static int ccgDM_getNumEdges(DerivedMesh *dm) {
962         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
963
964         return ccgSubSurf_getNumFinalEdges(ccgdm->ss);
965 }
966 static int ccgDM_getNumFaces(DerivedMesh *dm) {
967         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
968
969         return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
970 }
971
972 static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
973 {
974         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
975         CCGSubSurf *ss = ccgdm->ss;
976         int i;
977
978         memset(mv, 0, sizeof(*mv));
979
980         if(vertNum < ccgdm->edgeMap[0].startVert) {
981                 /* this vert comes from face data */
982                 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
983                 CCGFace *f;
984                 int x, y, grid, numVerts;
985                 int offset;
986                 int gridSize = ccgSubSurf_getGridSize(ss);
987                 int gridSideVerts;
988                 int gridInternalVerts;
989                 int gridSideEnd;
990                 int gridInternalEnd;
991
992                 i = 0;
993                 while(i < lastface && vertNum >= ccgdm->faceMap[i + 1].startVert)
994                         ++i;
995
996                 f = ccgdm->faceMap[i].face;
997                 numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
998
999                 gridSideVerts = gridSize - 2;
1000                 gridInternalVerts = gridSideVerts * gridSideVerts;
1001
1002                 gridSideEnd = 1 + numVerts * gridSideVerts;
1003                 gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
1004
1005                 offset = vertNum - ccgdm->faceMap[i].startVert;
1006                 if(offset < 1) {
1007                         VecCopyf(mv->co, ccgSubSurf_getFaceCenterData(ss, f));
1008                 } else if(offset < gridSideEnd) {
1009                         offset -= 1;
1010                         grid = offset / gridSideVerts;
1011                         x = offset % gridSideVerts + 1;
1012                         VecCopyf(mv->co, ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x));
1013                 } else if(offset < gridInternalEnd) {
1014                         offset -= gridSideEnd;
1015                         grid = offset / gridInternalVerts;
1016                         offset %= gridInternalVerts;
1017                         y = offset / gridSideVerts + 1;
1018                         x = offset % gridSideVerts + 1;
1019                         VecCopyf(mv->co, ccgSubSurf_getFaceGridData(ss, f, grid, x, y));
1020                 }
1021         } else if(vertNum < ccgdm->vertMap[0].startVert) {
1022                 /* this vert comes from edge data */
1023                 CCGEdge *e;
1024                 int lastedge = ccgSubSurf_getNumEdges(ss) - 1;
1025                 int x;
1026
1027                 i = 0;
1028                 while(i < lastedge && vertNum >= ccgdm->edgeMap[i + 1].startVert)
1029                         ++i;
1030
1031                 e = ccgdm->edgeMap[i].edge;
1032
1033                 x = vertNum - ccgdm->edgeMap[i].startVert + 1;
1034                 VecCopyf(mv->co, ccgSubSurf_getEdgeData(ss, e, x));
1035         } else {
1036                 /* this vert comes from vert data */
1037                 CCGVert *v;
1038                 i = vertNum - ccgdm->vertMap[0].startVert;
1039
1040                 v = ccgdm->vertMap[i].vert;
1041                 VecCopyf(mv->co, ccgSubSurf_getVertData(ss, v));
1042         }
1043 }
1044
1045 static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
1046 {
1047         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1048         CCGSubSurf *ss = ccgdm->ss;
1049         int i;
1050
1051         memset(med, 0, sizeof(*med));
1052
1053         if(edgeNum < ccgdm->edgeMap[0].startEdge) {
1054                 /* this edge comes from face data */
1055                 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
1056                 CCGFace *f;
1057                 int x, y, grid, numVerts;
1058                 int offset;
1059                 int gridSize = ccgSubSurf_getGridSize(ss);
1060                 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1061                 int gridSideEdges;
1062                 int gridInternalEdges;
1063
1064                 i = 0;
1065                 while(i < lastface && edgeNum >= ccgdm->faceMap[i + 1].startEdge)
1066                         ++i;
1067
1068                 f = ccgdm->faceMap[i].face;
1069                 numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1070
1071                 gridSideEdges = gridSize - 1;
1072                 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
1073
1074                 offset = edgeNum - ccgdm->faceMap[i].startEdge;
1075                 grid = offset / (gridSideEdges + gridInternalEdges);
1076                 offset %= (gridSideEdges + gridInternalEdges);
1077
1078                 if(offset < gridSideEdges) {
1079                         x = offset;
1080                         med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, gridSize);
1081                         med->v2 = getFaceIndex(ss, f, grid, x+1, 0, edgeSize, gridSize);
1082                 } else {
1083                         offset -= gridSideEdges;
1084                         x = (offset / 2) / gridSideEdges + 1;
1085                         y = (offset / 2) % gridSideEdges;
1086                         if(offset % 2 == 0) {
1087                                 med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSize, gridSize);
1088                                 med->v2 = getFaceIndex(ss, f, grid, x, y+1, edgeSize, gridSize);
1089                         } else {
1090                                 med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSize, gridSize);
1091                                 med->v2 = getFaceIndex(ss, f, grid, y+1, x, edgeSize, gridSize);
1092                         }
1093                 }
1094         } else {
1095                 /* this vert comes from edge data */
1096                 CCGEdge *e;
1097                 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1098                 int x, *edgeFlag;
1099                 unsigned int flags = 0;
1100
1101                 i = (edgeNum - ccgdm->edgeMap[0].startEdge) / (edgeSize - 1);
1102
1103                 e = ccgdm->edgeMap[i].edge;
1104
1105                 if(!ccgSubSurf_getEdgeNumFaces(ss, e)) flags |= ME_LOOSEEDGE;
1106
1107                 x = edgeNum - ccgdm->edgeMap[i].startEdge;
1108
1109                 med->v1 = getEdgeIndex(ss, e, x, edgeSize);
1110                 med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
1111
1112                 edgeFlag = dm->getEdgeData(dm, edgeNum, CD_FLAGS);
1113                 if(edgeFlag)
1114                         flags |= (*edgeFlag & (ME_SEAM | ME_SHARP))
1115                                          | ME_EDGEDRAW | ME_EDGERENDER;
1116                 else
1117                         flags |= ME_EDGEDRAW | ME_EDGERENDER;
1118
1119                 med->flag = flags;
1120         }
1121 }
1122
1123 static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
1124 {
1125         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1126         CCGSubSurf *ss = ccgdm->ss;
1127         int gridSize = ccgSubSurf_getGridSize(ss);
1128         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1129         int gridSideEdges = gridSize - 1;
1130         int gridFaces = gridSideEdges * gridSideEdges;
1131         int i;
1132         CCGFace *f;
1133         int numVerts;
1134         int offset;
1135         int grid;
1136         int x, y;
1137         int lastface = ccgSubSurf_getNumFaces(ss) - 1;
1138         char *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
1139
1140         memset(mf, 0, sizeof(*mf));
1141
1142         i = 0;
1143         while(i < lastface && faceNum >= ccgdm->faceMap[i + 1].startFace)
1144                 ++i;
1145
1146         f = ccgdm->faceMap[i].face;
1147         numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1148
1149         offset = faceNum - ccgdm->faceMap[i].startFace;
1150         grid = offset / gridFaces;
1151         offset %= gridFaces;
1152         y = offset / gridSideEdges;
1153         x = offset % gridSideEdges;
1154
1155         mf->v1 = getFaceIndex(ss, f, grid, x+0, y+0, edgeSize, gridSize);
1156         mf->v2 = getFaceIndex(ss, f, grid, x+0, y+1, edgeSize, gridSize);
1157         mf->v3 = getFaceIndex(ss, f, grid, x+1, y+1, edgeSize, gridSize);
1158         mf->v4 = getFaceIndex(ss, f, grid, x+1, y+0, edgeSize, gridSize);
1159
1160         if(faceFlags) mf->flag = faceFlags[i*4];
1161         else mf->flag = ME_SMOOTH;
1162 }
1163
1164 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
1165 {
1166         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1167         CCGSubSurf *ss = ccgdm->ss;
1168         int index;
1169         int totvert, totedge, totface;
1170         int gridSize = ccgSubSurf_getGridSize(ss);
1171         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1172         int i = 0;
1173
1174         totface = ccgSubSurf_getNumFaces(ss);
1175         for(index = 0; index < totface; index++) {
1176                 CCGFace *f = ccgdm->faceMap[index].face;
1177                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1178
1179                 VecCopyf(mvert[i++].co, ccgSubSurf_getFaceCenterData(ss, f));
1180                 
1181                 for(S = 0; S < numVerts; S++) {
1182                         for(x = 1; x < gridSize - 1; x++) {
1183                                 VecCopyf(mvert[i++].co,
1184                                          ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1185                         }
1186                 }
1187
1188                 for(S = 0; S < numVerts; S++) {
1189                         for(y = 1; y < gridSize - 1; y++) {
1190                                 for(x = 1; x < gridSize - 1; x++) {
1191                                         VecCopyf(mvert[i++].co,
1192                                                  ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1193                                 }
1194                         }
1195                 }
1196         }
1197
1198         totedge = ccgSubSurf_getNumEdges(ss);
1199         for(index = 0; index < totedge; index++) {
1200                 CCGEdge *e = ccgdm->edgeMap[index].edge;
1201                 int x;
1202
1203                 for(x = 1; x < edgeSize - 1; x++) {
1204                         VecCopyf(mvert[i++].co, ccgSubSurf_getEdgeData(ss, e, x));
1205                 }
1206         }
1207
1208         totvert = ccgSubSurf_getNumVerts(ss);
1209         for(index = 0; index < totvert; index++) {
1210                 CCGVert *v = ccgdm->vertMap[index].vert;
1211
1212                 VecCopyf(mvert[i].co, ccgSubSurf_getVertData(ss, v));
1213
1214                 i++;
1215         }
1216 }
1217
1218 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
1219 {
1220         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1221         CCGSubSurf *ss = ccgdm->ss;
1222         int index;
1223         int totedge, totface;
1224         int gridSize = ccgSubSurf_getGridSize(ss);
1225         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1226         int i = 0;
1227         int *edgeFlags = dm->getEdgeDataArray(dm, CD_FLAGS);
1228
1229         totface = ccgSubSurf_getNumFaces(ss);
1230         for(index = 0; index < totface; index++) {
1231                 CCGFace *f = ccgdm->faceMap[index].face;
1232                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1233
1234                 for(S = 0; S < numVerts; S++) {
1235                         for(x = 0; x < gridSize - 1; x++) {
1236                                 MEdge *med = &medge[i];
1237
1238                                 if(ccgdm->drawInteriorEdges)
1239                                     med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1240                                 med->v1 = getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize);
1241                                 med->v2 = getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize);
1242                                 i++;
1243                         }
1244
1245                         for(x = 1; x < gridSize - 1; x++) {
1246                                 for(y = 0; y < gridSize - 1; y++) {
1247                                         MEdge *med;
1248
1249                                         med = &medge[i];
1250                                         if(ccgdm->drawInteriorEdges)
1251                                             med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1252                                         med->v1 = getFaceIndex(ss, f, S, x, y,
1253                                                                edgeSize, gridSize);
1254                                         med->v2 = getFaceIndex(ss, f, S, x, y + 1,
1255                                                                edgeSize, gridSize);
1256                                         i++;
1257
1258                                         med = &medge[i];
1259                                         if(ccgdm->drawInteriorEdges)
1260                                             med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1261                                         med->v1 = getFaceIndex(ss, f, S, y, x,
1262                                                                edgeSize, gridSize);
1263                                         med->v2 = getFaceIndex(ss, f, S, y + 1, x,
1264                                                                edgeSize, gridSize);
1265                                         i++;
1266                                 }
1267                         }
1268                 }
1269         }
1270
1271         totedge = ccgSubSurf_getNumEdges(ss);
1272         for(index = 0; index < totedge; index++) {
1273                 CCGEdge *e = ccgdm->edgeMap[index].edge;
1274                 unsigned int flags = 0;
1275                 int x;
1276                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e));
1277
1278                 if(!ccgSubSurf_getEdgeNumFaces(ss, e)) flags |= ME_LOOSEEDGE;
1279
1280                 if(edgeFlags) {
1281                         if(edgeIdx != -1) {
1282                                 flags |= (edgeFlags[i] & (ME_SEAM | ME_SHARP))
1283                                          | ME_EDGEDRAW | ME_EDGERENDER;
1284                         }
1285                 } else {
1286                         flags |= ME_EDGEDRAW | ME_EDGERENDER;
1287                 }
1288
1289                 for(x = 0; x < edgeSize - 1; x++) {
1290                         MEdge *med = &medge[i];
1291                         med->v1 = getEdgeIndex(ss, e, x, edgeSize);
1292                         med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
1293                         med->flag = flags;
1294                         i++;
1295                 }
1296         }
1297 }
1298
1299 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
1300 {
1301         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1302         CCGSubSurf *ss = ccgdm->ss;
1303         int index;
1304         int totface;
1305         int gridSize = ccgSubSurf_getGridSize(ss);
1306         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1307         int i = 0;
1308         char *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
1309
1310         totface = ccgSubSurf_getNumFaces(ss);
1311         for(index = 0; index < totface; index++) {
1312                 CCGFace *f = ccgdm->faceMap[index].face;
1313                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1314                 int mat_nr = 0;
1315                 int flag = ME_SMOOTH; /* assume face is smooth by default */
1316
1317                 for(S = 0; S < numVerts; S++) {
1318                         for(y = 0; y < gridSize - 1; y++) {
1319                                 for(x = 0; x < gridSize - 1; x++) {
1320                                         MFace *mf = &mface[i];
1321                                         mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1322                                                               edgeSize, gridSize);
1323                                         mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1324                                                               edgeSize, gridSize);
1325                                         mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1326                                                               edgeSize, gridSize);
1327                                         mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1328                                                               edgeSize, gridSize);
1329                                         mf->mat_nr = mat_nr;
1330                                         if(faceFlags) mf->flag = faceFlags[index*4];
1331                                         else mf->flag = flag;
1332
1333                                         i++;
1334                                 }
1335                         }
1336                 }
1337         }
1338 }
1339
1340 static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
1341         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1342         CCGSubSurf *ss = ccgdm->ss;
1343         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1344         int gridSize = ccgSubSurf_getGridSize(ss);
1345         int i;
1346         CCGVertIterator *vi;
1347         CCGEdgeIterator *ei;
1348         CCGFaceIterator *fi;
1349         CCGFace **faceMap2;
1350         CCGEdge **edgeMap2;
1351         CCGVert **vertMap2;
1352         int index, totvert, totedge, totface;
1353         
1354         totvert = ccgSubSurf_getNumVerts(ss);
1355         vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
1356         vi = ccgSubSurf_getVertIterator(ss);
1357         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1358                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1359
1360                 vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v))] = v;
1361         }
1362         ccgVertIterator_free(vi);
1363
1364         totedge = ccgSubSurf_getNumEdges(ss);
1365         edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
1366         ei = ccgSubSurf_getEdgeIterator(ss);
1367         for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
1368                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1369
1370                 edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e))] = e;
1371         }
1372
1373         totface = ccgSubSurf_getNumFaces(ss);
1374         faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
1375         fi = ccgSubSurf_getFaceIterator(ss);
1376         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1377                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1378
1379                 faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f;
1380         }
1381         ccgFaceIterator_free(fi);
1382
1383         i = 0;
1384         for (index=0; index<totface; index++) {
1385                 CCGFace *f = faceMap2[index];
1386                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1387
1388                 VecCopyf(cos[i++], ccgSubSurf_getFaceCenterData(ss, f));
1389                 
1390                 for (S=0; S<numVerts; S++) {
1391                         for (x=1; x<gridSize-1; x++) {
1392                                 VecCopyf(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1393                         }
1394                 }
1395
1396                 for (S=0; S<numVerts; S++) {
1397                         for (y=1; y<gridSize-1; y++) {
1398                                 for (x=1; x<gridSize-1; x++) {
1399                                         VecCopyf(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1400                                 }
1401                         }
1402                 }
1403         }
1404
1405         for (index=0; index<totedge; index++) {
1406                 CCGEdge *e= edgeMap2[index];
1407                 int x;
1408
1409                 for (x=1; x<edgeSize-1; x++) {
1410                         VecCopyf(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
1411                 }
1412         }
1413
1414         for (index=0; index<totvert; index++) {
1415                 CCGVert *v = vertMap2[index];
1416                 VecCopyf(cos[i++], ccgSubSurf_getVertData(ss, v));
1417         }
1418
1419         MEM_freeN(vertMap2);
1420         MEM_freeN(edgeMap2);
1421         MEM_freeN(faceMap2);
1422 }
1423 static void ccgDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
1424         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1425         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
1426
1427         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1428                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1429                 VertData *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
1430                 int index = ccgDM_getVertMapIndex(ccgdm, ccgdm->ss, v);
1431
1432                 if (index!=-1)
1433                         func(userData, index, vd->co, vd->no, NULL);
1434         }
1435
1436         ccgVertIterator_free(vi);
1437 }
1438 static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
1439         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1440         CCGSubSurf *ss = ccgdm->ss;
1441         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1442         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1443
1444         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1445                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1446                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1447                 int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
1448
1449                 if (index!=-1) {
1450                         for (i=0; i<edgeSize-1; i++)
1451                                 func(userData, index, edgeData[i].co, edgeData[i+1].co);
1452                 }
1453         }
1454
1455         ccgEdgeIterator_free(ei);
1456 }
1457
1458 static void ccgDM_drawVerts(DerivedMesh *dm) {
1459         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1460         CCGSubSurf *ss = ccgdm->ss;
1461         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1462         int gridSize = ccgSubSurf_getGridSize(ss);
1463         CCGVertIterator *vi;
1464         CCGEdgeIterator *ei;
1465         CCGFaceIterator *fi;
1466
1467         glBegin(GL_POINTS);
1468         vi = ccgSubSurf_getVertIterator(ss);
1469         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1470                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1471                 glVertex3fv(ccgSubSurf_getVertData(ss, v));
1472         }
1473         ccgVertIterator_free(vi);
1474
1475         ei = ccgSubSurf_getEdgeIterator(ss);
1476         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1477                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1478                 int x;
1479
1480                 for (x=1; x<edgeSize-1; x++)
1481                         glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
1482         }
1483         ccgEdgeIterator_free(ei);
1484
1485         fi = ccgSubSurf_getFaceIterator(ss);
1486         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1487                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1488                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1489
1490                 glVertex3fv(ccgSubSurf_getFaceCenterData(ss, f));
1491                 for (S=0; S<numVerts; S++)
1492                         for (x=1; x<gridSize-1; x++)
1493                                 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1494                 for (S=0; S<numVerts; S++)
1495                         for (y=1; y<gridSize-1; y++)
1496                                 for (x=1; x<gridSize-1; x++)
1497                                         glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1498         }
1499         ccgFaceIterator_free(fi);
1500         glEnd();
1501 }
1502 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) {
1503         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1504         CCGSubSurf *ss = ccgdm->ss;
1505         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1506         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1507         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1508         int gridSize = ccgSubSurf_getGridSize(ss);
1509         int useAging;
1510
1511         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1512
1513         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1514                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1515                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1516
1517                 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(ss, e))
1518                         continue;
1519
1520                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1521                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1522                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1523                 }
1524
1525                 glBegin(GL_LINE_STRIP);
1526                 for (i=0; i<edgeSize-1; i++) {
1527                         glVertex3fv(edgeData[i].co);
1528                         glVertex3fv(edgeData[i+1].co);
1529                 }
1530                 glEnd();
1531         }
1532
1533         if (useAging && !(G.f&G_BACKBUFSEL)) {
1534                 glColor3ub(0, 0, 0);
1535         }
1536
1537         if (ccgdm->drawInteriorEdges) {
1538                 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1539                         CCGFace *f = ccgFaceIterator_getCurrent(fi);
1540                         int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1541
1542                         for (S=0; S<numVerts; S++) {
1543                                 VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1544
1545                                 glBegin(GL_LINE_STRIP);
1546                                 for (x=0; x<gridSize; x++)
1547                                         glVertex3fv(faceGridData[x].co);
1548                                 glEnd();
1549                                 for (y=1; y<gridSize-1; y++) {
1550                                         glBegin(GL_LINE_STRIP);
1551                                         for (x=0; x<gridSize; x++)
1552                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1553                                         glEnd();
1554                                 }
1555                                 for (x=1; x<gridSize-1; x++) {
1556                                         glBegin(GL_LINE_STRIP);
1557                                         for (y=0; y<gridSize; y++)
1558                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1559                                         glEnd();
1560                                 }
1561                         }
1562                 }
1563         }
1564
1565         ccgFaceIterator_free(fi);
1566         ccgEdgeIterator_free(ei);
1567 }
1568 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
1569         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1570         CCGSubSurf *ss = ccgdm->ss;
1571         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1572         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1573
1574         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1575                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1576                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1577
1578                 if (!ccgSubSurf_getEdgeNumFaces(ss, e)) {
1579                         glBegin(GL_LINE_STRIP);
1580                         for (i=0; i<edgeSize-1; i++) {
1581                                 glVertex3fv(edgeData[i].co);
1582                                 glVertex3fv(edgeData[i+1].co);
1583                         }
1584                         glEnd();
1585                 }
1586         }
1587
1588         ccgEdgeIterator_free(ei);
1589 }
1590
1591 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
1592 {
1593         float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1594         float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1595         float no[3];
1596
1597         no[0] = b_dY*a_cZ - b_dZ*a_cY;
1598         no[1] = b_dZ*a_cX - b_dX*a_cZ;
1599         no[2] = b_dX*a_cY - b_dY*a_cX;
1600
1601         /* don't normalize, GL_NORMALIZE is be enabled */
1602         glNormal3fv(no);
1603 }
1604
1605         /* Only used by non-editmesh types */
1606 static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
1607         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1608         CCGSubSurf *ss = ccgdm->ss;
1609         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1610         int gridSize = ccgSubSurf_getGridSize(ss);
1611         char *faceFlags = DM_get_face_data_layer(dm, CD_FLAGS);
1612
1613         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1614                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1615                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1616                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1617                 int drawSmooth, mat_nr;
1618
1619                 if(faceFlags) {
1620                         drawSmooth = (faceFlags[index*4] & ME_SMOOTH);
1621                         mat_nr= faceFlags[index*4 + 1];
1622                 }
1623                 else {
1624                         drawSmooth = 1;
1625                         mat_nr= 0;
1626                 }
1627                 
1628                 if (!setMaterial(mat_nr+1, NULL))
1629                         continue;
1630
1631                 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1632                 for (S=0; S<numVerts; S++) {
1633                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1634
1635                         if (drawSmooth) {
1636                                 for (y=0; y<gridSize-1; y++) {
1637                                         glBegin(GL_QUAD_STRIP);
1638                                         for (x=0; x<gridSize; x++) {
1639                                                 VertData *a = &faceGridData[(y+0)*gridSize + x];
1640                                                 VertData *b = &faceGridData[(y+1)*gridSize + x];
1641
1642                                                 glNormal3fv(a->no);
1643                                                 glVertex3fv(a->co);
1644                                                 glNormal3fv(b->no);
1645                                                 glVertex3fv(b->co);
1646                                         }
1647                                         glEnd();
1648                                 }
1649                         } else {
1650                                 glBegin(GL_QUADS);
1651                                 for (y=0; y<gridSize-1; y++) {
1652                                         for (x=0; x<gridSize-1; x++) {
1653                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
1654                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1655                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1656                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
1657
1658                                                 ccgDM_glNormalFast(a, b, c, d);
1659
1660                                                 glVertex3fv(d);
1661                                                 glVertex3fv(c);
1662                                                 glVertex3fv(b);
1663                                                 glVertex3fv(a);
1664                                         }
1665                                 }
1666                                 glEnd();
1667                         }
1668                 }
1669         }
1670
1671         ccgFaceIterator_free(fi);
1672 }
1673
1674         /* Only used by non-editmesh types */
1675 static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) {
1676         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1677         CCGSubSurf *ss = ccgdm->ss;
1678         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1679         GPUVertexAttribs gattribs;
1680         DMVertexAttribs attribs;
1681         MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE);
1682         int gridSize = ccgSubSurf_getGridSize(ss);
1683         int gridFaces = gridSize - 1;
1684         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1685         int transp, orig_transp, new_transp;
1686         char *faceFlags = DM_get_face_data_layer(dm, CD_FLAGS);
1687         int a, b, i, doDraw, numVerts, matnr, new_matnr, totface;
1688
1689         doDraw = 0;
1690         numVerts = 0;
1691         matnr = -1;
1692         transp = GPU_get_material_blend_mode();
1693         orig_transp = transp;
1694
1695         memset(&attribs, 0, sizeof(attribs));
1696
1697 #define PASSATTRIB(dx, dy, vert) {                                                                                              \
1698         if(attribs.totorco) {                                                                                                           \
1699                 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize);                 \
1700                 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
1701         }                                                                                                                                                       \
1702         for(b = 0; b < attribs.tottface; b++) {                                                                         \
1703                 MTFace *tf = &attribs.tface[b].array[a];                                                                \
1704                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);                   \
1705         }                                                                                                                                                       \
1706         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
1707                 MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
1708                 GLubyte col[4];                                                                                                                 \
1709                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
1710                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
1711         }                                                                                                                                                       \
1712         if(attribs.tottang) {                                                                                                           \
1713                 float *tang = attribs.tang.array[a*4 + vert];                                                   \
1714                 glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
1715         }                                                                                                                                                       \
1716 }
1717
1718         totface = ccgSubSurf_getNumFaces(ss);
1719         for(a = 0, i = 0; i < totface; i++) {
1720                 CCGFace *f = ccgdm->faceMap[i].face;
1721                 int S, x, y, drawSmooth;
1722                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1723                 int origIndex = ccgDM_getFaceMapIndex(ccgdm, ss, f);
1724                 
1725                 numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1726
1727                 if(faceFlags) {
1728                         drawSmooth = (faceFlags[index*4] & ME_SMOOTH);
1729                         new_matnr= faceFlags[index*4 + 1] + 1;
1730                 }
1731                 else {
1732                         drawSmooth = 1;
1733                         new_matnr= 1;
1734                 }
1735
1736                 if(new_matnr != matnr) {
1737                         doDraw = setMaterial(matnr = new_matnr, &gattribs);
1738                         if(doDraw)
1739                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1740                 }
1741
1742                 if(!doDraw || (setDrawOptions && !setDrawOptions(userData, origIndex))) {
1743                         a += gridFaces*gridFaces*numVerts;
1744                         continue;
1745                 }
1746
1747                 if(tf) {
1748                         new_transp = tf[i].transp;
1749
1750                         if(new_transp != transp) {
1751                                 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
1752                                         GPU_set_material_blend_mode(orig_transp);
1753                                 else
1754                                         GPU_set_material_blend_mode(new_transp);
1755                                 transp = new_transp;
1756                         }
1757                 }
1758
1759                 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1760                 for (S=0; S<numVerts; S++) {
1761                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1762                         VertData *vda, *vdb;
1763
1764                         if (drawSmooth) {
1765                                 for (y=0; y<gridFaces; y++) {
1766                                         glBegin(GL_QUAD_STRIP);
1767                                         for (x=0; x<gridFaces; x++) {
1768                                                 vda = &faceGridData[(y+0)*gridSize + x];
1769                                                 vdb = &faceGridData[(y+1)*gridSize + x];
1770                                                 
1771                                                 PASSATTRIB(0, 0, 0);
1772                                                 glNormal3fv(vda->no);
1773                                                 glVertex3fv(vda->co);
1774
1775                                                 PASSATTRIB(0, 1, 1);
1776                                                 glNormal3fv(vdb->no);
1777                                                 glVertex3fv(vdb->co);
1778
1779                                                 if(x != gridFaces-1)
1780                                                         a++;
1781                                         }
1782
1783                                         vda = &faceGridData[(y+0)*gridSize + x];
1784                                         vdb = &faceGridData[(y+1)*gridSize + x];
1785
1786                                         PASSATTRIB(0, 0, 3);
1787                                         glNormal3fv(vda->no);
1788                                         glVertex3fv(vda->co);
1789
1790                                         PASSATTRIB(0, 1, 2);
1791                                         glNormal3fv(vdb->no);
1792                                         glVertex3fv(vdb->co);
1793
1794                                         glEnd();
1795
1796                                         a++;
1797                                 }
1798                         } else {
1799                                 glBegin(GL_QUADS);
1800                                 for (y=0; y<gridFaces; y++) {
1801                                         for (x=0; x<gridFaces; x++) {
1802                                                 float *aco = faceGridData[(y+0)*gridSize + x].co;
1803                                                 float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
1804                                                 float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
1805                                                 float *dco = faceGridData[(y+1)*gridSize + x].co;
1806
1807                                                 ccgDM_glNormalFast(aco, bco, cco, dco);
1808
1809                                                 PASSATTRIB(0, 1, 1);
1810                                                 glVertex3fv(dco);
1811                                                 PASSATTRIB(1, 1, 2);
1812                                                 glVertex3fv(cco);
1813                                                 PASSATTRIB(1, 0, 3);
1814                                                 glVertex3fv(bco);
1815                                                 PASSATTRIB(0, 0, 0);
1816                                                 glVertex3fv(aco);
1817                                                 
1818                                                 a++;
1819                                         }
1820                                 }
1821                                 glEnd();
1822                         }
1823                 }
1824         }
1825
1826 #undef PASSATTRIB
1827
1828         ccgFaceIterator_free(fi);
1829 }
1830
1831 static void ccgDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
1832         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1833 }
1834
1835 static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2) {
1836         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1837         CCGSubSurf *ss = ccgdm->ss;
1838         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1839         int gridSize = ccgSubSurf_getGridSize(ss);
1840         unsigned char *cp1, *cp2;
1841         int useTwoSide=1;
1842
1843         cp1= col1;
1844         if(col2) {
1845                 cp2= col2;
1846         } else {
1847                 cp2= NULL;
1848                 useTwoSide= 0;
1849         }
1850
1851         glShadeModel(GL_SMOOTH);
1852         if(col1 && col2)
1853                 glEnable(GL_CULL_FACE);
1854
1855         glBegin(GL_QUADS);
1856         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1857                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1858                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1859
1860                 for (S=0; S<numVerts; S++) {
1861                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1862                         for (y=0; y<gridSize-1; y++) {
1863                                 for (x=0; x<gridSize-1; x++) {
1864                                         float *a = faceGridData[(y+0)*gridSize + x].co;
1865                                         float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1866                                         float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1867                                         float *d = faceGridData[(y+1)*gridSize + x].co;
1868
1869                                         glColor3ub(cp1[3], cp1[2], cp1[1]);
1870                                         glVertex3fv(d);
1871                                         glColor3ub(cp1[7], cp1[6], cp1[5]);
1872                                         glVertex3fv(c);
1873                                         glColor3ub(cp1[11], cp1[10], cp1[9]);
1874                                         glVertex3fv(b);
1875                                         glColor3ub(cp1[15], cp1[14], cp1[13]);
1876                                         glVertex3fv(a);
1877
1878                                         if (useTwoSide) {
1879                                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
1880                                                 glVertex3fv(a);
1881                                                 glColor3ub(cp2[11], cp2[10], cp2[9]);
1882                                                 glVertex3fv(b);
1883                                                 glColor3ub(cp2[7], cp2[6], cp2[5]);
1884                                                 glVertex3fv(c);
1885                                                 glColor3ub(cp2[3], cp2[2], cp2[1]);
1886                                                 glVertex3fv(d);
1887                                         }
1888
1889                                         if (cp2) cp2+=16;
1890                                         cp1+=16;
1891                                 }
1892                         }
1893                 }
1894         }
1895         glEnd();
1896
1897         ccgFaceIterator_free(fi);
1898 }
1899
1900 static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
1901         int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
1902         int (*drawParamsMapped)(void *userData, int index),
1903         void *userData) 
1904 {
1905         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1906         CCGSubSurf *ss = ccgdm->ss;
1907         MCol *mcol = DM_get_face_data_layer(dm, CD_MCOL);
1908         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
1909         char *faceFlags = DM_get_face_data_layer(dm, CD_FLAGS);
1910         int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss);
1911         int gridFaces = gridSize - 1;
1912
1913         totface = ccgSubSurf_getNumFaces(ss);
1914         for(i = 0; i < totface; i++) {
1915                 CCGFace *f = ccgdm->faceMap[i].face;
1916                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1917                 int drawSmooth, index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
1918                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1919                 unsigned char *cp= NULL;
1920                 int mat_nr;
1921
1922                 if(faceFlags) {
1923                         drawSmooth = (faceFlags[origIndex*4] & ME_SMOOTH);
1924                         mat_nr= faceFlags[origIndex*4 + 1];
1925                 }
1926                 else {
1927                         drawSmooth = 1;
1928                         mat_nr= 0;
1929                 }
1930
1931                 if(drawParams)
1932                         flag = drawParams(tf, mcol, mat_nr);
1933                 else
1934                         flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1;
1935                 
1936                 if (flag == 0) { /* flag 0 == the face is hidden or invisible */
1937                         if(tf) tf += gridFaces*gridFaces*numVerts;
1938                         if(mcol) mcol += gridFaces*gridFaces*numVerts*4;
1939                         continue;
1940                 }
1941
1942                 /* flag 1 == use vertex colors */
1943                 if(mcol) {
1944                         if(flag==1) cp= (unsigned char*)mcol;
1945                         mcol += gridFaces*gridFaces*numVerts*4;
1946                 }
1947
1948                 for (S=0; S<numVerts; S++) {
1949                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1950                         VertData *a, *b;
1951
1952                         if (drawSmooth) {
1953                                 glShadeModel(GL_SMOOTH);
1954                                 for (y=0; y<gridFaces; y++) {
1955                                         glBegin(GL_QUAD_STRIP);
1956                                         for (x=0; x<gridFaces; x++) {
1957                                                 a = &faceGridData[(y+0)*gridSize + x];
1958                                                 b = &faceGridData[(y+1)*gridSize + x];
1959
1960                                                 if(tf) glTexCoord2fv(tf->uv[0]);
1961                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1962                                                 glNormal3fv(a->no);
1963                                                 glVertex3fv(a->co);
1964
1965                                                 if(tf) glTexCoord2fv(tf->uv[1]);
1966                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1967                                                 glNormal3fv(b->no);
1968                                                 glVertex3fv(b->co);
1969                                                 
1970                                                 if(x != gridFaces-1) {
1971                                                         if(tf) tf++;
1972                                                         if(cp) cp += 16;
1973                                                 }
1974                                         }
1975
1976                                         a = &faceGridData[(y+0)*gridSize + x];
1977                                         b = &faceGridData[(y+1)*gridSize + x];
1978
1979                                         if(tf) glTexCoord2fv(tf->uv[3]);
1980                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1981                                         glNormal3fv(a->no);
1982                                         glVertex3fv(a->co);
1983
1984                                         if(tf) glTexCoord2fv(tf->uv[2]);
1985                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1986                                         glNormal3fv(b->no);
1987                                         glVertex3fv(b->co);
1988
1989                                         if(tf) tf++;
1990                                         if(cp) cp += 16;
1991
1992                                         glEnd();
1993                                 }
1994                         } else {
1995                                 glShadeModel(GL_FLAT);
1996                                 glBegin(GL_QUADS);
1997                                 for (y=0; y<gridFaces; y++) {
1998                                         for (x=0; x<gridFaces; x++) {
1999                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
2000                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
2001                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
2002                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
2003
2004                                                 ccgDM_glNormalFast(a, b, c, d);
2005
2006                                                 if(tf) glTexCoord2fv(tf->uv[1]);
2007                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2008                                                 glVertex3fv(d);
2009
2010                                                 if(tf) glTexCoord2fv(tf->uv[2]);
2011                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2012                                                 glVertex3fv(c);
2013
2014                                                 if(tf) glTexCoord2fv(tf->uv[3]);
2015                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2016                                                 glVertex3fv(b);
2017
2018                                                 if(tf) glTexCoord2fv(tf->uv[0]);
2019                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2020                                                 glVertex3fv(a);
2021
2022                                                 if(tf) tf++;
2023                                                 if(cp) cp += 16;
2024                                         }
2025                                 }
2026                                 glEnd();
2027                         }
2028                 }
2029         }
2030 }
2031
2032 static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
2033 {
2034         ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
2035 }
2036
2037 static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
2038 {
2039         ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
2040 }
2041
2042 static void ccgDM_drawUVEdges(DerivedMesh *dm)
2043 {
2044
2045         MFace *mf = dm->getFaceArray(dm);
2046         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
2047         int i;
2048         
2049         if (tf) {
2050                 glBegin(GL_LINES);
2051                 for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
2052                         if(!(mf->flag&ME_HIDE)) {
2053                                 glVertex2fv(tf->uv[0]);
2054                                 glVertex2fv(tf->uv[1]);
2055         
2056                                 glVertex2fv(tf->uv[1]);
2057                                 glVertex2fv(tf->uv[2]);
2058         
2059                                 if(!mf->v4) {
2060                                         glVertex2fv(tf->uv[2]);
2061                                         glVertex2fv(tf->uv[0]);
2062                                 } else {
2063                                         glVertex2fv(tf->uv[2]);
2064                                         glVertex2fv(tf->uv[3]);
2065         
2066                                         glVertex2fv(tf->uv[3]);
2067                                         glVertex2fv(tf->uv[0]);
2068                                 }
2069                         }
2070                 }
2071                 glEnd();
2072         }
2073 }
2074
2075 static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) {
2076         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2077         CCGSubSurf *ss = ccgdm->ss;
2078         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
2079         int i, gridSize = ccgSubSurf_getGridSize(ss);
2080         char *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
2081
2082         for (i=0; !ccgFaceIterator_isStopped(fi); i++,ccgFaceIterator_next(fi)) {
2083                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2084                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
2085                 int drawSmooth, index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
2086                 int origIndex;
2087
2088                 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2089
2090                 if(faceFlags) drawSmooth = (faceFlags[origIndex*4] & ME_SMOOTH);
2091                 else drawSmooth = 1;
2092                 
2093                 if (index!=-1) {
2094                         int draw;
2095                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, index, &drawSmooth);
2096                         
2097                         if (draw) {
2098                                 if (draw==2) {
2099                                         glEnable(GL_POLYGON_STIPPLE);
2100                                         glPolygonStipple(stipple_quarttone);
2101                                 }
2102                                 
2103                                 for (S=0; S<numVerts; S++) {
2104                                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2105                                         if (drawSmooth) {
2106                                                 glShadeModel(GL_SMOOTH);
2107                                                 for (y=0; y<gridSize-1; y++) {
2108                                                         glBegin(GL_QUAD_STRIP);
2109                                                         for (x=0; x<gridSize; x++) {
2110                                                                 VertData *a = &faceGridData[(y+0)*gridSize + x];
2111                                                                 VertData *b = &faceGridData[(y+1)*gridSize + x];
2112         
2113                                                                 glNormal3fv(a->no);
2114                                                                 glVertex3fv(a->co);
2115                                                                 glNormal3fv(b->no);
2116                                                                 glVertex3fv(b->co);
2117                                                         }
2118                                                         glEnd();
2119                                                 }
2120                                         } else {
2121                                                 glShadeModel(GL_FLAT);
2122                                                 glBegin(GL_QUADS);
2123                                                 for (y=0; y<gridSize-1; y++) {
2124                                                         for (x=0; x<gridSize-1; x++) {
2125                                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
2126                                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
2127                                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
2128                                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
2129                                                                 float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
2130                                                                 float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
2131                                                                 float no[3];
2132         
2133                                                                 no[0] = b_dY*a_cZ - b_dZ*a_cY;
2134                                                                 no[1] = b_dZ*a_cX - b_dX*a_cZ;
2135                                                                 no[2] = b_dX*a_cY - b_dY*a_cX;
2136                                                                 glNormal3fv(no);
2137         
2138                                                                 glVertex3fv(d);
2139                                                                 glVertex3fv(c);
2140                                                                 glVertex3fv(b);
2141                                                                 glVertex3fv(a);
2142                                                         }
2143                                                 }
2144                                                 glEnd();
2145                                         }
2146                                 }
2147                                 if (draw==2)
2148                                         glDisable(GL_POLYGON_STIPPLE);
2149                         }
2150                 }
2151         }
2152
2153         ccgFaceIterator_free(fi);
2154 }
2155 static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
2156         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2157         CCGSubSurf *ss = ccgdm->ss;
2158         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2159         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2160
2161         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2162
2163         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2164                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2165                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2166                 int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
2167
2168                 glBegin(GL_LINE_STRIP);
2169                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2170                         if (useAging && !(G.f&G_BACKBUFSEL)) {
2171                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2172                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
2173                         }
2174
2175                         for (i=0; i<edgeSize-1; i++) {
2176                                 glVertex3fv(edgeData[i].co);
2177                                 glVertex3fv(edgeData[i+1].co);
2178                         }
2179                 }
2180                 glEnd();
2181         }
2182
2183         ccgEdgeIterator_free(ei);
2184 }
2185 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
2186         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2187         CCGSubSurf *ss = ccgdm->ss;
2188         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2189         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2190
2191         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2192
2193         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2194                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2195                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2196                 int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
2197
2198                 glBegin(GL_LINE_STRIP);
2199                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2200                         for (i=0; i<edgeSize; i++) {
2201                                 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
2202
2203                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
2204                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2205                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
2206                                 }
2207
2208                                 glVertex3fv(edgeData[i].co);
2209                         }
2210                 }
2211                 glEnd();
2212         }
2213
2214         ccgEdgeIterator_free(ei);
2215 }
2216 static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
2217         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2218         CCGSubSurf *ss = ccgdm->ss;
2219         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
2220
2221         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2222                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2223                 int index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
2224
2225                 if (index!=-1) {
2226                                 /* Face center data normal isn't updated atm. */
2227                         VertData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
2228
2229                         func(userData, index, vd->co, vd->no);
2230                 }
2231         }
2232
2233         ccgFaceIterator_free(fi);
2234 }
2235
2236 static void ccgDM_release(DerivedMesh *dm) {
2237         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2238
2239         if (DM_release(dm)) {
2240                 MEM_freeN(ccgdm->vertMap);
2241                 MEM_freeN(ccgdm->edgeMap);
2242                 MEM_freeN(ccgdm->faceMap);
2243                 MEM_freeN(ccgdm);
2244         }
2245 }
2246
2247 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2248                                          int drawInteriorEdges,
2249                                          int useSubsurfUv,
2250                                          DerivedMesh *dm)
2251 {
2252         CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
2253         CCGVertIterator *vi;
2254         CCGEdgeIterator *ei;
2255         CCGFaceIterator *fi;
2256         int index, totvert, totedge, totface;
2257         int i;
2258         int vertNum, edgeNum, faceNum;
2259         int *vertOrigIndex, *edgeOrigIndex, *faceOrigIndex;
2260         int *edgeFlags;
2261         char *faceFlags;
2262         int edgeSize;
2263         int gridSize;
2264         int gridFaces;
2265         int gridSideVerts;
2266         int gridInternalVerts;
2267         int gridSideEdges;
2268         int gridInternalEdges;
2269         MVert *mvert = NULL;
2270         MEdge *medge = NULL;
2271         MFace *mface = NULL;
2272         FaceVertWeight *qweight, *tweight;
2273
2274         DM_from_template(&ccgdm->dm, dm, ccgSubSurf_getNumFinalVerts(ss),
2275                                          ccgSubSurf_getNumFinalEdges(ss),
2276                                          ccgSubSurf_getNumFinalFaces(ss));
2277         DM_add_face_layer(&ccgdm->dm, CD_FLAGS, CD_CALLOC, NULL);
2278         DM_add_edge_layer(&ccgdm->dm, CD_FLAGS, CD_CALLOC, NULL);
2279
2280         CustomData_set_layer_flag(&ccgdm->dm.faceData, CD_FLAGS, CD_FLAG_NOCOPY);
2281         CustomData_set_layer_flag(&ccgdm->dm.edgeData, CD_FLAGS, CD_FLAG_NOCOPY);
2282
2283         ccgdm->dm.getMinMax = ccgDM_getMinMax;
2284         ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
2285         ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
2286
2287         ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
2288         ccgdm->dm.getVert = ccgDM_getFinalVert;
2289         ccgdm->dm.getEdge = ccgDM_getFinalEdge;
2290         ccgdm->dm.getFace = ccgDM_getFinalFace;
2291         ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2292         ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2293         ccgdm->dm.copyFaceArray = ccgDM_copyFinalFaceArray;
2294         ccgdm->dm.getVertData = DM_get_vert_data;
2295         ccgdm->dm.getEdgeData = DM_get_edge_data;
2296         ccgdm->dm.getFaceData = DM_get_face_data;
2297         ccgdm->dm.getVertDataArray = DM_get_vert_data_layer;
2298         ccgdm->dm.getEdgeDataArray = DM_get_edge_data_layer;
2299         ccgdm->dm.getFaceDataArray = DM_get_face_data_layer;
2300
2301         ccgdm->dm.getVertCos = ccgdm_getVertCos;
2302         ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
2303         ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
2304         ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
2305         
2306         ccgdm->dm.drawVerts = ccgDM_drawVerts;
2307         ccgdm->dm.drawEdges = ccgDM_drawEdges;
2308         ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
2309         ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
2310         ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
2311         ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
2312         ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL;
2313         ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
2314         ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
2315         ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL;
2316         ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
2317
2318         ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
2319         ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
2320         
2321         ccgdm->dm.release = ccgDM_release;
2322         
2323         ccgdm->ss = ss;
2324         ccgdm->drawInteriorEdges = drawInteriorEdges;
2325         ccgdm->useSubsurfUv = useSubsurfUv;
2326
2327         totvert = ccgSubSurf_getNumVerts(ss);
2328         ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
2329         vi = ccgSubSurf_getVertIterator(ss);
2330         for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2331                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2332
2333                 ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v))].vert = v;
2334         }
2335         ccgVertIterator_free(vi);
2336
2337         totedge = ccgSubSurf_getNumEdges(ss);
2338         ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
2339         ei = ccgSubSurf_getEdgeIterator(ss);
2340         for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2341                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2342
2343                 ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e))].edge = e;
2344         }
2345
2346         totface = ccgSubSurf_getNumFaces(ss);
2347         ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
2348         fi = ccgSubSurf_getFaceIterator(ss);
2349         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2350                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2351
2352                 ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
2353         }
2354         ccgFaceIterator_free(fi);
2355
2356         edgeSize = ccgSubSurf_getEdgeSize(ss);
2357         gridSize = ccgSubSurf_getGridSize(ss);
2358         gridFaces = gridSize - 1;
2359         gridSideVerts = gridSize - 2;
2360         gridInternalVerts = gridSideVerts * gridSideVerts;
2361         gridSideEdges = gridSize - 1;
2362         gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
2363
2364         calc_ss_weights(gridFaces, &qweight, &tweight);
2365
2366         vertNum = 0;
2367         edgeNum = 0;
2368         faceNum = 0;
2369
2370         mvert = dm->getVertArray(dm);
2371         medge = dm->getEdgeArray(dm);
2372         mface = dm->getFaceArray(dm);
2373
2374         vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2375         edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2376         faceOrigIndex = DM_get_face_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2377
2378         faceFlags = DM_get_face_data_layer(&ccgdm->dm, CD_FLAGS);
2379
2380         for(index = 0; index < totface; ++index) {
2381                 CCGFace *f = ccgdm->faceMap[index].face;
2382                 int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
2383                 int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
2384                 int mapIndex = ccgDM_getFaceMapIndex(ccgdm, ss, f);
2385                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2386                 FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
2387                 int S, x, y;
2388                 int vertIdx[4];
2389
2390                 ccgdm->faceMap[index].startVert = vertNum;
2391                 ccgdm->faceMap[index].startEdge = edgeNum;
2392                 ccgdm->faceMap[index].startFace = faceNum;
2393
2394                 /* set the face base vert */
2395                 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
2396
2397                 for(S = 0; S < numVerts; S++) {
2398                         CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
2399
2400                         vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
2401                 }
2402
2403                 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, weight[0][0],
2404                                     numVerts, vertNum);
2405                 *vertOrigIndex = ORIGINDEX_NONE;
2406                 ++vertOrigIndex;
2407                 ++vertNum;
2408
2409                 for(S = 0; S < numVerts; S++) {
2410                         int prevS = (S - 1 + numVerts) % numVerts;
2411                         int nextS = (S + 1) % numVerts;
2412                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2413                         for(x = 1; x < gridFaces; x++) {
2414                                 float w[4];
2415                                 w[prevS]  = weight[x][0][0];
2416                                 w[S]      = weight[x][0][1];
2417                                 w[nextS]  = weight[x][0][2];
2418                                 w[otherS] = weight[x][0][3];
2419                                 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2420                                                     numVerts, vertNum);
2421                                 *vertOrigIndex = ORIGINDEX_NONE;
2422                                 ++vertOrigIndex;
2423                                 ++vertNum;
2424                         }
2425                 }
2426
2427                 for(S = 0; S < numVerts; S++) {
2428                         int prevS = (S - 1 + numVerts) % numVerts;
2429                         int nextS = (S + 1) % numVerts;
2430                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2431                         for(y = 1; y < gridFaces; y++) {
2432                                 for(x = 1; x < gridFaces; x++) {
2433                                         float w[4];
2434                                         w[prevS]  = weight[y * gridFaces + x][0][0];
2435                                         w[S]      = weight[y * gridFaces + x][0][1];
2436                                         w[nextS]  = weight[y * gridFaces + x][0][2];
2437                                         w[otherS] = weight[y * gridFaces + x][0][3];
2438                                         DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2439                                                             numVerts, vertNum);
2440                                         *vertOrigIndex = ORIGINDEX_NONE;
2441                                         ++vertOrigIndex;
2442                                         ++vertNum;
2443                                 }
2444                         }
2445                 }
2446
2447                 for(i = 0; i < numFinalEdges; ++i)
2448                         *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i,
2449                                                  CD_ORIGINDEX) = ORIGINDEX_NONE;
2450
2451                 for(S = 0; S < numVerts; S++) {
2452                         int prevS = (S - 1 + numVerts) % numVerts;
2453                         int nextS = (S + 1) % numVerts;
2454                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2455
2456                         weight = (numVerts == 4) ? qweight : tweight;
2457
2458                         for(y = 0; y < gridFaces; y++) {
2459                                 for(x = 0; x < gridFaces; x++) {
2460                                         FaceVertWeight w;
2461                                         int j;
2462
2463                                         for(j = 0; j < 4; ++j) {
2464                                                 w[j][prevS]  = (*weight)[j][0];
2465                                                 w[j][S]      = (*weight)[j][1];
2466                                                 w[j][nextS]  = (*weight)[j][2];
2467                                                 w[j][otherS] = (*weight)[j][3];
2468                                         }
2469
2470                                         DM_interp_face_data(dm, &ccgdm->dm, &origIndex, NULL,
2471                                                             &w, 1, faceNum);
2472                                         weight++;
2473
2474                                         *faceOrigIndex = mapIndex;
2475
2476                                         ++faceOrigIndex;
2477                                         ++faceNum;
2478                                 }
2479                         }
2480                 }
2481
2482                 faceFlags[index*4] = mface[origIndex].flag;
2483                 faceFlags[index*4 + 1] = mface[origIndex].mat_nr;
2484
2485                 edgeNum += numFinalEdges;
2486         }
2487
2488         if(useSubsurfUv) {
2489                 CustomData *fdata = &ccgdm->dm.faceData;
2490                 CustomData *dmfdata = &dm->faceData;
2491                 int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
2492                 int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
2493
2494                 for (i=0; i<numlayer && i<dmnumlayer; i++)
2495                         set_subsurf_uv(ss, dm, &ccgdm->dm, i);
2496         }
2497
2498         edgeFlags = DM_get_edge_data_layer(&ccgdm->dm, CD_FLAGS);
2499
2500         for(index = 0; index < totedge; ++index) {
2501                 CCGEdge *e = ccgdm->edgeMap[index].edge;
2502                 int numFinalEdges = edgeSize - 1;
2503                 int mapIndex = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
2504                 int x;
2505                 int vertIdx[2];
2506                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(ss, e));
2507
2508                 CCGVert *v;
2509                 v = ccgSubSurf_getEdgeVert0(ss, e);
2510                 vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
2511                 v = ccgSubSurf_getEdgeVert1(ss, e);
2512                 vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
2513
2514                 ccgdm->edgeMap[index].startVert = vertNum;
2515                 ccgdm->edgeMap[index].startEdge = edgeNum;
2516
2517                 /* set the edge base vert */
2518                 *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
2519
2520                 for(x = 1; x < edgeSize - 1; x++) {
2521                         float w[2];
2522                         w[1] = (float) x / (edgeSize - 1);
2523                         w[0] = 1 - w[1];
2524                         DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
2525                         *vertOrigIndex = ORIGINDEX_NONE;
2526                         ++vertOrigIndex;
2527                         ++vertNum;
2528                 }
2529
2530                 for(i = 0; i < numFinalEdges; ++i) {
2531                         if(edgeIdx >= 0 && edgeFlags)
2532                                         edgeFlags[edgeNum + i] = medge[edgeIdx].flag;
2533
2534                         *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i,
2535                                                  CD_ORIGINDEX) = mapIndex;
2536                 }
2537
2538                 edgeNum += numFinalEdges;
2539         }
2540
2541         for(index = 0; index < totvert; ++index) {
2542                 CCGVert *v = ccgdm->vertMap[index].vert;
2543                 int mapIndex = ccgDM_getVertMapIndex(ccgdm, ccgdm->ss, v);
2544                 int vertIdx;
2545
2546                 vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
2547
2548                 ccgdm->vertMap[index].startVert = vertNum;
2549
2550                 /* set the vert base vert */
2551                 *((int*) ccgSubSurf_getVertUserData(ss, v)) = vertNum;
2552
2553                 DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
2554
2555                 *vertOrigIndex = mapIndex;
2556                 ++vertOrigIndex;
2557                 ++vertNum;
2558         }
2559
2560         MEM_freeN(qweight);
2561         MEM_freeN(tweight);
2562
2563         return ccgdm;
2564 }
2565
2566 /***/
2567
2568 struct DerivedMesh *subsurf_make_derived_from_derived(
2569                         struct DerivedMesh *dm,
2570                         struct SubsurfModifierData *smd,
2571                         int useRenderParams, float (*vertCos)[3],
2572                         int isFinalCalc, int editMode)
2573 {
2574         int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF;
2575         int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2576         int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv;
2577         int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
2578         DerivedMesh *result;
2579
2580         if(editMode) {
2581                 smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0,
2582                                            useSimple);
2583                 ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
2584
2585                 return (DerivedMesh *)getCCGDerivedMesh(smd->emCache,
2586                                                         drawInteriorEdges,
2587                                                     useSubsurfUv, dm);
2588         } else if(useRenderParams) {
2589                 /* Do not use cache in render mode. */
2590                 CCGSubSurf *ss;
2591                 int levels;
2592                 
2593                 levels= get_render_subsurf_level(&G.scene->r, smd->renderLevels);
2594                 if(levels == 0)
2595                         return dm;
2596                 
2597                 ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
2598
2599                 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2600
2601                 result = ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
2602                                              useSubsurfUv, dm);
2603
2604                 ccgSubSurf_free(ss);
2605                 
2606                 return result;
2607         } else {
2608                 int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
2609                 int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2610                 CCGSubSurf *ss;
2611                 
2612                 /* It is quite possible there is a much better place to do this. It
2613                  * depends a bit on how rigourously we expect this function to never
2614                  * be called in editmode. In semi-theory we could share a single
2615                  * cache, but the handles used inside and outside editmode are not
2616                  * the same so we would need some way of converting them. Its probably
2617                  * not worth the effort. But then why am I even writing this long
2618                  * comment that no one will read? Hmmm. - zr
2619                  */
2620                 if(smd->emCache) {
2621                         ccgSubSurf_free(smd->emCache);
2622                         smd->emCache = NULL;
2623                 }
2624
2625                 if(useIncremental && isFinalCalc) {
2626                         smd->mCache = ss = _getSubSurf(smd->mCache, smd->levels,
2627                                                        useAging, 0, useSimple);
2628
2629                         ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2630
2631
2632                         return ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
2633                                                useSubsurfUv, dm);
2634
2635                         /*return (DerivedMesh *)getCCGDerivedMesh(smd->mCache,
2636                                                         drawInteriorEdges,
2637                                                     useSubsurfUv, dm);*/
2638                 } else {
2639                         if (smd->mCache && isFinalCalc) {
2640                                 ccgSubSurf_free(smd->mCache);
2641                                 smd->mCache = NULL;
2642                         }
2643
2644                         ss = _getSubSurf(NULL, smd->levels, 0, 1, useSimple);
2645                         ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2646
2647                         /*smd->mCache = ss;
2648                         result = (DerivedMesh *)getCCGDerivedMesh(smd->mCache,
2649                                                         drawInteriorEdges,
2650                                                     useSubsurfUv, dm);*/
2651
2652                         result = ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
2653                                                      useSubsurfUv, dm);
2654
2655                         ccgSubSurf_free(ss);
2656
2657                         return result;
2658                 }
2659         }
2660 }
2661
2662 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 
2663 {
2664         /* Finds the subsurf limit positions for the verts in a mesh 
2665          * and puts them in an array of floats. Please note that the 
2666          * calculated vert positions is incorrect for the verts 
2667          * on the boundary of the mesh.
2668          */
2669         CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0);
2670         float edge_sum[3], face_sum[3];
2671         CCGVertIterator *vi;
2672         DerivedMesh *dm = CDDM_from_mesh(me, NULL);
2673
2674         ss_sync_from_derivedmesh(ss, dm, NULL, 0);
2675
2676         vi = ccgSubSurf_getVertIterator(ss);
2677         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2678                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2679                 int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(ss, v));
2680                 int N = ccgSubSurf_getVertNumEdges(ss, v);
2681                 int numFaces = ccgSubSurf_getVertNumFaces(ss, v);
2682                 float *co;
2683                 int i;
2684                 
2685                 edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0;
2686                 face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
2687
2688                 for (i=0; i<N; i++) {
2689                         CCGEdge *e = ccgSubSurf_getVertEdge(ss, v, i);
2690                         VecAddf(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
2691                 }
2692                 for (i=0; i<numFaces; i++) {
2693                         CCGFace *f = ccgSubSurf_getVertFace(ss, v, i);
2694                         VecAddf(face_sum, face_sum, ccgSubSurf_getFaceCenterData(ss, f));
2695                 }
2696
2697                 /* ad-hoc correction for boundary vertices, to at least avoid them
2698                    moving completely out of place (brecht) */
2699                 if(numFaces && numFaces != N)
2700                         VecMulf(face_sum, (float)N/(float)numFaces);
2701
2702                 co = ccgSubSurf_getVertData(ss, v);
2703                 positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
2704                 positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
2705                 positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
2706         }
2707         ccgVertIterator_free(vi);
2708
2709         ccgSubSurf_free(ss);
2710
2711         dm->release(dm);
2712 }
2713