88b2eecf89198bcd06333d8c94ecd28220e2f55c
[blender.git] / source / blender / blenkernel / intern / subsurf_ccg.c
1 #ifdef USE_CCGSUBSURFLIB
2
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdio.h>
6 #include <math.h>
7 #include "MEM_guardedalloc.h"
8
9 #include "DNA_mesh_types.h"
10 #include "DNA_meshdata_types.h"
11 #include "DNA_object_types.h"
12
13 #include "BKE_bad_level_calls.h"
14 #include "BKE_global.h"
15 #include "BKE_mesh.h"
16 #include "BKE_subsurf.h"
17 #include "BKE_displist.h"
18
19 #include "BLI_blenlib.h"
20 #include "BLI_editVert.h"
21 #include "BLI_arithb.h"
22 #include "BLI_linklist.h"
23 #include "BLI_memarena.h"
24
25 #include "CCGSubSurf.h"
26
27 #define USE_CREASING
28
29 typedef struct _SubSurf {
30         CCGSubSurf *subSurf;
31
32         int controlType;
33 #define SUBSURF_CONTROLTYPE_MESH                1
34 #define SUBSURF_CONTROLTYPE_EDITMESH    2
35
36                 /* used by editmesh control type */
37         EditMesh *em;
38
39                 /* used by mesh control type */
40         Mesh *me;
41 } SubSurf;
42
43 static void _subsurfNew_meshIFC_vertDataCopy(CCGMeshHDL mv, void *tv, void *av) {
44         float *t= tv, *a= av;
45         t[0]= a[0];
46         t[1]= a[1];
47         t[2]= a[2];
48 }
49 static int _subsurfNew_meshIFC_vertDataEqual(CCGMeshHDL mv, void *av, void *bv) {
50         float *a= av, *b= bv;
51         return (a[0]==b[0] && a[1]==b[1] && a[2]==b[2]);
52 }
53 static void _subsurfNew_meshIFC_vertDataZero(CCGMeshHDL mv, void *tv) {
54         float *t= tv;
55         t[0]= t[1]= t[2]= 0.0;
56 }
57 static void _subsurfNew_meshIFC_vertDataAdd(CCGMeshHDL mv, void *tav, void *bv) {
58         float *ta= tav, *b= bv;
59         ta[0]+= b[0];
60         ta[1]+= b[1];
61         ta[2]+= b[2];
62 }
63 static void _subsurfNew_meshIFC_vertDataSub(CCGMeshHDL mv, void *tav, void *bv) {
64         float *ta= tav, *b= bv;
65         ta[0]-= b[0];
66         ta[1]-= b[1];
67         ta[2]-= b[2];
68 }
69 static void _subsurfNew_meshIFC_vertDataMulN(CCGMeshHDL mv, void *tav, double n) {
70         float *ta= tav;
71         ta[0]*= (float) n;
72         ta[1]*= (float) n;
73         ta[2]*= (float) n;
74 }
75 static void _subsurfNew_meshIFC_ifc_vertDataAvg4(CCGMeshHDL mv, void *tv, void *av, void *bv, void *cv, void *dv) {
76         float *t= tv, *a= av, *b= bv, *c= cv, *d= dv;
77         t[0] = (a[0]+b[0]+c[0]+d[0])*0.25f;
78         t[1] = (a[1]+b[1]+c[1]+d[1])*0.25f;
79         t[2] = (a[2]+b[2]+c[2]+d[2])*0.25f;
80 }
81
82 ///
83
84 static void *arena_alloc(CCGAllocatorHDL a, int numBytes) {
85         return BLI_memarena_alloc(a, numBytes);
86 }
87 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) {
88         void *p2 = BLI_memarena_alloc(a, newSize);
89         if (ptr) {
90                 memcpy(p2, ptr, oldSize);
91         }
92         return p2;
93 }
94 static void arena_free(CCGAllocatorHDL a, void *ptr) {
95 }
96 static void arena_release(CCGAllocatorHDL a) {
97         BLI_memarena_free(a);
98 }
99
100 static CCGSubSurf *_getSubSurf(SubSurf *ss, int subdivLevels) {
101         CCGMeshIFC ifc;
102         CCGAllocatorIFC allocatorIFC, *allocatorIFCp;
103         CCGAllocatorHDL allocator;
104
105         ifc.vertUserSize = 4;
106         ifc.edgeUserSize = 8;
107         ifc.faceUserSize = 4;
108         ifc.vertDataSize= 12;
109         ifc.vertDataZero= _subsurfNew_meshIFC_vertDataZero;
110         ifc.vertDataEqual= _subsurfNew_meshIFC_vertDataEqual;
111         ifc.vertDataCopy= _subsurfNew_meshIFC_vertDataCopy;
112         ifc.vertDataAdd= _subsurfNew_meshIFC_vertDataAdd;
113         ifc.vertDataSub= _subsurfNew_meshIFC_vertDataSub;
114         ifc.vertDataMulN= _subsurfNew_meshIFC_vertDataMulN;
115         ifc.vertDataAvg4= _subsurfNew_meshIFC_ifc_vertDataAvg4;
116
117         allocatorIFC.alloc = arena_alloc;
118         allocatorIFC.realloc = arena_realloc;
119         allocatorIFC.free = arena_free;
120         allocatorIFC.release = arena_release;
121         allocatorIFCp = &allocatorIFC;
122         allocator = BLI_memarena_new((1<<16));
123
124         return ccgSubSurf_new(&ifc, ss, subdivLevels, allocatorIFCp, allocator);
125 }
126
127 static SubSurf *subSurf_fromEditmesh(EditMesh *em, int subdivLevels) {
128         SubSurf *ss= MEM_mallocN(sizeof(*ss), "ss");
129
130         ss->controlType= SUBSURF_CONTROLTYPE_EDITMESH;
131         ss->subSurf= _getSubSurf(ss, subdivLevels);
132         ss->em = em;
133
134         return ss;
135 }
136
137 static SubSurf *subSurf_fromMesh(Mesh *me, int subdivLevels) {
138         SubSurf *ss= MEM_mallocN(sizeof(*ss), "ss");
139
140         ss->controlType= SUBSURF_CONTROLTYPE_MESH;
141         ss->subSurf= _getSubSurf(ss, subdivLevels);
142         ss->me= me;
143
144         ccgSubSurf_setAllowEdgeCreation(ss->subSurf, 1);
145
146         return ss;
147 }
148
149 static void subSurf_free(SubSurf *ss) {
150         ccgSubSurf_free(ss->subSurf);
151         MEM_freeN(ss);
152 }
153
154 static void Vec3Cpy(float *t, float *a) {
155         t[0]= a[0];
156         t[1]= a[1];
157         t[2]= a[2];
158 }
159
160 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
161         CCGVert *v0 = ccgSubSurf_getEdgeVert0(ss, e);
162         CCGVert *v1 = ccgSubSurf_getEdgeVert1(ss, e);
163         int v0idx = *((int*) ccgSubSurf_getVertUserData(ss, v0));
164         int v1idx = *((int*) ccgSubSurf_getVertUserData(ss, v1));
165         int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
166
167         if (x==0) {
168                 return v0idx;
169         } else if (x==edgeSize-1) {
170                 return v1idx;
171         } else {
172                 return edgeBase + x-1;
173         }
174 }
175 static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) {
176         int faceBase = *((int*) ccgSubSurf_getFaceUserData(ss, f));
177         int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
178
179         if (x==gridSize-1 && y==gridSize-1) {
180                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
181                 return *((int*) ccgSubSurf_getVertUserData(ss, v));
182         } else if (x==gridSize-1) {
183                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
184                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S);
185                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
186                 if (v==ccgSubSurf_getEdgeVert0(ss, e)) {
187                         return edgeBase + (gridSize-1-y)-1;
188                 } else {
189                         return edgeBase + (edgeSize-2-1)-((gridSize-1-y)-1);
190                 }
191         } else if (y==gridSize-1) {
192                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
193                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts);
194                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
195                 if (v==ccgSubSurf_getEdgeVert0(ss, e)) {
196                         return edgeBase + (gridSize-1-x)-1;
197                 } else {
198                         return edgeBase + (edgeSize-2-1)-((gridSize-1-x)-1);
199                 }
200         } else if (x==0 && y==0) {
201                 return faceBase;
202         } else if (x==0) {
203                 S = (S+numVerts-1)%numVerts;
204                 return faceBase + 1 + (gridSize-2)*S + (y-1);
205         } else if (y==0) {
206                 return faceBase + 1 + (gridSize-2)*S + (x-1);
207         } else {
208                 return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1);
209         }
210 }
211 static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm, int doOptEdges) {
212         CCGSubSurf *ss= ssm->subSurf;
213         DispListMesh *dlm= MEM_callocN(sizeof(*dlm), "dlm");
214         int edgeSize= ccgSubSurf_getEdgeSize(ss);
215         int gridSize= ccgSubSurf_getGridSize(ss);
216         int edgeIndexBase, edgeBase, faceIndexBase, faceBase;
217         int i, j, k, S, x, y;
218         int vertBase= 0;
219         MFace *mf;
220         CCGVertIterator *vi;
221         CCGEdgeIterator *ei;
222         CCGFaceIterator *fi;
223         
224         if (doOptEdges) {
225                 dlm->flag= ME_OPT_EDGES;
226         } else {
227                 dlm->flag= 0;
228         }
229
230         dlm->totvert= ccgSubSurf_getNumFinalVerts(ss);
231         dlm->totedge= ccgSubSurf_getNumFinalEdges(ss);
232         dlm->totface= ccgSubSurf_getNumFinalFaces(ss);
233
234         dlm->mvert= MEM_callocN(dlm->totvert*sizeof(*dlm->mvert), "dlm->mvert");
235         dlm->medge= MEM_callocN(dlm->totedge*sizeof(*dlm->medge), "dlm->medge");
236         dlm->mface= MEM_callocN(dlm->totface*sizeof(*dlm->mface), "dlm->mface");
237         if (ssm->controlType==SUBSURF_CONTROLTYPE_EDITMESH) {
238                 dlm->editedge= MEM_callocN(dlm->totedge*sizeof(EditEdge *), "dlm->editface");
239                 dlm->editface= MEM_mallocN(dlm->totface*sizeof(EditFace *), "dlm->editedge");
240         }
241         if ((ssm->controlType==SUBSURF_CONTROLTYPE_MESH) && ssm->me->tface) {
242                 dlm->tface= MEM_callocN(dlm->totface*sizeof(*dlm->tface), "dlm->tface");
243                 dlm->mcol= NULL;
244         } else if ((ssm->controlType==SUBSURF_CONTROLTYPE_MESH) && ssm->me->mcol) {
245                 dlm->tface= NULL;
246                 dlm->mcol= MEM_mallocN(dlm->totface*4*sizeof(*dlm->mcol), "dlm->mcol");
247         } else {
248                 dlm->tface= NULL;
249                 dlm->mcol= NULL;
250         }
251
252                 // load vertices
253
254         vertBase = i = 0;
255         vi= ccgSubSurf_getVertIterator(ss);
256         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
257                 CCGVert *v = ccgVertIterator_getCurrent(vi);
258                 Vec3Cpy(dlm->mvert[i].co, ccgSubSurf_getVertData(ss, v));
259
260                 if (ssm->controlType==SUBSURF_CONTROLTYPE_EDITMESH) {
261                         EditVert *ev = ccgSubSurf_getVertVertHandle(ss, v);
262                         
263                         ev->ssco = dlm->mvert[i].co;
264                 }
265
266                 *((int*) ccgSubSurf_getVertUserData(ss, v)) = i++;
267         }
268         ccgVertIterator_free(vi);
269
270         edgeIndexBase = edgeBase = i;
271         ei= ccgSubSurf_getEdgeIterator(ss);
272         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
273                 CCGEdge *e= ccgEdgeIterator_getCurrent(ei);
274                 int x;
275
276                 for (x=1; x<edgeSize-1; x++) {
277                         Vec3Cpy(dlm->mvert[i++].co, ccgSubSurf_getEdgeData(ss, e, x));
278                 }
279
280                 *((int*) ccgSubSurf_getEdgeUserData(ss, e)) = edgeBase;
281                 edgeBase += edgeSize-2;
282         }
283         ccgEdgeIterator_free(ei);
284
285         faceIndexBase = faceBase = i;
286         fi= ccgSubSurf_getFaceIterator(ss);
287         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
288                 CCGFace *f= ccgFaceIterator_getCurrent(fi);
289                 int x, y, S, numVerts= ccgSubSurf_getFaceNumVerts(ss, f);
290
291                 Vec3Cpy(dlm->mvert[i++].co, ccgSubSurf_getFaceCenterData(ss, f));
292                 
293                 for (S=0; S<numVerts; S++) {
294                         for (x=1; x<gridSize-1; x++) {
295                                 Vec3Cpy(dlm->mvert[i++].co, ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
296                         }
297                 }
298
299                 for (S=0; S<numVerts; S++) {
300                         for (y=1; y<gridSize-1; y++) {
301                                 for (x=1; x<gridSize-1; x++) {
302                                         Vec3Cpy(dlm->mvert[i++].co, ccgSubSurf_getFaceGridData(ss, f, S, x, y));
303                                 }
304                         }
305                 }
306
307                 *((int*) ccgSubSurf_getFaceUserData(ss, f)) = faceBase;
308                 faceBase += 1 + numVerts*((gridSize-2) + (gridSize-2)*(gridSize-2));
309         }
310         ccgFaceIterator_free(fi);
311
312                 // load edges
313
314         i=0;
315         ei= ccgSubSurf_getEdgeIterator(ss);
316         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
317                 CCGEdge *e= ccgEdgeIterator_getCurrent(ei);
318                 for (x=0; x<edgeSize-1; x++) {
319                         MEdge *med= &dlm->medge[i];
320                         med->v1= getEdgeIndex(ss, e, x, edgeSize);
321                         med->v2= getEdgeIndex(ss, e, x+1, edgeSize);
322                         med->flag = ME_EDGEDRAW;
323
324                         if (ssm->controlType==SUBSURF_CONTROLTYPE_EDITMESH) {
325                                 EditEdge *ee = ccgSubSurf_getEdgeEdgeHandle(ss, e);
326
327                                 dlm->editedge[i] = ee;
328
329                                 if (ee->seam) {
330                                         med->flag |= ME_SEAM;
331                                 }
332                         } else {
333                                 int edgeIdx = (int) ccgSubSurf_getEdgeEdgeHandle(ss, e);
334
335                                         /* Edges created by lib have handle of -1 */
336                                 if (edgeIdx!=-1 && ssm->me->medge) {
337                                         MEdge *origMed = &ssm->me->medge[edgeIdx];
338
339                                         med->flag |= (origMed->flag&ME_SEAM);
340                                 }
341                         }
342
343                         i++;
344                 }
345         }
346         ccgEdgeIterator_free(ei);
347
348         fi= ccgSubSurf_getFaceIterator(ss);
349         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
350                 CCGFace *f= ccgFaceIterator_getCurrent(fi);
351                 int numVerts= ccgSubSurf_getFaceNumVerts(ss, f);
352
353                 for (k=0; k<numVerts; k++) {
354                         for (x=0; x<gridSize-1; x++) {
355                                 MEdge *med= &dlm->medge[i];
356                                 med->v1= getFaceIndex(ss, f, k, x, 0, edgeSize, gridSize);
357                                 med->v2= getFaceIndex(ss, f, k, x+1, 0, edgeSize, gridSize);
358                                 i++;
359                         }
360
361                         for (x=1; x<gridSize-1; x++) {
362                                 for (y=0; y<gridSize-1; y++) {
363                                         MEdge *med;
364                                         
365                                         med= &dlm->medge[i];
366                                         med->v1= getFaceIndex(ss, f, k, x, y, edgeSize, gridSize);
367                                         med->v2= getFaceIndex(ss, f, k, x, y+1, edgeSize, gridSize);
368                                         i++;
369
370                                         med= &dlm->medge[i];
371                                         med->v1= getFaceIndex(ss, f, k, y, x, edgeSize, gridSize);
372                                         med->v2= getFaceIndex(ss, f, k, y+1, x, edgeSize, gridSize);
373                                         i++;
374                                 }
375                         }
376                 }
377         }
378         ccgFaceIterator_free(fi);
379
380                 // load faces
381
382         i= 0;
383         fi= ccgSubSurf_getFaceIterator(ss);
384         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
385                 CCGFace *f= ccgFaceIterator_getCurrent(fi);
386                 int numVerts= ccgSubSurf_getFaceNumVerts(ss, f);
387                 float edge_data[4][6];
388                 float corner_data[4][6];
389                 float center_data[6]= {0};
390                 int numDataComponents;
391                 TFace *origTFace= NULL;
392                 MCol *origMCol= NULL;
393                 int mat_nr;
394                 int flag;
395
396                 if (ssm->controlType==SUBSURF_CONTROLTYPE_MESH) {
397                         int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
398                         MFace *origMFace= &((MFace*) ssm->me->mface)[origIdx];
399                         if (ssm->me->tface)
400                                 origTFace= &((TFace*)ssm->me->tface)[origIdx];
401                         if (ssm->me->mcol)
402                                 origMCol= &ssm->me->mcol[origIdx*4];
403                         mat_nr= origMFace->mat_nr;
404                         flag= origMFace->flag;
405                 } else {
406                         EditFace *ef= ccgSubSurf_getFaceFaceHandle(ss, f);
407                         mat_nr= ef->mat_nr;
408                         flag= ef->flag;
409                 }
410
411                 if (origTFace) {
412                         for (S=0; S<numVerts; S++) {
413                                 unsigned char *col= (unsigned char*) &origTFace->col[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                                 corner_data[S][4]= origTFace->uv[S][0];
419                                 corner_data[S][5]= origTFace->uv[S][1];
420                         }
421                         numDataComponents= 6;
422                 } else if (origMCol) {
423                         for (S=0; S<numVerts; S++) {
424                                 unsigned char *col= (unsigned char*) &origMCol[S];
425                                 corner_data[S][0]= col[0]/255.0f;
426                                 corner_data[S][1]= col[1]/255.0f;
427                                 corner_data[S][2]= col[2]/255.0f;
428                                 corner_data[S][3]= col[3]/255.0f;
429                         }
430                         numDataComponents= 4;
431                 } else {
432                         numDataComponents= 0;
433                 }
434
435                 for (S=0; S<numVerts; S++) {
436                         for (k=0; k<numDataComponents; k++) {
437                                 edge_data[S][k]= (corner_data[S][k] + corner_data[(S+1)%numVerts][k])*0.5f;
438                                 center_data[k]+= corner_data[S][k];
439                         }
440                 }
441                 for (k=0; k<numDataComponents; k++) {
442                         center_data[k]/= numVerts;
443                 }
444
445                 for (S=0; S<numVerts; S++) {
446                         int prevS= (S-1+numVerts)%numVerts;
447                         for (y=0; y<gridSize-1; y++) {
448                                 for (x=0; x<gridSize-1; x++) {
449                                         mf= &dlm->mface[i];
450                                         mf->v1= getFaceIndex(ss, f, S, x+0, y+1, edgeSize, gridSize);
451                                         mf->v2= getFaceIndex(ss, f, S, x+1, y+1, edgeSize, gridSize);
452                                         mf->v3= getFaceIndex(ss, f, S, x+1, y+0, edgeSize, gridSize);
453                                         mf->v4= getFaceIndex(ss, f, S, x+0, y+0, edgeSize, gridSize);
454                                         mf->mat_nr= mat_nr;
455                                         mf->flag= flag;
456                                         mf->edcode= 0;
457
458                                         if (ssm->controlType==SUBSURF_CONTROLTYPE_EDITMESH) {
459                                                 dlm->editface[i] = ccgSubSurf_getFaceFaceHandle(ss, f);
460                                         }
461
462                                         if (doOptEdges) {
463                                                 if (x+1==gridSize-1)
464                                                         mf->edcode|= ME_V2V3;
465                                                 if (y+1==gridSize-1)
466                                                         mf->edcode|= ME_V1V2;
467                                         }
468
469                                         for (j=0; j<4; j++) {
470                                                 int fx= x + (j==1||j==2);
471                                                 int fy= y + (j==0||j==1);
472                                                 float x_v= (float) fx/(gridSize-1);
473                                                 float y_v= (float) fy/(gridSize-1);
474                                                 float data[6];
475
476                                                 for (k=0; k<numDataComponents; k++) {
477                                                         data[k]= (center_data[k]*(1.0f-x_v) + edge_data[S][k]*x_v)*(1.0f-y_v) + 
478                                                                         (edge_data[prevS][k]*(1.0f-x_v) + corner_data[S][k]*x_v)*y_v;
479                                                 }
480
481                                                 if (dlm->tface) {
482                                                         TFace *tf= &dlm->tface[i];
483                                                         unsigned char col[4];
484                                                         col[0]= (int) (data[0]*255);
485                                                         col[1]= (int) (data[1]*255);
486                                                         col[2]= (int) (data[2]*255);
487                                                         col[3]= (int) (data[3]*255);
488                                                         tf->col[j]= *((unsigned int*) col);
489                                                         tf->uv[j][0]= data[4];
490                                                         tf->uv[j][1]= data[5];
491                                                 } else if (dlm->mcol) {
492                                                         unsigned char *col= (unsigned char*) &dlm->mcol[i*4+j];
493                                                         col[0]= (int) (data[0]*255);
494                                                         col[1]= (int) (data[1]*255);
495                                                         col[2]= (int) (data[2]*255);
496                                                         col[3]= (int) (data[3]*255);
497                                                 }
498                                         }
499                                         if (dlm->tface) {
500                                                 TFace *tf= &dlm->tface[i];
501                                                 tf->tpage= origTFace->tpage;
502                                                 tf->flag= origTFace->flag;
503                                                 tf->transp= origTFace->transp;
504                                                 tf->mode= origTFace->mode;
505                                                 tf->tile= origTFace->tile;
506                                         }
507
508                                         i++;
509                                 }
510                         }
511                 }
512         }
513         ccgFaceIterator_free(fi);
514
515         displistmesh_calc_normals(dlm);
516
517         return dlm;
518 }
519
520 static void subSurf_sync(SubSurf *ss) {
521         float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss->subSurf);
522
523         ccgSubSurf_initFullSync(ss->subSurf);
524
525         if (ss->controlType==SUBSURF_CONTROLTYPE_MESH) {
526                 int i, fVerts[4];
527
528                 for (i=0; i<ss->me->totvert; i++) {
529                         ccgSubSurf_syncVert(ss->subSurf, (CCGVertHDL) i, ss->me->mvert[i].co);
530                 }
531
532                 if (ss->me->medge) {
533                         for (i=0; i<ss->me->totedge; i++) {
534                                 MEdge *med = &ss->me->medge[i];
535
536                                 ccgSubSurf_syncEdge(ss->subSurf, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2);
537
538 #ifdef USE_CREASING
539                                 {
540                                         CCGEdge *e = ccgSubSurf_getEdge(ss->subSurf, (CCGEdgeHDL) i);
541                                         float *userData = ccgSubSurf_getEdgeUserData(ss->subSurf, e);
542
543                                         userData[1] = med->crease*creaseFactor/255.0f;
544                                 }
545 #endif
546                         }
547                 } else {
548                         for (i=0; i<ss->me->totface; i++) {
549                                 MFace *mf = &((MFace*) ss->me->mface)[i];
550
551                                 if (!mf->v3) {
552                                         ccgSubSurf_syncEdge(ss->subSurf, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2);
553                                 }
554                         }
555                 }
556
557                 for (i=0; i<ss->me->totface; i++) {
558                         MFace *mf = &((MFace*) ss->me->mface)[i];
559
560                         if (mf->v3) {
561                                 fVerts[0] = mf->v1;
562                                 fVerts[1] = mf->v2;
563                                 fVerts[2] = mf->v3;
564                                 fVerts[3] = mf->v4;
565
566                                 ccgSubSurf_syncFace(ss->subSurf, (CCGFaceHDL) i, fVerts[3]?4:3, (CCGVertHDL*) fVerts);
567                         }
568                 }
569         } else {
570                 EditVert *ev, *fVerts[4];
571                 EditEdge *ee;
572                 EditFace *ef;
573
574                 for (ev=ss->em->verts.first; ev; ev=ev->next) {
575                         ccgSubSurf_syncVert(ss->subSurf, ev, ev->co);
576                 }
577
578                 for (ee=ss->em->edges.first; ee; ee=ee->next) {
579                         ccgSubSurf_syncEdge(ss->subSurf, ee, ee->v1, ee->v2);
580
581 #ifdef USE_CREASING
582                         {
583                                 CCGEdge *e = ccgSubSurf_getEdge(ss->subSurf, ee);
584                                 float *userData = ccgSubSurf_getEdgeUserData(ss->subSurf, e);
585
586                                 userData[1] = ee->crease*creaseFactor;
587                         }
588 #endif
589                 }
590
591                 for (ef=ss->em->faces.first; ef; ef=ef->next) {
592                         fVerts[0] = ef->v1;
593                         fVerts[1] = ef->v2;
594                         fVerts[2] = ef->v3;
595                         fVerts[3] = ef->v4;
596
597                         ccgSubSurf_syncFace(ss->subSurf, ef, ef->v4?4:3, (CCGVertHDL*) fVerts);
598                 }
599         }
600
601         ccgSubSurf_processSync(ss->subSurf);
602 }
603
604 DispListMesh *subsurf_ccg_make_dispListMesh_from_editmesh(EditMesh *em, int subdivLevels, int flags) {
605         SubSurf *ss= subSurf_fromEditmesh(em, subdivLevels);
606         DispListMesh *dlm;
607
608         subSurf_sync(ss);
609
610         dlm= subSurf_createDispListMesh(ss, (flags&ME_OPT_EDGES)?1:0);
611
612         subSurf_free(ss);
613
614         return dlm;
615 }
616
617 DispListMesh *subsurf_ccg_make_dispListMesh_from_mesh(Mesh *me, int subdivLevels, int flags) {
618         SubSurf *ss= subSurf_fromMesh(me, subdivLevels);
619         DispListMesh *dlm;
620
621         subSurf_sync(ss);
622
623         dlm= subSurf_createDispListMesh(ss, (flags&ME_OPT_EDGES)?1:0);
624         
625         subSurf_free(ss);
626         
627         return dlm;
628 }
629
630 #endif