- split {curve,lattice,armature}_deform_verts out of mesh_deform
[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 "MEM_guardedalloc.h"
38
39 #include "DNA_mesh_types.h"
40 #include "DNA_meshdata_types.h"
41 #include "DNA_object_types.h"
42
43 #include "BKE_bad_level_calls.h"
44 #include "BKE_utildefines.h"
45 #include "BKE_global.h"
46 #include "BKE_mesh.h"
47 #include "BKE_subsurf.h"
48 #include "BKE_displist.h"
49 #include "BKE_DerivedMesh.h"
50
51 #include "BLI_blenlib.h"
52 #include "BLI_editVert.h"
53 #include "BLI_arithb.h"
54 #include "BLI_linklist.h"
55 #include "BLI_memarena.h"
56
57 #include "BIF_gl.h"
58
59 #include "CCGSubSurf.h"
60
61 typedef struct _SubSurf {
62         CCGSubSurf *subSurf;
63
64         int useAging;
65         int controlType;
66 #define SUBSURF_CONTROLTYPE_MESH                1
67 #define SUBSURF_CONTROLTYPE_EDITMESH    2
68
69                 /* used by editmesh control type */
70         EditMesh *em;
71
72                 /* used by mesh control type */
73         Mesh *me;
74
75         float (*vertCos)[3];
76         DispListMesh *dlm;
77 } SubSurf;
78
79 typedef struct _VertData {
80         float co[3];
81         float no[3];
82 } VertData;
83
84 ///
85
86 static void *arena_alloc(CCGAllocatorHDL a, int numBytes) {
87         return BLI_memarena_alloc(a, numBytes);
88 }
89 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) {
90         void *p2 = BLI_memarena_alloc(a, newSize);
91         if (ptr) {
92                 memcpy(p2, ptr, oldSize);
93         }
94         return p2;
95 }
96 static void arena_free(CCGAllocatorHDL a, void *ptr) {
97 }
98 static void arena_release(CCGAllocatorHDL a) {
99         BLI_memarena_free(a);
100 }
101
102 static CCGSubSurf *_getSubSurf(SubSurf *ss, int subdivLevels, int useArena) {
103         CCGMeshIFC ifc;
104         CCGSubSurf *ccgSS;
105         CCGAllocatorIFC allocatorIFC, *allocatorIFCp;
106         CCGAllocatorHDL allocator;
107
108         if (ss->useAging) {
109                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
110         } else {
111                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 4;
112         }
113         ifc.vertDataSize = sizeof(VertData);
114
115         if (useArena) {
116                 allocatorIFC.alloc = arena_alloc;
117                 allocatorIFC.realloc = arena_realloc;
118                 allocatorIFC.free = arena_free;
119                 allocatorIFC.release = arena_release;
120                 allocatorIFCp = &allocatorIFC;
121                 allocator = BLI_memarena_new((1<<16));
122
123                 ccgSS = ccgSubSurf_new(&ifc, ss, subdivLevels, allocatorIFCp, allocator);
124         } else {
125                 ccgSS = ccgSubSurf_new(&ifc, ss, subdivLevels, NULL, NULL);
126         }
127
128         if (ss->useAging) {
129                 ccgSubSurf_setUseAgeCounts(ccgSS, 1, 4, 4, 4);
130         }
131
132         ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(VertData, no));
133
134         return ccgSS;
135 }
136
137 static SubSurf *subSurf_fromEditmesh(EditMesh *em, int subdivLevels, int useAging, int useArena) {
138         SubSurf *ss = MEM_mallocN(sizeof(*ss), "ss_em");
139
140         ss->useAging = useAging;
141         ss->controlType = SUBSURF_CONTROLTYPE_EDITMESH;
142         ss->subSurf = _getSubSurf(ss, subdivLevels, useArena);
143         ss->em = em;
144
145         return ss;
146 }
147
148 static SubSurf *subSurf_fromMesh(Mesh *me, int useFlatSubdiv, int subdivLevels, float (*vertCos)[3], DispListMesh *dlm) {
149         SubSurf *ss = MEM_mallocN(sizeof(*ss), "ss_m");
150
151         ss->controlType = SUBSURF_CONTROLTYPE_MESH;
152         ss->useAging=0;
153         ss->subSurf = _getSubSurf(ss, subdivLevels, 1);
154         ss->me = me;
155         ss->dlm = dlm;
156         ss->vertCos = vertCos;
157
158         ccgSubSurf_setAllowEdgeCreation(ss->subSurf, 1, useFlatSubdiv?subdivLevels:0.0f);
159
160         return ss;
161 }
162
163 static void subSurf_free(SubSurf *ss) {
164         ccgSubSurf_free(ss->subSurf);
165         MEM_freeN(ss);
166 }
167
168 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
169         CCGVert *v0 = ccgSubSurf_getEdgeVert0(ss, e);
170         CCGVert *v1 = ccgSubSurf_getEdgeVert1(ss, e);
171         int v0idx = *((int*) ccgSubSurf_getVertUserData(ss, v0));
172         int v1idx = *((int*) ccgSubSurf_getVertUserData(ss, v1));
173         int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
174
175         if (x==0) {
176                 return v0idx;
177         } else if (x==edgeSize-1) {
178                 return v1idx;
179         } else {
180                 return edgeBase + x-1;
181         }
182 }
183 static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) {
184         int faceBase = *((int*) ccgSubSurf_getFaceUserData(ss, f));
185         int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
186
187         if (x==gridSize-1 && y==gridSize-1) {
188                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
189                 return *((int*) ccgSubSurf_getVertUserData(ss, v));
190         } else if (x==gridSize-1) {
191                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
192                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S);
193                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
194                 if (v==ccgSubSurf_getEdgeVert0(ss, e)) {
195                         return edgeBase + (gridSize-1-y)-1;
196                 } else {
197                         return edgeBase + (edgeSize-2-1)-((gridSize-1-y)-1);
198                 }
199         } else if (y==gridSize-1) {
200                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
201                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts);
202                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
203                 if (v==ccgSubSurf_getEdgeVert0(ss, e)) {
204                         return edgeBase + (gridSize-1-x)-1;
205                 } else {
206                         return edgeBase + (edgeSize-2-1)-((gridSize-1-x)-1);
207                 }
208         } else if (x==0 && y==0) {
209                 return faceBase;
210         } else if (x==0) {
211                 S = (S+numVerts-1)%numVerts;
212                 return faceBase + 1 + (gridSize-2)*S + (y-1);
213         } else if (y==0) {
214                 return faceBase + 1 + (gridSize-2)*S + (x-1);
215         } else {
216                 return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1);
217         }
218 }
219 static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
220         CCGSubSurf *ss = ssm->subSurf;
221         DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
222         int edgeSize = ccgSubSurf_getEdgeSize(ss);
223         int gridSize = ccgSubSurf_getGridSize(ss);
224         int edgeIndexBase, edgeBase, faceIndexBase, faceBase;
225         int i, j, k, S, x, y;
226         int vertBase = 0;
227         MFace *mf;
228         CCGVertIterator *vi;
229         CCGEdgeIterator *ei;
230         CCGFaceIterator *fi;
231         
232         dlm->totvert = ccgSubSurf_getNumFinalVerts(ss);
233         dlm->totedge = ccgSubSurf_getNumFinalEdges(ss);
234         dlm->totface = ccgSubSurf_getNumFinalFaces(ss);
235
236         dlm->mvert = MEM_callocN(dlm->totvert*sizeof(*dlm->mvert), "dlm->mvert");
237         dlm->medge = MEM_callocN(dlm->totedge*sizeof(*dlm->medge), "dlm->medge");
238         dlm->mface = MEM_callocN(dlm->totface*sizeof(*dlm->mface), "dlm->mface");
239         if ((ssm->controlType==SUBSURF_CONTROLTYPE_MESH) && ssm->me->tface) {
240                 dlm->tface = MEM_callocN(dlm->totface*sizeof(*dlm->tface), "dlm->tface");
241                 dlm->mcol = NULL;
242         } else if ((ssm->controlType==SUBSURF_CONTROLTYPE_MESH) && ssm->me->mcol) {
243                 dlm->tface = NULL;
244                 dlm->mcol = MEM_mallocN(dlm->totface*4*sizeof(*dlm->mcol), "dlm->mcol");
245         } else {
246                 dlm->tface = NULL;
247                 dlm->mcol = NULL;
248         }
249
250                 // load vertices
251
252         vertBase = i = 0;
253         vi = ccgSubSurf_getVertIterator(ss);
254         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
255                 CCGVert *v = ccgVertIterator_getCurrent(vi);
256                 VecCopyf(dlm->mvert[i].co, ccgSubSurf_getVertData(ss, v));
257                 *((int*) ccgSubSurf_getVertUserData(ss, v)) = i++;
258         }
259         ccgVertIterator_free(vi);
260
261         edgeIndexBase = edgeBase = i;
262         ei = ccgSubSurf_getEdgeIterator(ss);
263         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
264                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
265                 int x;
266
267                 for (x=1; x<edgeSize-1; x++) {
268                         VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getEdgeData(ss, e, x));
269                 }
270
271                 *((int*) ccgSubSurf_getEdgeUserData(ss, e)) = edgeBase;
272                 edgeBase += edgeSize-2;
273         }
274         ccgEdgeIterator_free(ei);
275
276         faceIndexBase = faceBase = i;
277         fi = ccgSubSurf_getFaceIterator(ss);
278         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
279                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
280                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
281
282                 VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getFaceCenterData(ss, f));
283                 
284                 for (S=0; S<numVerts; S++) {
285                         for (x=1; x<gridSize-1; x++) {
286                                 VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
287                         }
288                 }
289
290                 for (S=0; S<numVerts; S++) {
291                         for (y=1; y<gridSize-1; y++) {
292                                 for (x=1; x<gridSize-1; x++) {
293                                         VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getFaceGridData(ss, f, S, x, y));
294                                 }
295                         }
296                 }
297
298                 *((int*) ccgSubSurf_getFaceUserData(ss, f)) = faceBase;
299                 faceBase += 1 + numVerts*((gridSize-2) + (gridSize-2)*(gridSize-2));
300         }
301         ccgFaceIterator_free(fi);
302
303                 // load edges
304
305         i=0;
306         ei = ccgSubSurf_getEdgeIterator(ss);
307         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
308                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
309                 for (x=0; x<edgeSize-1; x++) {
310                         MEdge *med = &dlm->medge[i];
311                         med->v1 = getEdgeIndex(ss, e, x, edgeSize);
312                         med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
313                         med->flag = ME_EDGEDRAW;
314
315                         if (ssm->controlType==SUBSURF_CONTROLTYPE_EDITMESH) {
316                                 EditEdge *ee = ccgSubSurf_getEdgeEdgeHandle(ss, e);
317
318                                 if (ee->seam) {
319                                         med->flag|= ME_SEAM;
320                                 }
321                         } else {
322                                 int edgeIdx = (int) ccgSubSurf_getEdgeEdgeHandle(ss, e);
323
324                                         /* Edges created by lib have handle of -1 */
325                                 if (edgeIdx!=-1 && ssm->me->medge) {
326                                         MEdge *origMed = &ssm->me->medge[edgeIdx];
327
328                                         med->flag|= (origMed->flag&ME_SEAM);
329                                 }
330                         }
331
332                         i++;
333                 }
334         }
335         ccgEdgeIterator_free(ei);
336
337         fi = ccgSubSurf_getFaceIterator(ss);
338         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
339                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
340                 int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
341
342                 for (k=0; k<numVerts; k++) {
343                         for (x=0; x<gridSize-1; x++) {
344                                 MEdge *med = &dlm->medge[i];
345                                 med->v1 = getFaceIndex(ss, f, k, x, 0, edgeSize, gridSize);
346                                 med->v2 = getFaceIndex(ss, f, k, x+1, 0, edgeSize, gridSize);
347                                 i++;
348                         }
349
350                         for (x=1; x<gridSize-1; x++) {
351                                 for (y=0; y<gridSize-1; y++) {
352                                         MEdge *med;
353                                         
354                                         med = &dlm->medge[i];
355                                         med->v1 = getFaceIndex(ss, f, k, x, y, edgeSize, gridSize);
356                                         med->v2 = getFaceIndex(ss, f, k, x, y+1, edgeSize, gridSize);
357                                         i++;
358
359                                         med = &dlm->medge[i];
360                                         med->v1 = getFaceIndex(ss, f, k, y, x, edgeSize, gridSize);
361                                         med->v2 = getFaceIndex(ss, f, k, y+1, x, edgeSize, gridSize);
362                                         i++;
363                                 }
364                         }
365                 }
366         }
367         ccgFaceIterator_free(fi);
368
369                 // load faces
370
371         i = 0;
372         fi = ccgSubSurf_getFaceIterator(ss);
373         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
374                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
375                 int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
376                 float edge_data[4][6];
377                 float corner_data[4][6];
378                 float center_data[6] = {0};
379                 int numDataComponents;
380                 TFace *origTFace = NULL;
381                 MCol *origMCol = NULL;
382                 int mat_nr;
383                 int flag;
384
385                 if (ssm->controlType==SUBSURF_CONTROLTYPE_MESH) {
386                         int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
387                         MFace *origMFace = &((MFace*) ssm->me->mface)[origIdx];
388                         if (ssm->me->tface)
389                                 origTFace = &((TFace*)ssm->me->tface)[origIdx];
390                         if (ssm->me->mcol)
391                                 origMCol = &ssm->me->mcol[origIdx*4];
392                         mat_nr = origMFace->mat_nr;
393                         flag = origMFace->flag;
394                 } else {
395                         EditFace *ef = ccgSubSurf_getFaceFaceHandle(ss, f);
396                         mat_nr = ef->mat_nr;
397                         flag = ef->flag;
398                 }
399
400                 if (origTFace) {
401                         for (S=0; S<numVerts; S++) {
402                                 unsigned char *col = (unsigned char*) &origTFace->col[S];
403                                 corner_data[S][0] = col[0]/255.0f;
404                                 corner_data[S][1] = col[1]/255.0f;
405                                 corner_data[S][2] = col[2]/255.0f;
406                                 corner_data[S][3] = col[3]/255.0f;
407                                 corner_data[S][4] = origTFace->uv[S][0];
408                                 corner_data[S][5] = origTFace->uv[S][1];
409                         }
410                         numDataComponents = 6;
411                 } else if (origMCol) {
412                         for (S=0; S<numVerts; S++) {
413                                 unsigned char *col = (unsigned char*) &origMCol[S];
414                                 corner_data[S][0] = col[0]/255.0f;
415                                 corner_data[S][1] = col[1]/255.0f;
416                                 corner_data[S][2] = col[2]/255.0f;
417                                 corner_data[S][3] = col[3]/255.0f;
418                         }
419                         numDataComponents = 4;
420                 } else {
421                         numDataComponents = 0;
422                 }
423
424                 for (S=0; S<numVerts; S++) {
425                         for (k=0; k<numDataComponents; k++) {
426                                 edge_data[S][k] = (corner_data[S][k] + corner_data[(S+1)%numVerts][k])*0.5f;
427                                 center_data[k]+= corner_data[S][k];
428                         }
429                 }
430                 for (k=0; k<numDataComponents; k++) {
431                         center_data[k]/= numVerts;
432                 }
433
434                 for (S=0; S<numVerts; S++) {
435                         int prevS= (S-1+numVerts)%numVerts;
436                         for (y=0; y<gridSize-1; y++) {
437                                 for (x=0; x<gridSize-1; x++) {
438                                         mf = &dlm->mface[i];
439                                         mf->v1 = getFaceIndex(ss, f, S, x+0, y+1, edgeSize, gridSize);
440                                         mf->v2 = getFaceIndex(ss, f, S, x+1, y+1, edgeSize, gridSize);
441                                         mf->v3 = getFaceIndex(ss, f, S, x+1, y+0, edgeSize, gridSize);
442                                         mf->v4 = getFaceIndex(ss, f, S, x+0, y+0, edgeSize, gridSize);
443                                         mf->mat_nr = mat_nr;
444                                         mf->flag = flag;
445                                         mf->edcode = 0;
446
447                                         if (x+1==gridSize-1)
448                                                 mf->edcode|= ME_V2V3;
449                                         if (y+1==gridSize-1)
450                                                 mf->edcode|= ME_V1V2;
451
452                                         for (j=0; j<4; j++) {
453                                                 int fx = x + (j==1||j==2);
454                                                 int fy = y + (j==0||j==1);
455                                                 float x_v = (float) fx/(gridSize-1);
456                                                 float y_v = (float) fy/(gridSize-1);
457                                                 float data[6];
458
459                                                 for (k=0; k<numDataComponents; k++) {
460                                                         data[k] = (center_data[k]*(1.0f-x_v) + edge_data[S][k]*x_v)*(1.0f-y_v) + 
461                                                                         (edge_data[prevS][k]*(1.0f-x_v) + corner_data[S][k]*x_v)*y_v;
462                                                 }
463
464                                                 if (dlm->tface) {
465                                                         TFace *tf = &dlm->tface[i];
466                                                         unsigned char col[4];
467                                                         col[0] = (int) (data[0]*255);
468                                                         col[1] = (int) (data[1]*255);
469                                                         col[2] = (int) (data[2]*255);
470                                                         col[3] = (int) (data[3]*255);
471                                                         tf->col[j] = *((unsigned int*) col);
472                                                         tf->uv[j][0] = data[4];
473                                                         tf->uv[j][1] = data[5];
474                                                 } else if (dlm->mcol) {
475                                                         unsigned char *col = (unsigned char*) &dlm->mcol[i*4+j];
476                                                         col[0] = (int) (data[0]*255);
477                                                         col[1] = (int) (data[1]*255);
478                                                         col[2] = (int) (data[2]*255);
479                                                         col[3] = (int) (data[3]*255);
480                                                 }
481                                         }
482                                         if (dlm->tface) {
483                                                 TFace *tf = &dlm->tface[i];
484                                                 tf->tpage = origTFace->tpage;
485                                                 tf->flag = origTFace->flag;
486                                                 tf->transp = origTFace->transp;
487                                                 tf->mode = origTFace->mode;
488                                                 tf->tile = origTFace->tile;
489                                         }
490
491                                         i++;
492                                 }
493                         }
494                 }
495         }
496         ccgFaceIterator_free(fi);
497
498         mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
499
500         return dlm;
501 }
502
503 static void subSurf_sync(SubSurf *ss, int useFlatSubdiv) {
504         float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss->subSurf);
505
506         ccgSubSurf_initFullSync(ss->subSurf);
507
508         if (ss->controlType==SUBSURF_CONTROLTYPE_MESH) {
509                 CCGVertHDL fVerts[4];
510                 MVert *mvert = ss->dlm?ss->dlm->mvert:ss->me->mvert;
511                 MEdge *medge = ss->dlm?ss->dlm->medge:ss->me->medge;
512                 MFace *mface = ss->dlm?ss->dlm->mface:ss->me->mface;
513                 int totvert = ss->dlm?ss->dlm->totvert:ss->me->totvert;
514                 int totedge = ss->dlm?ss->dlm->totedge:ss->me->totedge;
515                 int totface = ss->dlm?ss->dlm->totface:ss->me->totface;
516                 int i;
517
518                 if (ss->vertCos) {
519                         for (i=0; i<totvert; i++) {
520                                 ccgSubSurf_syncVert(ss->subSurf, (CCGVertHDL) i, ss->vertCos[i]);
521                         }
522                 } else {
523                         for (i=0; i<totvert; i++) {
524                                 ccgSubSurf_syncVert(ss->subSurf, (CCGVertHDL) i, mvert[i].co);
525                         }
526                 }
527
528                 if (medge) {
529                         for (i=0; i<totedge; i++) {
530                                 MEdge *med = &medge[i];
531                                 float crease = useFlatSubdiv?creaseFactor:med->crease*creaseFactor/255.0f;
532
533                                 ccgSubSurf_syncEdge(ss->subSurf, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2, crease);
534                         }
535                 } else {
536                         for (i=0; i<totface; i++) {
537                                 MFace *mf = &((MFace*) mface)[i];
538
539                                 if (!mf->v3) {
540                                         ccgSubSurf_syncEdge(ss->subSurf, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0);
541                                 }
542                         }
543                 }
544
545                 for (i=0; i<totface; i++) {
546                         MFace *mf = &((MFace*) mface)[i];
547
548                         if (mf->v3) {
549                                 fVerts[0] = (CCGVertHDL) mf->v1;
550                                 fVerts[1] = (CCGVertHDL) mf->v2;
551                                 fVerts[2] = (CCGVertHDL) mf->v3;
552                                 fVerts[3] = (CCGVertHDL) mf->v4;
553
554                                 ccgSubSurf_syncFace(ss->subSurf, (CCGFaceHDL) i, fVerts[3]?4:3, fVerts);
555                         }
556                 }
557         } else {
558                 EditVert *ev, *fVerts[4];
559                 EditEdge *ee;
560                 EditFace *ef;
561
562                 for (ev=ss->em->verts.first; ev; ev=ev->next) {
563                         ccgSubSurf_syncVert(ss->subSurf, ev, ev->co);
564                 }
565
566                 for (ee=ss->em->edges.first; ee; ee=ee->next) {
567                         ccgSubSurf_syncEdge(ss->subSurf, ee, ee->v1, ee->v2, useFlatSubdiv?creaseFactor:ee->crease*creaseFactor);
568                 }
569
570                 for (ef=ss->em->faces.first; ef; ef=ef->next) {
571                         fVerts[0] = ef->v1;
572                         fVerts[1] = ef->v2;
573                         fVerts[2] = ef->v3;
574                         fVerts[3] = ef->v4;
575
576                         ccgSubSurf_syncFace(ss->subSurf, ef, ef->v4?4:3, (CCGVertHDL*) fVerts);
577                 }
578         }
579
580         ccgSubSurf_processSync(ss->subSurf);
581 }
582
583 /***/
584
585 typedef struct {
586         DerivedMesh dm;
587
588         SubSurf *ss;
589 } CCGDerivedMesh;
590
591 static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
592         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
593         CCGSubSurf *ss = ccgdm->ss->subSurf;
594         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
595         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
596         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
597         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
598         int gridSize = ccgSubSurf_getGridSize(ss);
599
600         if (!ccgSubSurf_getNumVerts(ss))
601                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
602
603         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
604                 CCGVert *v = ccgVertIterator_getCurrent(vi);
605                 float *co = ccgSubSurf_getVertData(ss, v);
606
607                 DO_MINMAX(co, min_r, max_r);
608         }
609
610         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
611                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
612                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
613
614                 for (i=1; i<edgeSize-1; i++)
615                         DO_MINMAX(edgeData[i].co, min_r, max_r);
616         }
617
618         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
619                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
620                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
621
622                 for (S=0; S<numVerts; S++) {
623                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
624
625                         for (x=0; x<gridSize; x++)
626                                 DO_MINMAX(faceGridData[x].co, min_r, max_r);
627                         for (y=0; y<gridSize; y++)
628                                 for (x=0; x<gridSize; x++)
629                                         DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r);
630                 }
631         }
632
633         ccgFaceIterator_free(fi);
634         ccgEdgeIterator_free(ei);
635         ccgVertIterator_free(vi);
636 }
637 static int ccgDM_getNumVerts(DerivedMesh *dm) {
638         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
639
640         return ccgSubSurf_getNumFinalVerts(ccgdm->ss->subSurf);
641 }
642 static int ccgDM_getNumFaces(DerivedMesh *dm) {
643         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
644
645         return ccgSubSurf_getNumFinalFaces(ccgdm->ss->subSurf);
646 }
647 static void ccgDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3]) {
648         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
649         CCGVert *v = ccgSubSurf_getVert(ccgdm->ss->subSurf, vert);
650         float *co = ccgSubSurf_getVertData(ccgdm->ss->subSurf, v);
651
652         co_r[0] = co[0];
653         co_r[1] = co[1];
654         co_r[2] = co[2];
655 }
656 static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm) {
657         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
658
659         return subSurf_createDispListMesh(ccgdm->ss);
660 }
661
662 static void ccgDM_drawVerts(DerivedMesh *dm) {
663 //      CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
664 }
665 static void ccgDM_drawEdges(DerivedMesh *dm) {
666         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
667         CCGSubSurf *ss = ccgdm->ss->subSurf;
668         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
669         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
670         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
671         int gridSize = ccgSubSurf_getGridSize(ss);
672
673         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
674                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
675                 EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(ss, e);
676                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
677
678                 if (eed->h!=0)
679                         continue;
680
681                 if (ccgdm->ss->useAging && !(G.f&G_BACKBUFSEL)) {
682                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
683                         glColor3ub(0, ageCol>0?ageCol:0, 0);
684                 }
685
686                 glBegin(GL_LINE_STRIP);
687                 for (i=0; i<edgeSize-1; i++) {
688                         glVertex3fv(edgeData[i].co);
689                         glVertex3fv(edgeData[i+1].co);
690                 }
691                 glEnd();
692         }
693
694         if (ccgdm->ss->useAging && !(G.f&G_BACKBUFSEL)) {
695                 glColor3ub(0, 0, 0);
696         }
697
698         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
699                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
700                 EditFace *efa = ccgSubSurf_getFaceFaceHandle(ss, f);
701                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
702
703                 if (efa->h!=0)
704                         continue;
705
706                 for (S=0; S<numVerts; S++) {
707                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
708
709                         glBegin(GL_LINE_STRIP);
710                         for (x=0; x<gridSize; x++)
711                                 glVertex3fv(faceGridData[x].co);
712                         glEnd();
713                         for (y=1; y<gridSize-1; y++) {
714                                 glBegin(GL_LINE_STRIP);
715                                 for (x=0; x<gridSize; x++)
716                                         glVertex3fv(faceGridData[y*gridSize + x].co);
717                                 glEnd();
718                         }
719                         for (x=1; x<gridSize-1; x++) {
720                                 glBegin(GL_LINE_STRIP);
721                                 for (y=0; y<gridSize; y++)
722                                         glVertex3fv(faceGridData[y*gridSize + x].co);
723                                 glEnd();
724                         }
725                 }
726         }
727
728         ccgFaceIterator_free(fi);
729         ccgEdgeIterator_free(ei);
730 }
731 static void ccgDM_drawMappedEdges(DerivedMesh *dm) {
732         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
733         CCGSubSurf *ss = ccgdm->ss->subSurf;
734         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
735         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
736
737         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
738                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
739                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
740
741                 glBegin(GL_LINE_STRIP);
742                 for (i=0; i<edgeSize-1; i++) {
743                         glVertex3fv(edgeData[i].co);
744                         glVertex3fv(edgeData[i+1].co);
745                 }
746                 glEnd();
747         }
748
749         ccgEdgeIterator_free(ei);
750 }
751 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
752         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
753         CCGSubSurf *ss = ccgdm->ss->subSurf;
754         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
755         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
756
757         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
758                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
759
760                 if (!ccgSubSurf_getEdgeNumFaces(ss, e)) {
761                         VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
762
763                         glBegin(GL_LINE_STRIP);
764                         for (i=0; i<edgeSize-1; i++) {
765                                 glVertex3fv(edgeData[i].co);
766                                 glVertex3fv(edgeData[i+1].co);
767                         }
768                         glEnd();
769                 }
770         }
771
772         ccgEdgeIterator_free(ei);
773 }
774
775 static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
776         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
777         CCGSubSurf *ss = ccgdm->ss->subSurf;
778         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
779         int gridSize = ccgSubSurf_getGridSize(ss);
780
781         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
782                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
783                 EditFace *efa = ccgSubSurf_getFaceFaceHandle(ss, f);
784                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
785                 int isSmooth = efa->flag&ME_SMOOTH;
786
787                 if (efa->h!=0)
788                         continue;
789
790                 if (!setMaterial(efa->mat_nr+1))
791                         continue;
792
793                 glShadeModel(isSmooth?GL_SMOOTH:GL_FLAT);
794                 for (S=0; S<numVerts; S++) {
795                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
796
797                         if (isSmooth) {
798                                 for (y=0; y<gridSize-1; y++) {
799                                         glBegin(GL_QUAD_STRIP);
800                                         for (x=0; x<gridSize; x++) {
801                                                 VertData *a = &faceGridData[(y+0)*gridSize + x];
802                                                 VertData *b = &faceGridData[(y+1)*gridSize + x];
803
804                                                 glNormal3fv(a->no);
805                                                 glVertex3fv(a->co);
806                                                 glNormal3fv(b->no);
807                                                 glVertex3fv(b->co);
808                                         }
809                                         glEnd();
810                                 }
811                         } else {
812                                 glBegin(GL_QUADS);
813                                 for (y=0; y<gridSize-1; y++) {
814                                         for (x=0; x<gridSize-1; x++) {
815                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
816                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
817                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
818                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
819                                                 float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
820                                                 float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
821                                                 float no[3];
822
823                                                 no[0] = b_dY*a_cZ - b_dZ*a_cY;
824                                                 no[1] = b_dZ*a_cX - b_dX*a_cZ;
825                                                 no[2] = b_dX*a_cY - b_dY*a_cX;
826                                                 glNormal3fv(no);
827
828                                                 glVertex3fv(d);
829                                                 glVertex3fv(c);
830                                                 glVertex3fv(b);
831                                                 glVertex3fv(a);
832                                         }
833                                 }
834                                 glEnd();
835                         }
836                 }
837         }
838
839         ccgFaceIterator_free(fi);
840 }
841 static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2) {
842 //      CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
843 }
844 static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr)) {
845 //      CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
846 }
847
848 static void ccgDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditVert *vert), void *userData) {
849         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
850         CCGSubSurf *ss = ccgdm->ss->subSurf;
851         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
852
853         bglBegin(GL_POINTS);
854         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
855                 CCGVert *v = ccgVertIterator_getCurrent(vi);
856                 EditVert *vert = ccgSubSurf_getVertVertHandle(ss,v);
857
858                 if (!setDrawOptions || setDrawOptions(userData, vert)) {
859                         bglVertex3fv(ccgSubSurf_getVertData(ss, v));
860                 }
861         }
862         bglEnd();
863
864         ccgVertIterator_free(vi);
865 }
866 static void ccgDM_drawMappedEdgeEM(DerivedMesh *dm, void *edge) {
867         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
868         CCGSubSurf *ss = ccgdm->ss->subSurf;
869         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
870         CCGEdge *e = ccgSubSurf_getEdge(ss, edge);
871         VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
872         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
873
874         glBegin(GL_LINE_STRIP);
875         for (i=0; i<edgeSize; i++)
876                 glVertex3fv(edgeData[i].co);
877         glEnd();
878
879         ccgEdgeIterator_free(ei);
880 }
881 static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) {
882         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
883         CCGSubSurf *ss = ccgdm->ss->subSurf;
884         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
885         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
886
887         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
888                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
889                 EditEdge *edge = ccgSubSurf_getEdgeEdgeHandle(ss, e);
890                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
891
892                 glBegin(GL_LINE_STRIP);
893                 if (!setDrawOptions || setDrawOptions(userData, edge)) {
894                         if (ccgdm->ss->useAging && !(G.f&G_BACKBUFSEL)) {
895                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
896                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
897                         }
898
899                         for (i=0; i<edgeSize-1; i++) {
900                                 glVertex3fv(edgeData[i].co);
901                                 glVertex3fv(edgeData[i+1].co);
902                         }
903                 }
904                 glEnd();
905         }
906
907         ccgEdgeIterator_free(ei);
908 }
909 static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void (*setDrawInterpOptions)(void *userData, EditEdge *edge, float t), void *userData) {
910         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
911         CCGSubSurf *ss = ccgdm->ss->subSurf;
912         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
913         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
914
915         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
916                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
917                 EditEdge *edge = ccgSubSurf_getEdgeEdgeHandle(ss, e);
918                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
919
920                 glBegin(GL_LINE_STRIP);
921                 if (!setDrawOptions || setDrawOptions(userData, edge)) {
922                         for (i=0; i<edgeSize; i++) {
923                                 setDrawInterpOptions(userData, edge, (float) i/(edgeSize-1));
924
925                                 if (ccgdm->ss->useAging && !(G.f&G_BACKBUFSEL)) {
926                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
927                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
928                                 }
929
930                                 glVertex3fv(edgeData[i].co);
931                         }
932                 }
933                 glEnd();
934         }
935 }
936 static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData) {
937         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
938         CCGSubSurf *ss = ccgdm->ss->subSurf;
939         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
940         int gridSize = ccgSubSurf_getGridSize(ss);
941
942         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
943                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
944                 EditFace *efa = ccgSubSurf_getFaceFaceHandle(ss, f);
945                 if (!setDrawOptions || setDrawOptions(userData, efa)) {
946                         int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
947
948                         for (S=0; S<numVerts; S++) {
949                                 VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
950
951                                 for (y=0; y<gridSize-1; y++) {
952                                         glBegin(GL_QUAD_STRIP);
953                                         for (x=0; x<gridSize; x++) {
954                                                 glVertex3fv(faceGridData[(y+0)*gridSize + x].co);
955                                                 glVertex3fv(faceGridData[(y+1)*gridSize + x].co);
956                                         }
957                                         glEnd();
958                                 }
959                         }
960                 }
961         }
962
963         ccgFaceIterator_free(fi);
964 }
965
966 static void ccgDM_release(DerivedMesh *dm) {
967         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
968
969         subSurf_free(ccgdm->ss);
970
971         MEM_freeN(ccgdm);
972 }
973
974 static CCGDerivedMesh *getCCGDerivedMesh(SubSurf *ss) {
975         CCGDerivedMesh *ccgdm = MEM_mallocN(sizeof(*ccgdm), "ccgdm");
976
977         ccgdm->dm.getMinMax = ccgDM_getMinMax;
978         ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
979         ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
980         ccgdm->dm.getMappedVertCoEM = ccgDM_getMappedVertCoEM;
981         ccgdm->dm.convertToDispListMesh = ccgDM_convertToDispListMesh;
982
983         ccgdm->dm.drawVerts = ccgDM_drawVerts;
984         ccgdm->dm.drawEdges = ccgDM_drawEdges;
985         ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
986         ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
987         ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
988         ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
989         ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
990
991         ccgdm->dm.drawMappedVertsEM = ccgDM_drawMappedVertsEM;
992         ccgdm->dm.drawMappedEdgeEM = ccgDM_drawMappedEdgeEM;
993         ccgdm->dm.drawMappedEdgesInterpEM = ccgDM_drawMappedEdgesInterpEM;
994         ccgdm->dm.drawMappedEdgesEM = ccgDM_drawMappedEdgesEM;
995         ccgdm->dm.drawMappedFacesEM = ccgDM_drawMappedFacesEM;
996
997         ccgdm->dm.release = ccgDM_release;
998         
999         ccgdm->ss = ss;
1000
1001         return ccgdm;
1002 }
1003
1004 /***/
1005
1006 DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, int subdivLevels, short type, DerivedMesh *oldDerived) {
1007         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) oldDerived;
1008
1009         if (!ccgdm || ccgSubSurf_getSubdivisionLevels(ccgdm->ss->subSurf)!=subdivLevels) {
1010                 if (ccgdm) {
1011                         oldDerived->release(oldDerived);
1012                 }
1013
1014                 ccgdm = getCCGDerivedMesh(subSurf_fromEditmesh(em, subdivLevels, G.rt==52, 0));
1015         }
1016
1017         subSurf_sync(ccgdm->ss, type==ME_SIMPLE_SUBSURF);
1018
1019         return (DerivedMesh*) ccgdm;
1020 }
1021
1022 DerivedMesh *subsurf_make_derived_from_dlm(DispListMesh *dlm, int subdivType, int subdivLevels) {
1023         SubSurf *ss = subSurf_fromMesh(NULL, subdivType==ME_SIMPLE_SUBSURF, subdivLevels, NULL, dlm);
1024
1025         subSurf_sync(ss, subdivType==ME_SIMPLE_SUBSURF);
1026
1027         dlm = subSurf_createDispListMesh(ss);
1028         
1029         subSurf_free(ss);
1030         
1031         return derivedmesh_from_displistmesh(dlm);
1032 }
1033 DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, int subdivType, int subdivLevels, float (*vertCos)[3]) {
1034         SubSurf *ss = subSurf_fromMesh(me, subdivType==ME_SIMPLE_SUBSURF, subdivLevels, vertCos, NULL);
1035         DispListMesh *dlm;
1036
1037         subSurf_sync(ss, subdivType==ME_SIMPLE_SUBSURF);
1038
1039         dlm = subSurf_createDispListMesh(ss);
1040         
1041         subSurf_free(ss);
1042         
1043         return derivedmesh_from_displistmesh(dlm);
1044 }
1045
1046 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 
1047 {
1048                 /* Finds the subsurf limit positions for the verts in a mesh 
1049                  * and puts them in an array of floats. Please note that the 
1050                  * calculated vert positions is incorrect for the verts 
1051                  * on the boundary of the mesh.
1052                  */
1053         SubSurf *ss = subSurf_fromMesh(me, 0, 1, NULL, NULL);
1054         float edge_sum[3], face_sum[3];
1055         CCGVertIterator *vi;
1056
1057         subSurf_sync(ss, 0);
1058
1059         vi = ccgSubSurf_getVertIterator(ss->subSurf);
1060         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1061                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1062                 int idx = (int) ccgSubSurf_getVertVertHandle(ss->subSurf, v);
1063                 int N = ccgSubSurf_getVertNumEdges(ss->subSurf, v);
1064                 int numFaces = ccgSubSurf_getVertNumFaces(ss->subSurf, v);
1065                 float *co;
1066                 int i;
1067                 
1068                 edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0;
1069                 face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
1070
1071                 for (i=0; i<N; i++) {
1072                         CCGEdge *e = ccgSubSurf_getVertEdge(ss->subSurf, v, i);
1073                         VecAddf(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss->subSurf, e, 1));
1074                 }
1075                 for (i=0; i<numFaces; i++) {
1076                         CCGFace *f = ccgSubSurf_getVertFace(ss->subSurf, v, i);
1077                         VecAddf(face_sum, face_sum, ccgSubSurf_getFaceCenterData(ss->subSurf, f));
1078                 }
1079
1080                 co = ccgSubSurf_getVertData(ss->subSurf, v);
1081                 positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
1082                 positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
1083                 positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
1084         }
1085         ccgVertIterator_free(vi);
1086
1087         subSurf_free(ss);
1088 }
1089