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