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