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