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