Warning fix in subsurf_ccg.c. Also changed subsurf UV vertex and edge
[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 <float.h>
38
39 #include "MEM_guardedalloc.h"
40
41 #include "DNA_mesh_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_modifier_types.h"
44 #include "DNA_object_types.h"
45
46 #include "BKE_bad_level_calls.h"
47 #include "BKE_utildefines.h"
48 #include "BKE_global.h"
49 #include "BKE_mesh.h"
50 #include "BKE_subsurf.h"
51 #include "BKE_displist.h"
52 #include "BKE_DerivedMesh.h"
53
54 #include "BLI_blenlib.h"
55 #include "BLI_editVert.h"
56 #include "BLI_arithb.h"
57 #include "BLI_linklist.h"
58 #include "BLI_memarena.h"
59 #include "BLI_edgehash.h"
60
61 #include "BIF_gl.h"
62
63 #include "CCGSubSurf.h"
64
65 typedef struct _VertData {
66         float co[3];
67         float no[3];
68 } VertData;
69
70 struct CCGDerivedMesh {
71         DerivedMesh dm;
72
73         CCGSubSurf *ss;
74         int fromEditmesh, drawInteriorEdges, useSubsurfUv;
75
76         Mesh *me;
77         DispListMesh *dlm;
78 };
79
80 typedef struct CCGDerivedMesh CCGDerivedMesh;
81
82 static int ccgDM_getVertMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGVert *v);
83 static int ccgDM_getEdgeMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGEdge *e);
84 static int ccgDM_getFaceMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGFace *f);
85
86 ///
87
88 static void *arena_alloc(CCGAllocatorHDL a, int numBytes) {
89         return BLI_memarena_alloc(a, numBytes);
90 }
91 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) {
92         void *p2 = BLI_memarena_alloc(a, newSize);
93         if (ptr) {
94                 memcpy(p2, ptr, oldSize);
95         }
96         return p2;
97 }
98 static void arena_free(CCGAllocatorHDL a, void *ptr) {
99 }
100 static void arena_release(CCGAllocatorHDL a) {
101         BLI_memarena_free(a);
102 }
103
104 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int useFlatSubdiv) {
105         CCGMeshIFC ifc;
106         CCGSubSurf *ccgSS;
107
108                 /* subdivLevels==0 is not allowed */
109         subdivLevels = MAX2(subdivLevels, 1);
110
111         if (prevSS) {
112                 int oldUseAging;
113
114                 useAging = !!useAging;
115                 ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
116
117                 if (oldUseAging!=useAging) {
118                         ccgSubSurf_free(prevSS);
119                 } else {
120                         ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
121
122                         return prevSS;
123                 }
124         }
125
126         if (useAging) {
127                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
128         } else {
129                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
130         }
131         ifc.vertDataSize = sizeof(VertData);
132
133         if (useArena) {
134                 CCGAllocatorIFC allocatorIFC;
135                 CCGAllocatorHDL allocator = BLI_memarena_new((1<<16));
136
137                 allocatorIFC.alloc = arena_alloc;
138                 allocatorIFC.realloc = arena_realloc;
139                 allocatorIFC.free = arena_free;
140                 allocatorIFC.release = arena_release;
141
142                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
143         } else {
144                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
145         }
146
147         if (useAging) {
148                 ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
149         }
150
151         ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(VertData, no));
152
153         return ccgSS;
154 }
155
156 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
157         CCGVert *v0 = ccgSubSurf_getEdgeVert0(ss, e);
158         CCGVert *v1 = ccgSubSurf_getEdgeVert1(ss, e);
159         int v0idx = *((int*) ccgSubSurf_getVertUserData(ss, v0));
160         int v1idx = *((int*) ccgSubSurf_getVertUserData(ss, v1));
161         int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
162
163         if (x==0) {
164                 return v0idx;
165         } else if (x==edgeSize-1) {
166                 return v1idx;
167         } else {
168                 return edgeBase + x-1;
169         }
170 }
171 static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) {
172         int faceBase = *((int*) ccgSubSurf_getFaceUserData(ss, f));
173         int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
174
175         if (x==gridSize-1 && y==gridSize-1) {
176                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
177                 return *((int*) ccgSubSurf_getVertUserData(ss, v));
178         } else if (x==gridSize-1) {
179                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
180                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S);
181                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
182                 if (v==ccgSubSurf_getEdgeVert0(ss, e)) {
183                         return edgeBase + (gridSize-1-y)-1;
184                 } else {
185                         return edgeBase + (edgeSize-2-1)-((gridSize-1-y)-1);
186                 }
187         } else if (y==gridSize-1) {
188                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
189                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts);
190                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
191                 if (v==ccgSubSurf_getEdgeVert0(ss, e)) {
192                         return edgeBase + (gridSize-1-x)-1;
193                 } else {
194                         return edgeBase + (edgeSize-2-1)-((gridSize-1-x)-1);
195                 }
196         } else if (x==0 && y==0) {
197                 return faceBase;
198         } else if (x==0) {
199                 S = (S+numVerts-1)%numVerts;
200                 return faceBase + 1 + (gridSize-2)*S + (y-1);
201         } else if (y==0) {
202                 return faceBase + 1 + (gridSize-2)*S + (x-1);
203         } else {
204                 return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1);
205         }
206 }
207
208 static float *getFaceUV(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize)
209 {
210         int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
211
212         if (x==gridSize-1 && y==gridSize-1) {
213                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
214                 return ccgSubSurf_getVertData(ss, v);
215         }
216         else if (x==gridSize-1) {
217                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
218                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S);
219
220                 if (v==ccgSubSurf_getEdgeVert0(ss, e))
221                         return ccgSubSurf_getEdgeData(ss, e, gridSize-1-y);
222                 else
223                         return ccgSubSurf_getEdgeData(ss, e, (edgeSize-2-1)-(gridSize-1-y-2));
224         }
225         else if (y==gridSize-1) {
226                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
227                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts);
228
229                 if (v==ccgSubSurf_getEdgeVert0(ss, e))
230                         return ccgSubSurf_getEdgeData(ss, e, gridSize-1-x);
231                 else
232                         return ccgSubSurf_getEdgeData(ss, e, (edgeSize-2-1)-(gridSize-1-x-2));
233         }
234         else if (x==0 && y==0)
235                 return ccgSubSurf_getFaceCenterData(ss, f);
236         else if (x==0)
237                 return ccgSubSurf_getFaceGridEdgeData(ss, f, (S+numVerts-1)%numVerts, y);
238         else if (y==0)
239                 return ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
240         else
241                 return ccgSubSurf_getFaceGridData(ss, f, S, x, y);
242 }
243
244 static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCGVertHDL *fverts) {
245         unsigned int *fv = &mf->v1;
246         UvMapVert *v, *nv;
247         int j, nverts= mf->v4? 4: 3;
248
249         for (j=0; j<nverts; j++, fv++) {
250                 for (nv=v=get_uv_map_vert(vmap, *fv); v; v=v->next) {
251                         if (v->separate)
252                                 nv= v;
253                         if (v->f == fi)
254                                 break;
255                 }
256
257                 fverts[j]= (CCGVertHDL)(nv->f*4 + nv->tfindex);
258         }
259 }
260
261 static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, Mesh *me, DispListMesh *dlm) {
262         MFace *mface = dlm?dlm->mface:me->mface;
263         TFace *tface = dlm?dlm->tface:me->tface;
264         MVert *mvert = dlm?dlm->mvert:me->mvert;
265         int totvert = dlm?dlm->totvert:me->totvert;
266         int totface = dlm?dlm->totface:me->totface;
267         int i, j, seam;
268         UvMapVert *v;
269         UvVertMap *vmap;
270         float limit[2];
271         CCGVertHDL fverts[4];
272         EdgeHash *ehash;
273         float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
274
275         limit[0]= limit[1]= 0.0001f;
276         vmap= make_uv_vert_map(mface, tface, totface, totvert, 0, limit);
277         if (!vmap)
278                 return 0;
279         
280         ccgSubSurf_initFullSync(ss);
281
282         /* create vertices */
283         for (i=0; i<totvert; i++) {
284                 if (!get_uv_map_vert(vmap, i))
285                         continue;
286
287                 for (v=get_uv_map_vert(vmap, i)->next; v; v=v->next)
288                         if (v->separate)
289                                 break;
290
291                 seam = (v != NULL) || ((mvert+i)->flag & ME_VERT_MERGED);
292
293                 for (v=get_uv_map_vert(vmap, i); v; v=v->next) {
294                         if (v->separate) {
295                                 CCGVert *ssv;
296                                 CCGVertHDL vhdl = (CCGVertHDL)(v->f*4 + v->tfindex);
297                                 float uv[3];
298
299                                 uv[0]= (tface+v->f)->uv[v->tfindex][0];
300                                 uv[1]= (tface+v->f)->uv[v->tfindex][1];
301                                 uv[2]= 0.0f;
302
303                                 ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
304                         }
305                 }
306         }
307
308         /* create edges */
309         ehash = BLI_edgehash_new();
310
311         for (i=0; i<totface; i++) {
312                 MFace *mf = &((MFace*) mface)[i];
313                 int nverts= mf->v4? 4: 3;
314                 CCGFace *origf= ccgSubSurf_getFace(origss, (CCGFaceHDL)i);
315                 unsigned int *fv = &mf->v1;
316
317                 get_face_uv_map_vert(vmap, mf, i, fverts);
318
319                 for (j=0; j<nverts; j++) {
320                         int v0 = (int)fverts[j];
321                         int v1 = (int)fverts[(j+1)%nverts];
322                         MVert *mv0 = mvert + *(fv+j);
323                         MVert *mv1 = mvert + *(fv+((j+1)%nverts));
324
325                         if (!BLI_edgehash_haskey(ehash, v0, v1)) {
326                                 CCGEdge *e, *orige= ccgSubSurf_getFaceEdge(origss, origf, j);
327                                 CCGEdgeHDL ehdl= (CCGEdgeHDL)(i*4 + j);
328                                 float crease;
329
330                                 if ((mv0->flag&mv1->flag) & ME_VERT_MERGED)
331                                         crease = creaseFactor;
332                                 else
333                                         crease = ccgSubSurf_getEdgeCrease(origss, orige);
334
335                                 ccgSubSurf_syncEdge(ss, ehdl, fverts[j], fverts[(j+1)%nverts], crease, &e);
336                                 BLI_edgehash_insert(ehash, v0, v1, NULL);
337                         }
338                 }
339         }
340
341         BLI_edgehash_free(ehash, NULL);
342
343         /* create faces */
344         for (i=0; i<totface; i++) {
345                 MFace *mf = &((MFace*) mface)[i];
346                 int nverts= mf->v4? 4: 3;
347                 CCGFace *f;
348
349                 get_face_uv_map_vert(vmap, mf, i, fverts);
350                 ccgSubSurf_syncFace(ss, (CCGFaceHDL)i, nverts, fverts, &f);
351         }
352
353         free_uv_vert_map(vmap);
354         ccgSubSurf_processSync(ss);
355
356         return 1;
357 }
358
359 #if 0
360 static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditmesh, DispListMesh *dlm, MEdge *medge, TFace *tface)
361 {
362         unsigned int flags = 0;
363         int N = ccgSubSurf_getEdgeNumFaces(ss, e);
364
365         if (!N) flags |= ME_LOOSEEDGE;
366
367         if (ssFromEditmesh) {
368                 EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(ss, e);
369
370                 flags |= ME_EDGEDRAW|ME_EDGERENDER;
371                 if (eed->seam) {
372                         flags |= ME_SEAM;
373                 }
374         } else {
375                 if (edgeIdx!=-1) {
376                         MEdge *origMed = &medge[edgeIdx];
377
378                         if (dlm) {
379                                 flags |= origMed->flag&~ME_EDGE_STEPINDEX;
380                         } else {
381                                 flags |= (origMed->flag&ME_SEAM)|ME_EDGEDRAW|ME_EDGERENDER;
382                         }
383                 }
384         }
385
386         return flags;
387 }
388 #endif
389
390 static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, int ssFromEditmesh, int drawInteriorEdges, int useSubsurfUv, Mesh *inMe, DispListMesh *inDLM) {
391         DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
392         int edgeSize = ccgSubSurf_getEdgeSize(ss);
393         int gridSize = ccgSubSurf_getGridSize(ss);
394         int edgeBase, faceBase;
395         int i, j, k, S, x, y, index, lastIndex;
396         int vertBase = 0;
397         TFace *tface = NULL;
398         MEdge *medge = NULL;
399         MFace *mface = NULL;
400         MCol *mcol = NULL;
401         CCGVertIterator *vi;
402         CCGEdgeIterator *ei;
403         CCGFaceIterator *fi;
404         CCGFace **faceMap2, **faceMap2Uv = NULL;
405         CCGEdge **edgeMap2;
406         CCGVert **vertMap2;
407         int totvert, totedge, totface;
408         CCGSubSurf *uvss= NULL;
409
410         totvert = ccgSubSurf_getNumVerts(ss);
411         vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
412         vi = ccgSubSurf_getVertIterator(ss);
413         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
414                 CCGVert *v = ccgVertIterator_getCurrent(vi);
415
416                 if (ssFromEditmesh) {
417                         vertMap2[ccgDM_getVertMapIndex(ccgdm,ss,v)] = v;
418                 } else {
419                         vertMap2[(int) ccgSubSurf_getVertVertHandle(ss, v)] = v;
420                 }
421         }
422         ccgVertIterator_free(vi);
423
424         totedge = ccgSubSurf_getNumEdges(ss);
425         edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
426         ei = ccgSubSurf_getEdgeIterator(ss);
427         for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
428                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
429
430                 if (ssFromEditmesh) {
431                         edgeMap2[ccgDM_getEdgeMapIndex(ccgdm,ss,e)] = e;
432                 } else {
433                         edgeMap2[(int) ccgSubSurf_getEdgeEdgeHandle(ss, e)] = e;
434                 }
435         }
436
437         totface = ccgSubSurf_getNumFaces(ss);
438         faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
439         fi = ccgSubSurf_getFaceIterator(ss);
440         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
441                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
442
443                 if (ssFromEditmesh) {
444                         faceMap2[ccgDM_getFaceMapIndex(ccgdm,ss,f)] = f;
445                 } else {
446                         faceMap2[(int) ccgSubSurf_getFaceFaceHandle(ss, f)] = f;
447                 }
448         }
449         ccgFaceIterator_free(fi);
450
451         if (!ssFromEditmesh) {
452                 if (inDLM) {
453                         tface = inDLM->tface;
454                         medge = inDLM->medge;
455                         mface = inDLM->mface;
456                         mcol = inDLM->mcol;
457                 } else if (inMe) {
458                         tface = inMe->tface;
459                         medge = inMe->medge;
460                         mface = inMe->mface;
461                         mcol = inMe->mcol;
462                 }
463         }
464
465         dlm->totvert = ccgSubSurf_getNumFinalVerts(ss);
466         dlm->totedge = ccgSubSurf_getNumFinalEdges(ss);
467         dlm->totface = ccgSubSurf_getNumFinalFaces(ss);
468
469         dlm->mvert = MEM_callocN(dlm->totvert*sizeof(*dlm->mvert), "dlm->mvert");
470         dlm->medge = MEM_callocN(dlm->totedge*sizeof(*dlm->medge), "dlm->medge");
471         dlm->mface = MEM_callocN(dlm->totface*sizeof(*dlm->mface), "dlm->mface");
472         if (!ssFromEditmesh && tface) {
473                 dlm->tface = MEM_callocN(dlm->totface*sizeof(*dlm->tface), "dlm->tface");
474                 dlm->mcol = NULL;
475         } else if (!ssFromEditmesh && mcol) {
476                 dlm->tface = NULL;
477                 dlm->mcol = MEM_mallocN(dlm->totface*4*sizeof(*dlm->mcol), "dlm->mcol");
478         } else {
479                 dlm->tface = NULL;
480                 dlm->mcol = NULL;
481         }
482
483         
484         if (useSubsurfUv && tface) {
485                 /* not for editmesh currently */
486                 uvss= _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0);
487
488                 if (ss_sync_from_uv(uvss, ss, inMe, inDLM)) {
489                         faceMap2Uv = MEM_mallocN(totface*sizeof(*faceMap2Uv), "facemapuv");
490
491                         fi = ccgSubSurf_getFaceIterator(uvss);
492                         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
493                                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
494                                 faceMap2Uv[(int) ccgSubSurf_getFaceFaceHandle(uvss, f)] = f;
495                         }
496                         ccgFaceIterator_free(fi);
497                 }
498         }
499
500                 /* Load vertices... we do in this funny order because 
501                  * all "added" vertices" are required to appear first 
502                  * in the displist (before STEPINDEX flags start). Also
503                  * note that the vertex with index 0 is always a face
504                  * center vert, this is relied upon to ensure we don't
505                  * need to do silly test_index_face calls.
506                  */
507
508         faceBase = i = 0;
509         for (index=0; index<totface; index++) {
510                 CCGFace *f = faceMap2[index];
511                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
512
513                 VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getFaceCenterData(ss, f));
514                 
515                 for (S=0; S<numVerts; S++) {
516                         for (x=1; x<gridSize-1; x++) {
517                                 VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
518                         }
519                 }
520
521                 for (S=0; S<numVerts; S++) {
522                         for (y=1; y<gridSize-1; y++) {
523                                 for (x=1; x<gridSize-1; x++) {
524                                         VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getFaceGridData(ss, f, S, x, y));
525                                 }
526                         }
527                 }
528
529                 *((int*) ccgSubSurf_getFaceUserData(ss, f)) = faceBase;
530                 faceBase += 1 + numVerts*((gridSize-2) + (gridSize-2)*(gridSize-2));
531         }
532
533         edgeBase = i;
534         for (index=0; index<totedge; index++) {
535                 CCGEdge *e= edgeMap2[index];
536                 int x;
537
538                 for (x=1; x<edgeSize-1; x++) {
539                         VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getEdgeData(ss, e, x));
540                 }
541
542                 *((int*) ccgSubSurf_getEdgeUserData(ss, e)) = edgeBase;
543                 edgeBase += edgeSize-2;
544         }
545
546         vertBase = i;
547         lastIndex = -1;
548         for (index=0; index<totvert; index++) {
549                 CCGVert *v = vertMap2[index];
550                 int mapIndex = ccgDM_getVertMapIndex(ccgdm, ss, v);
551                 VecCopyf(dlm->mvert[i].co, ccgSubSurf_getVertData(ss, v));
552                 if (mapIndex!=lastIndex)
553                         dlm->mvert[i].flag = ME_VERT_STEPINDEX;
554                 *((int*) ccgSubSurf_getVertUserData(ss, v)) = i++;
555                 lastIndex = mapIndex;
556         }
557
558                 // load edges
559
560         i = 0;
561         for (index=0; index<totface; index++) {
562                 CCGFace *f = faceMap2[index];
563                 int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
564
565                 for (k=0; k<numVerts; k++) {
566                         for (x=0; x<gridSize-1; x++) {
567                                 MEdge *med = &dlm->medge[i];
568                                 if (drawInteriorEdges) med->flag = ME_EDGEDRAW|ME_EDGERENDER;
569                                 med->v1 = getFaceIndex(ss, f, k, x, 0, edgeSize, gridSize);
570                                 med->v2 = getFaceIndex(ss, f, k, x+1, 0, edgeSize, gridSize);
571                                 i++;
572                         }
573
574                         for (x=1; x<gridSize-1; x++) {
575                                 for (y=0; y<gridSize-1; y++) {
576                                         MEdge *med;
577                                         
578                                         med = &dlm->medge[i];
579                                         if (drawInteriorEdges) med->flag = ME_EDGEDRAW|ME_EDGERENDER;
580                                         med->v1 = getFaceIndex(ss, f, k, x, y, edgeSize, gridSize);
581                                         med->v2 = getFaceIndex(ss, f, k, x, y+1, edgeSize, gridSize);
582                                         i++;
583
584                                         med = &dlm->medge[i];
585                                         if (drawInteriorEdges) med->flag = ME_EDGEDRAW|ME_EDGERENDER;
586                                         med->v1 = getFaceIndex(ss, f, k, y, x, edgeSize, gridSize);
587                                         med->v2 = getFaceIndex(ss, f, k, y+1, x, edgeSize, gridSize);
588                                         i++;
589                                 }
590                         }
591                 }
592         }
593
594         lastIndex = -1;
595         for (index=0; index<totedge; index++) {
596                 CCGEdge *e= edgeMap2[index];
597                 int mapIndex = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
598                 int edgeStart = i;
599                 unsigned int flags = 0;
600
601                 if (!ccgSubSurf_getEdgeNumFaces(ss, e)) flags |= ME_LOOSEEDGE;
602
603                 if (ssFromEditmesh) {
604                         EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(ss, e);
605
606                         flags |= ME_EDGEDRAW|ME_EDGERENDER;
607                         if (eed->seam) {
608                                 flags |= ME_SEAM;
609                         }
610                 } else {
611                         int edgeIdx = (int) ccgSubSurf_getEdgeEdgeHandle(ss, e);
612
613                         if (edgeIdx!=-1) {
614                                 MEdge *origMed = &medge[edgeIdx];
615
616                                 if (inDLM) {
617                                         flags |= origMed->flag&~ME_EDGE_STEPINDEX;
618                                 } else {
619                                         flags |= (origMed->flag&ME_SEAM)|ME_EDGEDRAW|ME_EDGERENDER;
620                                 }
621                         }
622                 }
623
624                 for (x=0; x<edgeSize-1; x++) {
625                         MEdge *med = &dlm->medge[i];
626                         med->v1 = getEdgeIndex(ss, e, x, edgeSize);
627                         med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
628                         med->flag = flags;
629                         i++;
630                 }
631
632                 if (mapIndex!=lastIndex)
633                         dlm->medge[edgeStart].flag |= ME_EDGE_STEPINDEX;
634                 lastIndex = mapIndex;
635         }
636
637                 // load faces
638
639         i=0;
640         lastIndex = -1;
641         for (index=0; index<totface; index++) {
642                 CCGFace *f = faceMap2[index];
643                 CCGFace *uvf = faceMap2Uv? faceMap2Uv[index]: NULL;
644                 int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
645                 float edge_data[4][6];
646                 float corner_data[4][6];
647                 float center_data[6] = {0};
648                 int numDataComponents = 0;
649                 TFace *origTFace = NULL;
650                 int mat_nr;
651                 int flag;
652                 int mapIndex = ccgDM_getFaceMapIndex(ccgdm, ss, f);
653
654                 if (!ssFromEditmesh) {
655                         int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
656                         MFace *origMFace = &mface[origIdx];
657                         
658                         if (tface) {
659                                 origTFace = &tface[origIdx];
660
661                                 for (S=0; S<numVerts; S++) {
662                                         unsigned char *col = (unsigned char*) &origTFace->col[S];
663                                         corner_data[S][0] = col[0]/255.0f;
664                                         corner_data[S][1] = col[1]/255.0f;
665                                         corner_data[S][2] = col[2]/255.0f;
666                                         corner_data[S][3] = col[3]/255.0f;
667                                         if (!uvf) {
668                                                 corner_data[S][4] = origTFace->uv[S][0];
669                                                 corner_data[S][5] = origTFace->uv[S][1];
670                                         }
671                                 }
672                                 numDataComponents = uvf? 4: 6;
673                         } else if (mcol) {
674                                 MCol *origMCol = &mcol[origIdx*4];
675
676                                 for (S=0; S<numVerts; S++) {
677                                         unsigned char *col = (unsigned char*) &origMCol[S];
678                                         corner_data[S][0] = col[0]/255.0f;
679                                         corner_data[S][1] = col[1]/255.0f;
680                                         corner_data[S][2] = col[2]/255.0f;
681                                         corner_data[S][3] = col[3]/255.0f;
682                                 }
683                                 numDataComponents = 4;
684                         }
685
686                         for (S=0; S<numVerts; S++) {
687                                 for (k=0; k<numDataComponents; k++) {
688                                         edge_data[S][k] = (corner_data[S][k] + corner_data[(S+1)%numVerts][k])*0.5f;
689                                         center_data[k]+= corner_data[S][k];
690                                 }
691                         }
692                         for (k=0; k<numDataComponents; k++) {
693                                 center_data[k]/= numVerts;
694                         }
695
696                         mat_nr = origMFace->mat_nr;
697                         flag = origMFace->flag;
698                 } else {
699                         EditFace *ef = ccgSubSurf_getFaceFaceHandle(ss, f);
700                         mat_nr = ef->mat_nr;
701                         flag = ef->flag;
702                 }
703
704                 for (S=0; S<numVerts; S++) {
705                         int prevS= (S-1+numVerts)%numVerts;
706
707                         for (y=0; y<gridSize-1; y++) {
708                                 for (x=0; x<gridSize-1; x++) {
709                                         float smoothuv[4][3];
710
711                                         MFace *mf = &dlm->mface[i];
712                                         mf->v1 = getFaceIndex(ss, f, S, x+0, y+0, edgeSize, gridSize);
713                                         mf->v2 = getFaceIndex(ss, f, S, x+0, y+1, edgeSize, gridSize);
714                                         mf->v3 = getFaceIndex(ss, f, S, x+1, y+1, edgeSize, gridSize);
715                                         mf->v4 = getFaceIndex(ss, f, S, x+1, y+0, edgeSize, gridSize);
716                                         mf->mat_nr = mat_nr;
717                                         mf->flag = flag&~ME_FACE_STEPINDEX;
718
719                                         if(uvf) {
720                                                 VECCOPY(smoothuv[0], getFaceUV(uvss, uvf, S, x+0, y+0, edgeSize, gridSize));
721                                                 VECCOPY(smoothuv[1], getFaceUV(uvss, uvf, S, x+0, y+1, edgeSize, gridSize));
722                                                 VECCOPY(smoothuv[2], getFaceUV(uvss, uvf, S, x+1, y+1, edgeSize, gridSize));
723                                                 VECCOPY(smoothuv[3], getFaceUV(uvss, uvf, S, x+1, y+0, edgeSize, gridSize));
724                                         }
725
726                                         if (S==0 && x==0 && y==0) {
727                                                 if (mapIndex!=lastIndex)
728                                                         mf->flag |= ME_FACE_STEPINDEX;
729                                                 lastIndex = mapIndex;
730                                         }
731
732                                         for (j=0; j<4; j++) {
733                                                 int fx = x + (j==2||j==3);
734                                                 int fy = y + (j==1||j==2);
735                                                 float x_v = (float) fx/(gridSize-1);
736                                                 float y_v = (float) fy/(gridSize-1);
737                                                 float data[6];
738
739                                                 for (k=0; k<numDataComponents; k++) {
740                                                         data[k] = (center_data[k]*(1.0f-x_v) + edge_data[S][k]*x_v)*(1.0f-y_v) + 
741                                                                         (edge_data[prevS][k]*(1.0f-x_v) + corner_data[S][k]*x_v)*y_v;
742                                                 }
743
744                                                 if (dlm->tface) {
745                                                         TFace *tf = &dlm->tface[i];
746                                                         unsigned char col[4];
747                                                         col[0] = (int) (data[0]*255);
748                                                         col[1] = (int) (data[1]*255);
749                                                         col[2] = (int) (data[2]*255);
750                                                         col[3] = (int) (data[3]*255);
751                                                         tf->col[j] = *((unsigned int*) col);
752                                                         if (uvf) {
753                                                                 tf->uv[j][0] = smoothuv[j][0];
754                                                                 tf->uv[j][1] = smoothuv[j][1];
755                                                         }
756                                                         else {
757                                                                 tf->uv[j][0] = (float)(data[4]);
758                                                                 tf->uv[j][1] = (float)(data[5]);
759                                                         }
760                                                 } else if (dlm->mcol) {
761                                                         unsigned char *col = (unsigned char*) &dlm->mcol[i*4+j];
762                                                         col[0] = (int) (data[0]*255);
763                                                         col[1] = (int) (data[1]*255);
764                                                         col[2] = (int) (data[2]*255);
765                                                         col[3] = (int) (data[3]*255);
766                                                 }
767                                         }
768
769                                         if (dlm->tface) {
770                                                 TFace *tf = &dlm->tface[i];
771                                                 tf->tpage = origTFace->tpage;
772                                                 tf->flag = origTFace->flag;
773                                                 tf->transp = origTFace->transp;
774                                                 tf->mode = origTFace->mode;
775                                                 tf->tile = origTFace->tile;
776                                         }
777
778                                         i++;
779                                 }
780                         }
781                 }
782         }
783
784         MEM_freeN(faceMap2);
785         MEM_freeN(edgeMap2);
786         MEM_freeN(vertMap2);
787
788         if(uvss) {
789                 ccgSubSurf_free(uvss);
790                 MEM_freeN(faceMap2Uv);
791         }
792
793         mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
794
795         return dlm;
796 }
797
798 static void ss_sync_from_mesh(CCGSubSurf *ss, Mesh *me, DispListMesh *dlm, float (*vertexCos)[3], int useFlatSubdiv) {
799         float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
800         CCGVertHDL fVerts[4];
801         MVert *mvert = dlm?dlm->mvert:me->mvert;
802         MEdge *medge = dlm?dlm->medge:me->medge;
803         MFace *mface = dlm?dlm->mface:me->mface;
804         int totvert = dlm?dlm->totvert:me->totvert;
805         int totedge = dlm?dlm->totedge:me->totedge;
806         int totface = dlm?dlm->totface:me->totface;
807         int i, index;
808
809         ccgSubSurf_initFullSync(ss);
810
811         for (i=0,index=-1; i<totvert; i++) {
812                 CCGVert *v;
813                 ccgSubSurf_syncVert(ss, (CCGVertHDL) i, vertexCos?vertexCos[i]:mvert[i].co, 0, &v);
814
815                 if (!dlm || (mvert[i].flag&ME_VERT_STEPINDEX)) index++;
816                 ((int*) ccgSubSurf_getVertUserData(ss, v))[1] = index;
817         }
818
819         if (medge) {
820                 for (i=0, index=-1; i<totedge; i++) {
821                         MEdge *med = &medge[i];
822                         CCGEdge *e;
823                         float crease = useFlatSubdiv?creaseFactor:med->crease*creaseFactor/255.0f;
824
825                         ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2, crease, &e);
826
827                         if (!dlm || (med->flag&ME_EDGE_STEPINDEX)) index++;
828                         ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1] = index;
829                 }
830         }
831
832         for (i=0, index=-1; i<totface; i++) {
833                 MFace *mf = &((MFace*) mface)[i];
834                 CCGFace *f;
835
836                 if (!dlm || (mf->flag&ME_FACE_STEPINDEX)) index++;
837
838                 fVerts[0] = (CCGVertHDL) mf->v1;
839                 fVerts[1] = (CCGVertHDL) mf->v2;
840                 fVerts[2] = (CCGVertHDL) mf->v3;
841                 fVerts[3] = (CCGVertHDL) mf->v4;
842
843                         // this is very bad, means mesh is internally consistent.
844                         // it is not really possible to continue without modifying
845                         // other parts of code significantly to handle missing faces.
846                         // since this really shouldn't even be possible we just bail.
847                 if (ccgSubSurf_syncFace(ss, (CCGFaceHDL) i, fVerts[3]?4:3, fVerts, &f)==eCCGError_InvalidValue) {
848                         static int hasGivenError = 0;
849
850                         if (!hasGivenError) {
851                                 if (!me) {
852                                         error("Unrecoverable error in SubSurf calculation, mesh is inconsistent.");
853                                 } else {
854                                         error("Unrecoverable error in SubSurf calculation, mesh(%s) is inconsistent.", me->id.name+2);
855                                 }
856
857                                 hasGivenError = 1;
858                         }
859
860                         return;
861                 }
862
863                 ((int*) ccgSubSurf_getFaceUserData(ss, f))[1] = index;
864         }
865
866         ccgSubSurf_processSync(ss);
867 }
868
869 void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, float (*vertCos)[3], int useFlatSubdiv)
870 {
871         float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
872         EditVert *ev, *fVerts[4];
873         EditEdge *ee;
874         EditFace *ef;
875         int i;
876
877         ccgSubSurf_initFullSync(ss);
878
879         if (vertCos) {
880                 for (i=0,ev=em->verts.first; ev; i++,ev=ev->next) {
881                         CCGVert *v;
882                         ccgSubSurf_syncVert(ss, ev, vertCos[i], 0, &v);
883                         ((int*) ccgSubSurf_getVertUserData(ss, v))[1] = i;
884                 }
885         } else {
886                 for (i=0,ev=em->verts.first; ev; i++,ev=ev->next) {
887                         CCGVert *v;
888                         ccgSubSurf_syncVert(ss, ev, ev->co, 0, &v);
889                         ((int*) ccgSubSurf_getVertUserData(ss, v))[1] = i;
890                 }
891         }
892
893         for (i=0,ee=em->edges.first; ee; i++,ee=ee->next) {
894                 CCGEdge *e;
895                 ccgSubSurf_syncEdge(ss, ee, ee->v1, ee->v2, useFlatSubdiv?creaseFactor:ee->crease*creaseFactor, &e);
896                 ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1] = i;
897         }
898
899         for (i=0,ef=em->faces.first; ef; i++,ef=ef->next) {
900                 CCGFace *f;
901
902                 fVerts[0] = ef->v1;
903                 fVerts[1] = ef->v2;
904                 fVerts[2] = ef->v3;
905                 fVerts[3] = ef->v4;
906
907                 ccgSubSurf_syncFace(ss, ef, ef->v4?4:3, (CCGVertHDL*) fVerts, &f);
908                 ((int*) ccgSubSurf_getFaceUserData(ss, f))[1] = i;
909         }
910
911         ccgSubSurf_processSync(ss);
912 }
913
914 /***/
915
916 static int ccgDM_getVertMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGVert *v) {
917         return ((int*) ccgSubSurf_getVertUserData(ss, v))[1];
918 }
919
920 static int ccgDM_getEdgeMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGEdge *e) {
921         return ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1];
922 }
923
924 static int ccgDM_getFaceMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGFace *f) {
925         return ((int*) ccgSubSurf_getFaceUserData(ss, f))[1];
926 }
927
928 static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
929         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
930         CCGSubSurf *ss = ccgdm->ss;
931         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
932         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
933         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
934         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
935         int gridSize = ccgSubSurf_getGridSize(ss);
936
937         if (!ccgSubSurf_getNumVerts(ss))
938                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
939
940         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
941                 CCGVert *v = ccgVertIterator_getCurrent(vi);
942                 float *co = ccgSubSurf_getVertData(ss, v);
943
944                 DO_MINMAX(co, min_r, max_r);
945         }
946
947         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
948                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
949                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
950
951                 for (i=0; i<edgeSize; i++)
952                         DO_MINMAX(edgeData[i].co, min_r, max_r);
953         }
954
955         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
956                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
957                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
958
959                 for (S=0; S<numVerts; S++) {
960                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
961
962                         for (y=0; y<gridSize; y++)
963                                 for (x=0; x<gridSize; x++)
964                                         DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r);
965                 }
966         }
967
968         ccgFaceIterator_free(fi);
969         ccgEdgeIterator_free(ei);
970         ccgVertIterator_free(vi);
971 }
972 static int ccgDM_getNumVerts(DerivedMesh *dm) {
973         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
974
975         return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
976 }
977 static int ccgDM_getNumFaces(DerivedMesh *dm) {
978         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
979
980         return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
981 }
982 static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
983         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
984         CCGSubSurf *ss = ccgdm->ss;
985         int edgeSize = ccgSubSurf_getEdgeSize(ss);
986         int gridSize = ccgSubSurf_getGridSize(ss);
987         int i;
988         CCGVertIterator *vi;
989         CCGEdgeIterator *ei;
990         CCGFaceIterator *fi;
991         CCGFace **faceMap2;
992         CCGEdge **edgeMap2;
993         CCGVert **vertMap2;
994         int index, totvert, totedge, totface;
995         
996         totvert = ccgSubSurf_getNumVerts(ss);
997         vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
998         vi = ccgSubSurf_getVertIterator(ss);
999         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1000                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1001
1002                 if (ccgdm->fromEditmesh) {
1003                         vertMap2[ccgDM_getVertMapIndex(ccgdm,ss,v)] = v;
1004                 } else {
1005                         vertMap2[(int) ccgSubSurf_getVertVertHandle(ss, v)] = v;
1006                 }
1007         }
1008         ccgVertIterator_free(vi);
1009
1010         totedge = ccgSubSurf_getNumEdges(ss);
1011         edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
1012         ei = ccgSubSurf_getEdgeIterator(ss);
1013         for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
1014                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1015
1016                 if (ccgdm->fromEditmesh) {
1017                         edgeMap2[ccgDM_getEdgeMapIndex(ccgdm,ss,e)] = e;
1018                 } else {
1019                         edgeMap2[(int) ccgSubSurf_getEdgeEdgeHandle(ss, e)] = e;
1020                 }
1021         }
1022
1023         totface = ccgSubSurf_getNumFaces(ss);
1024         faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
1025         fi = ccgSubSurf_getFaceIterator(ss);
1026         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1027                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1028
1029                 if (ccgdm->fromEditmesh) {
1030                         faceMap2[ccgDM_getFaceMapIndex(ccgdm,ss,f)] = f;
1031                 } else {
1032                         faceMap2[(int) ccgSubSurf_getFaceFaceHandle(ss, f)] = f;
1033                 }
1034         }
1035         ccgFaceIterator_free(fi);
1036
1037         i = 0;
1038         for (index=0; index<totface; index++) {
1039                 CCGFace *f = faceMap2[index];
1040                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1041
1042                 VecCopyf(cos[i++], ccgSubSurf_getFaceCenterData(ss, f));
1043                 
1044                 for (S=0; S<numVerts; S++) {
1045                         for (x=1; x<gridSize-1; x++) {
1046                                 VecCopyf(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1047                         }
1048                 }
1049
1050                 for (S=0; S<numVerts; S++) {
1051                         for (y=1; y<gridSize-1; y++) {
1052                                 for (x=1; x<gridSize-1; x++) {
1053                                         VecCopyf(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1054                                 }
1055                         }
1056                 }
1057         }
1058
1059         for (index=0; index<totedge; index++) {
1060                 CCGEdge *e= edgeMap2[index];
1061                 int x;
1062
1063                 for (x=1; x<edgeSize-1; x++) {
1064                         VecCopyf(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
1065                 }
1066         }
1067
1068         for (index=0; index<totvert; index++) {
1069                 CCGVert *v = vertMap2[index];
1070                 VecCopyf(cos[i++], ccgSubSurf_getVertData(ss, v));
1071         }
1072
1073         MEM_freeN(vertMap2);
1074         MEM_freeN(edgeMap2);
1075         MEM_freeN(faceMap2);
1076 }
1077 static void ccgDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
1078         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1079         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
1080
1081         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1082                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1083                 VertData *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
1084                 int index = ccgDM_getVertMapIndex(ccgdm, ccgdm->ss, v);
1085
1086                 if (index!=-1)
1087                         func(userData, index, vd->co, vd->no, NULL);
1088         }
1089
1090         ccgVertIterator_free(vi);
1091 }
1092 static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
1093         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1094         CCGSubSurf *ss = ccgdm->ss;
1095         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1096         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1097
1098         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1099                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1100                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1101                 int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
1102
1103                 if (index!=-1) {
1104                         for (i=0; i<edgeSize-1; i++)
1105                                 func(userData, index, edgeData[i].co, edgeData[i+1].co);
1106                 }
1107         }
1108
1109         ccgEdgeIterator_free(ei);
1110 }
1111 static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm, int allowShared) {
1112         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1113
1114         return ss_to_displistmesh(ccgdm->ss, ccgdm, ccgdm->fromEditmesh, ccgdm->drawInteriorEdges, ccgdm->useSubsurfUv, ccgdm->me, ccgdm->dlm);
1115 }
1116
1117 static void ccgDM_drawVerts(DerivedMesh *dm) {
1118         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1119         CCGSubSurf *ss = ccgdm->ss;
1120         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1121         int gridSize = ccgSubSurf_getGridSize(ss);
1122         CCGVertIterator *vi;
1123         CCGEdgeIterator *ei;
1124         CCGFaceIterator *fi;
1125
1126         glBegin(GL_POINTS);
1127         vi = ccgSubSurf_getVertIterator(ss);
1128         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1129                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1130                 glVertex3fv(ccgSubSurf_getVertData(ss, v));
1131         }
1132         ccgVertIterator_free(vi);
1133
1134         ei = ccgSubSurf_getEdgeIterator(ss);
1135         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1136                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1137                 int x;
1138
1139                 for (x=1; x<edgeSize-1; x++)
1140                         glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
1141         }
1142         ccgEdgeIterator_free(ei);
1143
1144         fi = ccgSubSurf_getFaceIterator(ss);
1145         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1146                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1147                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1148
1149                 glVertex3fv(ccgSubSurf_getFaceCenterData(ss, f));
1150                 for (S=0; S<numVerts; S++)
1151                         for (x=1; x<gridSize-1; x++)
1152                                 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1153                 for (S=0; S<numVerts; S++)
1154                         for (y=1; y<gridSize-1; y++)
1155                                 for (x=1; x<gridSize-1; x++)
1156                                         glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1157         }
1158         ccgFaceIterator_free(fi);
1159         glEnd();
1160 }
1161 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) {
1162         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1163         CCGSubSurf *ss = ccgdm->ss;
1164         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1165         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1166         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1167         int gridSize = ccgSubSurf_getGridSize(ss);
1168         int useAging;
1169
1170         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1171
1172         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1173                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1174                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1175
1176                 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(ss, e))
1177                         continue;
1178
1179                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1180                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1181                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1182                 }
1183
1184                 glBegin(GL_LINE_STRIP);
1185                 for (i=0; i<edgeSize-1; i++) {
1186                         glVertex3fv(edgeData[i].co);
1187                         glVertex3fv(edgeData[i+1].co);
1188                 }
1189                 glEnd();
1190         }
1191
1192         if (useAging && !(G.f&G_BACKBUFSEL)) {
1193                 glColor3ub(0, 0, 0);
1194         }
1195
1196         if (ccgdm->drawInteriorEdges) {
1197                 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1198                         CCGFace *f = ccgFaceIterator_getCurrent(fi);
1199                         int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1200
1201                         for (S=0; S<numVerts; S++) {
1202                                 VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1203
1204                                 glBegin(GL_LINE_STRIP);
1205                                 for (x=0; x<gridSize; x++)
1206                                         glVertex3fv(faceGridData[x].co);
1207                                 glEnd();
1208                                 for (y=1; y<gridSize-1; y++) {
1209                                         glBegin(GL_LINE_STRIP);
1210                                         for (x=0; x<gridSize; x++)
1211                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1212                                         glEnd();
1213                                 }
1214                                 for (x=1; x<gridSize-1; x++) {
1215                                         glBegin(GL_LINE_STRIP);
1216                                         for (y=0; y<gridSize; y++)
1217                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1218                                         glEnd();
1219                                 }
1220                         }
1221                 }
1222         }
1223
1224         ccgFaceIterator_free(fi);
1225         ccgEdgeIterator_free(ei);
1226 }
1227 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
1228         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1229         CCGSubSurf *ss = ccgdm->ss;
1230         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1231         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1232
1233         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1234                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1235                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1236
1237                 if (!ccgSubSurf_getEdgeNumFaces(ss, e)) {
1238                         glBegin(GL_LINE_STRIP);
1239                         for (i=0; i<edgeSize-1; i++) {
1240                                 glVertex3fv(edgeData[i].co);
1241                                 glVertex3fv(edgeData[i+1].co);
1242                         }
1243                         glEnd();
1244                 }
1245         }
1246
1247         ccgEdgeIterator_free(ei);
1248 }
1249
1250         /* Only used by non-editmesh types */
1251 static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
1252         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1253         CCGSubSurf *ss = ccgdm->ss;
1254         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1255         int gridSize = ccgSubSurf_getGridSize(ss);
1256         MFace *mface = ccgdm->dlm?ccgdm->dlm->mface:ccgdm->me->mface;
1257
1258         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1259                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1260                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1261                 int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
1262                 MFace *mf = &mface[index];
1263                 
1264                 if (!setMaterial(mf->mat_nr+1))
1265                         continue;
1266
1267                 glShadeModel((mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT);
1268                 for (S=0; S<numVerts; S++) {
1269                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1270
1271                         if (mf->flag&ME_SMOOTH) {
1272                                 for (y=0; y<gridSize-1; y++) {
1273                                         glBegin(GL_QUAD_STRIP);
1274                                         for (x=0; x<gridSize; x++) {
1275                                                 VertData *a = &faceGridData[(y+0)*gridSize + x];
1276                                                 VertData *b = &faceGridData[(y+1)*gridSize + x];
1277
1278                                                 glNormal3fv(a->no);
1279                                                 glVertex3fv(a->co);
1280                                                 glNormal3fv(b->no);
1281                                                 glVertex3fv(b->co);
1282                                         }
1283                                         glEnd();
1284                                 }
1285                         } else {
1286                                 glBegin(GL_QUADS);
1287                                 for (y=0; y<gridSize-1; y++) {
1288                                         for (x=0; x<gridSize-1; x++) {
1289                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
1290                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1291                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1292                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
1293                                                 float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1294                                                 float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1295                                                 float no[3];
1296
1297                                                 no[0] = b_dY*a_cZ - b_dZ*a_cY;
1298                                                 no[1] = b_dZ*a_cX - b_dX*a_cZ;
1299                                                 no[2] = b_dX*a_cY - b_dY*a_cX;
1300                                                 glNormal3fv(no);
1301
1302                                                 glVertex3fv(d);
1303                                                 glVertex3fv(c);
1304                                                 glVertex3fv(b);
1305                                                 glVertex3fv(a);
1306                                         }
1307                                 }
1308                                 glEnd();
1309                         }
1310                 }
1311         }
1312
1313         ccgFaceIterator_free(fi);
1314 }
1315 static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2) {
1316         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1317         CCGSubSurf *ss = ccgdm->ss;
1318         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1319         int gridSize = ccgSubSurf_getGridSize(ss);
1320         unsigned char *cp1, *cp2;
1321         int useTwoSide=1;
1322
1323         cp1= col1;
1324         if(col2) {
1325                 cp2= col2;
1326         } else {
1327                 cp2= NULL;
1328                 useTwoSide= 0;
1329         }
1330
1331         glShadeModel(GL_SMOOTH);
1332         if(col1 && col2)
1333                 glEnable(GL_CULL_FACE);
1334
1335         glBegin(GL_QUADS);
1336         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1337                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1338                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1339
1340                 for (S=0; S<numVerts; S++) {
1341                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1342                         for (y=0; y<gridSize-1; y++) {
1343                                 for (x=0; x<gridSize-1; x++) {
1344                                         float *a = faceGridData[(y+0)*gridSize + x].co;
1345                                         float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1346                                         float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1347                                         float *d = faceGridData[(y+1)*gridSize + x].co;
1348
1349                                         glColor3ub(cp1[3], cp1[2], cp1[1]);
1350                                         glVertex3fv(d);
1351                                         glColor3ub(cp1[7], cp1[6], cp1[5]);
1352                                         glVertex3fv(c);
1353                                         glColor3ub(cp1[11], cp1[10], cp1[9]);
1354                                         glVertex3fv(b);
1355                                         glColor3ub(cp1[15], cp1[14], cp1[13]);
1356                                         glVertex3fv(a);
1357
1358                                         if (useTwoSide) {
1359                                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
1360                                                 glVertex3fv(a);
1361                                                 glColor3ub(cp2[11], cp2[10], cp2[9]);
1362                                                 glVertex3fv(b);
1363                                                 glColor3ub(cp2[7], cp2[6], cp2[5]);
1364                                                 glVertex3fv(c);
1365                                                 glColor3ub(cp2[3], cp2[2], cp2[1]);
1366                                                 glVertex3fv(d);
1367                                         }
1368
1369                                         if (cp2) cp2+=16;
1370                                         cp1+=16;
1371                                 }
1372                         }
1373                 }
1374         }
1375         glEnd();
1376
1377         ccgFaceIterator_free(fi);
1378 }
1379 static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index, int matnr), void *userData) {
1380         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1381         CCGSubSurf *ss = ccgdm->ss;
1382         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1383         int gridSize = ccgSubSurf_getGridSize(ss);
1384         MFace *mface = ccgdm->dlm?ccgdm->dlm->mface:ccgdm->me->mface;
1385         TFace *tface = ccgdm->dlm?ccgdm->dlm->tface:ccgdm->me->tface;
1386         MCol *mcol = ccgdm->dlm?ccgdm->dlm->mcol:ccgdm->me->mcol;
1387 //      float uv[4][2];
1388 //      float col[4][3];
1389
1390         glBegin(GL_QUADS);
1391         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1392                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1393                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1394                 int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
1395                 MFace *mf = &mface[index];
1396                 TFace *tf = tface?&tface[index]:NULL;
1397                 unsigned char *cp= NULL;
1398                 int findex = ccgDM_getFaceMapIndex(ccgdm, ss, f); 
1399                 int flag = (findex == -1)? 0: setDrawParams(userData, findex, mf->mat_nr);
1400
1401                 if (flag==0) {
1402                         continue;
1403                 } else if (flag==1) {
1404                         if (tf) {
1405                                 cp= (unsigned char*) tf->col;
1406                         } else if (mcol) {
1407                                 cp= (unsigned char*) &mcol[index*4];
1408                         }
1409                 }
1410
1411                 for (S=0; S<numVerts; S++) {
1412                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1413                         for (y=0; y<gridSize-1; y++) {
1414                                 for (x=0; x<gridSize-1; x++) {
1415                                         VertData *a = &faceGridData[(y+0)*gridSize + x + 0];
1416                                         VertData *b = &faceGridData[(y+0)*gridSize + x + 1];
1417                                         VertData *c = &faceGridData[(y+1)*gridSize + x + 1];
1418                                         VertData *d = &faceGridData[(y+1)*gridSize + x + 0];
1419
1420                                         if (!(mf->flag&ME_SMOOTH)) {
1421                                                 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];
1422                                                 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];
1423                                                 float no[3];
1424
1425                                                 no[0] = b_dY*a_cZ - b_dZ*a_cY;
1426                                                 no[1] = b_dZ*a_cX - b_dX*a_cZ;
1427                                                 no[2] = b_dX*a_cY - b_dY*a_cX;
1428
1429                                                 glNormal3fv(no);
1430                                         }
1431
1432 //                                      if (tf) glTexCoord2fv(tf->uv[0]);
1433 //                                      if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1434 //                                      if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no);
1435 //                                      glVertex3fv(mvert[mf->v1].co);
1436
1437 /*
1438                                         {
1439                                                 float x_v = (float) fx/(gridSize-1);
1440                                                 float y_v = (float) fy/(gridSize-1);
1441                                                 float data[6];
1442
1443                                                 for (k=0; k<numDataComponents; k++) {
1444                                                         data[k] = (center_data[k]*(1.0f-x_v) + edge_data[S][k]*x_v)*(1.0f-y_v) + 
1445                                                                         (edge_data[prevS][k]*(1.0f-x_v) + corner_data[S][k]*x_v)*y_v;
1446                                         }
1447 */
1448
1449 //                                      if (cp) glColor3ub(cp[3], cp[2], cp[1]);
1450                                         if (mf->flag&ME_SMOOTH) glNormal3fv(d->no);
1451                                         glVertex3fv(d->co);
1452 //                                      if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1453                                         if (mf->flag&ME_SMOOTH) glNormal3fv(c->no);
1454                                         glVertex3fv(c->co);
1455 //                                      if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1456                                         if (mf->flag&ME_SMOOTH) glNormal3fv(b->no);
1457                                         glVertex3fv(b->co);
1458 //                                      if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1459                                         if (mf->flag&ME_SMOOTH) glNormal3fv(a->no);
1460                                         glVertex3fv(a->co);
1461                                 }
1462                         }
1463                 }
1464         }
1465         glEnd();
1466
1467         ccgFaceIterator_free(fi);
1468 /*
1469         MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
1470         Mesh *me = mdm->me;
1471         MVert *mvert= mdm->verts;
1472         MFace *mface= me->mface;
1473         TFace *tface = me->tface;
1474         float *nors = mdm->nors;
1475         int a;
1476
1477         for (a=0; a<me->totface; a++) {
1478                 MFace *mf= &mface[a];
1479                 if (tf) glTexCoord2fv(tf->uv[1]);
1480                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
1481                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no);
1482                 glVertex3fv(mvert[mf->v2].co);
1483
1484                 if (tf) glTexCoord2fv(tf->uv[2]);
1485                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
1486                 if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no);
1487                 glVertex3fv(mvert[mf->v3].co);
1488
1489                 if(mf->v4) {
1490                         if (tf) glTexCoord2fv(tf->uv[3]);
1491                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
1492                         if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no);
1493                         glVertex3fv(mvert[mf->v4].co);
1494                 }
1495                 glEnd();
1496         }
1497 */
1498 }
1499 static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) {
1500         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1501         CCGSubSurf *ss = ccgdm->ss;
1502         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1503         int i, gridSize = ccgSubSurf_getGridSize(ss);
1504
1505         for (i=0; !ccgFaceIterator_isStopped(fi); i++,ccgFaceIterator_next(fi)) {
1506                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1507                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
1508                 int drawSmooth = 1, index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
1509
1510                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index, &drawSmooth))) {
1511                         for (S=0; S<numVerts; S++) {
1512                                 VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1513                                 if (drawSmooth) {
1514                                         glShadeModel(GL_SMOOTH);
1515                                         for (y=0; y<gridSize-1; y++) {
1516                                                 glBegin(GL_QUAD_STRIP);
1517                                                 for (x=0; x<gridSize; x++) {
1518                                                         VertData *a = &faceGridData[(y+0)*gridSize + x];
1519                                                         VertData *b = &faceGridData[(y+1)*gridSize + x];
1520
1521                                                         glNormal3fv(a->no);
1522                                                         glVertex3fv(a->co);
1523                                                         glNormal3fv(b->no);
1524                                                         glVertex3fv(b->co);
1525                                                 }
1526                                                 glEnd();
1527                                         }
1528                                 } else {
1529                                         glShadeModel(GL_FLAT);
1530                                         glBegin(GL_QUADS);
1531                                         for (y=0; y<gridSize-1; y++) {
1532                                                 for (x=0; x<gridSize-1; x++) {
1533                                                         float *a = faceGridData[(y+0)*gridSize + x].co;
1534                                                         float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1535                                                         float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1536                                                         float *d = faceGridData[(y+1)*gridSize + x].co;
1537                                                         float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1538                                                         float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1539                                                         float no[3];
1540
1541                                                         no[0] = b_dY*a_cZ - b_dZ*a_cY;
1542                                                         no[1] = b_dZ*a_cX - b_dX*a_cZ;
1543                                                         no[2] = b_dX*a_cY - b_dY*a_cX;
1544                                                         glNormal3fv(no);
1545
1546                                                         glVertex3fv(d);
1547                                                         glVertex3fv(c);
1548                                                         glVertex3fv(b);
1549                                                         glVertex3fv(a);
1550                                                 }
1551                                         }
1552                                         glEnd();
1553                                 }
1554                         }
1555                 }
1556         }
1557
1558         ccgFaceIterator_free(fi);
1559 }
1560 static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
1561         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1562         CCGSubSurf *ss = ccgdm->ss;
1563         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1564         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
1565
1566         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1567
1568         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1569                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1570                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1571                 int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
1572
1573                 glBegin(GL_LINE_STRIP);
1574                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
1575                         if (useAging && !(G.f&G_BACKBUFSEL)) {
1576                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1577                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
1578                         }
1579
1580                         for (i=0; i<edgeSize-1; i++) {
1581                                 glVertex3fv(edgeData[i].co);
1582                                 glVertex3fv(edgeData[i+1].co);
1583                         }
1584                 }
1585                 glEnd();
1586         }
1587
1588         ccgEdgeIterator_free(ei);
1589 }
1590 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
1591         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1592         CCGSubSurf *ss = ccgdm->ss;
1593         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1594         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
1595
1596         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1597
1598         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1599                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1600                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1601                 int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
1602
1603                 glBegin(GL_LINE_STRIP);
1604                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
1605                         for (i=0; i<edgeSize; i++) {
1606                                 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
1607
1608                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1609                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1610                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1611                                 }
1612
1613                                 glVertex3fv(edgeData[i].co);
1614                         }
1615                 }
1616                 glEnd();
1617         }
1618
1619         ccgEdgeIterator_free(ei);
1620 }
1621 static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
1622         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1623         CCGSubSurf *ss = ccgdm->ss;
1624         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1625
1626         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1627                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1628                 int index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
1629
1630                 if (index!=-1) {
1631                                 /* Face center data normal isn't updated atm. */
1632                         VertData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
1633
1634                         func(userData, index, vd->co, vd->no);
1635                 }
1636         }
1637
1638         ccgFaceIterator_free(fi);
1639 }
1640
1641 static void ccgDM_release(DerivedMesh *dm) {
1642         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1643
1644         if (ccgdm->dlm) displistmesh_free(ccgdm->dlm);
1645
1646         MEM_freeN(ccgdm);
1647 }
1648
1649 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int drawInteriorEdges, int useSubsurfUv, Mesh *me, DispListMesh *dlm) {
1650         CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
1651
1652         ccgdm->dm.getMinMax = ccgDM_getMinMax;
1653         ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
1654         ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
1655         ccgdm->dm.getVertCos = ccgdm_getVertCos;
1656         ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
1657         ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
1658         ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
1659         ccgdm->dm.convertToDispListMesh = ccgDM_convertToDispListMesh;
1660         
1661         ccgdm->dm.drawVerts = ccgDM_drawVerts;
1662         ccgdm->dm.drawEdges = ccgDM_drawEdges;
1663         ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
1664         ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
1665         ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
1666         ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
1667         ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
1668
1669         ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
1670         ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
1671         
1672         ccgdm->dm.release = ccgDM_release;
1673         
1674         ccgdm->ss = ss;
1675         ccgdm->fromEditmesh = fromEditmesh;
1676         ccgdm->drawInteriorEdges = drawInteriorEdges;
1677         ccgdm->useSubsurfUv = useSubsurfUv;
1678         ccgdm->me = me;
1679         ccgdm->dlm = dlm;
1680
1681         return ccgdm;
1682 }
1683
1684 /***/
1685
1686 DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, SubsurfModifierData *smd, float (*vertCos)[3]) {
1687         int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
1688         int useAging = smd->flags&eSubsurfModifierFlag_DebugIncr;
1689         int drawInteriorEdges = !(smd->flags&eSubsurfModifierFlag_ControlEdges);
1690
1691         smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0, useSimple);
1692         ss_sync_from_editmesh(smd->emCache, em, vertCos, useSimple);
1693
1694         return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 1, drawInteriorEdges, 0, NULL, NULL);
1695 }
1696
1697 DerivedMesh *subsurf_make_derived_from_dlm_em(DispListMesh *dlm, SubsurfModifierData *smd, float (*vertCos)[3]) {
1698         int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
1699         int useAging = smd->flags&eSubsurfModifierFlag_DebugIncr;
1700         int useSubsurfUv = smd->flags&eSubsurfModifierFlag_SubsurfUv;
1701         int drawInteriorEdges = !(smd->flags&eSubsurfModifierFlag_ControlEdges);
1702                 
1703         smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0, useSimple);
1704
1705         ss_sync_from_mesh(smd->emCache, NULL, dlm, vertCos, useSimple);
1706
1707         return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 0, drawInteriorEdges, useSubsurfUv, NULL, dlm);
1708 }
1709
1710 DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3], int isFinalCalc) {
1711         int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
1712         int useSubsurfUv = smd->flags&eSubsurfModifierFlag_SubsurfUv;
1713         int drawInteriorEdges = !(smd->flags&eSubsurfModifierFlag_ControlEdges);
1714         DispListMesh *ndlm;
1715
1716                 /* Do not use cache in render mode. */
1717         if (useRenderParams) {
1718                 CCGSubSurf *ss = _getSubSurf(NULL, smd->renderLevels, 0, 1, useSimple);
1719
1720                 ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
1721
1722                 ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, useSubsurfUv, me, dlm);
1723                 if (dlm) displistmesh_free(dlm);
1724
1725                 ccgSubSurf_free(ss);
1726                 
1727                 return derivedmesh_from_displistmesh(ndlm, NULL);
1728         } else {
1729                 int useIncremental = (smd->flags&eSubsurfModifierFlag_Incremental);
1730                 int useAging = smd->flags&eSubsurfModifierFlag_DebugIncr;
1731                 CCGSubSurf *ss;
1732                 
1733                         /* It is quite possible there is a much better place to do this. It
1734                          * depends a bit on how rigourously we expect this function to never
1735                          * be called in editmode. In semi-theory we could share a single
1736                          * cache, but the handles used inside and outside editmode are not
1737                          * the same so we would need some way of converting them. Its probably
1738                          * not worth the effort. But then why am I even writing this long
1739                          * comment that no one will read? Hmmm. - zr
1740                          */
1741                 if (smd->emCache) {
1742                         ccgSubSurf_free(smd->emCache);
1743                         smd->emCache = NULL;
1744                 }
1745
1746                 if (useIncremental && isFinalCalc) {
1747                         smd->mCache = ss = _getSubSurf(smd->mCache, smd->levels, useAging, 0, useSimple);
1748
1749                         ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
1750
1751                         return (DerivedMesh*) getCCGDerivedMesh(ss, 0, drawInteriorEdges, useSubsurfUv, me, dlm);
1752                 } else {
1753                         if (smd->mCache && isFinalCalc) {
1754                                 ccgSubSurf_free(smd->mCache);
1755                                 smd->mCache = NULL;
1756                         }
1757
1758                         ss = _getSubSurf(NULL, smd->levels, 0, 1, useSimple);
1759                         ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
1760
1761                         ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, useSubsurfUv, me, dlm);
1762
1763                         if (dlm) displistmesh_free(dlm);
1764                         ccgSubSurf_free(ss);
1765
1766                         return derivedmesh_from_displistmesh(ndlm, NULL);
1767                 }
1768         }
1769 }
1770
1771 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 
1772 {
1773                 /* Finds the subsurf limit positions for the verts in a mesh 
1774                  * and puts them in an array of floats. Please note that the 
1775                  * calculated vert positions is incorrect for the verts 
1776                  * on the boundary of the mesh.
1777                  */
1778         CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0);
1779         float edge_sum[3], face_sum[3];
1780         CCGVertIterator *vi;
1781
1782         ss_sync_from_mesh(ss, me, NULL, NULL, 0);
1783
1784         vi = ccgSubSurf_getVertIterator(ss);
1785         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1786                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1787                 int idx = (int) ccgSubSurf_getVertVertHandle(ss, v);
1788                 int N = ccgSubSurf_getVertNumEdges(ss, v);
1789                 int numFaces = ccgSubSurf_getVertNumFaces(ss, v);
1790                 float *co;
1791                 int i;
1792                 
1793                 edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0;
1794                 face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
1795
1796                 for (i=0; i<N; i++) {
1797                         CCGEdge *e = ccgSubSurf_getVertEdge(ss, v, i);
1798                         VecAddf(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
1799                 }
1800                 for (i=0; i<numFaces; i++) {
1801                         CCGFace *f = ccgSubSurf_getVertFace(ss, v, i);
1802                         VecAddf(face_sum, face_sum, ccgSubSurf_getFaceCenterData(ss, f));
1803                 }
1804
1805                 co = ccgSubSurf_getVertData(ss, v);
1806                 positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
1807                 positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
1808                 positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
1809         }
1810         ccgVertIterator_free(vi);
1811
1812         ccgSubSurf_free(ss);
1813 }
1814