I made multitude of fixes based on the comments provided online:
[blender.git] / source / blender / blenkernel / intern / subsurf_ccg.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2005 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /** \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 #include "GL/glew.h"
65
66 #include "GPU_draw.h"
67 #include "GPU_extensions.h"
68 #include "GPU_material.h"
69
70 #include "CCGSubSurf.h"
71
72 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
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                                 for (S=0; S<numVerts; S++) {
1833                                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1834                                         if (drawSmooth) {
1835                                                 glShadeModel(GL_SMOOTH);
1836                                                 for (y=0; y<gridFaces; y++) {
1837                                                         DMGridData *a, *b;
1838                                                         glBegin(GL_QUAD_STRIP);
1839                                                         for (x=0; x<gridFaces; x++) {
1840                                                                 a = &faceGridData[(y+0)*gridSize + x];
1841                                                                 b = &faceGridData[(y+1)*gridSize + x];
1842         
1843                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1844                                                                 glNormal3fv(a->no);
1845                                                                 glVertex3fv(a->co);
1846                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1847                                                                 glNormal3fv(b->no);
1848                                                                 glVertex3fv(b->co);
1849
1850                                                                 if(x != gridFaces-1) {
1851                                                                         if(cp) cp += 16;
1852                                                                 }
1853                                                         }
1854
1855                                                         a = &faceGridData[(y+0)*gridSize + x];
1856                                                         b = &faceGridData[(y+1)*gridSize + x];
1857
1858                                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1859                                                         glNormal3fv(a->no);
1860                                                         glVertex3fv(a->co);
1861                                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1862                                                         glNormal3fv(b->no);
1863                                                         glVertex3fv(b->co);
1864
1865                                                         if(cp) cp += 16;
1866
1867                                                         glEnd();
1868                                                 }
1869                                         } else {
1870                                                 glShadeModel(GL_FLAT);
1871                                                 glBegin(GL_QUADS);
1872                                                 for (y=0; y<gridFaces; y++) {
1873                                                         for (x=0; x<gridFaces; x++) {
1874                                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
1875                                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1876                                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1877                                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
1878
1879                                                                 ccgDM_glNormalFast(a, b, c, d);
1880         
1881                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1882                                                                 glVertex3fv(d);
1883                                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1884                                                                 glVertex3fv(c);
1885                                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1886                                                                 glVertex3fv(b);
1887                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1888                                                                 glVertex3fv(a);
1889
1890                                                                 if(cp) cp += 16;
1891                                                         }
1892                                                 }
1893                                                 glEnd();
1894                                         }
1895                                 }
1896                                 if (draw==2)
1897                                         glDisable(GL_POLYGON_STIPPLE);
1898                         }
1899                 }
1900         }
1901 }
1902 static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
1903         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1904         CCGSubSurf *ss = ccgdm->ss;
1905         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1906         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
1907
1908         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1909
1910         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1911                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1912                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1913                 int index = ccgDM_getEdgeMapIndex(ss, e);
1914
1915                 glBegin(GL_LINE_STRIP);
1916                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
1917                         if (useAging && !(G.f&G_BACKBUFSEL)) {
1918                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1919                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
1920                         }
1921
1922                         for (i=0; i<edgeSize-1; i++) {
1923                                 glVertex3fv(edgeData[i].co);
1924                                 glVertex3fv(edgeData[i+1].co);
1925                         }
1926                 }
1927                 glEnd();
1928         }
1929
1930         ccgEdgeIterator_free(ei);
1931 }
1932 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
1933         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1934         CCGSubSurf *ss = ccgdm->ss;
1935         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1936         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
1937
1938         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1939
1940         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1941                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1942                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1943                 int index = ccgDM_getEdgeMapIndex(ss, e);
1944
1945                 glBegin(GL_LINE_STRIP);
1946                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
1947                         for (i=0; i<edgeSize; i++) {
1948                                 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
1949
1950                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1951                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1952                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1953                                 }
1954
1955                                 glVertex3fv(edgeData[i].co);
1956                         }
1957                 }
1958                 glEnd();
1959         }
1960
1961         ccgEdgeIterator_free(ei);
1962 }
1963 static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
1964         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1965         CCGSubSurf *ss = ccgdm->ss;
1966         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1967
1968         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1969                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1970                 int index = ccgDM_getFaceMapIndex(ss, f);
1971
1972                 if (index!=-1) {
1973                                 /* Face center data normal isn't updated atm. */
1974                         DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
1975
1976                         func(userData, index, vd->co, vd->no);
1977                 }
1978         }
1979
1980         ccgFaceIterator_free(fi);
1981 }
1982
1983 static void ccgDM_release(DerivedMesh *dm) {
1984         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1985
1986         if (DM_release(dm)) {
1987                 /* Before freeing, need to update the displacement map */
1988                 if(ccgdm->multires.modified) {
1989                         /* Check that mmd still exists */
1990                         if(!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
1991                                 ccgdm->multires.mmd = NULL;
1992                         if(ccgdm->multires.mmd)
1993                                 ccgdm->multires.update(dm);
1994                 }
1995
1996                 if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
1997                 if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
1998                 if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
1999                 if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
2000                 if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
2001                 if(ccgdm->fmap) MEM_freeN(ccgdm->fmap);
2002                 if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem);
2003                 MEM_freeN(ccgdm->edgeFlags);
2004                 MEM_freeN(ccgdm->faceFlags);
2005                 MEM_freeN(ccgdm->vertMap);
2006                 MEM_freeN(ccgdm->edgeMap);
2007                 MEM_freeN(ccgdm->faceMap);
2008                 MEM_freeN(ccgdm);
2009         }
2010 }
2011
2012 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
2013 {
2014         if(type == CD_ORIGINDEX) {
2015                 /* create origindex on demand to save memory */
2016                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2017                 CCGSubSurf *ss= ccgdm->ss;
2018                 int *origindex;
2019                 int a, index, totnone, totorig;
2020
2021                 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2022                 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
2023
2024                 totorig = ccgSubSurf_getNumVerts(ss);
2025                 totnone= dm->numVertData - totorig;
2026
2027                 /* original vertices are at the end */
2028                 for(a=0; a<totnone; a++)
2029                         origindex[a]= ORIGINDEX_NONE;
2030
2031                 for(index=0; index<totorig; index++, a++) {
2032                         CCGVert *v = ccgdm->vertMap[index].vert;
2033                         origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
2034                 }
2035
2036                 return origindex;
2037         }
2038
2039         return DM_get_vert_data_layer(dm, type);
2040 }
2041
2042 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
2043 {
2044         if(type == CD_ORIGINDEX) {
2045                 /* create origindex on demand to save memory */
2046                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2047                 CCGSubSurf *ss= ccgdm->ss;
2048                 int *origindex;
2049                 int a, i, index, totnone, totorig, totedge;
2050                 int edgeSize= ccgSubSurf_getEdgeSize(ss);
2051
2052                 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2053                 origindex= DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2054
2055                 totedge= ccgSubSurf_getNumEdges(ss);
2056                 totorig= totedge*(edgeSize - 1);
2057                 totnone= dm->numEdgeData - totorig;
2058
2059                 /* original edges are at the end */
2060                 for(a=0; a<totnone; a++)
2061                         origindex[a]= ORIGINDEX_NONE;
2062
2063                 for(index=0; index<totedge; index++) {
2064                         CCGEdge *e= ccgdm->edgeMap[index].edge;
2065                         int mapIndex= ccgDM_getEdgeMapIndex(ss, e);
2066
2067                         for(i = 0; i < edgeSize - 1; i++, a++)
2068                                 origindex[a]= mapIndex;
2069                 }
2070
2071                 return origindex;
2072         }
2073
2074         return DM_get_edge_data_layer(dm, type);
2075 }
2076
2077 static void *ccgDM_get_face_data_layer(DerivedMesh *dm, int type)
2078 {
2079         if(type == CD_ORIGINDEX) {
2080                 /* create origindex on demand to save memory */
2081                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2082                 CCGSubSurf *ss= ccgdm->ss;
2083                 int *origindex;
2084                 int a, i, index, totface;
2085                 int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
2086
2087                 DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2088                 origindex= DM_get_face_data_layer(dm, CD_ORIGINDEX);
2089
2090                 totface= ccgSubSurf_getNumFaces(ss);
2091
2092                 for(a=0, index=0; index<totface; index++) {
2093                         CCGFace *f = ccgdm->faceMap[index].face;
2094                         int numVerts = ccgSubSurf_getFaceNumVerts(f);
2095                         int mapIndex = ccgDM_getFaceMapIndex(ss, f);
2096
2097                         for(i=0; i<gridFaces*gridFaces*numVerts; i++, a++)
2098                                 origindex[a]= mapIndex;
2099                 }
2100
2101                 return origindex;
2102         }
2103
2104         return DM_get_face_data_layer(dm, type);
2105 }
2106
2107 static int ccgDM_getNumGrids(DerivedMesh *dm)
2108 {
2109         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2110         int index, numFaces, numGrids;
2111
2112         numFaces= ccgSubSurf_getNumFaces(ccgdm->ss);
2113         numGrids= 0;
2114
2115         for(index=0; index<numFaces; index++) {
2116                 CCGFace *f = ccgdm->faceMap[index].face;
2117                 numGrids += ccgSubSurf_getFaceNumVerts(f);
2118         }
2119
2120         return numGrids;
2121 }
2122
2123 static int ccgDM_getGridSize(DerivedMesh *dm)
2124 {
2125         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2126         return ccgSubSurf_getGridSize(ccgdm->ss);
2127 }
2128
2129 static int ccgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset)
2130 {
2131         CCGFace *adjf;
2132         CCGEdge *e;
2133         int i, j= 0, numFaces, fIndex, numEdges= 0;
2134
2135         e = ccgSubSurf_getFaceEdge(ss, f, S);
2136         numFaces = ccgSubSurf_getEdgeNumFaces(e);
2137
2138         if(numFaces != 2)
2139                 return -1;
2140
2141         for(i = 0; i < numFaces; i++) {
2142                 adjf = ccgSubSurf_getEdgeFace(e, i);
2143
2144                 if(adjf != f) {
2145                         numEdges = ccgSubSurf_getFaceNumVerts(adjf);
2146                         for(j = 0; j < numEdges; j++)
2147                                 if(ccgSubSurf_getFaceEdge(ss, adjf, j) == e)
2148                                         break;
2149
2150                         if(j != numEdges)
2151                                 break;
2152                 }
2153         }
2154         
2155         fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, adjf));
2156
2157         return gridOffset[fIndex] + (j + offset)%numEdges;
2158 }
2159
2160 static void ccgdm_create_grids(DerivedMesh *dm)
2161 {
2162         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2163         CCGSubSurf *ss= ccgdm->ss;
2164         DMGridData **gridData;
2165         DMGridAdjacency *gridAdjacency, *adj;
2166         CCGFace **gridFaces;
2167         int *gridOffset;
2168         int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
2169
2170         if(ccgdm->gridData)
2171                 return;
2172         
2173         numGrids = ccgDM_getNumGrids(dm);
2174         numFaces = ccgSubSurf_getNumFaces(ss);
2175         /*gridSize = ccgDM_getGridSize(dm);*/  /*UNUSED*/
2176
2177         /* compute offset into grid array for each face */
2178         gridOffset = MEM_mallocN(sizeof(int)*numFaces, "ccgdm.gridOffset");
2179
2180         for(gIndex = 0, index = 0; index < numFaces; index++) {
2181                 CCGFace *f = ccgdm->faceMap[index].face;
2182                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2183
2184                 gridOffset[index] = gIndex;
2185                 gIndex += numVerts;
2186         }
2187
2188         /* compute grid data */
2189         gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "ccgdm.gridData");
2190         gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "ccgdm.gridAdjacency");
2191         gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "ccgdm.gridFaces");
2192
2193         for(gIndex = 0, index = 0; index < numFaces; index++) {
2194                 CCGFace *f = ccgdm->faceMap[index].face;
2195                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2196
2197                 for(S = 0; S < numVerts; S++, gIndex++) {
2198                         int prevS = (S - 1 + numVerts) % numVerts;
2199                         int nextS = (S + 1 + numVerts) % numVerts;
2200
2201                         gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2202                         gridFaces[gIndex] = f;
2203
2204                         adj = &gridAdjacency[gIndex];
2205
2206                         adj->index[0] = gIndex - S + nextS;
2207                         adj->rotation[0] = 3;
2208                         adj->index[1] = ccgdm_adjacent_grid(ss, gridOffset, f, prevS, 0);
2209                         adj->rotation[1] = 1;
2210                         adj->index[2] = ccgdm_adjacent_grid(ss, gridOffset, f, S, 1);
2211                         adj->rotation[2] = 3;
2212                         adj->index[3] = gIndex - S + prevS;
2213                         adj->rotation[3] = 1;
2214                 }
2215         }
2216
2217         ccgdm->gridData = gridData;
2218         ccgdm->gridFaces = gridFaces;
2219         ccgdm->gridAdjacency = gridAdjacency;
2220         ccgdm->gridOffset = gridOffset;
2221 }
2222
2223 static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
2224 {
2225         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2226
2227         ccgdm_create_grids(dm);
2228         return ccgdm->gridData;
2229 }
2230
2231 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm)
2232 {
2233         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2234
2235         ccgdm_create_grids(dm);
2236         return ccgdm->gridAdjacency;
2237 }
2238
2239 static int *ccgDM_getGridOffset(DerivedMesh *dm)
2240 {
2241         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2242
2243         ccgdm_create_grids(dm);
2244         return ccgdm->gridOffset;
2245 }
2246
2247 static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
2248 {
2249         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2250
2251         if(!ccgdm->multires.mmd && !ccgdm->fmap && ob->type == OB_MESH) {
2252                 Mesh *me= ob->data;
2253
2254                 create_vert_face_map(&ccgdm->fmap, &ccgdm->fmap_mem, me->mface,
2255                                      me->totvert, me->totface);
2256         }
2257
2258         return ccgdm->fmap;
2259 }
2260
2261 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
2262 {
2263         MultiresModifierData *mmd= ccgdm->multires.mmd;
2264
2265         /* both of multires and subsurm modifiers are CCG, but
2266            grids should only be used when sculpting on multires */
2267         if(!mmd)
2268                 return 0;
2269
2270         return 1;
2271 }
2272
2273 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
2274 {
2275         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2276         int gridSize, numGrids, grid_pbvh;
2277
2278         if(!ob) {
2279                 ccgdm->pbvh= NULL;
2280                 return NULL;
2281         }
2282
2283         if(!ob->sculpt)
2284                 return NULL;
2285
2286         grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
2287
2288         if(ob->sculpt->pbvh) {
2289                 if(grid_pbvh) {
2290                         /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
2291                            but this can be freed on ccgdm release, this updates the pointers
2292                            when the ccgdm gets remade, the assumption is that the topology
2293                            does not change. */
2294                         ccgdm_create_grids(dm);
2295                         BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
2296                 }
2297
2298                 ccgdm->pbvh = ob->sculpt->pbvh;
2299         }
2300
2301         if(ccgdm->pbvh)
2302                 return ccgdm->pbvh;
2303
2304         /* no pbvh exists yet, we need to create one. only in case of multires
2305            we build a pbvh over the modified mesh, in other cases the base mesh
2306            is being sculpted, so we build a pbvh from that. */
2307         if(grid_pbvh) {
2308                 ccgdm_create_grids(dm);
2309
2310                 gridSize = ccgDM_getGridSize(dm);
2311                 numGrids = ccgDM_getNumGrids(dm);
2312
2313                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2314                 BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
2315                         numGrids, gridSize, (void**)ccgdm->gridFaces);
2316         } else if(ob->type == OB_MESH) {
2317                 Mesh *me= ob->data;
2318                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2319                 BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
2320                                    me->totface, me->totvert);
2321         }
2322
2323         return ccgdm->pbvh;
2324 }
2325
2326 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2327                                                                                  int drawInteriorEdges,
2328                                                                                  int useSubsurfUv,
2329                                                                                  DerivedMesh *dm)
2330 {
2331         CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
2332         CCGVertIterator *vi;
2333         CCGEdgeIterator *ei;
2334         CCGFaceIterator *fi;
2335         int index, totvert, totedge, totface;
2336         int i;
2337         int vertNum, edgeNum, faceNum;
2338         short *edgeFlags;
2339         char *faceFlags;
2340         int edgeSize;
2341         int gridSize;
2342         int gridFaces;
2343         /*int gridSideVerts;*/
2344         int gridSideEdges;
2345         int gridInternalEdges;
2346         MEdge *medge = NULL;
2347         MFace *mface = NULL;
2348         int *orig_indices;
2349         FaceVertWeight *qweight, *tweight;
2350
2351         DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
2352                                          ccgSubSurf_getNumFinalVerts(ss),
2353                                          ccgSubSurf_getNumFinalEdges(ss),
2354                                          ccgSubSurf_getNumFinalFaces(ss));
2355
2356         ccgdm->dm.getMinMax = ccgDM_getMinMax;
2357         ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
2358         ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
2359
2360         ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
2361         ccgdm->dm.getVert = ccgDM_getFinalVert;
2362         ccgdm->dm.getEdge = ccgDM_getFinalEdge;
2363         ccgdm->dm.getFace = ccgDM_getFinalFace;
2364         ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
2365         ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
2366         ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2367         ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2368         ccgdm->dm.copyFaceArray = ccgDM_copyFinalFaceArray;
2369         ccgdm->dm.getVertData = DM_get_vert_data;
2370         ccgdm->dm.getEdgeData = DM_get_edge_data;
2371         ccgdm->dm.getFaceData = DM_get_face_data;
2372         ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
2373         ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
2374         ccgdm->dm.getFaceDataArray = ccgDM_get_face_data_layer;
2375         ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
2376         ccgdm->dm.getGridSize = ccgDM_getGridSize;
2377         ccgdm->dm.getGridData = ccgDM_getGridData;
2378         ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency;
2379         ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
2380         ccgdm->dm.getFaceMap = ccgDM_getFaceMap;
2381         ccgdm->dm.getPBVH = ccgDM_getPBVH;
2382
2383         ccgdm->dm.getVertCos = ccgdm_getVertCos;
2384         ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
2385         ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
2386         ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
2387         
2388         ccgdm->dm.drawVerts = ccgDM_drawVerts;
2389         ccgdm->dm.drawEdges = ccgDM_drawEdges;
2390         ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
2391         ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
2392         ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
2393         ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
2394         ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL;
2395         ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
2396         ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
2397         ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL;
2398         ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
2399
2400         ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
2401         ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
2402         
2403         ccgdm->dm.release = ccgDM_release;
2404         
2405         ccgdm->ss = ss;
2406         ccgdm->drawInteriorEdges = drawInteriorEdges;
2407         ccgdm->useSubsurfUv = useSubsurfUv;
2408
2409         totvert = ccgSubSurf_getNumVerts(ss);
2410         ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
2411         vi = ccgSubSurf_getVertIterator(ss);
2412         for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2413                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2414
2415                 ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
2416         }
2417         ccgVertIterator_free(vi);
2418
2419         totedge = ccgSubSurf_getNumEdges(ss);
2420         ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
2421         ei = ccgSubSurf_getEdgeIterator(ss);
2422         for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2423                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2424
2425                 ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
2426         }
2427
2428         totface = ccgSubSurf_getNumFaces(ss);
2429         ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
2430         fi = ccgSubSurf_getFaceIterator(ss);
2431         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2432                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2433
2434                 ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
2435         }
2436         ccgFaceIterator_free(fi);
2437
2438         edgeSize = ccgSubSurf_getEdgeSize(ss);
2439         gridSize = ccgSubSurf_getGridSize(ss);
2440         gridFaces = gridSize - 1;
2441         /*gridSideVerts = gridSize - 2;*/ /*UNUSED*/
2442         /*gridInternalVerts = gridSideVerts * gridSideVerts; */ /*UNUSED*/
2443         gridSideEdges = gridSize - 1;
2444         gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
2445
2446         calc_ss_weights(gridFaces, &qweight, &tweight);
2447
2448         vertNum = 0;
2449         edgeNum = 0;
2450         faceNum = 0;
2451
2452         /* mvert = dm->getVertArray(dm); - as yet unused */
2453         medge = dm->getEdgeArray(dm);
2454         mface = dm->getFaceArray(dm);
2455
2456         faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags");
2457
2458         orig_indices = (int*)ccgdm->dm.getFaceDataArray(&ccgdm->dm, CD_ORIGINDEX);
2459         for(index = 0; index < totface; ++index) {
2460                 CCGFace *f = ccgdm->faceMap[index].face;
2461                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2462                 int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
2463                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2464                 FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
2465                 int S, x, y;
2466                 int vertIdx[4];
2467
2468                 ccgdm->faceMap[index].startVert = vertNum;
2469                 ccgdm->faceMap[index].startEdge = edgeNum;
2470                 ccgdm->faceMap[index].startFace = faceNum;
2471
2472                 if(orig_indices)
2473                         orig_indices[faceNum] = origIndex;
2474
2475                 /* set the face base vert */
2476                 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
2477
2478                 for(S = 0; S < numVerts; S++) {
2479                         CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
2480
2481                         vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2482                 }
2483
2484                 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, weight[0][0],
2485                                                         numVerts, vertNum);
2486                 ++vertNum;
2487
2488                 for(S = 0; S < numVerts; S++) {
2489                         int prevS = (S - 1 + numVerts) % numVerts;
2490                         int nextS = (S + 1) % numVerts;
2491                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2492                         for(x = 1; x < gridFaces; x++) {
2493                                 float w[4];
2494                                 w[prevS]  = weight[x][0][0];
2495                                 w[S]      = weight[x][0][1];
2496                                 w[nextS]  = weight[x][0][2];
2497                                 w[otherS] = weight[x][0][3];
2498                                 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2499                                                                         numVerts, vertNum);
2500                                 ++vertNum;
2501                         }
2502                 }
2503
2504                 for(S = 0; S < numVerts; S++) {
2505                         int prevS = (S - 1 + numVerts) % numVerts;
2506                         int nextS = (S + 1) % numVerts;
2507                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2508                         for(y = 1; y < gridFaces; y++) {
2509                                 for(x = 1; x < gridFaces; x++) {
2510                                         float w[4];
2511                                         w[prevS]  = weight[y * gridFaces + x][0][0];
2512                                         w[S]      = weight[y * gridFaces + x][0][1];
2513                                         w[nextS]  = weight[y * gridFaces + x][0][2];
2514                                         w[otherS] = weight[y * gridFaces + x][0][3];
2515                                         DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2516                                                                                 numVerts, vertNum);
2517                                         ++vertNum;
2518                                 }
2519                         }
2520                 }
2521
2522                 for(S = 0; S < numVerts; S++) {
2523                         int prevS = (S - 1 + numVerts) % numVerts;
2524                         int nextS = (S + 1) % numVerts;
2525                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2526
2527                         weight = (numVerts == 4) ? qweight : tweight;
2528
2529                         for(y = 0; y < gridFaces; y++) {
2530                                 for(x = 0; x < gridFaces; x++) {
2531                                         FaceVertWeight w;
2532                                         int j;
2533
2534                                         for(j = 0; j < 4; ++j) {
2535                                                 w[j][prevS]  = (*weight)[j][0];
2536                                                 w[j][S]      = (*weight)[j][1];
2537                                                 w[j][nextS]  = (*weight)[j][2];
2538                                                 w[j][otherS] = (*weight)[j][3];
2539                                         }
2540
2541                                         DM_interp_face_data(dm, &ccgdm->dm, &origIndex, NULL,
2542                                                                                 &w, 1, faceNum);
2543                                         weight++;
2544
2545                                         ++faceNum;
2546                                 }
2547                         }
2548                 }
2549
2550                 faceFlags[index*2] = mface[origIndex].flag;
2551                 faceFlags[index*2 + 1] = mface[origIndex].mat_nr;
2552
2553                 edgeNum += numFinalEdges;
2554         }
2555
2556         if(useSubsurfUv) {
2557                 CustomData *fdata = &ccgdm->dm.faceData;
2558                 CustomData *dmfdata = &dm->faceData;
2559                 int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
2560                 int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
2561
2562                 for (i=0; i<numlayer && i<dmnumlayer; i++)
2563                         set_subsurf_uv(ss, dm, &ccgdm->dm, i);
2564         }
2565
2566         edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "edgeFlags");
2567
2568         for(index = 0; index < totedge; ++index) {
2569                 CCGEdge *e = ccgdm->edgeMap[index].edge;
2570                 int numFinalEdges = edgeSize - 1;
2571                 int x;
2572                 int vertIdx[2];
2573                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
2574
2575                 CCGVert *v;
2576                 v = ccgSubSurf_getEdgeVert0(e);
2577                 vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2578                 v = ccgSubSurf_getEdgeVert1(e);
2579                 vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2580
2581                 ccgdm->edgeMap[index].startVert = vertNum;
2582                 ccgdm->edgeMap[index].startEdge = edgeNum;
2583
2584                 /* set the edge base vert */
2585                 *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
2586
2587                 for(x = 1; x < edgeSize - 1; x++) {
2588                         float w[2];
2589                         w[1] = (float) x / (edgeSize - 1);
2590                         w[0] = 1 - w[1];
2591                         DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
2592                         ++vertNum;
2593                 }
2594
2595                 edgeFlags[index]= medge[edgeIdx].flag;
2596
2597                 edgeNum += numFinalEdges;
2598         }
2599
2600         for(index = 0; index < totvert; ++index) {
2601                 CCGVert *v = ccgdm->vertMap[index].vert;
2602                 int vertIdx;
2603
2604                 vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2605
2606                 ccgdm->vertMap[index].startVert = vertNum;
2607
2608                 /* set the vert base vert */
2609                 *((int*) ccgSubSurf_getVertUserData(ss, v)) = vertNum;
2610
2611                 DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
2612
2613                 ++vertNum;
2614         }
2615
2616         MEM_freeN(qweight);
2617         MEM_freeN(tweight);
2618
2619         return ccgdm;
2620 }
2621
2622 /***/
2623
2624 struct DerivedMesh *subsurf_make_derived_from_derived(
2625                                                 struct DerivedMesh *dm,
2626                                                 struct SubsurfModifierData *smd,
2627                                                 int useRenderParams, float (*vertCos)[3],
2628                                                 int isFinalCalc, int forEditMode, int inEditMode)
2629 {
2630         int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF;
2631         int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2632         int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv;
2633         int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
2634         CCGDerivedMesh *result;
2635
2636         if(forEditMode) {
2637                 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
2638
2639                 smd->emCache = _getSubSurf(smd->emCache, levels, useAging, 0,
2640                                                                    useSimple);
2641                 ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
2642
2643                 result = getCCGDerivedMesh(smd->emCache,
2644                                                                    drawInteriorEdges,
2645                                                                    useSubsurfUv, dm);
2646         } else if(useRenderParams) {
2647                 /* Do not use cache in render mode. */
2648                 CCGSubSurf *ss;
2649                 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->renderLevels): smd->renderLevels;
2650
2651                 if(levels == 0)
2652                         return dm;
2653                 
2654                 ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
2655
2656                 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2657
2658                 result = getCCGDerivedMesh(ss,
2659                         drawInteriorEdges, useSubsurfUv, dm);
2660
2661                 result->freeSS = 1;
2662         } else {
2663                 int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
2664                 int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2665                 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
2666                 CCGSubSurf *ss;
2667
2668                 /* It is quite possible there is a much better place to do this. It
2669                  * depends a bit on how rigourously we expect this function to never
2670                  * be called in editmode. In semi-theory we could share a single
2671                  * cache, but the handles used inside and outside editmode are not
2672                  * the same so we would need some way of converting them. Its probably
2673                  * not worth the effort. But then why am I even writing this long
2674                  * comment that no one will read? Hmmm. - zr
2675                  *
2676                  * Addendum: we can't really ensure that this is never called in edit
2677                  * mode, so now we have a parameter to verify it. - brecht
2678                  */
2679                 if(!inEditMode && smd->emCache) {
2680                         ccgSubSurf_free(smd->emCache);
2681                         smd->emCache = NULL;
2682                 }
2683
2684                 if(useIncremental && isFinalCalc) {
2685                         smd->mCache = ss = _getSubSurf(smd->mCache, levels,
2686                                                                                    useAging, 0, useSimple);
2687
2688                         ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2689
2690                         result = getCCGDerivedMesh(smd->mCache,
2691                                                                            drawInteriorEdges,
2692                                                                            useSubsurfUv, dm);
2693                 } else {
2694                         if (smd->mCache && isFinalCalc) {
2695                                 ccgSubSurf_free(smd->mCache);
2696                                 smd->mCache = NULL;
2697                         }
2698
2699                         ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
2700                         ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2701
2702                         result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
2703
2704                         if(isFinalCalc)
2705                                 smd->mCache = ss;
2706                         else
2707                                 result->freeSS = 1;
2708                 }
2709         }
2710
2711         return (DerivedMesh*)result;
2712 }
2713
2714 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 
2715 {
2716         /* Finds the subsurf limit positions for the verts in a mesh 
2717          * and puts them in an array of floats. Please note that the 
2718          * calculated vert positions is incorrect for the verts 
2719          * on the boundary of the mesh.
2720          */
2721         CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0);
2722         float edge_sum[3], face_sum[3];
2723         CCGVertIterator *vi;
2724         DerivedMesh *dm = CDDM_from_mesh(me, NULL);
2725
2726         ss_sync_from_derivedmesh(ss, dm, NULL, 0);
2727
2728         vi = ccgSubSurf_getVertIterator(ss);
2729         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2730                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2731                 int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2732                 int N = ccgSubSurf_getVertNumEdges(v);
2733                 int numFaces = ccgSubSurf_getVertNumFaces(v);
2734                 float *co;
2735                 int i;
2736
2737                 edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0;
2738                 face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
2739
2740                 for (i=0; i<N; i++) {
2741                         CCGEdge *e = ccgSubSurf_getVertEdge(v, i);
2742                         add_v3_v3v3(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
2743                 }
2744                 for (i=0; i<numFaces; i++) {
2745                         CCGFace *f = ccgSubSurf_getVertFace(v, i);
2746                         add_v3_v3(face_sum, ccgSubSurf_getFaceCenterData(f));
2747                 }
2748
2749                 /* ad-hoc correction for boundary vertices, to at least avoid them
2750                    moving completely out of place (brecht) */
2751                 if(numFaces && numFaces != N)
2752                         mul_v3_fl(face_sum, (float)N/(float)numFaces);
2753
2754                 co = ccgSubSurf_getVertData(ss, v);
2755                 positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
2756                 positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
2757                 positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
2758         }
2759         ccgVertIterator_free(vi);
2760
2761         ccgSubSurf_free(ss);
2762
2763         dm->release(dm);
2764 }
2765