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