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