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