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