- added mesh_strip_loose_faces, works in conjunction with make_edges
[blender.git] / source / blender / blenkernel / intern / subsurf_ccg.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2005 Blender Foundation.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <stdlib.h>
34 #include <string.h>
35 #include <stdio.h>
36 #include <math.h>
37 #include <float.h>
38
39 #include "MEM_guardedalloc.h"
40
41 #include "DNA_mesh_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_modifier_types.h"
44 #include "DNA_object_types.h"
45
46 #include "BKE_bad_level_calls.h"
47 #include "BKE_utildefines.h"
48 #include "BKE_global.h"
49 #include "BKE_mesh.h"
50 #include "BKE_subsurf.h"
51 #include "BKE_displist.h"
52 #include "BKE_DerivedMesh.h"
53
54 #include "BLI_blenlib.h"
55 #include "BLI_editVert.h"
56 #include "BLI_arithb.h"
57 #include "BLI_linklist.h"
58 #include "BLI_memarena.h"
59
60 #include "BIF_gl.h"
61
62 #include "CCGSubSurf.h"
63
64 typedef struct _VertData {
65         float co[3];
66         float no[3];
67 } VertData;
68
69 typedef struct CCGDerivedMesh CCGDerivedMesh;
70
71 static int ccgDM_getVertMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGVert *v);
72 static int ccgDM_getEdgeMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGEdge *e);
73 static int ccgDM_getFaceMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGFace *f);
74
75 ///
76
77 static void *arena_alloc(CCGAllocatorHDL a, int numBytes) {
78         return BLI_memarena_alloc(a, numBytes);
79 }
80 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) {
81         void *p2 = BLI_memarena_alloc(a, newSize);
82         if (ptr) {
83                 memcpy(p2, ptr, oldSize);
84         }
85         return p2;
86 }
87 static void arena_free(CCGAllocatorHDL a, void *ptr) {
88 }
89 static void arena_release(CCGAllocatorHDL a) {
90         BLI_memarena_free(a);
91 }
92
93 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int useFlatSubdiv) {
94         CCGMeshIFC ifc;
95         CCGSubSurf *ccgSS;
96
97                 /* subdivLevels==0 is not allowed */
98         subdivLevels = MAX2(subdivLevels, 1);
99
100         if (prevSS) {
101                 int oldUseAging;
102
103                 useAging = !!useAging;
104                 ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
105
106                 if (oldUseAging!=useAging) {
107                         ccgSubSurf_free(prevSS);
108                 } else {
109                         ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
110
111                         return prevSS;
112                 }
113         }
114
115         if (useAging) {
116                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
117         } else {
118                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
119         }
120         ifc.vertDataSize = sizeof(VertData);
121
122         if (useArena) {
123                 CCGAllocatorIFC allocatorIFC;
124                 CCGAllocatorHDL allocator = BLI_memarena_new((1<<16));
125
126                 allocatorIFC.alloc = arena_alloc;
127                 allocatorIFC.realloc = arena_realloc;
128                 allocatorIFC.free = arena_free;
129                 allocatorIFC.release = arena_release;
130
131                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
132         } else {
133                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
134         }
135
136         if (useAging) {
137                 ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
138         }
139
140         ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(VertData, no));
141
142         return ccgSS;
143 }
144
145 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
146         CCGVert *v0 = ccgSubSurf_getEdgeVert0(ss, e);
147         CCGVert *v1 = ccgSubSurf_getEdgeVert1(ss, e);
148         int v0idx = *((int*) ccgSubSurf_getVertUserData(ss, v0));
149         int v1idx = *((int*) ccgSubSurf_getVertUserData(ss, v1));
150         int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
151
152         if (x==0) {
153                 return v0idx;
154         } else if (x==edgeSize-1) {
155                 return v1idx;
156         } else {
157                 return edgeBase + x-1;
158         }
159 }
160 static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) {
161         int faceBase = *((int*) ccgSubSurf_getFaceUserData(ss, f));
162         int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
163
164         if (x==gridSize-1 && y==gridSize-1) {
165                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
166                 return *((int*) ccgSubSurf_getVertUserData(ss, v));
167         } else if (x==gridSize-1) {
168                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
169                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S);
170                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
171                 if (v==ccgSubSurf_getEdgeVert0(ss, e)) {
172                         return edgeBase + (gridSize-1-y)-1;
173                 } else {
174                         return edgeBase + (edgeSize-2-1)-((gridSize-1-y)-1);
175                 }
176         } else if (y==gridSize-1) {
177                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
178                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts);
179                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
180                 if (v==ccgSubSurf_getEdgeVert0(ss, e)) {
181                         return edgeBase + (gridSize-1-x)-1;
182                 } else {
183                         return edgeBase + (edgeSize-2-1)-((gridSize-1-x)-1);
184                 }
185         } else if (x==0 && y==0) {
186                 return faceBase;
187         } else if (x==0) {
188                 S = (S+numVerts-1)%numVerts;
189                 return faceBase + 1 + (gridSize-2)*S + (y-1);
190         } else if (y==0) {
191                 return faceBase + 1 + (gridSize-2)*S + (x-1);
192         } else {
193                 return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1);
194         }
195 }
196
197 static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditmesh, DispListMesh *dlm, MEdge *medge, TFace *tface)
198 {
199         unsigned int flags = 0;
200         int j, N = ccgSubSurf_getEdgeNumFaces(ss, e);
201
202         if (!N) flags |= ME_LOOSEEDGE;
203
204         if (ssFromEditmesh) {
205                 EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(ss, e);
206
207                 flags |= ME_EDGEDRAW|ME_EDGERENDER|ME_EDGEMAPPED;
208                 if (eed->seam) {
209                         flags |= ME_SEAM;
210                 }
211         } else {
212                 int makeFlags = 0, edgeIdx = (int) ccgSubSurf_getEdgeEdgeHandle(ss, e);
213
214                 if (edgeIdx==-1) {
215                         if (!medge) {
216                                 makeFlags = 1;
217                         }
218                 } else if (medge) { // can happen for loose edges on mesh with no medge
219                         MEdge *origMed = &medge[edgeIdx];
220
221                         if (dlm) {
222                                 flags |= origMed->flag&~ME_EDGE_STEPINDEX;
223                         } else {
224                                 flags |= (origMed->flag&ME_SEAM);
225                                 makeFlags = 1;
226                         }
227                 } else {
228                         makeFlags = 1;
229                 }
230                 
231                 if (makeFlags) {
232                         flags |= ME_EDGEDRAW|ME_EDGERENDER|ME_EDGEMAPPED;
233
234                         if (tface) {
235                                 for (j=0; j<N; j++) {
236                                         CCGFace *f = ccgSubSurf_getEdgeFace(ss, e, j);
237                                         int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
238                                         TFace *tf = &tface[origIdx];
239
240                                         if (!(tf->flag&TF_HIDE)) flags |= ME_EDGE_TFVISIBLE;
241                                         if (tf->flag&TF_SELECT) flags |= ME_EDGE_TFSEL;
242
243                                         if (tf->flag&TF_ACTIVE) {
244                                                 int fN = ccgSubSurf_getFaceNumVerts(ss, f);
245                                                 int k = ccgSubSurf_getFaceEdgeIndex(ss, f, e);
246
247                                                 flags |= ME_EDGE_TFACT;
248
249                                                 if (k==0) {
250                                                         flags |= ME_EDGE_TFACTFIRST;
251                                                 }
252                                                 else if (k==fN-1) {
253                                                         flags |= ME_EDGE_TFACTLAST;
254                                                 } 
255                                         }
256                                 }
257                         }
258                 }
259         }
260
261         return flags;
262 }
263
264 static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, int ssFromEditmesh, int drawInteriorEdges, Mesh *inMe, DispListMesh *inDLM) {
265         DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
266         int edgeSize = ccgSubSurf_getEdgeSize(ss);
267         int gridSize = ccgSubSurf_getGridSize(ss);
268         int edgeBase, faceBase;
269         int i, j, k, S, x, y, index, lastIndex;
270         int vertBase = 0;
271         TFace *tface = NULL;
272         MEdge *medge = NULL;
273         MFace *mface = NULL;
274         MCol *mcol = NULL;
275         CCGVertIterator *vi;
276         CCGEdgeIterator *ei;
277         CCGFaceIterator *fi;
278         CCGFace **faceMap2;
279         CCGEdge **edgeMap2;
280         CCGVert **vertMap2;
281         int totvert, totedge, totface;
282         
283         totvert = ccgSubSurf_getNumVerts(ss);
284         vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
285         vi = ccgSubSurf_getVertIterator(ss);
286         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
287                 CCGVert *v = ccgVertIterator_getCurrent(vi);
288
289                 if (ssFromEditmesh) {
290                         vertMap2[ccgDM_getVertMapIndex(ccgdm,ss,v)] = v;
291                 } else {
292                         vertMap2[(int) ccgSubSurf_getVertVertHandle(ss, v)] = v;
293                 }
294         }
295         ccgVertIterator_free(vi);
296
297         totedge = ccgSubSurf_getNumEdges(ss);
298         edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
299         ei = ccgSubSurf_getEdgeIterator(ss);
300         for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
301                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
302
303                 if (ssFromEditmesh) {
304                         edgeMap2[ccgDM_getEdgeMapIndex(ccgdm,ss,e)] = e;
305                 } else {
306                         edgeMap2[(int) ccgSubSurf_getEdgeEdgeHandle(ss, e)] = e;
307                 }
308         }
309
310         totface = ccgSubSurf_getNumFaces(ss);
311         faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
312         fi = ccgSubSurf_getFaceIterator(ss);
313         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
314                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
315
316                 if (ssFromEditmesh) {
317                         faceMap2[ccgDM_getFaceMapIndex(ccgdm,ss,f)] = f;
318                 } else {
319                         faceMap2[(int) ccgSubSurf_getFaceFaceHandle(ss, f)] = f;
320                 }
321         }
322         ccgFaceIterator_free(fi);
323
324         if (!ssFromEditmesh) {
325                 if (inDLM) {
326                         tface = inDLM->tface;
327                         medge = inDLM->medge;
328                         mface = inDLM->mface;
329                         mcol = inDLM->mcol;
330                 } else if (inMe) {
331                         tface = inMe->tface;
332                         medge = inMe->medge;
333                         mface = inMe->mface;
334                         mcol = inMe->mcol;
335                 }
336         }
337
338         dlm->totvert = ccgSubSurf_getNumFinalVerts(ss);
339         dlm->totedge = ccgSubSurf_getNumFinalEdges(ss);
340         dlm->totface = ccgSubSurf_getNumFinalFaces(ss);
341
342         dlm->mvert = MEM_callocN(dlm->totvert*sizeof(*dlm->mvert), "dlm->mvert");
343         dlm->medge = MEM_callocN(dlm->totedge*sizeof(*dlm->medge), "dlm->medge");
344         dlm->mface = MEM_callocN(dlm->totface*sizeof(*dlm->mface), "dlm->mface");
345         if (!ssFromEditmesh && tface) {
346                 dlm->tface = MEM_callocN(dlm->totface*sizeof(*dlm->tface), "dlm->tface");
347                 dlm->mcol = NULL;
348         } else if (!ssFromEditmesh && mcol) {
349                 dlm->tface = NULL;
350                 dlm->mcol = MEM_mallocN(dlm->totface*4*sizeof(*dlm->mcol), "dlm->mcol");
351         } else {
352                 dlm->tface = NULL;
353                 dlm->mcol = NULL;
354         }
355
356                 /* Load vertices... we do in this funny order because 
357                  * all "added" vertices" are required to appear first 
358                  * in the displist (before STEPINDEX flags start). Also
359                  * note that the vertex with index 0 is always a face
360                  * center vert, this is relied upon to ensure we don't
361                  * need to do silly test_index_face calls.
362                  */
363
364         faceBase = i = 0;
365         for (index=0; index<totface; index++) {
366                 CCGFace *f = faceMap2[index];
367                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
368
369                 VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getFaceCenterData(ss, f));
370                 
371                 for (S=0; S<numVerts; S++) {
372                         for (x=1; x<gridSize-1; x++) {
373                                 VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
374                         }
375                 }
376
377                 for (S=0; S<numVerts; S++) {
378                         for (y=1; y<gridSize-1; y++) {
379                                 for (x=1; x<gridSize-1; x++) {
380                                         VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getFaceGridData(ss, f, S, x, y));
381                                 }
382                         }
383                 }
384
385                 *((int*) ccgSubSurf_getFaceUserData(ss, f)) = faceBase;
386                 faceBase += 1 + numVerts*((gridSize-2) + (gridSize-2)*(gridSize-2));
387         }
388
389         edgeBase = i;
390         for (index=0; index<totedge; index++) {
391                 CCGEdge *e= edgeMap2[index];
392                 int x;
393
394                 for (x=1; x<edgeSize-1; x++) {
395                         VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getEdgeData(ss, e, x));
396                 }
397
398                 *((int*) ccgSubSurf_getEdgeUserData(ss, e)) = edgeBase;
399                 edgeBase += edgeSize-2;
400         }
401
402         vertBase = i;
403         lastIndex = -1;
404         for (index=0; index<totvert; index++) {
405                 CCGVert *v = vertMap2[index];
406                 int mapIndex = ccgDM_getVertMapIndex(ccgdm, ss, v);
407                 VecCopyf(dlm->mvert[i].co, ccgSubSurf_getVertData(ss, v));
408                 if (mapIndex!=lastIndex)
409                         dlm->mvert[i].flag = ME_VERT_STEPINDEX;
410                 *((int*) ccgSubSurf_getVertUserData(ss, v)) = i++;
411                 lastIndex = mapIndex;
412         }
413
414                 // load edges
415
416         i = 0;
417         for (index=0; index<totface; index++) {
418                 CCGFace *f = faceMap2[index];
419                 int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
420
421                 for (k=0; k<numVerts; k++) {
422                         for (x=0; x<gridSize-1; x++) {
423                                 MEdge *med = &dlm->medge[i];
424                                 if (drawInteriorEdges) med->flag = ME_EDGEDRAW|ME_EDGERENDER;
425                                 med->v1 = getFaceIndex(ss, f, k, x, 0, edgeSize, gridSize);
426                                 med->v2 = getFaceIndex(ss, f, k, x+1, 0, edgeSize, gridSize);
427                                 i++;
428                         }
429
430                         for (x=1; x<gridSize-1; x++) {
431                                 for (y=0; y<gridSize-1; y++) {
432                                         MEdge *med;
433                                         
434                                         med = &dlm->medge[i];
435                                         if (drawInteriorEdges) med->flag = ME_EDGEDRAW|ME_EDGERENDER;
436                                         med->v1 = getFaceIndex(ss, f, k, x, y, edgeSize, gridSize);
437                                         med->v2 = getFaceIndex(ss, f, k, x, y+1, edgeSize, gridSize);
438                                         i++;
439
440                                         med = &dlm->medge[i];
441                                         if (drawInteriorEdges) med->flag = ME_EDGEDRAW|ME_EDGERENDER;
442                                         med->v1 = getFaceIndex(ss, f, k, y, x, edgeSize, gridSize);
443                                         med->v2 = getFaceIndex(ss, f, k, y+1, x, edgeSize, gridSize);
444                                         i++;
445                                 }
446                         }
447                 }
448         }
449
450         lastIndex = -1;
451         for (index=0; index<totedge; index++) {
452                 CCGEdge *e= edgeMap2[index];
453                 unsigned int flags = ss_getEdgeFlags(ss, e, ssFromEditmesh, inDLM, medge, tface);
454                 int mapIndex = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
455                 int edgeStart = i;
456
457                 for (x=0; x<edgeSize-1; x++) {
458                         MEdge *med = &dlm->medge[i];
459                         med->v1 = getEdgeIndex(ss, e, x, edgeSize);
460                         med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
461                         med->flag = flags;
462                         i++;
463                 }
464
465                 if (mapIndex!=lastIndex)
466                         dlm->medge[edgeStart].flag |= ME_EDGE_STEPINDEX;
467                 lastIndex = mapIndex;
468         }
469
470                 // load faces
471
472         i=0;
473         lastIndex = -1;
474         for (index=0; index<totface; index++) {
475                 CCGFace *f = faceMap2[index];
476                 int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
477                 float edge_data[4][6];
478                 float corner_data[4][6];
479                 float center_data[6] = {0};
480                 int numDataComponents = 0;
481                 TFace *origTFace = NULL;
482                 int mat_nr;
483                 int flag;
484                 int mapIndex = ccgDM_getFaceMapIndex(ccgdm, ss, f);
485
486                 if (!ssFromEditmesh) {
487                         int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
488                         MFace *origMFace = &mface[origIdx];
489                         
490                         if (tface) {
491                                 origTFace = &tface[origIdx];
492
493                                 for (S=0; S<numVerts; S++) {
494                                         unsigned char *col = (unsigned char*) &origTFace->col[S];
495                                         corner_data[S][0] = col[0]/255.0f;
496                                         corner_data[S][1] = col[1]/255.0f;
497                                         corner_data[S][2] = col[2]/255.0f;
498                                         corner_data[S][3] = col[3]/255.0f;
499                                         corner_data[S][4] = origTFace->uv[S][0];
500                                         corner_data[S][5] = origTFace->uv[S][1];
501                                 }
502                                 numDataComponents = 6;
503                         } else if (mcol) {
504                                 MCol *origMCol = &mcol[origIdx*4];
505
506                                 for (S=0; S<numVerts; S++) {
507                                         unsigned char *col = (unsigned char*) &origMCol[S];
508                                         corner_data[S][0] = col[0]/255.0f;
509                                         corner_data[S][1] = col[1]/255.0f;
510                                         corner_data[S][2] = col[2]/255.0f;
511                                         corner_data[S][3] = col[3]/255.0f;
512                                 }
513                                 numDataComponents = 4;
514                         }
515
516                         for (S=0; S<numVerts; S++) {
517                                 for (k=0; k<numDataComponents; k++) {
518                                         edge_data[S][k] = (corner_data[S][k] + corner_data[(S+1)%numVerts][k])*0.5f;
519                                         center_data[k]+= corner_data[S][k];
520                                 }
521                         }
522                         for (k=0; k<numDataComponents; k++) {
523                                 center_data[k]/= numVerts;
524                         }
525
526                         mat_nr = origMFace->mat_nr;
527                         flag = origMFace->flag;
528                 } else {
529                         EditFace *ef = ccgSubSurf_getFaceFaceHandle(ss, f);
530                         mat_nr = ef->mat_nr;
531                         flag = ef->flag;
532                 }
533
534                 for (S=0; S<numVerts; S++) {
535                         int prevS= (S-1+numVerts)%numVerts;
536
537                         for (y=0; y<gridSize-1; y++) {
538                                 for (x=0; x<gridSize-1; x++) {
539                                         MFace *mf = &dlm->mface[i];
540                                         mf->v1 = getFaceIndex(ss, f, S, x+0, y+0, edgeSize, gridSize);
541                                         mf->v2 = getFaceIndex(ss, f, S, x+0, y+1, edgeSize, gridSize);
542                                         mf->v3 = getFaceIndex(ss, f, S, x+1, y+1, edgeSize, gridSize);
543                                         mf->v4 = getFaceIndex(ss, f, S, x+1, y+0, edgeSize, gridSize);
544                                         mf->mat_nr = mat_nr;
545                                         mf->flag = flag&~ME_FACE_STEPINDEX;
546
547                                         if (S==0 && x==0 && y==0) {
548                                                 if (mapIndex!=lastIndex)
549                                                         mf->flag |= ME_FACE_STEPINDEX;
550                                                 lastIndex = mapIndex;
551                                         }
552
553                                         for (j=0; j<4; j++) {
554                                                 int fx = x + (j==2||j==3);
555                                                 int fy = y + (j==1||j==2);
556                                                 float x_v = (float) fx/(gridSize-1);
557                                                 float y_v = (float) fy/(gridSize-1);
558                                                 float data[6];
559
560                                                 for (k=0; k<numDataComponents; k++) {
561                                                         data[k] = (center_data[k]*(1.0f-x_v) + edge_data[S][k]*x_v)*(1.0f-y_v) + 
562                                                                         (edge_data[prevS][k]*(1.0f-x_v) + corner_data[S][k]*x_v)*y_v;
563                                                 }
564
565                                                 if (dlm->tface) {
566                                                         TFace *tf = &dlm->tface[i];
567                                                         unsigned char col[4];
568                                                         col[0] = (int) (data[0]*255);
569                                                         col[1] = (int) (data[1]*255);
570                                                         col[2] = (int) (data[2]*255);
571                                                         col[3] = (int) (data[3]*255);
572                                                         tf->col[j] = *((unsigned int*) col);
573                                                         tf->uv[j][0] = data[4];
574                                                         tf->uv[j][1] = data[5];
575                                                 } else if (dlm->mcol) {
576                                                         unsigned char *col = (unsigned char*) &dlm->mcol[i*4+j];
577                                                         col[0] = (int) (data[0]*255);
578                                                         col[1] = (int) (data[1]*255);
579                                                         col[2] = (int) (data[2]*255);
580                                                         col[3] = (int) (data[3]*255);
581                                                 }
582                                         }
583
584                                         if (dlm->tface) {
585                                                 TFace *tf = &dlm->tface[i];
586                                                 tf->tpage = origTFace->tpage;
587                                                 tf->flag = origTFace->flag;
588                                                 tf->transp = origTFace->transp;
589                                                 tf->mode = origTFace->mode;
590                                                 tf->tile = origTFace->tile;
591                                         }
592
593                                         i++;
594                                 }
595                         }
596                 }
597         }
598
599         MEM_freeN(faceMap2);
600         MEM_freeN(edgeMap2);
601         MEM_freeN(vertMap2);
602
603         mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
604
605         return dlm;
606 }
607
608 static void ss_sync_from_mesh(CCGSubSurf *ss, Mesh *me, DispListMesh *dlm, float (*vertexCos)[3], int useFlatSubdiv) {
609         float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
610         CCGVertHDL fVerts[4];
611         MVert *mvert = dlm?dlm->mvert:me->mvert;
612         MEdge *medge = dlm?dlm->medge:me->medge;
613         MFace *mface = dlm?dlm->mface:me->mface;
614         int totvert = dlm?dlm->totvert:me->totvert;
615         int totedge = dlm?dlm->totedge:me->totedge;
616         int totface = dlm?dlm->totface:me->totface;
617         int i, index;
618
619         ccgSubSurf_initFullSync(ss);
620
621         for (i=0,index=-1; i<totvert; i++) {
622                 CCGVert *v;
623                 ccgSubSurf_syncVert(ss, (CCGVertHDL) i, vertexCos?vertexCos[i]:mvert[i].co, &v);
624
625                 if (!dlm || (mvert[i].flag&ME_VERT_STEPINDEX)) index++;
626                 ((int*) ccgSubSurf_getVertUserData(ss, v))[1] = index;
627         }
628
629         if (medge) {
630                 for (i=0, index=-1; i<totedge; i++) {
631                         MEdge *med = &medge[i];
632                         CCGEdge *e;
633                         float crease = useFlatSubdiv?creaseFactor:med->crease*creaseFactor/255.0f;
634
635                         ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2, crease, &e);
636
637                         if (!dlm || (med->flag&ME_EDGE_STEPINDEX)) index++;
638                         ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1] = index;
639                 }
640         }
641
642         for (i=0, index=-1; i<totface; i++) {
643                 MFace *mf = &((MFace*) mface)[i];
644                 CCGFace *f;
645
646                 if (!dlm || (mf->flag&ME_FACE_STEPINDEX)) index++;
647
648                 fVerts[0] = (CCGVertHDL) mf->v1;
649                 fVerts[1] = (CCGVertHDL) mf->v2;
650                 fVerts[2] = (CCGVertHDL) mf->v3;
651                 fVerts[3] = (CCGVertHDL) mf->v4;
652
653                 ccgSubSurf_syncFace(ss, (CCGFaceHDL) i, fVerts[3]?4:3, fVerts, &f);
654                 ((int*) ccgSubSurf_getFaceUserData(ss, f))[1] = index;
655         }
656
657         ccgSubSurf_processSync(ss);
658 }
659
660 void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, float (*vertCos)[3], int useFlatSubdiv)
661 {
662         float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
663         EditVert *ev, *fVerts[4];
664         EditEdge *ee;
665         EditFace *ef;
666         int i;
667
668         ccgSubSurf_initFullSync(ss);
669
670         if (vertCos) {
671                 for (i=0,ev=em->verts.first; ev; i++,ev=ev->next) {
672                         CCGVert *v;
673                         ccgSubSurf_syncVert(ss, ev, vertCos[i], &v);
674                         ((int*) ccgSubSurf_getVertUserData(ss, v))[1] = i;
675                 }
676         } else {
677                 for (i=0,ev=em->verts.first; ev; i++,ev=ev->next) {
678                         CCGVert *v;
679                         ccgSubSurf_syncVert(ss, ev, ev->co, &v);
680                         ((int*) ccgSubSurf_getVertUserData(ss, v))[1] = i;
681                 }
682         }
683
684         for (i=0,ee=em->edges.first; ee; i++,ee=ee->next) {
685                 CCGEdge *e;
686                 ccgSubSurf_syncEdge(ss, ee, ee->v1, ee->v2, useFlatSubdiv?creaseFactor:ee->crease*creaseFactor, &e);
687                 ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1] = i;
688         }
689
690         for (i=0,ef=em->faces.first; ef; i++,ef=ef->next) {
691                 CCGFace *f;
692
693                 fVerts[0] = ef->v1;
694                 fVerts[1] = ef->v2;
695                 fVerts[2] = ef->v3;
696                 fVerts[3] = ef->v4;
697
698                 ccgSubSurf_syncFace(ss, ef, ef->v4?4:3, (CCGVertHDL*) fVerts, &f);
699                 ((int*) ccgSubSurf_getFaceUserData(ss, f))[1] = i;
700         }
701
702         ccgSubSurf_processSync(ss);
703 }
704
705 /***/
706
707 struct CCGDerivedMesh {
708         DerivedMesh dm;
709
710         CCGSubSurf *ss;
711         int fromEditmesh, drawInteriorEdges;
712
713         Mesh *me;
714         DispListMesh *dlm;
715 };
716
717 static int ccgDM_getVertMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGVert *v) {
718         return ((int*) ccgSubSurf_getVertUserData(ss, v))[1];
719 }
720
721 static int ccgDM_getEdgeMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGEdge *e) {
722         return ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1];
723 }
724
725 static int ccgDM_getFaceMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGFace *f) {
726         return ((int*) ccgSubSurf_getFaceUserData(ss, f))[1];
727 }
728
729 static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
730         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
731         CCGSubSurf *ss = ccgdm->ss;
732         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
733         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
734         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
735         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
736         int gridSize = ccgSubSurf_getGridSize(ss);
737
738         if (!ccgSubSurf_getNumVerts(ss))
739                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
740
741         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
742                 CCGVert *v = ccgVertIterator_getCurrent(vi);
743                 float *co = ccgSubSurf_getVertData(ss, v);
744
745                 DO_MINMAX(co, min_r, max_r);
746         }
747
748         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
749                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
750                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
751
752                 for (i=0; i<edgeSize; i++)
753                         DO_MINMAX(edgeData[i].co, min_r, max_r);
754         }
755
756         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
757                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
758                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
759
760                 for (S=0; S<numVerts; S++) {
761                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
762
763                         for (y=0; y<gridSize; y++)
764                                 for (x=0; x<gridSize; x++)
765                                         DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r);
766                 }
767         }
768
769         ccgFaceIterator_free(fi);
770         ccgEdgeIterator_free(ei);
771         ccgVertIterator_free(vi);
772 }
773 static int ccgDM_getNumVerts(DerivedMesh *dm) {
774         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
775
776         return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
777 }
778 static int ccgDM_getNumFaces(DerivedMesh *dm) {
779         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
780
781         return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
782 }
783 static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
784         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
785         CCGSubSurf *ss = ccgdm->ss;
786         int edgeSize = ccgSubSurf_getEdgeSize(ss);
787         int gridSize = ccgSubSurf_getGridSize(ss);
788         int i;
789         CCGVertIterator *vi;
790         CCGEdgeIterator *ei;
791         CCGFaceIterator *fi;
792
793         i = 0;
794         vi = ccgSubSurf_getVertIterator(ss);
795         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
796                 CCGVert *v = ccgVertIterator_getCurrent(vi);
797                 VecCopyf(cos[i++], ccgSubSurf_getVertData(ss, v));
798         }
799         ccgVertIterator_free(vi);
800
801         ei = ccgSubSurf_getEdgeIterator(ss);
802         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
803                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
804                 int x;
805
806                 for (x=1; x<edgeSize-1; x++)
807                         VecCopyf(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
808         }
809         ccgEdgeIterator_free(ei);
810
811         fi = ccgSubSurf_getFaceIterator(ss);
812         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
813                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
814                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
815
816                 VecCopyf(cos[i++], ccgSubSurf_getFaceCenterData(ss, f));
817                 for (S=0; S<numVerts; S++)
818                         for (x=1; x<gridSize-1; x++)
819                                 VecCopyf(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
820                 for (S=0; S<numVerts; S++)
821                         for (y=1; y<gridSize-1; y++)
822                                 for (x=1; x<gridSize-1; x++)
823                                         VecCopyf(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
824         }
825         ccgFaceIterator_free(fi);
826 }
827 static void ccgDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
828         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
829         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
830
831         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
832                 CCGVert *v = ccgVertIterator_getCurrent(vi);
833                 VertData *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
834                 int index = ccgDM_getVertMapIndex(ccgdm, ccgdm->ss, v);
835
836                 if (index!=-1)
837                         func(userData, index, vd->co, vd->no, NULL);
838         }
839
840         ccgVertIterator_free(vi);
841 }
842 static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
843         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
844         CCGSubSurf *ss = ccgdm->ss;
845         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
846         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
847
848         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
849                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
850                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
851                 int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
852
853                 if (index!=-1) {
854                         for (i=0; i<edgeSize-1; i++)
855                                 func(userData, index, edgeData[i].co, edgeData[i+1].co);
856                 }
857         }
858
859         ccgEdgeIterator_free(ei);
860 }
861 static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm, int allowShared) {
862         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
863
864         return ss_to_displistmesh(ccgdm->ss, ccgdm, ccgdm->fromEditmesh, ccgdm->drawInteriorEdges, ccgdm->me, ccgdm->dlm);
865 }
866
867 static void ccgDM_drawVerts(DerivedMesh *dm) {
868         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
869         CCGSubSurf *ss = ccgdm->ss;
870         int edgeSize = ccgSubSurf_getEdgeSize(ss);
871         int gridSize = ccgSubSurf_getGridSize(ss);
872         CCGVertIterator *vi;
873         CCGEdgeIterator *ei;
874         CCGFaceIterator *fi;
875
876         glBegin(GL_POINTS);
877         vi = ccgSubSurf_getVertIterator(ss);
878         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
879                 CCGVert *v = ccgVertIterator_getCurrent(vi);
880                 glVertex3fv(ccgSubSurf_getVertData(ss, v));
881         }
882         ccgVertIterator_free(vi);
883
884         ei = ccgSubSurf_getEdgeIterator(ss);
885         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
886                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
887                 int x;
888
889                 for (x=1; x<edgeSize-1; x++)
890                         glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
891         }
892         ccgEdgeIterator_free(ei);
893
894         fi = ccgSubSurf_getFaceIterator(ss);
895         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
896                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
897                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
898
899                 glVertex3fv(ccgSubSurf_getFaceCenterData(ss, f));
900                 for (S=0; S<numVerts; S++)
901                         for (x=1; x<gridSize-1; x++)
902                                 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
903                 for (S=0; S<numVerts; S++)
904                         for (y=1; y<gridSize-1; y++)
905                                 for (x=1; x<gridSize-1; x++)
906                                         glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
907         }
908         ccgFaceIterator_free(fi);
909         glEnd();
910 }
911 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) {
912         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
913         CCGSubSurf *ss = ccgdm->ss;
914         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
915         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
916         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
917         int gridSize = ccgSubSurf_getGridSize(ss);
918         int useAging;
919
920         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
921
922         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
923                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
924                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
925
926                 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(ss, e))
927                         continue;
928
929                 if (useAging && !(G.f&G_BACKBUFSEL)) {
930                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
931                         glColor3ub(0, ageCol>0?ageCol:0, 0);
932                 }
933
934                 glBegin(GL_LINE_STRIP);
935                 for (i=0; i<edgeSize-1; i++) {
936                         glVertex3fv(edgeData[i].co);
937                         glVertex3fv(edgeData[i+1].co);
938                 }
939                 glEnd();
940         }
941
942         if (useAging && !(G.f&G_BACKBUFSEL)) {
943                 glColor3ub(0, 0, 0);
944         }
945
946         if (ccgdm->drawInteriorEdges) {
947                 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
948                         CCGFace *f = ccgFaceIterator_getCurrent(fi);
949                         int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
950
951                         for (S=0; S<numVerts; S++) {
952                                 VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
953
954                                 glBegin(GL_LINE_STRIP);
955                                 for (x=0; x<gridSize; x++)
956                                         glVertex3fv(faceGridData[x].co);
957                                 glEnd();
958                                 for (y=1; y<gridSize-1; y++) {
959                                         glBegin(GL_LINE_STRIP);
960                                         for (x=0; x<gridSize; x++)
961                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
962                                         glEnd();
963                                 }
964                                 for (x=1; x<gridSize-1; x++) {
965                                         glBegin(GL_LINE_STRIP);
966                                         for (y=0; y<gridSize; y++)
967                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
968                                         glEnd();
969                                 }
970                         }
971                 }
972         }
973
974         ccgFaceIterator_free(fi);
975         ccgEdgeIterator_free(ei);
976 }
977 static void ccgDM_drawEdgesFlag(DerivedMesh *dm, unsigned int mask, unsigned int value) {
978         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
979         CCGSubSurf *ss = ccgdm->ss;
980         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
981         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
982         MEdge *medge = NULL;
983         TFace *tface = NULL;
984
985         if (!ccgdm->fromEditmesh) {
986                 medge = ccgdm->dlm?ccgdm->dlm->medge:ccgdm->me->medge;
987                 tface = ccgdm->dlm?ccgdm->dlm->tface:ccgdm->me->tface;
988         }
989
990         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
991                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
992                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
993                 unsigned int flags = ss_getEdgeFlags(ss, e, ccgdm->fromEditmesh, ccgdm->dlm, medge, tface);
994
995                 if ((flags&mask)==value) {
996                         glBegin(GL_LINE_STRIP);
997                         for (i=0; i<edgeSize-1; i++) {
998                                 glVertex3fv(edgeData[i].co);
999                                 glVertex3fv(edgeData[i+1].co);
1000                         }
1001                         glEnd();
1002                 }
1003         }
1004
1005         ccgEdgeIterator_free(ei);
1006 }
1007
1008         /* Only used by non-editmesh types */
1009 static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
1010         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1011         CCGSubSurf *ss = ccgdm->ss;
1012         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1013         int gridSize = ccgSubSurf_getGridSize(ss);
1014         MFace *mface = ccgdm->dlm?ccgdm->dlm->mface:ccgdm->me->mface;
1015
1016         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1017                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1018                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1019                 int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
1020                 MFace *mf = &mface[index];
1021                 
1022                 if (!setMaterial(mf->mat_nr+1))
1023                         continue;
1024
1025                 glShadeModel((mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT);
1026                 for (S=0; S<numVerts; S++) {
1027                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1028
1029                         if (mf->flag&ME_SMOOTH) {
1030                                 for (y=0; y<gridSize-1; y++) {
1031                                         glBegin(GL_QUAD_STRIP);
1032                                         for (x=0; x<gridSize; x++) {
1033                                                 VertData *a = &faceGridData[(y+0)*gridSize + x];
1034                                                 VertData *b = &faceGridData[(y+1)*gridSize + x];
1035
1036                                                 glNormal3fv(a->no);
1037                                                 glVertex3fv(a->co);
1038                                                 glNormal3fv(b->no);
1039                                                 glVertex3fv(b->co);
1040                                         }
1041                                         glEnd();
1042                                 }
1043                         } else {
1044                                 glBegin(GL_QUADS);
1045                                 for (y=0; y<gridSize-1; y++) {
1046                                         for (x=0; x<gridSize-1; x++) {
1047                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
1048                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1049                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1050                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
1051                                                 float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1052                                                 float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1053                                                 float no[3];
1054
1055                                                 no[0] = b_dY*a_cZ - b_dZ*a_cY;
1056                                                 no[1] = b_dZ*a_cX - b_dX*a_cZ;
1057                                                 no[2] = b_dX*a_cY - b_dY*a_cX;
1058                                                 glNormal3fv(no);
1059
1060                                                 glVertex3fv(d);
1061                                                 glVertex3fv(c);
1062                                                 glVertex3fv(b);
1063                                                 glVertex3fv(a);
1064                                         }
1065                                 }
1066                                 glEnd();
1067                         }
1068                 }
1069         }
1070
1071         ccgFaceIterator_free(fi);
1072 }
1073 static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2) {
1074         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1075         CCGSubSurf *ss = ccgdm->ss;
1076         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1077         int gridSize = ccgSubSurf_getGridSize(ss);
1078         unsigned char *cp1, *cp2;
1079         int useTwoSide=1;
1080
1081         cp1= col1;
1082         if(col2) {
1083                 cp2= col2;
1084         } else {
1085                 cp2= NULL;
1086                 useTwoSide= 0;
1087         }
1088
1089         glShadeModel(GL_SMOOTH);
1090         if(col1 && col2)
1091                 glEnable(GL_CULL_FACE);
1092
1093         glBegin(GL_QUADS);
1094         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1095                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1096                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1097
1098                 for (S=0; S<numVerts; S++) {
1099                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1100                         for (y=0; y<gridSize-1; y++) {
1101                                 for (x=0; x<gridSize-1; x++) {
1102                                         float *a = faceGridData[(y+0)*gridSize + x].co;
1103                                         float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1104                                         float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1105                                         float *d = faceGridData[(y+1)*gridSize + x].co;
1106
1107                                         glColor3ub(cp1[3], cp1[2], cp1[1]);
1108                                         glVertex3fv(d);
1109                                         glColor3ub(cp1[7], cp1[6], cp1[5]);
1110                                         glVertex3fv(c);
1111                                         glColor3ub(cp1[11], cp1[10], cp1[9]);
1112                                         glVertex3fv(b);
1113                                         glColor3ub(cp1[15], cp1[14], cp1[13]);
1114                                         glVertex3fv(a);
1115
1116                                         if (useTwoSide) {
1117                                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
1118                                                 glVertex3fv(a);
1119                                                 glColor3ub(cp2[11], cp2[10], cp2[9]);
1120                                                 glVertex3fv(b);
1121                                                 glColor3ub(cp2[7], cp2[6], cp2[5]);
1122                                                 glVertex3fv(c);
1123                                                 glColor3ub(cp2[3], cp2[2], cp2[1]);
1124                                                 glVertex3fv(d);
1125                                         }
1126
1127                                         if (cp2) cp2+=16;
1128                                         cp1+=16;
1129                                 }
1130                         }
1131                 }
1132         }
1133         glEnd();
1134
1135         ccgFaceIterator_free(fi);
1136 }
1137 static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr)) {
1138         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1139         CCGSubSurf *ss = ccgdm->ss;
1140         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1141         int gridSize = ccgSubSurf_getGridSize(ss);
1142         MFace *mface = ccgdm->dlm?ccgdm->dlm->mface:ccgdm->me->mface;
1143         TFace *tface = ccgdm->dlm?ccgdm->dlm->tface:ccgdm->me->tface;
1144         MCol *mcol = ccgdm->dlm?ccgdm->dlm->mcol:ccgdm->me->mcol;
1145 //      float uv[4][2];
1146 //      float col[4][3];
1147
1148         glBegin(GL_QUADS);
1149         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1150                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1151                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1152                 int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
1153                 MFace *mf = &mface[index];
1154                 TFace *tf = tface?&tface[index]:NULL;
1155                 unsigned char *cp= NULL;
1156                 int flag = setDrawParams(tf, mf->mat_nr);
1157
1158                 if (flag==0) {
1159                         continue;
1160                 } else if (flag==1) {
1161                         if (tf) {
1162                                 cp= (unsigned char*) tf->col;
1163                         } else if (mcol) {
1164                                 cp= (unsigned char*) &mcol[index*4];
1165                         }
1166                 }
1167
1168                 for (S=0; S<numVerts; S++) {
1169                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1170                         for (y=0; y<gridSize-1; y++) {
1171                                 for (x=0; x<gridSize-1; x++) {
1172                                         VertData *a = &faceGridData[(y+0)*gridSize + x + 0];
1173                                         VertData *b = &faceGridData[(y+0)*gridSize + x + 1];
1174                                         VertData *c = &faceGridData[(y+1)*gridSize + x + 1];
1175                                         VertData *d = &faceGridData[(y+1)*gridSize + x + 0];
1176
1177                                         if (!(mf->flag&ME_SMOOTH)) {
1178                                                 float a_cX = c->co[0]-a->co[0], a_cY = c->co[1]-a->co[1], a_cZ = c->co[2]-a->co[2];
1179                                                 float b_dX = d->co[0]-b->co[0], b_dY = d->co[1]-b->co[1], b_dZ = d->co[2]-b->co[2];
1180                                                 float no[3];
1181
1182                                                 no[0] = b_dY*a_cZ - b_dZ*a_cY;
1183                                                 no[1] = b_dZ*a_cX - b_dX*a_cZ;
1184                                                 no[2] = b_dX*a_cY - b_dY*a_cX;
1185
1186                                                 glNormal3fv(no);
1187                                         }
1188
1189 //                                      if (tf) glTexCoord2fv(tf->uv[0]);
1190 //                                      if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1191 //                                      if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no);
1192 //                                      glVertex3fv(mvert[mf->v1].co);
1193
1194 /*
1195                                         {
1196                                                 float x_v = (float) fx/(gridSize-1);
1197                                                 float y_v = (float) fy/(gridSize-1);
1198                                                 float data[6];
1199
1200                                                 for (k=0; k<numDataComponents; k++) {
1201                                                         data[k] = (center_data[k]*(1.0f-x_v) + edge_data[S][k]*x_v)*(1.0f-y_v) + 
1202                                                                         (edge_data[prevS][k]*(1.0f-x_v) + corner_data[S][k]*x_v)*y_v;
1203                                         }
1204 */
1205
1206 //                                      if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1207                                         if (mf->flag&ME_SMOOTH) glNormal3fv(d->no);
1208                                         glVertex3fv(d->co);
1209 //                                      if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1210                                         if (mf->flag&ME_SMOOTH) glNormal3fv(c->no);
1211                                         glVertex3fv(c->co);
1212 //                                      if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1213                                         if (mf->flag&ME_SMOOTH) glNormal3fv(b->no);
1214                                         glVertex3fv(b->co);
1215 //                                      if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1216                                         if (mf->flag&ME_SMOOTH) glNormal3fv(a->no);
1217                                         glVertex3fv(a->co);
1218                                 }
1219                         }
1220                 }
1221         }
1222         glEnd();
1223
1224         ccgFaceIterator_free(fi);
1225 /*
1226         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
1227         Mesh *me = mdm->me;
1228         MVert *mvert= mdm->verts;
1229         MFace *mface= me->mface;
1230         TFace *tface = me->tface;
1231         float *nors = mdm->nors;
1232         int a;
1233
1234         for (a=0; a<me->totface; a++) {
1235                 MFace *mf= &mface[a];
1236                 if (tf) glTexCoord2fv(tf->uv[1]);
1237                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1238                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no);
1239                 glVertex3fv(mvert[mf->v2].co);
1240
1241                 if (tf) glTexCoord2fv(tf->uv[2]);
1242                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1243                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no);
1244                 glVertex3fv(mvert[mf->v3].co);
1245
1246                 if(mf->v4) {
1247                         if (tf) glTexCoord2fv(tf->uv[3]);
1248                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1249                         if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no);
1250                         glVertex3fv(mvert[mf->v4].co);
1251                 }
1252                 glEnd();
1253         }
1254 */
1255 }
1256 static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData) {
1257         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1258         CCGSubSurf *ss = ccgdm->ss;
1259         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1260         int i, gridSize = ccgSubSurf_getGridSize(ss);
1261
1262         for (i=0; !ccgFaceIterator_isStopped(fi); i++,ccgFaceIterator_next(fi)) {
1263                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1264                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1265                 int drawSmooth = 1, index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
1266
1267                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index, &drawSmooth))) {
1268                         for (S=0; S<numVerts; S++) {
1269                                 VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1270                                 if (drawSmooth) {
1271                                         glShadeModel(GL_SMOOTH);
1272                                         for (y=0; y<gridSize-1; y++) {
1273                                                 glBegin(GL_QUAD_STRIP);
1274                                                 for (x=0; x<gridSize; x++) {
1275                                                         VertData *a = &faceGridData[(y+0)*gridSize + x];
1276                                                         VertData *b = &faceGridData[(y+1)*gridSize + x];
1277
1278                                                         glNormal3fv(a->no);
1279                                                         glVertex3fv(a->co);
1280                                                         glNormal3fv(b->no);
1281                                                         glVertex3fv(b->co);
1282                                                 }
1283                                                 glEnd();
1284                                         }
1285                                 } else {
1286                                         glShadeModel(GL_FLAT);
1287                                         glBegin(GL_QUADS);
1288                                         for (y=0; y<gridSize-1; y++) {
1289                                                 for (x=0; x<gridSize-1; x++) {
1290                                                         float *a = faceGridData[(y+0)*gridSize + x].co;
1291                                                         float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1292                                                         float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1293                                                         float *d = faceGridData[(y+1)*gridSize + x].co;
1294                                                         float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1295                                                         float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1296                                                         float no[3];
1297
1298                                                         no[0] = b_dY*a_cZ - b_dZ*a_cY;
1299                                                         no[1] = b_dZ*a_cX - b_dX*a_cZ;
1300                                                         no[2] = b_dX*a_cY - b_dY*a_cX;
1301                                                         glNormal3fv(no);
1302
1303                                                         glVertex3fv(d);
1304                                                         glVertex3fv(c);
1305                                                         glVertex3fv(b);
1306                                                         glVertex3fv(a);
1307                                                 }
1308                                         }
1309                                         glEnd();
1310                                 }
1311                         }
1312                 }
1313         }
1314
1315         ccgFaceIterator_free(fi);
1316 }
1317 static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
1318         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1319         CCGSubSurf *ss = ccgdm->ss;
1320         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1321         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
1322
1323         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1324
1325         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1326                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1327                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1328                 int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
1329
1330                 glBegin(GL_LINE_STRIP);
1331                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
1332                         if (useAging && !(G.f&G_BACKBUFSEL)) {
1333                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1334                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
1335                         }
1336
1337                         for (i=0; i<edgeSize-1; i++) {
1338                                 glVertex3fv(edgeData[i].co);
1339                                 glVertex3fv(edgeData[i+1].co);
1340                         }
1341                 }
1342                 glEnd();
1343         }
1344
1345         ccgEdgeIterator_free(ei);
1346 }
1347 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
1348         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1349         CCGSubSurf *ss = ccgdm->ss;
1350         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1351         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
1352
1353         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1354
1355         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1356                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1357                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1358                 int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
1359
1360                 glBegin(GL_LINE_STRIP);
1361                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
1362                         for (i=0; i<edgeSize; i++) {
1363                                 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
1364
1365                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1366                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1367                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1368                                 }
1369
1370                                 glVertex3fv(edgeData[i].co);
1371                         }
1372                 }
1373                 glEnd();
1374         }
1375
1376         ccgEdgeIterator_free(ei);
1377 }
1378 static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
1379         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1380         CCGSubSurf *ss = ccgdm->ss;
1381         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1382
1383         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1384                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1385                 int index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
1386
1387                 if (index!=-1) {
1388                                 /* Face center data normal isn't updated atm. */
1389                         VertData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
1390
1391                         func(userData, index, vd->co, vd->no);
1392                 }
1393         }
1394
1395         ccgFaceIterator_free(fi);
1396 }
1397
1398 static void ccgDM_release(DerivedMesh *dm) {
1399         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1400
1401         if (ccgdm->dlm) displistmesh_free(ccgdm->dlm);
1402
1403         MEM_freeN(ccgdm);
1404 }
1405
1406 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int drawInteriorEdges, Mesh *me, DispListMesh *dlm) {
1407         CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
1408
1409         ccgdm->dm.getMinMax = ccgDM_getMinMax;
1410         ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
1411         ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
1412         ccgdm->dm.getVertCos = ccgdm_getVertCos;
1413         ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
1414         ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
1415         ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
1416         ccgdm->dm.convertToDispListMesh = ccgDM_convertToDispListMesh;
1417         
1418         ccgdm->dm.drawVerts = ccgDM_drawVerts;
1419         ccgdm->dm.drawEdges = ccgDM_drawEdges;
1420         ccgdm->dm.drawEdgesFlag = ccgDM_drawEdgesFlag;
1421         ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
1422         ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
1423         ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
1424         ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
1425
1426         ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
1427         ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
1428         
1429         ccgdm->dm.release = ccgDM_release;
1430         
1431         ccgdm->ss = ss;
1432         ccgdm->fromEditmesh = fromEditmesh;
1433         ccgdm->drawInteriorEdges = drawInteriorEdges;
1434         ccgdm->me = me;
1435         ccgdm->dlm = dlm;
1436
1437         return ccgdm;
1438 }
1439
1440 /***/
1441
1442 DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, SubsurfModifierData *smd, float (*vertCos)[3]) {
1443         int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
1444         int useAging = smd->flags&eSubsurfModifierFlag_DebugIncr;
1445         int drawInteriorEdges = !(smd->flags&eSubsurfModifierFlag_ControlEdges);
1446
1447         smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0, useSimple);
1448         ss_sync_from_editmesh(smd->emCache, em, vertCos, useSimple);
1449
1450         return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 1, drawInteriorEdges, NULL, NULL);
1451 }
1452
1453 DerivedMesh *subsurf_make_derived_from_dlm_em(DispListMesh *dlm, SubsurfModifierData *smd, float (*vertCos)[3]) {
1454         int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
1455         int useAging = smd->flags&eSubsurfModifierFlag_DebugIncr;
1456         int drawInteriorEdges = !(smd->flags&eSubsurfModifierFlag_ControlEdges);
1457                 
1458         smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0, useSimple);
1459
1460         ss_sync_from_mesh(smd->emCache, NULL, dlm, vertCos, useSimple);
1461
1462         return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 0, drawInteriorEdges, NULL, dlm);
1463 }
1464
1465 DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3], int isFinalCalc) {
1466         int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
1467         int drawInteriorEdges = !(smd->flags&eSubsurfModifierFlag_ControlEdges);
1468         DispListMesh *ndlm;
1469
1470                 /* Do not use cache in render mode. */
1471         if (useRenderParams) {
1472                 CCGSubSurf *ss = _getSubSurf(NULL, smd->renderLevels, 0, 1, useSimple);
1473
1474                 ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
1475
1476                 ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, me, dlm);
1477                 if (dlm) displistmesh_free(dlm);
1478
1479                 ccgSubSurf_free(ss);
1480                 
1481                 return derivedmesh_from_displistmesh(ndlm, NULL);
1482         } else {
1483                 int useIncremental = (smd->flags&eSubsurfModifierFlag_Incremental);
1484                 int useAging = smd->flags&eSubsurfModifierFlag_DebugIncr;
1485                 CCGSubSurf *ss;
1486                 
1487                         /* It is quite possible there is a much better place to do this. It
1488                          * depends a bit on how rigourously we expect this function to never
1489                          * be called in editmode. In semi-theory we could share a single
1490                          * cache, but the handles used inside and outside editmode are not
1491                          * the same so we would need some way of converting them. Its probably
1492                          * not worth the effort. But then why am I even writing this long
1493                          * comment that no one will read? Hmmm. - zr
1494                          */
1495                 if (smd->emCache) {
1496                         ccgSubSurf_free(smd->emCache);
1497                         smd->emCache = NULL;
1498                 }
1499
1500                 if (useIncremental && isFinalCalc) {
1501                         smd->mCache = ss = _getSubSurf(smd->mCache, smd->levels, useAging, 0, useSimple);
1502
1503                         ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
1504
1505                         return (DerivedMesh*) getCCGDerivedMesh(ss, 0, drawInteriorEdges, me, dlm);
1506                 } else {
1507                         if (smd->mCache && isFinalCalc) {
1508                                 ccgSubSurf_free(smd->mCache);
1509                                 smd->mCache = NULL;
1510                         }
1511
1512                         ss = _getSubSurf(NULL, smd->levels, 0, 1, useSimple);
1513                         ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
1514
1515                         ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, me, dlm);
1516
1517                         if (dlm) displistmesh_free(dlm);
1518                         ccgSubSurf_free(ss);
1519
1520                         return derivedmesh_from_displistmesh(ndlm, NULL);
1521                 }
1522         }
1523 }
1524
1525 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 
1526 {
1527                 /* Finds the subsurf limit positions for the verts in a mesh 
1528                  * and puts them in an array of floats. Please note that the 
1529                  * calculated vert positions is incorrect for the verts 
1530                  * on the boundary of the mesh.
1531                  */
1532         CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0);
1533         float edge_sum[3], face_sum[3];
1534         CCGVertIterator *vi;
1535
1536         ss_sync_from_mesh(ss, me, NULL, NULL, 0);
1537
1538         vi = ccgSubSurf_getVertIterator(ss);
1539         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1540                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1541                 int idx = (int) ccgSubSurf_getVertVertHandle(ss, v);
1542                 int N = ccgSubSurf_getVertNumEdges(ss, v);
1543                 int numFaces = ccgSubSurf_getVertNumFaces(ss, v);
1544                 float *co;
1545                 int i;
1546                 
1547                 edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0;
1548                 face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
1549
1550                 for (i=0; i<N; i++) {
1551                         CCGEdge *e = ccgSubSurf_getVertEdge(ss, v, i);
1552                         VecAddf(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
1553                 }
1554                 for (i=0; i<numFaces; i++) {
1555                         CCGFace *f = ccgSubSurf_getVertFace(ss, v, i);
1556                         VecAddf(face_sum, face_sum, ccgSubSurf_getFaceCenterData(ss, f));
1557                 }
1558
1559                 co = ccgSubSurf_getVertData(ss, v);
1560                 positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
1561                 positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
1562                 positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
1563         }
1564         ccgVertIterator_free(vi);
1565
1566         ccgSubSurf_free(ss);
1567 }
1568