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