svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r20855:20928
[blender.git] / source / blender / blenkernel / intern / subsurf_ccg.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL 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.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2005 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdio.h>
33 #include <math.h>
34 #include <float.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "DNA_mesh_types.h"
39 #include "DNA_meshdata_types.h"
40 #include "DNA_modifier_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_scene_types.h"
43
44 #include "BKE_cdderivedmesh.h"
45 #include "BKE_customdata.h"
46 #include "BKE_DerivedMesh.h"
47 #include "BKE_displist.h"
48 #include "BKE_utildefines.h"
49 #include "BKE_global.h"
50 #include "BKE_mesh.h"
51 #include "BKE_multires.h"
52 #include "BKE_scene.h"
53 #include "BKE_subsurf.h"
54
55 #include "BLI_blenlib.h"
56 #include "BLI_editVert.h"
57 #include "BLI_arithb.h"
58 #include "BLI_linklist.h"
59 #include "BLI_memarena.h"
60 #include "BLI_edgehash.h"
61
62 #include "BIF_gl.h"
63
64 #include "GPU_draw.h"
65 #include "GPU_extensions.h"
66 #include "GPU_material.h"
67
68 #include "CCGSubSurf.h"
69
70 typedef struct _VertData {
71         float co[3];
72         float no[3];
73 } VertData;
74
75 struct CCGDerivedMesh {
76         DerivedMesh dm;
77
78         CCGSubSurf *ss;
79         int drawInteriorEdges, useSubsurfUv;
80
81         struct {int startVert; CCGVert *vert;} *vertMap;
82         struct {int startVert; int startEdge; CCGEdge *edge;} *edgeMap;
83         struct {int startVert; int startEdge;
84                 int startFace; CCGFace *face;} *faceMap;
85 };
86
87 typedef struct CCGDerivedMesh CCGDerivedMesh;
88
89 static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v);
90 static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e);
91 static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f);
92
93 ///
94
95 static void *arena_alloc(CCGAllocatorHDL a, int numBytes) {
96         return BLI_memarena_alloc(a, numBytes);
97 }
98 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) {
99         void *p2 = BLI_memarena_alloc(a, newSize);
100         if (ptr) {
101                 memcpy(p2, ptr, oldSize);
102         }
103         return p2;
104 }
105 static void arena_free(CCGAllocatorHDL a, void *ptr) {
106 }
107 static void arena_release(CCGAllocatorHDL a) {
108         BLI_memarena_free(a);
109 }
110
111 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int useFlatSubdiv) {
112         CCGMeshIFC ifc;
113         CCGSubSurf *ccgSS;
114
115                 /* subdivLevels==0 is not allowed */
116         subdivLevels = MAX2(subdivLevels, 1);
117
118         if (prevSS) {
119                 int oldUseAging;
120
121                 useAging = !!useAging;
122                 ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
123
124                 if (oldUseAging!=useAging) {
125                         ccgSubSurf_free(prevSS);
126                 } else {
127                         ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
128
129                         return prevSS;
130                 }
131         }
132
133         if (useAging) {
134                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
135         } else {
136                 ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
137         }
138         ifc.vertDataSize = sizeof(VertData);
139
140         if (useArena) {
141                 CCGAllocatorIFC allocatorIFC;
142                 CCGAllocatorHDL allocator = BLI_memarena_new((1<<16));
143
144                 allocatorIFC.alloc = arena_alloc;
145                 allocatorIFC.realloc = arena_realloc;
146                 allocatorIFC.free = arena_free;
147                 allocatorIFC.release = arena_release;
148
149                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
150         } else {
151                 ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
152         }
153
154         if (useAging) {
155                 ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
156         }
157
158         ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(VertData, no));
159
160         return ccgSS;
161 }
162
163 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
164         CCGVert *v0 = ccgSubSurf_getEdgeVert0(e);
165         CCGVert *v1 = ccgSubSurf_getEdgeVert1(e);
166         int v0idx = *((int*) ccgSubSurf_getVertUserData(ss, v0));
167         int v1idx = *((int*) ccgSubSurf_getVertUserData(ss, v1));
168         int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
169
170         if (x==0) {
171                 return v0idx;
172         } else if (x==edgeSize-1) {
173                 return v1idx;
174         } else {
175                 return edgeBase + x-1;
176         }
177 }
178 static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) {
179         int faceBase = *((int*) ccgSubSurf_getFaceUserData(ss, f));
180         int numVerts = ccgSubSurf_getFaceNumVerts(f);
181
182         if (x==gridSize-1 && y==gridSize-1) {
183                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
184                 return *((int*) ccgSubSurf_getVertUserData(ss, v));
185         } else if (x==gridSize-1) {
186                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
187                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S);
188                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
189                 if (v==ccgSubSurf_getEdgeVert0(e)) {
190                         return edgeBase + (gridSize-1-y)-1;
191                 } else {
192                         return edgeBase + (edgeSize-2-1)-((gridSize-1-y)-1);
193                 }
194         } else if (y==gridSize-1) {
195                 CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
196                 CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts);
197                 int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e));
198                 if (v==ccgSubSurf_getEdgeVert0(e)) {
199                         return edgeBase + (gridSize-1-x)-1;
200                 } else {
201                         return edgeBase + (edgeSize-2-1)-((gridSize-1-x)-1);
202                 }
203         } else if (x==0 && y==0) {
204                 return faceBase;
205         } else if (x==0) {
206                 S = (S+numVerts-1)%numVerts;
207                 return faceBase + 1 + (gridSize-2)*S + (y-1);
208         } else if (y==0) {
209                 return faceBase + 1 + (gridSize-2)*S + (x-1);
210         } else {
211                 return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1);
212         }
213 }
214
215 static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCGVertHDL *fverts) {
216         unsigned int *fv = &mf->v1;
217         UvMapVert *v, *nv;
218         int j, nverts= mf->v4? 4: 3;
219
220         for (j=0; j<nverts; j++, fv++) {
221                 for (nv=v=get_uv_map_vert(vmap, *fv); v; v=v->next) {
222                         if (v->separate)
223                                 nv= v;
224                         if (v->f == fi)
225                                 break;
226                 }
227
228                 fverts[j]= SET_INT_IN_POINTER(nv->f*4 + nv->tfindex);
229         }
230 }
231
232 static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MTFace *tface) {
233         MFace *mface = dm->getFaceArray(dm);
234         MVert *mvert = dm->getVertArray(dm);
235         int totvert = dm->getNumVerts(dm);
236         int totface = dm->getNumFaces(dm);
237         int i, j, seam;
238         UvMapVert *v;
239         UvVertMap *vmap;
240         float limit[2];
241         CCGVertHDL fverts[4];
242         EdgeHash *ehash;
243         float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
244
245         limit[0]= limit[1]= STD_UV_CONNECT_LIMIT;
246         vmap= make_uv_vert_map(mface, tface, totface, totvert, 0, limit);
247         if (!vmap)
248                 return 0;
249         
250         ccgSubSurf_initFullSync(ss);
251
252         /* create vertices */
253         for (i=0; i<totvert; i++) {
254                 if (!get_uv_map_vert(vmap, i))
255                         continue;
256
257                 for (v=get_uv_map_vert(vmap, i)->next; v; v=v->next)
258                         if (v->separate)
259                                 break;
260
261                 seam = (v != NULL) || ((mvert+i)->flag & ME_VERT_MERGED);
262
263                 for (v=get_uv_map_vert(vmap, i); v; v=v->next) {
264                         if (v->separate) {
265                                 CCGVert *ssv;
266                                 CCGVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex);
267                                 float uv[3];
268
269                                 uv[0]= (tface+v->f)->uv[v->tfindex][0];
270                                 uv[1]= (tface+v->f)->uv[v->tfindex][1];
271                                 uv[2]= 0.0f;
272
273                                 ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
274                         }
275                 }
276         }
277
278         /* create edges */
279         ehash = BLI_edgehash_new();
280
281         for (i=0; i<totface; i++) {
282                 MFace *mf = &((MFace*) mface)[i];
283                 int nverts= mf->v4? 4: 3;
284                 CCGFace *origf= ccgSubSurf_getFace(origss, SET_INT_IN_POINTER(i));
285                 unsigned int *fv = &mf->v1;
286
287                 get_face_uv_map_vert(vmap, mf, i, fverts);
288
289                 for (j=0; j<nverts; j++) {
290                         int v0 = GET_INT_FROM_POINTER(fverts[j]);
291                         int v1 = GET_INT_FROM_POINTER(fverts[(j+1)%nverts]);
292                         MVert *mv0 = mvert + *(fv+j);
293                         MVert *mv1 = mvert + *(fv+((j+1)%nverts));
294
295                         if (!BLI_edgehash_haskey(ehash, v0, v1)) {
296                                 CCGEdge *e, *orige= ccgSubSurf_getFaceEdge(origss, origf, j);
297                                 CCGEdgeHDL ehdl= SET_INT_IN_POINTER(i*4 + j);
298                                 float crease;
299
300                                 if ((mv0->flag&mv1->flag) & ME_VERT_MERGED)
301                                         crease = creaseFactor;
302                                 else
303                                         crease = ccgSubSurf_getEdgeCrease(orige);
304
305                                 ccgSubSurf_syncEdge(ss, ehdl, fverts[j], fverts[(j+1)%nverts], crease, &e);
306                                 BLI_edgehash_insert(ehash, v0, v1, NULL);
307                         }
308                 }
309         }
310
311         BLI_edgehash_free(ehash, NULL);
312
313         /* create faces */
314         for (i=0; i<totface; i++) {
315                 MFace *mf = &((MFace*) mface)[i];
316                 int nverts= mf->v4? 4: 3;
317                 CCGFace *f;
318
319                 get_face_uv_map_vert(vmap, mf, i, fverts);
320                 ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), nverts, fverts, &f);
321         }
322
323         free_uv_vert_map(vmap);
324         ccgSubSurf_processSync(ss);
325
326         return 1;
327 }
328
329 static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
330 {
331         CCGSubSurf *uvss;
332         CCGFace **faceMap;
333         MTFace *tf;
334         CCGFaceIterator *fi;
335         int index, gridSize, gridFaces, edgeSize, totface, x, y, S;
336         MTFace *dmtface = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, n);
337         MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
338
339         if(!dmtface || !tface)
340                 return;
341
342         /* create a CCGSubsurf from uv's */
343         uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0);
344
345         if(!ss_sync_from_uv(uvss, ss, dm, dmtface)) {
346                 ccgSubSurf_free(uvss);
347                 return;
348         }
349
350         /* get some info from CCGSubsurf */
351         totface = ccgSubSurf_getNumFaces(uvss);
352         edgeSize = ccgSubSurf_getEdgeSize(uvss);
353         gridSize = ccgSubSurf_getGridSize(uvss);
354         gridFaces = gridSize - 1;
355
356         /* make a map from original faces to CCGFaces */
357         faceMap = MEM_mallocN(totface*sizeof(*faceMap), "facemapuv");
358
359         fi = ccgSubSurf_getFaceIterator(uvss);
360         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
361                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
362                 faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(uvss, f))] = f;
363         }
364         ccgFaceIterator_free(fi);
365
366         /* load coordinates from uvss into tface */
367         tf= tface;
368
369         for(index = 0; index < totface; index++) {
370                 CCGFace *f = faceMap[index];
371                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
372
373                 for (S=0; S<numVerts; S++) {
374                         VertData *faceGridData= ccgSubSurf_getFaceGridDataArray(uvss, f, S);
375
376                         for(y = 0; y < gridFaces; y++) {
377                                 for(x = 0; x < gridFaces; x++) {
378                                         float *a = faceGridData[(y + 0)*gridSize + x + 0].co;
379                                         float *b = faceGridData[(y + 0)*gridSize + x + 1].co;
380                                         float *c = faceGridData[(y + 1)*gridSize + x + 1].co;
381                                         float *d = faceGridData[(y + 1)*gridSize + x + 0].co;
382
383                                         tf->uv[0][0] = a[0]; tf->uv[0][1] = a[1];
384                                         tf->uv[1][0] = d[0]; tf->uv[1][1] = d[1];
385                                         tf->uv[2][0] = c[0]; tf->uv[2][1] = c[1];
386                                         tf->uv[3][0] = b[0]; tf->uv[3][1] = b[1];
387
388                                         tf++;
389                                 }
390                         }
391                 }
392         }
393
394         ccgSubSurf_free(uvss);
395         MEM_freeN(faceMap);
396 }
397
398 #if 0
399 static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditmesh, DispListMesh *dlm, MEdge *medge, MTFace *tface)
400 {
401         unsigned int flags = 0;
402         int N = ccgSubSurf_getEdgeNumFaces(e);
403
404         if (!N) flags |= ME_LOOSEEDGE;
405
406         if (ssFromEditmesh) {
407                 EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(e);
408
409                 flags |= ME_EDGEDRAW|ME_EDGERENDER;
410                 if (eed->seam) {
411                         flags |= ME_SEAM;
412                 }
413         } else {
414                 if (edgeIdx!=-1) {
415                         MEdge *origMed = &medge[edgeIdx];
416
417                         if (dlm) {
418                                 flags |= origMed->flag&~ME_EDGE_STEPINDEX;
419                         } else {
420                                 flags |= (origMed->flag&ME_SEAM)|ME_EDGEDRAW|ME_EDGERENDER;
421                         }
422                 }
423         }
424
425         return flags;
426 }
427 #endif
428
429 /* face weighting */
430 static void calc_ss_weights(int gridFaces,
431                             FaceVertWeight **qweight, FaceVertWeight **tweight)
432 {
433         FaceVertWeight *qw, *tw;
434         int x, y, j;
435         int numWeights = gridFaces * gridFaces;
436
437         *tweight = MEM_mallocN(sizeof(**tweight) * numWeights, "ssTriWeight");
438         *qweight = MEM_mallocN(sizeof(**qweight) * numWeights, "ssQuadWeight");
439
440         qw = *qweight;
441         tw = *tweight;
442
443         for (y = 0; y < gridFaces; y++) {
444                 for (x = 0; x < gridFaces; x++) {
445                         for (j = 0; j < 4; j++) {
446                                 int fx = x + (j == 2 || j == 3);
447                                 int fy = y + (j == 1 || j == 2);
448                                 float x_v = (float) fx / gridFaces;
449                                 float y_v = (float) fy / gridFaces;
450                                 float tx_v = (1.0f - x_v), ty_v = (1.0f - y_v);
451                                 float center = (1.0f / 3.0f) * tx_v * ty_v;
452
453                                 (*tw)[j][0] = center + 0.5f * tx_v * y_v;
454                                 (*tw)[j][2] = center + 0.5f * x_v * ty_v;
455                                 (*tw)[j][1] = 1.0f - (*tw)[j][0] - (*tw)[j][2];
456                                 (*tw)[j][3] = 0.0f;
457
458                                 tx_v *= 0.5f;
459                                 ty_v *= 0.5f;
460
461                                 (*qw)[j][3] = tx_v * ty_v;
462                                 (*qw)[j][0] = (*qw)[j][3] + tx_v * y_v;
463                                 (*qw)[j][2] = (*qw)[j][3] + x_v * ty_v;
464                                 (*qw)[j][1] = 1.0f - (*qw)[j][0] - (*qw)[j][2] - (*qw)[j][3];
465
466                         }
467                         tw++;
468                         qw++;
469                 }
470         }
471 }
472
473 static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh,
474                                  int drawInteriorEdges, int useSubsurfUv,
475                                  DerivedMesh *dm, MultiresSubsurf *ms)
476 {
477         DerivedMesh *result;
478         int edgeSize = ccgSubSurf_getEdgeSize(ss);
479         int gridSize = ccgSubSurf_getGridSize(ss);
480         int gridFaces = gridSize - 1;
481         int edgeBase, faceBase;
482         int i, j, k, S, x, y, index;
483         CCGVertIterator *vi;
484         CCGEdgeIterator *ei;
485         CCGFaceIterator *fi;
486         CCGFace **faceMap2;
487         CCGEdge **edgeMap2;
488         CCGVert **vertMap2;
489         int totvert, totedge, totface;
490         MVert *mvert;
491         MEdge *med;
492         MFace *mf;
493         int *origIndex;
494         FaceVertWeight *qweight, *tweight;
495
496         calc_ss_weights(gridFaces, &qweight, &tweight);
497
498         /* vert map */
499         totvert = ccgSubSurf_getNumVerts(ss);
500         vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
501         vi = ccgSubSurf_getVertIterator(ss);
502         for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
503                 CCGVert *v = ccgVertIterator_getCurrent(vi);
504
505                 vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v;
506         }
507         ccgVertIterator_free(vi);
508
509         totedge = ccgSubSurf_getNumEdges(ss);
510         edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
511         ei = ccgSubSurf_getEdgeIterator(ss);
512         for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
513                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
514
515                 edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
516         }
517
518         totface = ccgSubSurf_getNumFaces(ss);
519         faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
520         fi = ccgSubSurf_getFaceIterator(ss);
521         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
522                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
523
524                 faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f;
525         }
526         ccgFaceIterator_free(fi);
527
528         if(ms) {
529                 result = MultiresDM_new(ms, dm, ccgSubSurf_getNumFinalVerts(ss),
530                                         ccgSubSurf_getNumFinalEdges(ss),
531                                         ccgSubSurf_getNumFinalFaces(ss));
532         }
533         else {
534                 if(dm) {
535                         result = CDDM_from_template(dm, ccgSubSurf_getNumFinalVerts(ss),
536                                                     ccgSubSurf_getNumFinalEdges(ss),
537                                                     ccgSubSurf_getNumFinalFaces(ss));
538                 } else {
539                         result = CDDM_new(ccgSubSurf_getNumFinalVerts(ss),
540                                           ccgSubSurf_getNumFinalEdges(ss),
541                                           ccgSubSurf_getNumFinalFaces(ss));
542                 }
543         }
544
545         // load verts
546         faceBase = i = 0;
547         mvert = CDDM_get_verts(result);
548         origIndex = result->getVertData(result, 0, CD_ORIGINDEX);
549
550         for(index = 0; index < totface; index++) {
551                 CCGFace *f = faceMap2[index];
552                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
553                 FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
554                 int vertIdx[4];
555
556                 for(S = 0; S < numVerts; S++) {
557                         CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
558
559                         vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
560                 }
561
562                 DM_interp_vert_data(dm, result, vertIdx, weight[0][0], numVerts, i);
563                 VecCopyf(mvert->co, ccgSubSurf_getFaceCenterData(f));
564                 *origIndex = ORIGINDEX_NONE;
565                 ++mvert;
566                 ++origIndex;
567                 i++;
568
569                 for(S = 0; S < numVerts; S++) {
570                         int prevS = (S - 1 + numVerts) % numVerts;
571                         int nextS = (S + 1) % numVerts;
572                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
573
574                         for(x = 1; x < gridFaces; x++) {
575                                 float w[4];
576                                 w[prevS]  = weight[x][0][0];
577                                 w[S]      = weight[x][0][1];
578                                 w[nextS]  = weight[x][0][2];
579                                 w[otherS] = weight[x][0][3];
580                                 DM_interp_vert_data(dm, result, vertIdx, w, numVerts, i);
581                                 VecCopyf(mvert->co,
582                                          ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
583
584                                 *origIndex = ORIGINDEX_NONE;
585                                 ++mvert;
586                                 ++origIndex;
587                                 i++;
588                         }
589                 }
590
591                 for(S = 0; S < numVerts; S++) {
592                         int prevS = (S - 1 + numVerts) % numVerts;
593                         int nextS = (S + 1) % numVerts;
594                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
595
596                         for(y = 1; y < gridFaces; y++) {
597                                 for(x = 1; x < gridFaces; x++) {
598                                         float w[4];
599                                         w[prevS]  = weight[y * gridFaces + x][0][0];
600                                         w[S]      = weight[y * gridFaces + x][0][1];
601                                         w[nextS]  = weight[y * gridFaces + x][0][2];
602                                         w[otherS] = weight[y * gridFaces + x][0][3];
603                                         DM_interp_vert_data(dm, result, vertIdx, w, numVerts, i);
604                                         VecCopyf(mvert->co,
605                                                  ccgSubSurf_getFaceGridData(ss, f, S, x, y));
606                                         *origIndex = ORIGINDEX_NONE;
607                                         ++mvert;
608                                         ++origIndex;
609                                         i++;
610                                 }
611                         }
612                 }
613
614                 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = faceBase;
615                 faceBase += 1 + numVerts * ((gridSize-2) + (gridSize-2) * (gridSize-2));
616         }
617
618         edgeBase = i;
619         for(index = 0; index < totedge; index++) {
620                 CCGEdge *e = edgeMap2[index];
621                 int x;
622                 int vertIdx[2];
623
624                 CCGVert *v;
625                 v = ccgSubSurf_getEdgeVert0(e);
626                 vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
627                 v = ccgSubSurf_getEdgeVert1(e);
628                 vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
629
630                 for(x = 1; x < edgeSize - 1; x++) {
631                         float w[2];
632                         w[1] = (float) x / (edgeSize - 1);
633                         w[0] = 1 - w[1];
634                         DM_interp_vert_data(dm, result, vertIdx, w, 2, i);
635                         VecCopyf(mvert->co, ccgSubSurf_getEdgeData(ss, e, x));
636                         *origIndex = ORIGINDEX_NONE;
637                         ++mvert;
638                         ++origIndex;
639                         i++;
640                 }
641
642                 *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = edgeBase;
643                 edgeBase += edgeSize-2;
644         }
645
646         for(index = 0; index < totvert; index++) {
647                 CCGVert *v = vertMap2[index];
648                 int vertIdx;
649
650                 vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
651
652                 DM_copy_vert_data(dm, result, vertIdx, i, 1);
653                 VecCopyf(mvert->co, ccgSubSurf_getVertData(ss, v));
654
655                 *((int*)ccgSubSurf_getVertUserData(ss, v)) = i;
656                 *origIndex = ccgDM_getVertMapIndex(ss, v);
657                 ++mvert;
658                 ++origIndex;
659                 i++;
660         }
661
662         // load edges
663         i = 0;
664         med = CDDM_get_edges(result);
665         origIndex = result->getEdgeData(result, 0, CD_ORIGINDEX);
666
667         for(index = 0; index < totface; index++) {
668                 CCGFace *f = faceMap2[index];
669                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
670
671                 for(k = 0; k < numVerts; k++) {
672                         for(x = 0; x < gridFaces; x++) {
673                                 if(drawInteriorEdges) med->flag = ME_EDGEDRAW | ME_EDGERENDER;
674                                 med->v1 = getFaceIndex(ss, f, k, x, 0, edgeSize, gridSize);
675                                 med->v2 = getFaceIndex(ss, f, k, x+1, 0, edgeSize, gridSize);
676                                 *origIndex = ORIGINDEX_NONE;
677                                 ++med;
678                                 ++origIndex;
679                                 i++;
680                         }
681
682                         for(x = 1; x < gridFaces; x++) {
683                                 for(y = 0; y < gridFaces; y++) {
684                                         if(drawInteriorEdges)
685                                                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
686                                         med->v1 = getFaceIndex(ss, f, k, x, y, edgeSize, gridSize);
687                                         med->v2 = getFaceIndex(ss, f, k, x, y + 1,
688                                                                edgeSize, gridSize);
689                                         *origIndex = ORIGINDEX_NONE;
690                                         ++med;
691                                         ++origIndex;
692                                         i++;
693
694                                         if(drawInteriorEdges)
695                                                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
696                                         med->v1 = getFaceIndex(ss, f, k, y, x, edgeSize, gridSize);
697                                         med->v2 = getFaceIndex(ss, f, k, y + 1, x,
698                                                                edgeSize, gridSize);
699                                         *origIndex = ORIGINDEX_NONE;
700                                         ++med;
701                                         ++origIndex;
702                                         i++;
703                                 }
704                         }
705                 }
706         }
707
708         for(index = 0; index < totedge; index++) {
709                 CCGEdge *e = edgeMap2[index];
710                 unsigned int flags = 0;
711                 char bweight = 0;
712                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
713
714                 if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
715
716
717                 if(edgeIdx != -1 && dm) {
718                         MEdge origMed;
719                         dm->getEdge(dm, edgeIdx, &origMed);
720
721                         flags |= origMed.flag;
722                         bweight = origMed.bweight;
723                 }
724
725                 for(x = 0; x < edgeSize - 1; x++) {
726                         med->v1 = getEdgeIndex(ss, e, x, edgeSize);
727                         med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
728                         med->flag = flags;
729                         med->bweight = bweight;
730                         *origIndex = ccgDM_getEdgeMapIndex(ss, e);
731                         ++med;
732                         ++origIndex;
733                         i++;
734                 }
735         }
736
737         // load faces
738         i = 0;
739         mf = CDDM_get_faces(result);
740         origIndex = result->getFaceData(result, 0, CD_ORIGINDEX);
741
742         for(index = 0; index < totface; index++) {
743                 CCGFace *f = faceMap2[index];
744                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
745                 int mat_nr;
746                 int flag;
747                 int mapIndex = ccgDM_getFaceMapIndex(ss, f);
748                 int faceIdx = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
749
750                 if(!ssFromEditmesh) {
751                         MFace origMFace;
752                         dm->getFace(dm, faceIdx, &origMFace);
753                         
754                         mat_nr = origMFace.mat_nr;
755                         flag = origMFace.flag;
756                 } else {
757                         EditFace *ef = ccgSubSurf_getFaceFaceHandle(ss, f);
758                         mat_nr = ef->mat_nr;
759                         flag = ef->flag;
760                 }
761
762                 for(S = 0; S < numVerts; S++) {
763                         FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
764
765                         for(y = 0; y < gridFaces; y++) {
766                                 for(x = 0; x < gridFaces; x++) {
767                                         mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
768                                                               edgeSize, gridSize);
769                                         mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
770                                                               edgeSize, gridSize);
771                                         mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
772                                                               edgeSize, gridSize);
773                                         mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
774                                                               edgeSize, gridSize);
775                                         mf->mat_nr = mat_nr;
776                                         mf->flag = flag;
777
778                                         if(dm) {
779                                                 int prevS = (S - 1 + numVerts) % numVerts;
780                                                 int nextS = (S + 1) % numVerts;
781                                                 int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
782                                                 FaceVertWeight w;
783
784                                                 for(j = 0; j < 4; ++j) {
785                                                         w[j][prevS]  = (*weight)[j][0];
786                                                         w[j][S]      = (*weight)[j][1];
787                                                         w[j][nextS]  = (*weight)[j][2];
788                                                         w[j][otherS] = (*weight)[j][3];
789                                                 }
790
791                                                 DM_interp_face_data(dm, result, &faceIdx, NULL,
792                                                                     &w, 1, i);
793                                                 weight++;
794                                         }
795
796                                         *origIndex = mapIndex;
797                                         ++mf;
798                                         ++origIndex;
799                                         i++;
800                                 }
801                         }
802                 }
803         }
804
805         MEM_freeN(faceMap2);
806         MEM_freeN(edgeMap2);
807         MEM_freeN(vertMap2);
808
809         MEM_freeN(tweight);
810         MEM_freeN(qweight);
811
812         if(useSubsurfUv) {
813                 CustomData *fdata = &result->faceData;
814                 CustomData *dmfdata = &dm->faceData;
815                 int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
816                 int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
817                 
818                 for (i=0; i<numlayer && i<dmnumlayer; i++)
819                         set_subsurf_uv(ss, dm, result, i);
820         }
821
822         CDDM_calc_normals(result);
823
824         return result;
825 }
826
827 static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm,
828                                      float (*vertexCos)[3], int useFlatSubdiv)
829 {
830         float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
831         CCGVertHDL fVerts[4];
832         int totvert = dm->getNumVerts(dm);
833         int totedge = dm->getNumEdges(dm);
834         int totface = dm->getNumFaces(dm);
835         int i;
836         int *index;
837         MVert *mvert = dm->getVertArray(dm);
838         MEdge *medge = dm->getEdgeArray(dm);
839         MFace *mface = dm->getFaceArray(dm);
840         MVert *mv;
841         MEdge *me;
842         MFace *mf;
843
844         ccgSubSurf_initFullSync(ss);
845
846         mv = mvert;
847         index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
848         for(i = 0; i < totvert; i++, mv++, index++) {
849                 CCGVert *v;
850
851                 if(vertexCos) {
852                         ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), vertexCos[i], 0, &v);
853                 } else {
854                         ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), mv->co, 0, &v);
855                 }
856
857                 ((int*)ccgSubSurf_getVertUserData(ss, v))[1] = *index;
858         }
859
860         me = medge;
861         index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX);
862         for(i = 0; i < totedge; i++, me++, index++) {
863                 CCGEdge *e;
864                 float crease;
865
866                 crease = useFlatSubdiv ? creaseFactor :
867                                          me->crease * creaseFactor / 255.0f;
868
869                 ccgSubSurf_syncEdge(ss, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(me->v1),
870                                     SET_INT_IN_POINTER(me->v2), crease, &e);
871
872                 ((int*)ccgSubSurf_getEdgeUserData(ss, e))[1] = *index;
873         }
874
875         mf = mface;
876         index = (int *)dm->getFaceDataArray(dm, CD_ORIGINDEX);
877         for (i = 0; i < totface; i++, mf++, index++) {
878                 CCGFace *f;
879
880                 fVerts[0] = SET_INT_IN_POINTER(mf->v1);
881                 fVerts[1] = SET_INT_IN_POINTER(mf->v2);
882                 fVerts[2] = SET_INT_IN_POINTER(mf->v3);
883                 fVerts[3] = SET_INT_IN_POINTER(mf->v4);
884
885                 // this is very bad, means mesh is internally consistent.
886                 // it is not really possible to continue without modifying
887                 // other parts of code significantly to handle missing faces.
888                 // since this really shouldn't even be possible we just bail.
889                 if(ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), fVerts[3] ? 4 : 3,
890                                        fVerts, &f) == eCCGError_InvalidValue) {
891                         static int hasGivenError = 0;
892
893                         if(!hasGivenError) {
894                                 //XXX error("Unrecoverable error in SubSurf calculation,"
895                                 //      " mesh is inconsistent.");
896
897                                 hasGivenError = 1;
898                         }
899
900                         return;
901                 }
902
903                 ((int*)ccgSubSurf_getFaceUserData(ss, f))[1] = *index;
904         }
905
906         ccgSubSurf_processSync(ss);
907 }
908
909 /***/
910
911 static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v) {
912         return ((int*) ccgSubSurf_getVertUserData(ss, v))[1];
913 }
914
915 static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e) {
916         return ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1];
917 }
918
919 static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f) {
920         return ((int*) ccgSubSurf_getFaceUserData(ss, f))[1];
921 }
922
923 static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
924         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
925         CCGSubSurf *ss = ccgdm->ss;
926         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
927         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
928         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
929         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
930         int gridSize = ccgSubSurf_getGridSize(ss);
931
932         if (!ccgSubSurf_getNumVerts(ss))
933                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
934
935         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
936                 CCGVert *v = ccgVertIterator_getCurrent(vi);
937                 float *co = ccgSubSurf_getVertData(ss, v);
938
939                 DO_MINMAX(co, min_r, max_r);
940         }
941
942         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
943                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
944                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
945
946                 for (i=0; i<edgeSize; i++)
947                         DO_MINMAX(edgeData[i].co, min_r, max_r);
948         }
949
950         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
951                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
952                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
953
954                 for (S=0; S<numVerts; S++) {
955                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
956
957                         for (y=0; y<gridSize; y++)
958                                 for (x=0; x<gridSize; x++)
959                                         DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r);
960                 }
961         }
962
963         ccgFaceIterator_free(fi);
964         ccgEdgeIterator_free(ei);
965         ccgVertIterator_free(vi);
966 }
967 static int ccgDM_getNumVerts(DerivedMesh *dm) {
968         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
969
970         return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
971 }
972 static int ccgDM_getNumEdges(DerivedMesh *dm) {
973         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
974
975         return ccgSubSurf_getNumFinalEdges(ccgdm->ss);
976 }
977 static int ccgDM_getNumFaces(DerivedMesh *dm) {
978         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
979
980         return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
981 }
982
983 static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
984 {
985         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
986         CCGSubSurf *ss = ccgdm->ss;
987         int i;
988
989         memset(mv, 0, sizeof(*mv));
990
991         if((vertNum < ccgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) {
992                 /* this vert comes from face data */
993                 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
994                 CCGFace *f;
995                 int x, y, grid, numVerts;
996                 int offset;
997                 int gridSize = ccgSubSurf_getGridSize(ss);
998                 int gridSideVerts;
999                 int gridInternalVerts;
1000                 int gridSideEnd;
1001                 int gridInternalEnd;
1002
1003                 i = 0;
1004                 while(i < lastface && vertNum >= ccgdm->faceMap[i + 1].startVert)
1005                         ++i;
1006
1007                 f = ccgdm->faceMap[i].face;
1008                 numVerts = ccgSubSurf_getFaceNumVerts(f);
1009
1010                 gridSideVerts = gridSize - 2;
1011                 gridInternalVerts = gridSideVerts * gridSideVerts;
1012
1013                 gridSideEnd = 1 + numVerts * gridSideVerts;
1014                 gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
1015
1016                 offset = vertNum - ccgdm->faceMap[i].startVert;
1017                 if(offset < 1) {
1018                         VecCopyf(mv->co, ccgSubSurf_getFaceCenterData(f));
1019                 } else if(offset < gridSideEnd) {
1020                         offset -= 1;
1021                         grid = offset / gridSideVerts;
1022                         x = offset % gridSideVerts + 1;
1023                         VecCopyf(mv->co, ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x));
1024                 } else if(offset < gridInternalEnd) {
1025                         offset -= gridSideEnd;
1026                         grid = offset / gridInternalVerts;
1027                         offset %= gridInternalVerts;
1028                         y = offset / gridSideVerts + 1;
1029                         x = offset % gridSideVerts + 1;
1030                         VecCopyf(mv->co, ccgSubSurf_getFaceGridData(ss, f, grid, x, y));
1031                 }
1032         } else if((vertNum < ccgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
1033                 /* this vert comes from edge data */
1034                 CCGEdge *e;
1035                 int lastedge = ccgSubSurf_getNumEdges(ss) - 1;
1036                 int x;
1037
1038                 i = 0;
1039                 while(i < lastedge && vertNum >= ccgdm->edgeMap[i + 1].startVert)
1040                         ++i;
1041
1042                 e = ccgdm->edgeMap[i].edge;
1043
1044                 x = vertNum - ccgdm->edgeMap[i].startVert + 1;
1045                 VecCopyf(mv->co, ccgSubSurf_getEdgeData(ss, e, x));
1046         } else {
1047                 /* this vert comes from vert data */
1048                 CCGVert *v;
1049                 i = vertNum - ccgdm->vertMap[0].startVert;
1050
1051                 v = ccgdm->vertMap[i].vert;
1052                 VecCopyf(mv->co, ccgSubSurf_getVertData(ss, v));
1053         }
1054 }
1055
1056 static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
1057 {
1058         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1059         CCGSubSurf *ss = ccgdm->ss;
1060         int i;
1061
1062         memset(med, 0, sizeof(*med));
1063
1064         if(edgeNum < ccgdm->edgeMap[0].startEdge) {
1065                 /* this edge comes from face data */
1066                 int lastface = ccgSubSurf_getNumFaces(ss) - 1;
1067                 CCGFace *f;
1068                 int x, y, grid, numVerts;
1069                 int offset;
1070                 int gridSize = ccgSubSurf_getGridSize(ss);
1071                 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1072                 int gridSideEdges;
1073                 int gridInternalEdges;
1074
1075                 i = 0;
1076                 while(i < lastface && edgeNum >= ccgdm->faceMap[i + 1].startEdge)
1077                         ++i;
1078
1079                 f = ccgdm->faceMap[i].face;
1080                 numVerts = ccgSubSurf_getFaceNumVerts(f);
1081
1082                 gridSideEdges = gridSize - 1;
1083                 gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
1084
1085                 offset = edgeNum - ccgdm->faceMap[i].startEdge;
1086                 grid = offset / (gridSideEdges + gridInternalEdges);
1087                 offset %= (gridSideEdges + gridInternalEdges);
1088
1089                 if(offset < gridSideEdges) {
1090                         x = offset;
1091                         med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, gridSize);
1092                         med->v2 = getFaceIndex(ss, f, grid, x+1, 0, edgeSize, gridSize);
1093                 } else {
1094                         offset -= gridSideEdges;
1095                         x = (offset / 2) / gridSideEdges + 1;
1096                         y = (offset / 2) % gridSideEdges;
1097                         if(offset % 2 == 0) {
1098                                 med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSize, gridSize);
1099                                 med->v2 = getFaceIndex(ss, f, grid, x, y+1, edgeSize, gridSize);
1100                         } else {
1101                                 med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSize, gridSize);
1102                                 med->v2 = getFaceIndex(ss, f, grid, y+1, x, edgeSize, gridSize);
1103                         }
1104                 }
1105         } else {
1106                 /* this vert comes from edge data */
1107                 CCGEdge *e;
1108                 int edgeSize = ccgSubSurf_getEdgeSize(ss);
1109                 int x, *edgeFlag;
1110                 unsigned int flags = 0;
1111
1112                 i = (edgeNum - ccgdm->edgeMap[0].startEdge) / (edgeSize - 1);
1113
1114                 e = ccgdm->edgeMap[i].edge;
1115
1116                 if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
1117
1118                 x = edgeNum - ccgdm->edgeMap[i].startEdge;
1119
1120                 med->v1 = getEdgeIndex(ss, e, x, edgeSize);
1121                 med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
1122
1123                 edgeFlag = dm->getEdgeData(dm, edgeNum, CD_FLAGS);
1124                 if(edgeFlag)
1125                         flags |= (*edgeFlag & (ME_SEAM | ME_SHARP))
1126                                          | ME_EDGEDRAW | ME_EDGERENDER;
1127                 else
1128                         flags |= ME_EDGEDRAW | ME_EDGERENDER;
1129
1130                 med->flag = flags;
1131         }
1132 }
1133
1134 static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
1135 {
1136         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1137         CCGSubSurf *ss = ccgdm->ss;
1138         int gridSize = ccgSubSurf_getGridSize(ss);
1139         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1140         int gridSideEdges = gridSize - 1;
1141         int gridFaces = gridSideEdges * gridSideEdges;
1142         int i;
1143         CCGFace *f;
1144         int numVerts;
1145         int offset;
1146         int grid;
1147         int x, y;
1148         int lastface = ccgSubSurf_getNumFaces(ss) - 1;
1149         char *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
1150
1151         memset(mf, 0, sizeof(*mf));
1152
1153         i = 0;
1154         while(i < lastface && faceNum >= ccgdm->faceMap[i + 1].startFace)
1155                 ++i;
1156
1157         f = ccgdm->faceMap[i].face;
1158         numVerts = ccgSubSurf_getFaceNumVerts(f);
1159
1160         offset = faceNum - ccgdm->faceMap[i].startFace;
1161         grid = offset / gridFaces;
1162         offset %= gridFaces;
1163         y = offset / gridSideEdges;
1164         x = offset % gridSideEdges;
1165
1166         mf->v1 = getFaceIndex(ss, f, grid, x+0, y+0, edgeSize, gridSize);
1167         mf->v2 = getFaceIndex(ss, f, grid, x+0, y+1, edgeSize, gridSize);
1168         mf->v3 = getFaceIndex(ss, f, grid, x+1, y+1, edgeSize, gridSize);
1169         mf->v4 = getFaceIndex(ss, f, grid, x+1, y+0, edgeSize, gridSize);
1170
1171         if(faceFlags) mf->flag = faceFlags[i*4];
1172         else mf->flag = ME_SMOOTH;
1173 }
1174
1175 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
1176 {
1177         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1178         CCGSubSurf *ss = ccgdm->ss;
1179         int index;
1180         int totvert, totedge, totface;
1181         int gridSize = ccgSubSurf_getGridSize(ss);
1182         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1183         int i = 0;
1184
1185         totface = ccgSubSurf_getNumFaces(ss);
1186         for(index = 0; index < totface; index++) {
1187                 CCGFace *f = ccgdm->faceMap[index].face;
1188                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1189
1190                 VecCopyf(mvert[i++].co, ccgSubSurf_getFaceCenterData(f));
1191                 
1192                 for(S = 0; S < numVerts; S++) {
1193                         for(x = 1; x < gridSize - 1; x++) {
1194                                 VecCopyf(mvert[i++].co,
1195                                          ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1196                         }
1197                 }
1198
1199                 for(S = 0; S < numVerts; S++) {
1200                         for(y = 1; y < gridSize - 1; y++) {
1201                                 for(x = 1; x < gridSize - 1; x++) {
1202                                         VecCopyf(mvert[i++].co,
1203                                                  ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1204                                 }
1205                         }
1206                 }
1207         }
1208
1209         totedge = ccgSubSurf_getNumEdges(ss);
1210         for(index = 0; index < totedge; index++) {
1211                 CCGEdge *e = ccgdm->edgeMap[index].edge;
1212                 int x;
1213
1214                 for(x = 1; x < edgeSize - 1; x++) {
1215                         VecCopyf(mvert[i++].co, ccgSubSurf_getEdgeData(ss, e, x));
1216                 }
1217         }
1218
1219         totvert = ccgSubSurf_getNumVerts(ss);
1220         for(index = 0; index < totvert; index++) {
1221                 CCGVert *v = ccgdm->vertMap[index].vert;
1222
1223                 VecCopyf(mvert[i].co, ccgSubSurf_getVertData(ss, v));
1224
1225                 i++;
1226         }
1227 }
1228
1229 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
1230 {
1231         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1232         CCGSubSurf *ss = ccgdm->ss;
1233         int index;
1234         int totedge, totface;
1235         int gridSize = ccgSubSurf_getGridSize(ss);
1236         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1237         int i = 0;
1238         int *edgeFlags = dm->getEdgeDataArray(dm, CD_FLAGS);
1239
1240         totface = ccgSubSurf_getNumFaces(ss);
1241         for(index = 0; index < totface; index++) {
1242                 CCGFace *f = ccgdm->faceMap[index].face;
1243                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1244
1245                 for(S = 0; S < numVerts; S++) {
1246                         for(x = 0; x < gridSize - 1; x++) {
1247                                 MEdge *med = &medge[i];
1248
1249                                 if(ccgdm->drawInteriorEdges)
1250                                     med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1251                                 med->v1 = getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize);
1252                                 med->v2 = getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize);
1253                                 i++;
1254                         }
1255
1256                         for(x = 1; x < gridSize - 1; x++) {
1257                                 for(y = 0; y < gridSize - 1; y++) {
1258                                         MEdge *med;
1259
1260                                         med = &medge[i];
1261                                         if(ccgdm->drawInteriorEdges)
1262                                             med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1263                                         med->v1 = getFaceIndex(ss, f, S, x, y,
1264                                                                edgeSize, gridSize);
1265                                         med->v2 = getFaceIndex(ss, f, S, x, y + 1,
1266                                                                edgeSize, gridSize);
1267                                         i++;
1268
1269                                         med = &medge[i];
1270                                         if(ccgdm->drawInteriorEdges)
1271                                             med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1272                                         med->v1 = getFaceIndex(ss, f, S, y, x,
1273                                                                edgeSize, gridSize);
1274                                         med->v2 = getFaceIndex(ss, f, S, y + 1, x,
1275                                                                edgeSize, gridSize);
1276                                         i++;
1277                                 }
1278                         }
1279                 }
1280         }
1281
1282         totedge = ccgSubSurf_getNumEdges(ss);
1283         for(index = 0; index < totedge; index++) {
1284                 CCGEdge *e = ccgdm->edgeMap[index].edge;
1285                 unsigned int flags = 0;
1286                 int x;
1287                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
1288
1289                 if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
1290
1291                 if(edgeFlags) {
1292                         if(edgeIdx != -1) {
1293                                 flags |= (edgeFlags[i] & (ME_SEAM | ME_SHARP))
1294                                          | ME_EDGEDRAW | ME_EDGERENDER;
1295                         }
1296                 } else {
1297                         flags |= ME_EDGEDRAW | ME_EDGERENDER;
1298                 }
1299
1300                 for(x = 0; x < edgeSize - 1; x++) {
1301                         MEdge *med = &medge[i];
1302                         med->v1 = getEdgeIndex(ss, e, x, edgeSize);
1303                         med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
1304                         med->flag = flags;
1305                         i++;
1306                 }
1307         }
1308 }
1309
1310 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
1311 {
1312         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1313         CCGSubSurf *ss = ccgdm->ss;
1314         int index;
1315         int totface;
1316         int gridSize = ccgSubSurf_getGridSize(ss);
1317         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1318         int i = 0;
1319         char *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
1320
1321         totface = ccgSubSurf_getNumFaces(ss);
1322         for(index = 0; index < totface; index++) {
1323                 CCGFace *f = ccgdm->faceMap[index].face;
1324                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1325                 int mat_nr = 0;
1326                 int flag = ME_SMOOTH; /* assume face is smooth by default */
1327
1328                 for(S = 0; S < numVerts; S++) {
1329                         for(y = 0; y < gridSize - 1; y++) {
1330                                 for(x = 0; x < gridSize - 1; x++) {
1331                                         MFace *mf = &mface[i];
1332                                         mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1333                                                               edgeSize, gridSize);
1334                                         mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1335                                                               edgeSize, gridSize);
1336                                         mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1337                                                               edgeSize, gridSize);
1338                                         mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1339                                                               edgeSize, gridSize);
1340                                         mf->mat_nr = mat_nr;
1341                                         if(faceFlags) mf->flag = faceFlags[index*4];
1342                                         else mf->flag = flag;
1343
1344                                         i++;
1345                                 }
1346                         }
1347                 }
1348         }
1349 }
1350
1351 static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
1352         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1353         CCGSubSurf *ss = ccgdm->ss;
1354         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1355         int gridSize = ccgSubSurf_getGridSize(ss);
1356         int i;
1357         CCGVertIterator *vi;
1358         CCGEdgeIterator *ei;
1359         CCGFaceIterator *fi;
1360         CCGFace **faceMap2;
1361         CCGEdge **edgeMap2;
1362         CCGVert **vertMap2;
1363         int index, totvert, totedge, totface;
1364         
1365         totvert = ccgSubSurf_getNumVerts(ss);
1366         vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
1367         vi = ccgSubSurf_getVertIterator(ss);
1368         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1369                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1370
1371                 vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v;
1372         }
1373         ccgVertIterator_free(vi);
1374
1375         totedge = ccgSubSurf_getNumEdges(ss);
1376         edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
1377         ei = ccgSubSurf_getEdgeIterator(ss);
1378         for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
1379                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1380
1381                 edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
1382         }
1383
1384         totface = ccgSubSurf_getNumFaces(ss);
1385         faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
1386         fi = ccgSubSurf_getFaceIterator(ss);
1387         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1388                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1389
1390                 faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f;
1391         }
1392         ccgFaceIterator_free(fi);
1393
1394         i = 0;
1395         for (index=0; index<totface; index++) {
1396                 CCGFace *f = faceMap2[index];
1397                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1398
1399                 VecCopyf(cos[i++], ccgSubSurf_getFaceCenterData(f));
1400                 
1401                 for (S=0; S<numVerts; S++) {
1402                         for (x=1; x<gridSize-1; x++) {
1403                                 VecCopyf(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1404                         }
1405                 }
1406
1407                 for (S=0; S<numVerts; S++) {
1408                         for (y=1; y<gridSize-1; y++) {
1409                                 for (x=1; x<gridSize-1; x++) {
1410                                         VecCopyf(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1411                                 }
1412                         }
1413                 }
1414         }
1415
1416         for (index=0; index<totedge; index++) {
1417                 CCGEdge *e= edgeMap2[index];
1418                 int x;
1419
1420                 for (x=1; x<edgeSize-1; x++) {
1421                         VecCopyf(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
1422                 }
1423         }
1424
1425         for (index=0; index<totvert; index++) {
1426                 CCGVert *v = vertMap2[index];
1427                 VecCopyf(cos[i++], ccgSubSurf_getVertData(ss, v));
1428         }
1429
1430         MEM_freeN(vertMap2);
1431         MEM_freeN(edgeMap2);
1432         MEM_freeN(faceMap2);
1433 }
1434 static void ccgDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
1435         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1436         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
1437
1438         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1439                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1440                 VertData *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
1441                 int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
1442
1443                 if (index!=-1)
1444                         func(userData, index, vd->co, vd->no, NULL);
1445         }
1446
1447         ccgVertIterator_free(vi);
1448 }
1449 static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
1450         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1451         CCGSubSurf *ss = ccgdm->ss;
1452         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1453         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1454
1455         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1456                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1457                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1458                 int index = ccgDM_getEdgeMapIndex(ss, e);
1459
1460                 if (index!=-1) {
1461                         for (i=0; i<edgeSize-1; i++)
1462                                 func(userData, index, edgeData[i].co, edgeData[i+1].co);
1463                 }
1464         }
1465
1466         ccgEdgeIterator_free(ei);
1467 }
1468
1469 static void ccgDM_drawVerts(DerivedMesh *dm) {
1470         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1471         CCGSubSurf *ss = ccgdm->ss;
1472         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1473         int gridSize = ccgSubSurf_getGridSize(ss);
1474         CCGVertIterator *vi;
1475         CCGEdgeIterator *ei;
1476         CCGFaceIterator *fi;
1477
1478         glBegin(GL_POINTS);
1479         vi = ccgSubSurf_getVertIterator(ss);
1480         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1481                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1482                 glVertex3fv(ccgSubSurf_getVertData(ss, v));
1483         }
1484         ccgVertIterator_free(vi);
1485
1486         ei = ccgSubSurf_getEdgeIterator(ss);
1487         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1488                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1489                 int x;
1490
1491                 for (x=1; x<edgeSize-1; x++)
1492                         glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
1493         }
1494         ccgEdgeIterator_free(ei);
1495
1496         fi = ccgSubSurf_getFaceIterator(ss);
1497         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1498                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1499                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1500
1501                 glVertex3fv(ccgSubSurf_getFaceCenterData(f));
1502                 for (S=0; S<numVerts; S++)
1503                         for (x=1; x<gridSize-1; x++)
1504                                 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1505                 for (S=0; S<numVerts; S++)
1506                         for (y=1; y<gridSize-1; y++)
1507                                 for (x=1; x<gridSize-1; x++)
1508                                         glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1509         }
1510         ccgFaceIterator_free(fi);
1511         glEnd();
1512 }
1513 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) {
1514         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1515         CCGSubSurf *ss = ccgdm->ss;
1516         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1517         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1518         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1519         int gridSize = ccgSubSurf_getGridSize(ss);
1520         int useAging;
1521
1522         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1523
1524         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1525                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1526                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1527
1528                 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e))
1529                         continue;
1530
1531                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1532                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1533                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1534                 }
1535
1536                 glBegin(GL_LINE_STRIP);
1537                 for (i=0; i<edgeSize-1; i++) {
1538                         glVertex3fv(edgeData[i].co);
1539                         glVertex3fv(edgeData[i+1].co);
1540                 }
1541                 glEnd();
1542         }
1543
1544         if (useAging && !(G.f&G_BACKBUFSEL)) {
1545                 glColor3ub(0, 0, 0);
1546         }
1547
1548         if (ccgdm->drawInteriorEdges) {
1549                 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1550                         CCGFace *f = ccgFaceIterator_getCurrent(fi);
1551                         int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1552
1553                         for (S=0; S<numVerts; S++) {
1554                                 VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1555
1556                                 glBegin(GL_LINE_STRIP);
1557                                 for (x=0; x<gridSize; x++)
1558                                         glVertex3fv(faceGridData[x].co);
1559                                 glEnd();
1560                                 for (y=1; y<gridSize-1; y++) {
1561                                         glBegin(GL_LINE_STRIP);
1562                                         for (x=0; x<gridSize; x++)
1563                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1564                                         glEnd();
1565                                 }
1566                                 for (x=1; x<gridSize-1; x++) {
1567                                         glBegin(GL_LINE_STRIP);
1568                                         for (y=0; y<gridSize; y++)
1569                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1570                                         glEnd();
1571                                 }
1572                         }
1573                 }
1574         }
1575
1576         ccgFaceIterator_free(fi);
1577         ccgEdgeIterator_free(ei);
1578 }
1579 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
1580         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1581         CCGSubSurf *ss = ccgdm->ss;
1582         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1583         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1584
1585         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1586                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1587                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1588
1589                 if (!ccgSubSurf_getEdgeNumFaces(e)) {
1590                         glBegin(GL_LINE_STRIP);
1591                         for (i=0; i<edgeSize-1; i++) {
1592                                 glVertex3fv(edgeData[i].co);
1593                                 glVertex3fv(edgeData[i+1].co);
1594                         }
1595                         glEnd();
1596                 }
1597         }
1598
1599         ccgEdgeIterator_free(ei);
1600 }
1601
1602 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
1603 {
1604         float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1605         float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1606         float no[3];
1607
1608         no[0] = b_dY*a_cZ - b_dZ*a_cY;
1609         no[1] = b_dZ*a_cX - b_dX*a_cZ;
1610         no[2] = b_dX*a_cY - b_dY*a_cX;
1611
1612         /* don't normalize, GL_NORMALIZE is be enabled */
1613         glNormal3fv(no);
1614 }
1615
1616         /* Only used by non-editmesh types */
1617 static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
1618         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1619         CCGSubSurf *ss = ccgdm->ss;
1620         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1621         int gridSize = ccgSubSurf_getGridSize(ss);
1622         char *faceFlags = DM_get_face_data_layer(dm, CD_FLAGS);
1623
1624         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1625                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1626                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1627                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1628                 int drawSmooth, mat_nr;
1629
1630                 if(faceFlags) {
1631                         drawSmooth = (faceFlags[index*4] & ME_SMOOTH);
1632                         mat_nr= faceFlags[index*4 + 1];
1633                 }
1634                 else {
1635                         drawSmooth = 1;
1636                         mat_nr= 0;
1637                 }
1638                 
1639                 if (!setMaterial(mat_nr+1, NULL))
1640                         continue;
1641
1642                 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1643                 for (S=0; S<numVerts; S++) {
1644                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1645
1646                         if (drawSmooth) {
1647                                 for (y=0; y<gridSize-1; y++) {
1648                                         glBegin(GL_QUAD_STRIP);
1649                                         for (x=0; x<gridSize; x++) {
1650                                                 VertData *a = &faceGridData[(y+0)*gridSize + x];
1651                                                 VertData *b = &faceGridData[(y+1)*gridSize + x];
1652
1653                                                 glNormal3fv(a->no);
1654                                                 glVertex3fv(a->co);
1655                                                 glNormal3fv(b->no);
1656                                                 glVertex3fv(b->co);
1657                                         }
1658                                         glEnd();
1659                                 }
1660                         } else {
1661                                 glBegin(GL_QUADS);
1662                                 for (y=0; y<gridSize-1; y++) {
1663                                         for (x=0; x<gridSize-1; x++) {
1664                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
1665                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1666                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1667                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
1668
1669                                                 ccgDM_glNormalFast(a, b, c, d);
1670
1671                                                 glVertex3fv(d);
1672                                                 glVertex3fv(c);
1673                                                 glVertex3fv(b);
1674                                                 glVertex3fv(a);
1675                                         }
1676                                 }
1677                                 glEnd();
1678                         }
1679                 }
1680         }
1681
1682         ccgFaceIterator_free(fi);
1683 }
1684
1685         /* Only used by non-editmesh types */
1686 static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) {
1687         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1688         CCGSubSurf *ss = ccgdm->ss;
1689         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1690         GPUVertexAttribs gattribs;
1691         DMVertexAttribs attribs;
1692         MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE);
1693         int gridSize = ccgSubSurf_getGridSize(ss);
1694         int gridFaces = gridSize - 1;
1695         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1696         int transp, orig_transp, new_transp;
1697         char *faceFlags = DM_get_face_data_layer(dm, CD_FLAGS);
1698         int a, b, i, doDraw, numVerts, matnr, new_matnr, totface;
1699
1700         doDraw = 0;
1701         numVerts = 0;
1702         matnr = -1;
1703         transp = GPU_get_material_blend_mode();
1704         orig_transp = transp;
1705
1706         memset(&attribs, 0, sizeof(attribs));
1707
1708 #define PASSATTRIB(dx, dy, vert) {                                                                                              \
1709         if(attribs.totorco) {                                                                                                           \
1710                 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize);                 \
1711                 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
1712         }                                                                                                                                                       \
1713         for(b = 0; b < attribs.tottface; b++) {                                                                         \
1714                 MTFace *tf = &attribs.tface[b].array[a];                                                                \
1715                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);                   \
1716         }                                                                                                                                                       \
1717         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
1718                 MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
1719                 GLubyte col[4];                                                                                                                 \
1720                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
1721                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
1722         }                                                                                                                                                       \
1723         if(attribs.tottang) {                                                                                                           \
1724                 float *tang = attribs.tang.array[a*4 + vert];                                                   \
1725                 glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
1726         }                                                                                                                                                       \
1727 }
1728
1729         totface = ccgSubSurf_getNumFaces(ss);
1730         for(a = 0, i = 0; i < totface; i++) {
1731                 CCGFace *f = ccgdm->faceMap[i].face;
1732                 int S, x, y, drawSmooth;
1733                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1734                 int origIndex = ccgDM_getFaceMapIndex(ss, f);
1735                 
1736                 numVerts = ccgSubSurf_getFaceNumVerts(f);
1737
1738                 if(faceFlags) {
1739                         drawSmooth = (faceFlags[index*4] & ME_SMOOTH);
1740                         new_matnr= faceFlags[index*4 + 1] + 1;
1741                 }
1742                 else {
1743                         drawSmooth = 1;
1744                         new_matnr= 1;
1745                 }
1746
1747                 if(new_matnr != matnr) {
1748                         doDraw = setMaterial(matnr = new_matnr, &gattribs);
1749                         if(doDraw)
1750                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1751                 }
1752
1753                 if(!doDraw || (setDrawOptions && !setDrawOptions(userData, origIndex))) {
1754                         a += gridFaces*gridFaces*numVerts;
1755                         continue;
1756                 }
1757
1758                 if(tf) {
1759                         new_transp = tf[i].transp;
1760
1761                         if(new_transp != transp) {
1762                                 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
1763                                         GPU_set_material_blend_mode(orig_transp);
1764                                 else
1765                                         GPU_set_material_blend_mode(new_transp);
1766                                 transp = new_transp;
1767                         }
1768                 }
1769
1770                 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1771                 for (S=0; S<numVerts; S++) {
1772                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1773                         VertData *vda, *vdb;
1774
1775                         if (drawSmooth) {
1776                                 for (y=0; y<gridFaces; y++) {
1777                                         glBegin(GL_QUAD_STRIP);
1778                                         for (x=0; x<gridFaces; x++) {
1779                                                 vda = &faceGridData[(y+0)*gridSize + x];
1780                                                 vdb = &faceGridData[(y+1)*gridSize + x];
1781                                                 
1782                                                 PASSATTRIB(0, 0, 0);
1783                                                 glNormal3fv(vda->no);
1784                                                 glVertex3fv(vda->co);
1785
1786                                                 PASSATTRIB(0, 1, 1);
1787                                                 glNormal3fv(vdb->no);
1788                                                 glVertex3fv(vdb->co);
1789
1790                                                 if(x != gridFaces-1)
1791                                                         a++;
1792                                         }
1793
1794                                         vda = &faceGridData[(y+0)*gridSize + x];
1795                                         vdb = &faceGridData[(y+1)*gridSize + x];
1796
1797                                         PASSATTRIB(0, 0, 3);
1798                                         glNormal3fv(vda->no);
1799                                         glVertex3fv(vda->co);
1800
1801                                         PASSATTRIB(0, 1, 2);
1802                                         glNormal3fv(vdb->no);
1803                                         glVertex3fv(vdb->co);
1804
1805                                         glEnd();
1806
1807                                         a++;
1808                                 }
1809                         } else {
1810                                 glBegin(GL_QUADS);
1811                                 for (y=0; y<gridFaces; y++) {
1812                                         for (x=0; x<gridFaces; x++) {
1813                                                 float *aco = faceGridData[(y+0)*gridSize + x].co;
1814                                                 float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
1815                                                 float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
1816                                                 float *dco = faceGridData[(y+1)*gridSize + x].co;
1817
1818                                                 ccgDM_glNormalFast(aco, bco, cco, dco);
1819
1820                                                 PASSATTRIB(0, 1, 1);
1821                                                 glVertex3fv(dco);
1822                                                 PASSATTRIB(1, 1, 2);
1823                                                 glVertex3fv(cco);
1824                                                 PASSATTRIB(1, 0, 3);
1825                                                 glVertex3fv(bco);
1826                                                 PASSATTRIB(0, 0, 0);
1827                                                 glVertex3fv(aco);
1828                                                 
1829                                                 a++;
1830                                         }
1831                                 }
1832                                 glEnd();
1833                         }
1834                 }
1835         }
1836
1837 #undef PASSATTRIB
1838
1839         ccgFaceIterator_free(fi);
1840 }
1841
1842 static void ccgDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
1843         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1844 }
1845
1846 static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2) {
1847         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1848         CCGSubSurf *ss = ccgdm->ss;
1849         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1850         int gridSize = ccgSubSurf_getGridSize(ss);
1851         unsigned char *cp1, *cp2;
1852         int useTwoSide=1;
1853
1854         cp1= col1;
1855         if(col2) {
1856                 cp2= col2;
1857         } else {
1858                 cp2= NULL;
1859                 useTwoSide= 0;
1860         }
1861
1862         glShadeModel(GL_SMOOTH);
1863         if(col1 && col2)
1864                 glEnable(GL_CULL_FACE);
1865
1866         glBegin(GL_QUADS);
1867         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1868                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1869                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1870
1871                 for (S=0; S<numVerts; S++) {
1872                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1873                         for (y=0; y<gridSize-1; y++) {
1874                                 for (x=0; x<gridSize-1; x++) {
1875                                         float *a = faceGridData[(y+0)*gridSize + x].co;
1876                                         float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1877                                         float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1878                                         float *d = faceGridData[(y+1)*gridSize + x].co;
1879
1880                                         glColor3ub(cp1[3], cp1[2], cp1[1]);
1881                                         glVertex3fv(d);
1882                                         glColor3ub(cp1[7], cp1[6], cp1[5]);
1883                                         glVertex3fv(c);
1884                                         glColor3ub(cp1[11], cp1[10], cp1[9]);
1885                                         glVertex3fv(b);
1886                                         glColor3ub(cp1[15], cp1[14], cp1[13]);
1887                                         glVertex3fv(a);
1888
1889                                         if (useTwoSide) {
1890                                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
1891                                                 glVertex3fv(a);
1892                                                 glColor3ub(cp2[11], cp2[10], cp2[9]);
1893                                                 glVertex3fv(b);
1894                                                 glColor3ub(cp2[7], cp2[6], cp2[5]);
1895                                                 glVertex3fv(c);
1896                                                 glColor3ub(cp2[3], cp2[2], cp2[1]);
1897                                                 glVertex3fv(d);
1898                                         }
1899
1900                                         if (cp2) cp2+=16;
1901                                         cp1+=16;
1902                                 }
1903                         }
1904                 }
1905         }
1906         glEnd();
1907
1908         ccgFaceIterator_free(fi);
1909 }
1910
1911 static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
1912         int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
1913         int (*drawParamsMapped)(void *userData, int index),
1914         void *userData) 
1915 {
1916         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1917         CCGSubSurf *ss = ccgdm->ss;
1918         MCol *mcol = DM_get_face_data_layer(dm, CD_MCOL);
1919         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
1920         char *faceFlags = DM_get_face_data_layer(dm, CD_FLAGS);
1921         int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss);
1922         int gridFaces = gridSize - 1;
1923
1924         totface = ccgSubSurf_getNumFaces(ss);
1925         for(i = 0; i < totface; i++) {
1926                 CCGFace *f = ccgdm->faceMap[i].face;
1927                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1928                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
1929                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1930                 unsigned char *cp= NULL;
1931                 int mat_nr;
1932
1933                 if(faceFlags) {
1934                         drawSmooth = (faceFlags[origIndex*4] & ME_SMOOTH);
1935                         mat_nr= faceFlags[origIndex*4 + 1];
1936                 }
1937                 else {
1938                         drawSmooth = 1;
1939                         mat_nr= 0;
1940                 }
1941
1942                 if(drawParams)
1943                         flag = drawParams(tf, mcol, mat_nr);
1944                 else
1945                         flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1;
1946                 
1947                 if (flag == 0) { /* flag 0 == the face is hidden or invisible */
1948                         if(tf) tf += gridFaces*gridFaces*numVerts;
1949                         if(mcol) mcol += gridFaces*gridFaces*numVerts*4;
1950                         continue;
1951                 }
1952
1953                 /* flag 1 == use vertex colors */
1954                 if(mcol) {
1955                         if(flag==1) cp= (unsigned char*)mcol;
1956                         mcol += gridFaces*gridFaces*numVerts*4;
1957                 }
1958
1959                 for (S=0; S<numVerts; S++) {
1960                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1961                         VertData *a, *b;
1962
1963                         if (drawSmooth) {
1964                                 glShadeModel(GL_SMOOTH);
1965                                 for (y=0; y<gridFaces; y++) {
1966                                         glBegin(GL_QUAD_STRIP);
1967                                         for (x=0; x<gridFaces; x++) {
1968                                                 a = &faceGridData[(y+0)*gridSize + x];
1969                                                 b = &faceGridData[(y+1)*gridSize + x];
1970
1971                                                 if(tf) glTexCoord2fv(tf->uv[0]);
1972                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1973                                                 glNormal3fv(a->no);
1974                                                 glVertex3fv(a->co);
1975
1976                                                 if(tf) glTexCoord2fv(tf->uv[1]);
1977                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1978                                                 glNormal3fv(b->no);
1979                                                 glVertex3fv(b->co);
1980                                                 
1981                                                 if(x != gridFaces-1) {
1982                                                         if(tf) tf++;
1983                                                         if(cp) cp += 16;
1984                                                 }
1985                                         }
1986
1987                                         a = &faceGridData[(y+0)*gridSize + x];
1988                                         b = &faceGridData[(y+1)*gridSize + x];
1989
1990                                         if(tf) glTexCoord2fv(tf->uv[3]);
1991                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1992                                         glNormal3fv(a->no);
1993                                         glVertex3fv(a->co);
1994
1995                                         if(tf) glTexCoord2fv(tf->uv[2]);
1996                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1997                                         glNormal3fv(b->no);
1998                                         glVertex3fv(b->co);
1999
2000                                         if(tf) tf++;
2001                                         if(cp) cp += 16;
2002
2003                                         glEnd();
2004                                 }
2005                         } else {
2006                                 glShadeModel(GL_FLAT);
2007                                 glBegin(GL_QUADS);
2008                                 for (y=0; y<gridFaces; y++) {
2009                                         for (x=0; x<gridFaces; x++) {
2010                                                 float *a_co = faceGridData[(y+0)*gridSize + x].co;
2011                                                 float *b_co = faceGridData[(y+0)*gridSize + x + 1].co;
2012                                                 float *c_co = faceGridData[(y+1)*gridSize + x + 1].co;
2013                                                 float *d_co = faceGridData[(y+1)*gridSize + x].co;
2014
2015                                                 ccgDM_glNormalFast(a_co, b_co, c_co, d_co);
2016
2017                                                 if(tf) glTexCoord2fv(tf->uv[1]);
2018                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2019                                                 glVertex3fv(d_co);
2020
2021                                                 if(tf) glTexCoord2fv(tf->uv[2]);
2022                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2023                                                 glVertex3fv(c_co);
2024
2025                                                 if(tf) glTexCoord2fv(tf->uv[3]);
2026                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2027                                                 glVertex3fv(b_co);
2028
2029                                                 if(tf) glTexCoord2fv(tf->uv[0]);
2030                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2031                                                 glVertex3fv(a_co);
2032
2033                                                 if(tf) tf++;
2034                                                 if(cp) cp += 16;
2035                                         }
2036                                 }
2037                                 glEnd();
2038                         }
2039                 }
2040         }
2041 }
2042
2043 static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
2044 {
2045         ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
2046 }
2047
2048 static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
2049 {
2050         ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
2051 }
2052
2053 static void ccgDM_drawUVEdges(DerivedMesh *dm)
2054 {
2055
2056         MFace *mf = dm->getFaceArray(dm);
2057         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
2058         int i;
2059         
2060         if (tf) {
2061                 glBegin(GL_LINES);
2062                 for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
2063                         if(!(mf->flag&ME_HIDE)) {
2064                                 glVertex2fv(tf->uv[0]);
2065                                 glVertex2fv(tf->uv[1]);
2066         
2067                                 glVertex2fv(tf->uv[1]);
2068                                 glVertex2fv(tf->uv[2]);
2069         
2070                                 if(!mf->v4) {
2071                                         glVertex2fv(tf->uv[2]);
2072                                         glVertex2fv(tf->uv[0]);
2073                                 } else {
2074                                         glVertex2fv(tf->uv[2]);
2075                                         glVertex2fv(tf->uv[3]);
2076         
2077                                         glVertex2fv(tf->uv[3]);
2078                                         glVertex2fv(tf->uv[0]);
2079                                 }
2080                         }
2081                 }
2082                 glEnd();
2083         }
2084 }
2085
2086 static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) {
2087         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2088         CCGSubSurf *ss = ccgdm->ss;
2089         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
2090         int i, gridSize = ccgSubSurf_getGridSize(ss);
2091         char *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS);
2092
2093         for (i=0; !ccgFaceIterator_isStopped(fi); i++,ccgFaceIterator_next(fi)) {
2094                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2095                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2096                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
2097                 int origIndex;
2098
2099                 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2100
2101                 if(faceFlags) drawSmooth = (faceFlags[origIndex*4] & ME_SMOOTH);
2102                 else drawSmooth = 1;
2103                 
2104                 if (index!=-1) {
2105                         int draw;
2106                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, index, &drawSmooth);
2107                         
2108                         if (draw) {
2109                                 if (draw==2) {
2110                                         glEnable(GL_POLYGON_STIPPLE);
2111                                         glPolygonStipple(stipple_quarttone);
2112                                 }
2113                                 
2114                                 for (S=0; S<numVerts; S++) {
2115                                         VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2116                                         if (drawSmooth) {
2117                                                 glShadeModel(GL_SMOOTH);
2118                                                 for (y=0; y<gridSize-1; y++) {
2119                                                         glBegin(GL_QUAD_STRIP);
2120                                                         for (x=0; x<gridSize; x++) {
2121                                                                 VertData *a = &faceGridData[(y+0)*gridSize + x];
2122                                                                 VertData *b = &faceGridData[(y+1)*gridSize + x];
2123         
2124                                                                 glNormal3fv(a->no);
2125                                                                 glVertex3fv(a->co);
2126                                                                 glNormal3fv(b->no);
2127                                                                 glVertex3fv(b->co);
2128                                                         }
2129                                                         glEnd();
2130                                                 }
2131                                         } else {
2132                                                 glShadeModel(GL_FLAT);
2133                                                 glBegin(GL_QUADS);
2134                                                 for (y=0; y<gridSize-1; y++) {
2135                                                         for (x=0; x<gridSize-1; x++) {
2136                                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
2137                                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
2138                                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
2139                                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
2140                                                                 float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
2141                                                                 float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
2142                                                                 float no[3];
2143         
2144                                                                 no[0] = b_dY*a_cZ - b_dZ*a_cY;
2145                                                                 no[1] = b_dZ*a_cX - b_dX*a_cZ;
2146                                                                 no[2] = b_dX*a_cY - b_dY*a_cX;
2147                                                                 glNormal3fv(no);
2148         
2149                                                                 glVertex3fv(d);
2150                                                                 glVertex3fv(c);
2151                                                                 glVertex3fv(b);
2152                                                                 glVertex3fv(a);
2153                                                         }
2154                                                 }
2155                                                 glEnd();
2156                                         }
2157                                 }
2158                                 if (draw==2)
2159                                         glDisable(GL_POLYGON_STIPPLE);
2160                         }
2161                 }
2162         }
2163
2164         ccgFaceIterator_free(fi);
2165 }
2166 static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
2167         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2168         CCGSubSurf *ss = ccgdm->ss;
2169         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2170         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2171
2172         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2173
2174         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2175                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2176                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2177                 int index = ccgDM_getEdgeMapIndex(ss, e);
2178
2179                 glBegin(GL_LINE_STRIP);
2180                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2181                         if (useAging && !(G.f&G_BACKBUFSEL)) {
2182                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2183                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
2184                         }
2185
2186                         for (i=0; i<edgeSize-1; i++) {
2187                                 glVertex3fv(edgeData[i].co);
2188                                 glVertex3fv(edgeData[i+1].co);
2189                         }
2190                 }
2191                 glEnd();
2192         }
2193
2194         ccgEdgeIterator_free(ei);
2195 }
2196 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
2197         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2198         CCGSubSurf *ss = ccgdm->ss;
2199         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2200         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2201
2202         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2203
2204         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2205                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2206                 VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2207                 int index = ccgDM_getEdgeMapIndex(ss, e);
2208
2209                 glBegin(GL_LINE_STRIP);
2210                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2211                         for (i=0; i<edgeSize; i++) {
2212                                 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
2213
2214                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
2215                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2216                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
2217                                 }
2218
2219                                 glVertex3fv(edgeData[i].co);
2220                         }
2221                 }
2222                 glEnd();
2223         }
2224
2225         ccgEdgeIterator_free(ei);
2226 }
2227 static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
2228         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2229         CCGSubSurf *ss = ccgdm->ss;
2230         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
2231
2232         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2233                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2234                 int index = ccgDM_getFaceMapIndex(ss, f);
2235
2236                 if (index!=-1) {
2237                                 /* Face center data normal isn't updated atm. */
2238                         VertData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
2239
2240                         func(userData, index, vd->co, vd->no);
2241                 }
2242         }
2243
2244         ccgFaceIterator_free(fi);
2245 }
2246
2247 static void ccgDM_release(DerivedMesh *dm) {
2248         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2249
2250         if (DM_release(dm)) {
2251                 MEM_freeN(ccgdm->vertMap);
2252                 MEM_freeN(ccgdm->edgeMap);
2253                 MEM_freeN(ccgdm->faceMap);
2254                 MEM_freeN(ccgdm);
2255         }
2256 }
2257
2258 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2259                                          int drawInteriorEdges,
2260                                          int useSubsurfUv,
2261                                          DerivedMesh *dm)
2262 {
2263         CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
2264         CCGVertIterator *vi;
2265         CCGEdgeIterator *ei;
2266         CCGFaceIterator *fi;
2267         int index, totvert, totedge, totface;
2268         int i;
2269         int vertNum, edgeNum, faceNum;
2270         int *vertOrigIndex, *faceOrigIndex; /* *edgeOrigIndex - as yet, unused  */
2271         int *edgeFlags;
2272         char *faceFlags;
2273         int edgeSize;
2274         int gridSize;
2275         int gridFaces;
2276         int gridSideVerts;
2277         /*int gridInternalVerts; - as yet unused */
2278         int gridSideEdges;
2279         int gridInternalEdges;
2280         /* MVert *mvert = NULL; - as yet unused */
2281         MEdge *medge = NULL;
2282         MFace *mface = NULL;
2283         FaceVertWeight *qweight, *tweight;
2284
2285         DM_from_template(&ccgdm->dm, dm, ccgSubSurf_getNumFinalVerts(ss),
2286                                          ccgSubSurf_getNumFinalEdges(ss),
2287                                          ccgSubSurf_getNumFinalFaces(ss));
2288         DM_add_face_layer(&ccgdm->dm, CD_FLAGS, CD_CALLOC, NULL);
2289         DM_add_edge_layer(&ccgdm->dm, CD_FLAGS, CD_CALLOC, NULL);
2290
2291         CustomData_set_layer_flag(&ccgdm->dm.faceData, CD_FLAGS, CD_FLAG_NOCOPY);
2292         CustomData_set_layer_flag(&ccgdm->dm.edgeData, CD_FLAGS, CD_FLAG_NOCOPY);
2293
2294         ccgdm->dm.getMinMax = ccgDM_getMinMax;
2295         ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
2296         ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
2297
2298         ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
2299         ccgdm->dm.getVert = ccgDM_getFinalVert;
2300         ccgdm->dm.getEdge = ccgDM_getFinalEdge;
2301         ccgdm->dm.getFace = ccgDM_getFinalFace;
2302         ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2303         ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2304         ccgdm->dm.copyFaceArray = ccgDM_copyFinalFaceArray;
2305         ccgdm->dm.getVertData = DM_get_vert_data;
2306         ccgdm->dm.getEdgeData = DM_get_edge_data;
2307         ccgdm->dm.getFaceData = DM_get_face_data;
2308         ccgdm->dm.getVertDataArray = DM_get_vert_data_layer;
2309         ccgdm->dm.getEdgeDataArray = DM_get_edge_data_layer;
2310         ccgdm->dm.getFaceDataArray = DM_get_face_data_layer;
2311
2312         ccgdm->dm.getVertCos = ccgdm_getVertCos;
2313         ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
2314         ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
2315         ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
2316         
2317         ccgdm->dm.drawVerts = ccgDM_drawVerts;
2318         ccgdm->dm.drawEdges = ccgDM_drawEdges;
2319         ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
2320         ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
2321         ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
2322         ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
2323         ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL;
2324         ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
2325         ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
2326         ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL;
2327         ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
2328
2329         ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
2330         ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
2331         
2332         ccgdm->dm.release = ccgDM_release;
2333         
2334         ccgdm->ss = ss;
2335         ccgdm->drawInteriorEdges = drawInteriorEdges;
2336         ccgdm->useSubsurfUv = useSubsurfUv;
2337
2338         totvert = ccgSubSurf_getNumVerts(ss);
2339         ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
2340         vi = ccgSubSurf_getVertIterator(ss);
2341         for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2342                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2343
2344                 ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
2345         }
2346         ccgVertIterator_free(vi);
2347
2348         totedge = ccgSubSurf_getNumEdges(ss);
2349         ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
2350         ei = ccgSubSurf_getEdgeIterator(ss);
2351         for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2352                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2353
2354                 ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
2355         }
2356
2357         totface = ccgSubSurf_getNumFaces(ss);
2358         ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
2359         fi = ccgSubSurf_getFaceIterator(ss);
2360         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2361                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2362
2363                 ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
2364         }
2365         ccgFaceIterator_free(fi);
2366
2367         edgeSize = ccgSubSurf_getEdgeSize(ss);
2368         gridSize = ccgSubSurf_getGridSize(ss);
2369         gridFaces = gridSize - 1;
2370         gridSideVerts = gridSize - 2;
2371         /*gridInternalVerts = gridSideVerts * gridSideVerts; - as yet, unused */
2372         gridSideEdges = gridSize - 1;
2373         gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
2374
2375         calc_ss_weights(gridFaces, &qweight, &tweight);
2376
2377         vertNum = 0;
2378         edgeNum = 0;
2379         faceNum = 0;
2380
2381         /* mvert = dm->getVertArray(dm); - as yet unused */
2382         medge = dm->getEdgeArray(dm);
2383         mface = dm->getFaceArray(dm);
2384
2385         vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2386         /*edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);*/
2387         faceOrigIndex = DM_get_face_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2388
2389         faceFlags = DM_get_face_data_layer(&ccgdm->dm, CD_FLAGS);
2390
2391         for(index = 0; index < totface; ++index) {
2392                 CCGFace *f = ccgdm->faceMap[index].face;
2393                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2394                 int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
2395                 int mapIndex = ccgDM_getFaceMapIndex(ss, f);
2396                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2397                 FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
2398                 int S, x, y;
2399                 int vertIdx[4];
2400
2401                 ccgdm->faceMap[index].startVert = vertNum;
2402                 ccgdm->faceMap[index].startEdge = edgeNum;
2403                 ccgdm->faceMap[index].startFace = faceNum;
2404
2405                 /* set the face base vert */
2406                 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
2407
2408                 for(S = 0; S < numVerts; S++) {
2409                         CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
2410
2411                         vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2412                 }
2413
2414                 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, weight[0][0],
2415                                     numVerts, vertNum);
2416                 *vertOrigIndex = ORIGINDEX_NONE;
2417                 ++vertOrigIndex;
2418                 ++vertNum;
2419
2420                 for(S = 0; S < numVerts; S++) {
2421                         int prevS = (S - 1 + numVerts) % numVerts;
2422                         int nextS = (S + 1) % numVerts;
2423                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2424                         for(x = 1; x < gridFaces; x++) {
2425                                 float w[4];
2426                                 w[prevS]  = weight[x][0][0];
2427                                 w[S]      = weight[x][0][1];
2428                                 w[nextS]  = weight[x][0][2];
2429                                 w[otherS] = weight[x][0][3];
2430                                 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2431                                                     numVerts, vertNum);
2432                                 *vertOrigIndex = ORIGINDEX_NONE;
2433                                 ++vertOrigIndex;
2434                                 ++vertNum;
2435                         }
2436                 }
2437
2438                 for(S = 0; S < numVerts; S++) {
2439                         int prevS = (S - 1 + numVerts) % numVerts;
2440                         int nextS = (S + 1) % numVerts;
2441                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2442                         for(y = 1; y < gridFaces; y++) {
2443                                 for(x = 1; x < gridFaces; x++) {
2444                                         float w[4];
2445                                         w[prevS]  = weight[y * gridFaces + x][0][0];
2446                                         w[S]      = weight[y * gridFaces + x][0][1];
2447                                         w[nextS]  = weight[y * gridFaces + x][0][2];
2448                                         w[otherS] = weight[y * gridFaces + x][0][3];
2449                                         DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2450                                                             numVerts, vertNum);
2451                                         *vertOrigIndex = ORIGINDEX_NONE;
2452                                         ++vertOrigIndex;
2453                                         ++vertNum;
2454                                 }
2455                         }
2456                 }
2457
2458                 for(i = 0; i < numFinalEdges; ++i)
2459                         *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i,
2460                                                  CD_ORIGINDEX) = ORIGINDEX_NONE;
2461
2462                 for(S = 0; S < numVerts; S++) {
2463                         int prevS = (S - 1 + numVerts) % numVerts;
2464                         int nextS = (S + 1) % numVerts;
2465                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2466
2467                         weight = (numVerts == 4) ? qweight : tweight;
2468
2469                         for(y = 0; y < gridFaces; y++) {
2470                                 for(x = 0; x < gridFaces; x++) {
2471                                         FaceVertWeight w;
2472                                         int j;
2473
2474                                         for(j = 0; j < 4; ++j) {
2475                                                 w[j][prevS]  = (*weight)[j][0];
2476                                                 w[j][S]      = (*weight)[j][1];
2477                                                 w[j][nextS]  = (*weight)[j][2];
2478                                                 w[j][otherS] = (*weight)[j][3];
2479                                         }
2480
2481                                         DM_interp_face_data(dm, &ccgdm->dm, &origIndex, NULL,
2482                                                             &w, 1, faceNum);
2483                                         weight++;
2484
2485                                         *faceOrigIndex = mapIndex;
2486
2487                                         ++faceOrigIndex;
2488                                         ++faceNum;
2489                                 }
2490                         }
2491                 }
2492
2493                 faceFlags[index*4] = mface[origIndex].flag;
2494                 faceFlags[index*4 + 1] = mface[origIndex].mat_nr;
2495
2496                 edgeNum += numFinalEdges;
2497         }
2498
2499         if(useSubsurfUv) {
2500                 CustomData *fdata = &ccgdm->dm.faceData;
2501                 CustomData *dmfdata = &dm->faceData;
2502                 int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
2503                 int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
2504
2505                 for (i=0; i<numlayer && i<dmnumlayer; i++)
2506                         set_subsurf_uv(ss, dm, &ccgdm->dm, i);
2507         }
2508
2509         edgeFlags = DM_get_edge_data_layer(&ccgdm->dm, CD_FLAGS);
2510
2511         for(index = 0; index < totedge; ++index) {
2512                 CCGEdge *e = ccgdm->edgeMap[index].edge;
2513                 int numFinalEdges = edgeSize - 1;
2514                 int mapIndex = ccgDM_getEdgeMapIndex(ss, e);
2515                 int x;
2516                 int vertIdx[2];
2517                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
2518
2519                 CCGVert *v;
2520                 v = ccgSubSurf_getEdgeVert0(e);
2521                 vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2522                 v = ccgSubSurf_getEdgeVert1(e);
2523                 vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2524
2525                 ccgdm->edgeMap[index].startVert = vertNum;
2526                 ccgdm->edgeMap[index].startEdge = edgeNum;
2527
2528                 /* set the edge base vert */
2529                 *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
2530
2531                 for(x = 1; x < edgeSize - 1; x++) {
2532                         float w[2];
2533                         w[1] = (float) x / (edgeSize - 1);
2534                         w[0] = 1 - w[1];
2535                         DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
2536                         *vertOrigIndex = ORIGINDEX_NONE;
2537                         ++vertOrigIndex;
2538                         ++vertNum;
2539                 }
2540
2541                 for(i = 0; i < numFinalEdges; ++i) {
2542                         if(edgeIdx >= 0 && edgeFlags)
2543                                         edgeFlags[edgeNum + i] = medge[edgeIdx].flag;
2544
2545                         *(int *)DM_get_edge_data(&ccgdm->dm, edgeNum + i,
2546                                                  CD_ORIGINDEX) = mapIndex;
2547                 }
2548
2549                 edgeNum += numFinalEdges;
2550         }
2551
2552         for(index = 0; index < totvert; ++index) {
2553                 CCGVert *v = ccgdm->vertMap[index].vert;
2554                 int mapIndex = ccgDM_getVertMapIndex(ccgdm->ss, v);
2555                 int vertIdx;
2556
2557                 vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2558
2559                 ccgdm->vertMap[index].startVert = vertNum;
2560
2561                 /* set the vert base vert */
2562                 *((int*) ccgSubSurf_getVertUserData(ss, v)) = vertNum;
2563
2564                 DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
2565
2566                 *vertOrigIndex = mapIndex;
2567                 ++vertOrigIndex;
2568                 ++vertNum;
2569         }
2570
2571         MEM_freeN(qweight);
2572         MEM_freeN(tweight);
2573
2574         return ccgdm;
2575 }
2576
2577 /***/
2578
2579 struct DerivedMesh *subsurf_make_derived_from_derived_with_multires(
2580                         struct DerivedMesh *dm,
2581                         struct SubsurfModifierData *smd,
2582                         struct MultiresSubsurf *ms,
2583                         int useRenderParams, float (*vertCos)[3],
2584                         int isFinalCalc, int editMode)
2585 {
2586         int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF;
2587         int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2588         int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv;
2589         int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
2590         DerivedMesh *result;
2591
2592         if(editMode) {
2593                 smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0,
2594                                            useSimple);
2595                 ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
2596
2597                 return (DerivedMesh *)getCCGDerivedMesh(smd->emCache,
2598                                                         drawInteriorEdges,
2599                                                     useSubsurfUv, dm);
2600         } else if(useRenderParams) {
2601                 /* Do not use cache in render mode. */
2602                 CCGSubSurf *ss;
2603                 int levels;
2604                 
2605                 levels= smd->renderLevels; // XXX get_render_subsurf_level(&scene->r, smd->renderLevels);
2606                 if(levels == 0)
2607                         return dm;
2608                 
2609                 ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
2610
2611                 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2612
2613                 result = ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
2614                                              useSubsurfUv, dm, ms);
2615
2616                 ccgSubSurf_free(ss);
2617                 
2618                 return result;
2619         } else {
2620                 int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
2621                 int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2622                 CCGSubSurf *ss;
2623                 
2624                 /* It is quite possible there is a much better place to do this. It
2625                  * depends a bit on how rigourously we expect this function to never
2626                  * be called in editmode. In semi-theory we could share a single
2627                  * cache, but the handles used inside and outside editmode are not
2628                  * the same so we would need some way of converting them. Its probably
2629                  * not worth the effort. But then why am I even writing this long
2630                  * comment that no one will read? Hmmm. - zr
2631                  */
2632                 if(smd->emCache) {
2633                         ccgSubSurf_free(smd->emCache);
2634                         smd->emCache = NULL;
2635                 }
2636
2637                 if(useIncremental && isFinalCalc) {
2638                         smd->mCache = ss = _getSubSurf(smd->mCache, smd->levels,
2639                                                        useAging, 0, useSimple);
2640
2641                         ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2642
2643
2644                         return ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
2645                                                    useSubsurfUv, dm, ms);
2646
2647                         /*return (DerivedMesh *)getCCGDerivedMesh(smd->mCache,
2648                                                         drawInteriorEdges,
2649                                                     useSubsurfUv, dm);*/
2650                 } else {
2651                         if (smd->mCache && isFinalCalc) {
2652                                 ccgSubSurf_free(smd->mCache);
2653                                 smd->mCache = NULL;
2654                         }
2655
2656                         ss = _getSubSurf(NULL, smd->levels, 0, 1, useSimple);
2657                         ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2658
2659                         /*smd->mCache = ss;
2660                         result = (DerivedMesh *)getCCGDerivedMesh(smd->mCache,
2661                                                         drawInteriorEdges,
2662                                                     useSubsurfUv, dm);*/
2663
2664                         result = ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
2665                                                      useSubsurfUv, dm, ms);
2666
2667                         ccgSubSurf_free(ss);
2668
2669                         return result;
2670                 }
2671         }
2672 }
2673
2674 struct DerivedMesh *subsurf_make_derived_from_derived(
2675                         struct DerivedMesh *dm,
2676                         struct SubsurfModifierData *smd,
2677                         int useRenderParams, float (*vertCos)[3],
2678                         int isFinalCalc, int editMode)
2679 {
2680         return subsurf_make_derived_from_derived_with_multires(dm, smd, NULL, useRenderParams, vertCos, isFinalCalc, editMode);
2681 }
2682
2683 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 
2684 {
2685         /* Finds the subsurf limit positions for the verts in a mesh 
2686          * and puts them in an array of floats. Please note that the 
2687          * calculated vert positions is incorrect for the verts 
2688          * on the boundary of the mesh.
2689          */
2690         CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0);
2691         float edge_sum[3], face_sum[3];
2692         CCGVertIterator *vi;
2693         DerivedMesh *dm = CDDM_from_mesh(me, NULL);
2694
2695         ss_sync_from_derivedmesh(ss, dm, NULL, 0);
2696
2697         vi = ccgSubSurf_getVertIterator(ss);
2698         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2699                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2700                 int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2701                 int N = ccgSubSurf_getVertNumEdges(v);
2702                 int numFaces = ccgSubSurf_getVertNumFaces(v);
2703                 float *co;
2704                 int i;
2705                 
2706                 edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0;
2707                 face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
2708
2709                 for (i=0; i<N; i++) {
2710                         CCGEdge *e = ccgSubSurf_getVertEdge(v, i);
2711                         VecAddf(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
2712                 }
2713                 for (i=0; i<numFaces; i++) {
2714                         CCGFace *f = ccgSubSurf_getVertFace(v, i);
2715                         VecAddf(face_sum, face_sum, ccgSubSurf_getFaceCenterData(f));
2716                 }
2717
2718                 /* ad-hoc correction for boundary vertices, to at least avoid them
2719                    moving completely out of place (brecht) */
2720                 if(numFaces && numFaces != N)
2721                         VecMulf(face_sum, (float)N/(float)numFaces);
2722
2723                 co = ccgSubSurf_getVertData(ss, v);
2724                 positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
2725                 positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
2726                 positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
2727         }
2728         ccgVertIterator_free(vi);
2729
2730         ccgSubSurf_free(ss);
2731
2732         dm->release(dm);
2733 }
2734