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