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