some speedup for drawing mesh in texture mode.
[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                 /* keep types in sync with MFace, avoid many conversions */
972                 char flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH;
973                 short mat_nr = (faceFlags)? faceFlags[index*2+1]: 0;
974
975                 for(S = 0; S < numVerts; S++) {
976                         for(y = 0; y < gridSize - 1; y++) {
977                                 for(x = 0; x < gridSize - 1; x++) {
978                                         MFace *mf = &mface[i];
979                                         mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
980                                                                                   edgeSize, gridSize);
981                                         mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
982                                                                                   edgeSize, gridSize);
983                                         mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
984                                                                                   edgeSize, gridSize);
985                                         mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
986                                                                                   edgeSize, gridSize);
987                                         mf->mat_nr = mat_nr;
988                                         mf->flag = flag;
989
990                                         i++;
991                                 }
992                         }
993                 }
994         }
995 }
996
997 static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
998         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
999         CCGSubSurf *ss = ccgdm->ss;
1000         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1001         int gridSize = ccgSubSurf_getGridSize(ss);
1002         int i;
1003         CCGVertIterator *vi;
1004         CCGEdgeIterator *ei;
1005         CCGFaceIterator *fi;
1006         CCGFace **faceMap2;
1007         CCGEdge **edgeMap2;
1008         CCGVert **vertMap2;
1009         int index, totvert, totedge, totface;
1010         
1011         totvert = ccgSubSurf_getNumVerts(ss);
1012         vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
1013         vi = ccgSubSurf_getVertIterator(ss);
1014         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1015                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1016
1017                 vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v;
1018         }
1019         ccgVertIterator_free(vi);
1020
1021         totedge = ccgSubSurf_getNumEdges(ss);
1022         edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
1023         ei = ccgSubSurf_getEdgeIterator(ss);
1024         for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
1025                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1026
1027                 edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
1028         }
1029
1030         totface = ccgSubSurf_getNumFaces(ss);
1031         faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
1032         fi = ccgSubSurf_getFaceIterator(ss);
1033         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1034                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1035
1036                 faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f;
1037         }
1038         ccgFaceIterator_free(fi);
1039
1040         i = 0;
1041         for (index=0; index<totface; index++) {
1042                 CCGFace *f = faceMap2[index];
1043                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1044
1045                 copy_v3_v3(cos[i++], ccgSubSurf_getFaceCenterData(f));
1046                 
1047                 for (S=0; S<numVerts; S++) {
1048                         for (x=1; x<gridSize-1; x++) {
1049                                 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1050                         }
1051                 }
1052
1053                 for (S=0; S<numVerts; S++) {
1054                         for (y=1; y<gridSize-1; y++) {
1055                                 for (x=1; x<gridSize-1; x++) {
1056                                         copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1057                                 }
1058                         }
1059                 }
1060         }
1061
1062         for (index=0; index<totedge; index++) {
1063                 CCGEdge *e= edgeMap2[index];
1064                 int x;
1065
1066                 for (x=1; x<edgeSize-1; x++) {
1067                         copy_v3_v3(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
1068                 }
1069         }
1070
1071         for (index=0; index<totvert; index++) {
1072                 CCGVert *v = vertMap2[index];
1073                 copy_v3_v3(cos[i++], ccgSubSurf_getVertData(ss, v));
1074         }
1075
1076         MEM_freeN(vertMap2);
1077         MEM_freeN(edgeMap2);
1078         MEM_freeN(faceMap2);
1079 }
1080 static void ccgDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
1081         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1082         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
1083
1084         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1085                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1086                 DMGridData *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
1087                 int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
1088
1089                 if (index!=-1)
1090                         func(userData, index, vd->co, vd->no, NULL);
1091         }
1092
1093         ccgVertIterator_free(vi);
1094 }
1095 static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
1096         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1097         CCGSubSurf *ss = ccgdm->ss;
1098         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1099         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1100
1101         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1102                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1103                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1104                 int index = ccgDM_getEdgeMapIndex(ss, e);
1105
1106                 if (index!=-1) {
1107                         for (i=0; i<edgeSize-1; i++)
1108                                 func(userData, index, edgeData[i].co, edgeData[i+1].co);
1109                 }
1110         }
1111
1112         ccgEdgeIterator_free(ei);
1113 }
1114
1115 static void ccgDM_drawVerts(DerivedMesh *dm) {
1116         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1117         CCGSubSurf *ss = ccgdm->ss;
1118         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1119         int gridSize = ccgSubSurf_getGridSize(ss);
1120         CCGVertIterator *vi;
1121         CCGEdgeIterator *ei;
1122         CCGFaceIterator *fi;
1123
1124         glBegin(GL_POINTS);
1125         vi = ccgSubSurf_getVertIterator(ss);
1126         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1127                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1128                 glVertex3fv(ccgSubSurf_getVertData(ss, v));
1129         }
1130         ccgVertIterator_free(vi);
1131
1132         ei = ccgSubSurf_getEdgeIterator(ss);
1133         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1134                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1135                 int x;
1136
1137                 for (x=1; x<edgeSize-1; x++)
1138                         glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
1139         }
1140         ccgEdgeIterator_free(ei);
1141
1142         fi = ccgSubSurf_getFaceIterator(ss);
1143         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1144                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1145                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1146
1147                 glVertex3fv(ccgSubSurf_getFaceCenterData(f));
1148                 for (S=0; S<numVerts; S++)
1149                         for (x=1; x<gridSize-1; x++)
1150                                 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1151                 for (S=0; S<numVerts; S++)
1152                         for (y=1; y<gridSize-1; y++)
1153                                 for (x=1; x<gridSize-1; x++)
1154                                         glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1155         }
1156         ccgFaceIterator_free(fi);
1157         glEnd();
1158 }
1159
1160 static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
1161 {
1162         if(ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
1163                 CCGFace **faces;
1164                 int totface;
1165
1166                 BLI_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void***)&faces, &totface);
1167                 if(totface) {
1168                         ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface);
1169                         ccgSubSurf_updateNormals(ccgdm->ss, faces, totface);
1170                         MEM_freeN(faces);
1171                 }
1172         }
1173 }
1174
1175 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int UNUSED(drawAllEdges)) {
1176         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1177         CCGSubSurf *ss = ccgdm->ss;
1178         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1179         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1180         int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1181         int totedge = ccgSubSurf_getNumEdges(ss);
1182         int gridSize = ccgSubSurf_getGridSize(ss);
1183         int useAging;
1184
1185         ccgdm_pbvh_update(ccgdm);
1186
1187         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1188
1189         for (j=0; j< totedge; j++) {
1190                 CCGEdge *e = ccgdm->edgeMap[j].edge;
1191                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1192
1193                 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e))
1194                         continue;
1195
1196                 if(ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW))
1197                         continue;
1198
1199                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1200                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1201                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1202                 }
1203
1204                 glBegin(GL_LINE_STRIP);
1205                 for (i=0; i<edgeSize-1; i++) {
1206                         glVertex3fv(edgeData[i].co);
1207                         glVertex3fv(edgeData[i+1].co);
1208                 }
1209                 glEnd();
1210         }
1211
1212         if (useAging && !(G.f&G_BACKBUFSEL)) {
1213                 glColor3ub(0, 0, 0);
1214         }
1215
1216         if (ccgdm->drawInteriorEdges) {
1217                 for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1218                         CCGFace *f = ccgFaceIterator_getCurrent(fi);
1219                         int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1220
1221                         for (S=0; S<numVerts; S++) {
1222                                 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1223
1224                                 glBegin(GL_LINE_STRIP);
1225                                 for (x=0; x<gridSize; x++)
1226                                         glVertex3fv(faceGridData[x].co);
1227                                 glEnd();
1228                                 for (y=1; y<gridSize-1; y++) {
1229                                         glBegin(GL_LINE_STRIP);
1230                                         for (x=0; x<gridSize; x++)
1231                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1232                                         glEnd();
1233                                 }
1234                                 for (x=1; x<gridSize-1; x++) {
1235                                         glBegin(GL_LINE_STRIP);
1236                                         for (y=0; y<gridSize; y++)
1237                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1238                                         glEnd();
1239                                 }
1240                         }
1241                 }
1242         }
1243
1244         ccgFaceIterator_free(fi);
1245         ccgEdgeIterator_free(ei);
1246 }
1247 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
1248         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1249         CCGSubSurf *ss = ccgdm->ss;
1250         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1251         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1252
1253         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1254                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1255                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1256
1257                 if (!ccgSubSurf_getEdgeNumFaces(e)) {
1258                         glBegin(GL_LINE_STRIP);
1259                         for (i=0; i<edgeSize-1; i++) {
1260                                 glVertex3fv(edgeData[i].co);
1261                                 glVertex3fv(edgeData[i+1].co);
1262                         }
1263                         glEnd();
1264                 }
1265         }
1266
1267         ccgEdgeIterator_free(ei);
1268 }
1269
1270 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
1271 {
1272         float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1273         float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1274         float no[3];
1275
1276         no[0] = b_dY*a_cZ - b_dZ*a_cY;
1277         no[1] = b_dZ*a_cX - b_dX*a_cZ;
1278         no[2] = b_dX*a_cY - b_dY*a_cX;
1279
1280         /* don't normalize, GL_NORMALIZE is enabled */
1281         glNormal3fv(no);
1282 }
1283
1284         /* Only used by non-editmesh types */
1285 static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int fast, int (*setMaterial)(int, void *attribs)) {
1286         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1287         CCGSubSurf *ss = ccgdm->ss;
1288         CCGFaceIterator *fi;
1289         int gridSize = ccgSubSurf_getGridSize(ss);
1290         char *faceFlags = ccgdm->faceFlags;
1291         int step = (fast)? gridSize-1: 1;
1292
1293         ccgdm_pbvh_update(ccgdm);
1294
1295         if(ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
1296                 if(dm->numFaceData) {
1297                         /* should be per face */
1298                         if(!setMaterial(faceFlags[1]+1, NULL))
1299                                 return;
1300
1301                         glShadeModel((faceFlags[0] & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
1302                         BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, (faceFlags[0] & ME_SMOOTH));
1303                         glShadeModel(GL_FLAT);
1304                 }
1305
1306                 return;
1307         }
1308
1309         fi = ccgSubSurf_getFaceIterator(ss);
1310         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1311                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1312                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1313                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1314                 int drawSmooth, mat_nr;
1315
1316                 if(faceFlags) {
1317                         drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1318                         mat_nr= faceFlags[index*2 + 1];
1319                 }
1320                 else {
1321                         drawSmooth = 1;
1322                         mat_nr= 0;
1323                 }
1324                 
1325                 if (!setMaterial(mat_nr+1, NULL))
1326                         continue;
1327
1328                 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1329                 for (S=0; S<numVerts; S++) {
1330                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1331
1332                         if (drawSmooth) {
1333                                 for (y=0; y<gridSize-1; y+=step) {
1334                                         glBegin(GL_QUAD_STRIP);
1335                                         for (x=0; x<gridSize; x+=step) {
1336                                                 DMGridData *a = &faceGridData[(y+0)*gridSize + x];
1337                                                 DMGridData *b = &faceGridData[(y+step)*gridSize + x];
1338
1339                                                 glNormal3fv(a->no);
1340                                                 glVertex3fv(a->co);
1341                                                 glNormal3fv(b->no);
1342                                                 glVertex3fv(b->co);
1343                                         }
1344                                         glEnd();
1345                                 }
1346                         } else {
1347                                 glBegin(GL_QUADS);
1348                                 for (y=0; y<gridSize-1; y+=step) {
1349                                         for (x=0; x<gridSize-1; x+=step) {
1350                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
1351                                                 float *b = faceGridData[(y+0)*gridSize + x + step].co;
1352                                                 float *c = faceGridData[(y+step)*gridSize + x + step].co;
1353                                                 float *d = faceGridData[(y+step)*gridSize + x].co;
1354
1355                                                 ccgDM_glNormalFast(a, b, c, d);
1356
1357                                                 glVertex3fv(d);
1358                                                 glVertex3fv(c);
1359                                                 glVertex3fv(b);
1360                                                 glVertex3fv(a);
1361                                         }
1362                                 }
1363                                 glEnd();
1364                         }
1365                 }
1366         }
1367
1368         ccgFaceIterator_free(fi);
1369 }
1370
1371         /* Only used by non-editmesh types */
1372 static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) {
1373         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1374         CCGSubSurf *ss = ccgdm->ss;
1375         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1376         GPUVertexAttribs gattribs;
1377         DMVertexAttribs attribs= {{{NULL}}};
1378         /* MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1379         int gridSize = ccgSubSurf_getGridSize(ss);
1380         int gridFaces = gridSize - 1;
1381         int edgeSize = ccgSubSurf_getEdgeSize(ss);
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
1390 #define PASSATTRIB(dx, dy, vert) {                                                                                              \
1391         if(attribs.totorco) {                                                                                                           \
1392                 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize);                 \
1393                 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
1394         }                                                                                                                                                       \
1395         for(b = 0; b < attribs.tottface; b++) {                                                                         \
1396                 MTFace *tf = &attribs.tface[b].array[a];                                                                \
1397                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);                   \
1398         }                                                                                                                                                       \
1399         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
1400                 MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
1401                 GLubyte col[4];                                                                                                                 \
1402                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
1403                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
1404         }                                                                                                                                                       \
1405         if(attribs.tottang) {                                                                                                           \
1406                 float *tang = attribs.tang.array[a*4 + vert];                                                   \
1407                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
1408         }                                                                                                                                                       \
1409 }
1410
1411         totface = ccgSubSurf_getNumFaces(ss);
1412         for(a = 0, i = 0; i < totface; i++) {
1413                 CCGFace *f = ccgdm->faceMap[i].face;
1414                 int S, x, y, drawSmooth;
1415                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1416                 int origIndex = ccgDM_getFaceMapIndex(ss, f);
1417                 
1418                 numVerts = ccgSubSurf_getFaceNumVerts(f);
1419
1420                 if(faceFlags) {
1421                         drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1422                         new_matnr= faceFlags[index*2 + 1] + 1;
1423                 }
1424                 else {
1425                         drawSmooth = 1;
1426                         new_matnr= 1;
1427                 }
1428
1429                 if(new_matnr != matnr) {
1430                         doDraw = setMaterial(matnr = new_matnr, &gattribs);
1431                         if(doDraw)
1432                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1433                 }
1434
1435                 if(!doDraw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) && !setDrawOptions(userData, origIndex))) {
1436                         a += gridFaces*gridFaces*numVerts;
1437                         continue;
1438                 }
1439
1440                 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1441                 for (S=0; S<numVerts; S++) {
1442                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1443                         DMGridData *vda, *vdb;
1444
1445                         if (drawSmooth) {
1446                                 for (y=0; y<gridFaces; y++) {
1447                                         glBegin(GL_QUAD_STRIP);
1448                                         for (x=0; x<gridFaces; x++) {
1449                                                 vda = &faceGridData[(y+0)*gridSize + x];
1450                                                 vdb = &faceGridData[(y+1)*gridSize + x];
1451                                                 
1452                                                 PASSATTRIB(0, 0, 0);
1453                                                 glNormal3fv(vda->no);
1454                                                 glVertex3fv(vda->co);
1455
1456                                                 PASSATTRIB(0, 1, 1);
1457                                                 glNormal3fv(vdb->no);
1458                                                 glVertex3fv(vdb->co);
1459
1460                                                 if(x != gridFaces-1)
1461                                                         a++;
1462                                         }
1463
1464                                         vda = &faceGridData[(y+0)*gridSize + x];
1465                                         vdb = &faceGridData[(y+1)*gridSize + x];
1466
1467                                         PASSATTRIB(0, 0, 3);
1468                                         glNormal3fv(vda->no);
1469                                         glVertex3fv(vda->co);
1470
1471                                         PASSATTRIB(0, 1, 2);
1472                                         glNormal3fv(vdb->no);
1473                                         glVertex3fv(vdb->co);
1474
1475                                         glEnd();
1476
1477                                         a++;
1478                                 }
1479                         } else {
1480                                 glBegin(GL_QUADS);
1481                                 for (y=0; y<gridFaces; y++) {
1482                                         for (x=0; x<gridFaces; x++) {
1483                                                 float *aco = faceGridData[(y+0)*gridSize + x].co;
1484                                                 float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
1485                                                 float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
1486                                                 float *dco = faceGridData[(y+1)*gridSize + x].co;
1487
1488                                                 ccgDM_glNormalFast(aco, bco, cco, dco);
1489
1490                                                 PASSATTRIB(0, 1, 1);
1491                                                 glVertex3fv(dco);
1492                                                 PASSATTRIB(1, 1, 2);
1493                                                 glVertex3fv(cco);
1494                                                 PASSATTRIB(1, 0, 3);
1495                                                 glVertex3fv(bco);
1496                                                 PASSATTRIB(0, 0, 0);
1497                                                 glVertex3fv(aco);
1498                                                 
1499                                                 a++;
1500                                         }
1501                                 }
1502                                 glEnd();
1503                         }
1504                 }
1505         }
1506
1507 #undef PASSATTRIB
1508
1509         ccgFaceIterator_free(fi);
1510 }
1511
1512 static void ccgDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
1513         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1514 }
1515
1516 static void ccgDM_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) {
1517         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1518         CCGSubSurf *ss = ccgdm->ss;
1519         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1520         int gridSize = ccgSubSurf_getGridSize(ss);
1521         unsigned char *cp1, *cp2;
1522         int useTwoSide=1;
1523
1524         ccgdm_pbvh_update(ccgdm);
1525
1526         cp1= col1;
1527         if(col2) {
1528                 cp2= col2;
1529         } else {
1530                 cp2= NULL;
1531                 useTwoSide= 0;
1532         }
1533
1534         glShadeModel(GL_SMOOTH);
1535
1536         if(col2) {
1537                 glEnable(GL_CULL_FACE);
1538         }
1539
1540         glBegin(GL_QUADS);
1541         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1542                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1543                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1544
1545                 for (S=0; S<numVerts; S++) {
1546                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1547                         for (y=0; y<gridSize-1; y++) {
1548                                 for (x=0; x<gridSize-1; x++) {
1549                                         float *a = faceGridData[(y+0)*gridSize + x].co;
1550                                         float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1551                                         float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1552                                         float *d = faceGridData[(y+1)*gridSize + x].co;
1553
1554                                         glColor3ub(cp1[3], cp1[2], cp1[1]);
1555                                         glVertex3fv(d);
1556                                         glColor3ub(cp1[7], cp1[6], cp1[5]);
1557                                         glVertex3fv(c);
1558                                         glColor3ub(cp1[11], cp1[10], cp1[9]);
1559                                         glVertex3fv(b);
1560                                         glColor3ub(cp1[15], cp1[14], cp1[13]);
1561                                         glVertex3fv(a);
1562
1563                                         if (useTwoSide) {
1564                                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
1565                                                 glVertex3fv(a);
1566                                                 glColor3ub(cp2[11], cp2[10], cp2[9]);
1567                                                 glVertex3fv(b);
1568                                                 glColor3ub(cp2[7], cp2[6], cp2[5]);
1569                                                 glVertex3fv(c);
1570                                                 glColor3ub(cp2[3], cp2[2], cp2[1]);
1571                                                 glVertex3fv(d);
1572                                         }
1573
1574                                         if (cp2) cp2+=16;
1575                                         cp1+=16;
1576                                 }
1577                         }
1578                 }
1579         }
1580         glEnd();
1581
1582         ccgFaceIterator_free(fi);
1583 }
1584
1585 static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
1586         int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
1587         int (*drawParamsMapped)(void *userData, int index),
1588         void *userData) 
1589 {
1590         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1591         CCGSubSurf *ss = ccgdm->ss;
1592         MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
1593         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
1594         char *faceFlags = ccgdm->faceFlags;
1595         int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss);
1596         int gridFaces = gridSize - 1;
1597
1598         ccgdm_pbvh_update(ccgdm);
1599
1600         if(!mcol)
1601                 mcol = dm->getFaceDataArray(dm, CD_MCOL);
1602
1603         totface = ccgSubSurf_getNumFaces(ss);
1604         for(i = 0; i < totface; i++) {
1605                 CCGFace *f = ccgdm->faceMap[i].face;
1606                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1607                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
1608                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1609                 unsigned char *cp= NULL;
1610                 int mat_nr;
1611
1612                 if(faceFlags) {
1613                         drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
1614                         mat_nr= faceFlags[origIndex*2 + 1];
1615                 }
1616                 else {
1617                         drawSmooth = 1;
1618                         mat_nr= 0;
1619                 }
1620
1621                 if(drawParams)
1622                         flag = drawParams(tf, (mcol != NULL), mat_nr);
1623                 else if (index != ORIGINDEX_NONE)
1624                         flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1;
1625                 else
1626                         flag= GPU_enable_material(mat_nr, NULL) ? 1:0;
1627
1628
1629                 if (flag == 0) { /* flag 0 == the face is hidden or invisible */
1630                         if(tf) tf += gridFaces*gridFaces*numVerts;
1631                         if(mcol) mcol += gridFaces*gridFaces*numVerts*4;
1632                         continue;
1633                 }
1634
1635                 /* flag 1 == use vertex colors */
1636                 if(mcol) {
1637                         if(flag==1) cp= (unsigned char*)mcol;
1638                         mcol += gridFaces*gridFaces*numVerts*4;
1639                 }
1640
1641                 for (S=0; S<numVerts; S++) {
1642                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1643                         DMGridData *a, *b;
1644
1645                         if (drawSmooth) {
1646                                 glShadeModel(GL_SMOOTH);
1647                                 for (y=0; y<gridFaces; y++) {
1648                                         glBegin(GL_QUAD_STRIP);
1649                                         for (x=0; x<gridFaces; x++) {
1650                                                 a = &faceGridData[(y+0)*gridSize + x];
1651                                                 b = &faceGridData[(y+1)*gridSize + x];
1652
1653                                                 if(tf) glTexCoord2fv(tf->uv[0]);
1654                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1655                                                 glNormal3fv(a->no);
1656                                                 glVertex3fv(a->co);
1657
1658                                                 if(tf) glTexCoord2fv(tf->uv[1]);
1659                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1660                                                 glNormal3fv(b->no);
1661                                                 glVertex3fv(b->co);
1662                                                 
1663                                                 if(x != gridFaces-1) {
1664                                                         if(tf) tf++;
1665                                                         if(cp) cp += 16;
1666                                                 }
1667                                         }
1668
1669                                         a = &faceGridData[(y+0)*gridSize + x];
1670                                         b = &faceGridData[(y+1)*gridSize + x];
1671
1672                                         if(tf) glTexCoord2fv(tf->uv[3]);
1673                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1674                                         glNormal3fv(a->no);
1675                                         glVertex3fv(a->co);
1676
1677                                         if(tf) glTexCoord2fv(tf->uv[2]);
1678                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1679                                         glNormal3fv(b->no);
1680                                         glVertex3fv(b->co);
1681
1682                                         if(tf) tf++;
1683                                         if(cp) cp += 16;
1684
1685                                         glEnd();
1686                                 }
1687                         } else {
1688                                 glShadeModel(GL_FLAT);
1689                                 glBegin(GL_QUADS);
1690                                 for (y=0; y<gridFaces; y++) {
1691                                         for (x=0; x<gridFaces; x++) {
1692                                                 float *a_co = faceGridData[(y+0)*gridSize + x].co;
1693                                                 float *b_co = faceGridData[(y+0)*gridSize + x + 1].co;
1694                                                 float *c_co = faceGridData[(y+1)*gridSize + x + 1].co;
1695                                                 float *d_co = faceGridData[(y+1)*gridSize + x].co;
1696
1697                                                 ccgDM_glNormalFast(a_co, b_co, c_co, d_co);
1698
1699                                                 if(tf) glTexCoord2fv(tf->uv[1]);
1700                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1701                                                 glVertex3fv(d_co);
1702
1703                                                 if(tf) glTexCoord2fv(tf->uv[2]);
1704                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1705                                                 glVertex3fv(c_co);
1706
1707                                                 if(tf) glTexCoord2fv(tf->uv[3]);
1708                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1709                                                 glVertex3fv(b_co);
1710
1711                                                 if(tf) glTexCoord2fv(tf->uv[0]);
1712                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1713                                                 glVertex3fv(a_co);
1714
1715                                                 if(tf) tf++;
1716                                                 if(cp) cp += 16;
1717                                         }
1718                                 }
1719                                 glEnd();
1720                         }
1721                 }
1722         }
1723 }
1724
1725 static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr))
1726 {
1727         ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
1728 }
1729
1730 static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1731 {
1732         ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
1733 }
1734
1735 static void ccgDM_drawUVEdges(DerivedMesh *dm)
1736 {
1737
1738         MFace *mf = dm->getFaceArray(dm);
1739         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
1740         int i;
1741         
1742         if (tf) {
1743                 glBegin(GL_LINES);
1744                 for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
1745                         if(!(mf->flag&ME_HIDE)) {
1746                                 glVertex2fv(tf->uv[0]);
1747                                 glVertex2fv(tf->uv[1]);
1748         
1749                                 glVertex2fv(tf->uv[1]);
1750                                 glVertex2fv(tf->uv[2]);
1751         
1752                                 if(!mf->v4) {
1753                                         glVertex2fv(tf->uv[2]);
1754                                         glVertex2fv(tf->uv[0]);
1755                                 } else {
1756                                         glVertex2fv(tf->uv[2]);
1757                                         glVertex2fv(tf->uv[3]);
1758         
1759                                         glVertex2fv(tf->uv[3]);
1760                                         glVertex2fv(tf->uv[0]);
1761                                 }
1762                         }
1763                 }
1764                 glEnd();
1765         }
1766 }
1767
1768 static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs),
1769                         int (*compareDrawOptions)(void *userData, int cur_index, int next_index)) {
1770         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1771         CCGSubSurf *ss = ccgdm->ss;
1772         MCol *mcol= NULL;
1773         int i, gridSize = ccgSubSurf_getGridSize(ss);
1774         char *faceFlags = ccgdm->faceFlags;
1775         int gridFaces = gridSize - 1, totface;
1776
1777         /* currently unused -- each original face is handled separately */
1778         (void)compareDrawOptions;
1779
1780         if(useColors) {
1781                 mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
1782                 if(!mcol)
1783                         mcol = dm->getFaceDataArray(dm, CD_MCOL);
1784         }
1785
1786         totface = ccgSubSurf_getNumFaces(ss);
1787         for(i = 0; i < totface; i++) {
1788                 CCGFace *f = ccgdm->faceMap[i].face;
1789                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1790                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
1791                 int origIndex;
1792                 unsigned char *cp= NULL;
1793
1794                 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1795
1796                 if(faceFlags) drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
1797                 else drawSmooth = 1;
1798
1799                 if(mcol) {
1800                         cp= (unsigned char*)mcol;
1801                         mcol += gridFaces*gridFaces*numVerts*4;
1802                 }
1803
1804                 {
1805                         int draw= 1;
1806
1807                         if(index == ORIGINDEX_NONE)
1808                                 draw= setMaterial(faceFlags ? faceFlags[origIndex*2 + 1] + 1: 1, NULL); /* XXX, no faceFlags no material */
1809                         else if (setDrawOptions)
1810                                 draw= setDrawOptions(userData, index, &drawSmooth);
1811
1812                         if (draw) {
1813                                 if (draw==2) {
1814                                           glEnable(GL_POLYGON_STIPPLE);
1815                                           glPolygonStipple(stipple_quarttone);
1816                                 }
1817                                 
1818                                 for (S=0; S<numVerts; S++) {
1819                                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1820                                         if (drawSmooth) {
1821                                                 glShadeModel(GL_SMOOTH);
1822                                                 for (y=0; y<gridFaces; y++) {
1823                                                         DMGridData *a, *b;
1824                                                         glBegin(GL_QUAD_STRIP);
1825                                                         for (x=0; x<gridFaces; x++) {
1826                                                                 a = &faceGridData[(y+0)*gridSize + x];
1827                                                                 b = &faceGridData[(y+1)*gridSize + x];
1828         
1829                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1830                                                                 glNormal3fv(a->no);
1831                                                                 glVertex3fv(a->co);
1832                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1833                                                                 glNormal3fv(b->no);
1834                                                                 glVertex3fv(b->co);
1835
1836                                                                 if(x != gridFaces-1) {
1837                                                                         if(cp) cp += 16;
1838                                                                 }
1839                                                         }
1840
1841                                                         a = &faceGridData[(y+0)*gridSize + x];
1842                                                         b = &faceGridData[(y+1)*gridSize + x];
1843
1844                                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1845                                                         glNormal3fv(a->no);
1846                                                         glVertex3fv(a->co);
1847                                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1848                                                         glNormal3fv(b->no);
1849                                                         glVertex3fv(b->co);
1850
1851                                                         if(cp) cp += 16;
1852
1853                                                         glEnd();
1854                                                 }
1855                                         } else {
1856                                                 glShadeModel(GL_FLAT);
1857                                                 glBegin(GL_QUADS);
1858                                                 for (y=0; y<gridFaces; y++) {
1859                                                         for (x=0; x<gridFaces; x++) {
1860                                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
1861                                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1862                                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1863                                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
1864
1865                                                                 ccgDM_glNormalFast(a, b, c, d);
1866         
1867                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1868                                                                 glVertex3fv(d);
1869                                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1870                                                                 glVertex3fv(c);
1871                                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1872                                                                 glVertex3fv(b);
1873                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1874                                                                 glVertex3fv(a);
1875
1876                                                                 if(cp) cp += 16;
1877                                                         }
1878                                                 }
1879                                                 glEnd();
1880                                         }
1881                                 }
1882                                 if (draw==2)
1883                                         glDisable(GL_POLYGON_STIPPLE);
1884                         }
1885                 }
1886         }
1887 }
1888 static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
1889         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1890         CCGSubSurf *ss = ccgdm->ss;
1891         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1892         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
1893
1894         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1895
1896         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1897                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1898                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1899                 int index = ccgDM_getEdgeMapIndex(ss, e);
1900
1901                 glBegin(GL_LINE_STRIP);
1902                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
1903                         if (useAging && !(G.f&G_BACKBUFSEL)) {
1904                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1905                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
1906                         }
1907
1908                         for (i=0; i<edgeSize-1; i++) {
1909                                 glVertex3fv(edgeData[i].co);
1910                                 glVertex3fv(edgeData[i+1].co);
1911                         }
1912                 }
1913                 glEnd();
1914         }
1915
1916         ccgEdgeIterator_free(ei);
1917 }
1918 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
1919         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1920         CCGSubSurf *ss = ccgdm->ss;
1921         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1922         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
1923
1924         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1925
1926         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1927                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1928                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1929                 int index = ccgDM_getEdgeMapIndex(ss, e);
1930
1931                 glBegin(GL_LINE_STRIP);
1932                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
1933                         for (i=0; i<edgeSize; i++) {
1934                                 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
1935
1936                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1937                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1938                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1939                                 }
1940
1941                                 glVertex3fv(edgeData[i].co);
1942                         }
1943                 }
1944                 glEnd();
1945         }
1946
1947         ccgEdgeIterator_free(ei);
1948 }
1949 static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
1950         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1951         CCGSubSurf *ss = ccgdm->ss;
1952         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
1953
1954         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1955                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1956                 int index = ccgDM_getFaceMapIndex(ss, f);
1957
1958                 if (index!=-1) {
1959                                 /* Face center data normal isn't updated atm. */
1960                         DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
1961
1962                         func(userData, index, vd->co, vd->no);
1963                 }
1964         }
1965
1966         ccgFaceIterator_free(fi);
1967 }
1968
1969 static void ccgDM_release(DerivedMesh *dm) {
1970         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1971
1972         if (DM_release(dm)) {
1973                 /* Before freeing, need to update the displacement map */
1974                 if(ccgdm->multires.modified) {
1975                         /* Check that mmd still exists */
1976                         if(!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
1977                                 ccgdm->multires.mmd = NULL;
1978                         if(ccgdm->multires.mmd)
1979                                 ccgdm->multires.update(dm);
1980                 }
1981
1982                 if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
1983                 if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
1984                 if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
1985                 if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
1986                 if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
1987                 if(ccgdm->fmap) MEM_freeN(ccgdm->fmap);
1988                 if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem);
1989                 MEM_freeN(ccgdm->edgeFlags);
1990                 MEM_freeN(ccgdm->faceFlags);
1991                 MEM_freeN(ccgdm->vertMap);
1992                 MEM_freeN(ccgdm->edgeMap);
1993                 MEM_freeN(ccgdm->faceMap);
1994                 MEM_freeN(ccgdm);
1995         }
1996 }
1997
1998 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
1999 {
2000         if(type == CD_ORIGINDEX) {
2001                 /* create origindex on demand to save memory */
2002                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2003                 CCGSubSurf *ss= ccgdm->ss;
2004                 int *origindex;
2005                 int a, index, totnone, totorig;
2006
2007                 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2008                 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
2009
2010                 totorig = ccgSubSurf_getNumVerts(ss);
2011                 totnone= dm->numVertData - totorig;
2012
2013                 /* original vertices are at the end */
2014                 for(a=0; a<totnone; a++)
2015                         origindex[a]= ORIGINDEX_NONE;
2016
2017                 for(index=0; index<totorig; index++, a++) {
2018                         CCGVert *v = ccgdm->vertMap[index].vert;
2019                         origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
2020                 }
2021
2022                 return origindex;
2023         }
2024
2025         return DM_get_vert_data_layer(dm, type);
2026 }
2027
2028 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
2029 {
2030         if(type == CD_ORIGINDEX) {
2031                 /* create origindex on demand to save memory */
2032                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2033                 CCGSubSurf *ss= ccgdm->ss;
2034                 int *origindex;
2035                 int a, i, index, totnone, totorig, totedge;
2036                 int edgeSize= ccgSubSurf_getEdgeSize(ss);
2037
2038                 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2039                 origindex= DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2040
2041                 totedge= ccgSubSurf_getNumEdges(ss);
2042                 totorig= totedge*(edgeSize - 1);
2043                 totnone= dm->numEdgeData - totorig;
2044
2045                 /* original edges are at the end */
2046                 for(a=0; a<totnone; a++)
2047                         origindex[a]= ORIGINDEX_NONE;
2048
2049                 for(index=0; index<totedge; index++) {
2050                         CCGEdge *e= ccgdm->edgeMap[index].edge;
2051                         int mapIndex= ccgDM_getEdgeMapIndex(ss, e);
2052
2053                         for(i = 0; i < edgeSize - 1; i++, a++)
2054                                 origindex[a]= mapIndex;
2055                 }
2056
2057                 return origindex;
2058         }
2059
2060         return DM_get_edge_data_layer(dm, type);
2061 }
2062
2063 static void *ccgDM_get_face_data_layer(DerivedMesh *dm, int type)
2064 {
2065         if(type == CD_ORIGINDEX) {
2066                 /* create origindex on demand to save memory */
2067                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2068                 CCGSubSurf *ss= ccgdm->ss;
2069                 int *origindex;
2070                 int a, i, index, totface;
2071                 int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
2072
2073                 DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2074                 origindex= DM_get_face_data_layer(dm, CD_ORIGINDEX);
2075
2076                 totface= ccgSubSurf_getNumFaces(ss);
2077
2078                 for(a=0, index=0; index<totface; index++) {
2079                         CCGFace *f = ccgdm->faceMap[index].face;
2080                         int numVerts = ccgSubSurf_getFaceNumVerts(f);
2081                         int mapIndex = ccgDM_getFaceMapIndex(ss, f);
2082
2083                         for(i=0; i<gridFaces*gridFaces*numVerts; i++, a++)
2084                                 origindex[a]= mapIndex;
2085                 }
2086
2087                 return origindex;
2088         }
2089
2090         return DM_get_face_data_layer(dm, type);
2091 }
2092
2093 static int ccgDM_getNumGrids(DerivedMesh *dm)
2094 {
2095         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2096         int index, numFaces, numGrids;
2097
2098         numFaces= ccgSubSurf_getNumFaces(ccgdm->ss);
2099         numGrids= 0;
2100
2101         for(index=0; index<numFaces; index++) {
2102                 CCGFace *f = ccgdm->faceMap[index].face;
2103                 numGrids += ccgSubSurf_getFaceNumVerts(f);
2104         }
2105
2106         return numGrids;
2107 }
2108
2109 static int ccgDM_getGridSize(DerivedMesh *dm)
2110 {
2111         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2112         return ccgSubSurf_getGridSize(ccgdm->ss);
2113 }
2114
2115 static int ccgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset)
2116 {
2117         CCGFace *adjf;
2118         CCGEdge *e;
2119         int i, j= 0, numFaces, fIndex, numEdges= 0;
2120
2121         e = ccgSubSurf_getFaceEdge(ss, f, S);
2122         numFaces = ccgSubSurf_getEdgeNumFaces(e);
2123
2124         if(numFaces != 2)
2125                 return -1;
2126
2127         for(i = 0; i < numFaces; i++) {
2128                 adjf = ccgSubSurf_getEdgeFace(e, i);
2129
2130                 if(adjf != f) {
2131                         numEdges = ccgSubSurf_getFaceNumVerts(adjf);
2132                         for(j = 0; j < numEdges; j++)
2133                                 if(ccgSubSurf_getFaceEdge(ss, adjf, j) == e)
2134                                         break;
2135
2136                         if(j != numEdges)
2137                                 break;
2138                 }
2139         }
2140         
2141         fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, adjf));
2142
2143         return gridOffset[fIndex] + (j + offset)%numEdges;
2144 }
2145
2146 static void ccgdm_create_grids(DerivedMesh *dm)
2147 {
2148         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2149         CCGSubSurf *ss= ccgdm->ss;
2150         DMGridData **gridData;
2151         DMGridAdjacency *gridAdjacency, *adj;
2152         CCGFace **gridFaces;
2153         int *gridOffset;
2154         int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
2155
2156         if(ccgdm->gridData)
2157                 return;
2158         
2159         numGrids = ccgDM_getNumGrids(dm);
2160         numFaces = ccgSubSurf_getNumFaces(ss);
2161         /*gridSize = ccgDM_getGridSize(dm);*/  /*UNUSED*/
2162
2163         /* compute offset into grid array for each face */
2164         gridOffset = MEM_mallocN(sizeof(int)*numFaces, "ccgdm.gridOffset");
2165
2166         for(gIndex = 0, index = 0; index < numFaces; index++) {
2167                 CCGFace *f = ccgdm->faceMap[index].face;
2168                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2169
2170                 gridOffset[index] = gIndex;
2171                 gIndex += numVerts;
2172         }
2173
2174         /* compute grid data */
2175         gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "ccgdm.gridData");
2176         gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "ccgdm.gridAdjacency");
2177         gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "ccgdm.gridFaces");
2178
2179         for(gIndex = 0, index = 0; index < numFaces; index++) {
2180                 CCGFace *f = ccgdm->faceMap[index].face;
2181                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2182
2183                 for(S = 0; S < numVerts; S++, gIndex++) {
2184                         int prevS = (S - 1 + numVerts) % numVerts;
2185                         int nextS = (S + 1 + numVerts) % numVerts;
2186
2187                         gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2188                         gridFaces[gIndex] = f;
2189
2190                         adj = &gridAdjacency[gIndex];
2191
2192                         adj->index[0] = gIndex - S + nextS;
2193                         adj->rotation[0] = 3;
2194                         adj->index[1] = ccgdm_adjacent_grid(ss, gridOffset, f, prevS, 0);
2195                         adj->rotation[1] = 1;
2196                         adj->index[2] = ccgdm_adjacent_grid(ss, gridOffset, f, S, 1);
2197                         adj->rotation[2] = 3;
2198                         adj->index[3] = gIndex - S + prevS;
2199                         adj->rotation[3] = 1;
2200                 }
2201         }
2202
2203         ccgdm->gridData = gridData;
2204         ccgdm->gridFaces = gridFaces;
2205         ccgdm->gridAdjacency = gridAdjacency;
2206         ccgdm->gridOffset = gridOffset;
2207 }
2208
2209 static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
2210 {
2211         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2212
2213         ccgdm_create_grids(dm);
2214         return ccgdm->gridData;
2215 }
2216
2217 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm)
2218 {
2219         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2220
2221         ccgdm_create_grids(dm);
2222         return ccgdm->gridAdjacency;
2223 }
2224
2225 static int *ccgDM_getGridOffset(DerivedMesh *dm)
2226 {
2227         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2228
2229         ccgdm_create_grids(dm);
2230         return ccgdm->gridOffset;
2231 }
2232
2233 static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
2234 {
2235         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2236
2237         if(!ccgdm->multires.mmd && !ccgdm->fmap && ob->type == OB_MESH) {
2238                 Mesh *me= ob->data;
2239
2240                 create_vert_face_map(&ccgdm->fmap, &ccgdm->fmap_mem, me->mface,
2241                                      me->totvert, me->totface);
2242         }
2243
2244         return ccgdm->fmap;
2245 }
2246
2247 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
2248 {
2249         MultiresModifierData *mmd= ccgdm->multires.mmd;
2250
2251         /* both of multires and subsurm modifiers are CCG, but
2252            grids should only be used when sculpting on multires */
2253         if(!mmd)
2254                 return 0;
2255
2256         return 1;
2257 }
2258
2259 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
2260 {
2261         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2262         int gridSize, numGrids, grid_pbvh;
2263
2264         if(!ob) {
2265                 ccgdm->pbvh= NULL;
2266                 return NULL;
2267         }
2268
2269         if(!ob->sculpt)
2270                 return NULL;
2271
2272         grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
2273
2274         if(ob->sculpt->pbvh) {
2275                 if(grid_pbvh) {
2276                         /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
2277                            but this can be freed on ccgdm release, this updates the pointers
2278                            when the ccgdm gets remade, the assumption is that the topology
2279                            does not change. */
2280                         ccgdm_create_grids(dm);
2281                         BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
2282                 }
2283
2284                 ccgdm->pbvh = ob->sculpt->pbvh;
2285         }
2286
2287         if(ccgdm->pbvh)
2288                 return ccgdm->pbvh;
2289
2290         /* no pbvh exists yet, we need to create one. only in case of multires
2291            we build a pbvh over the modified mesh, in other cases the base mesh
2292            is being sculpted, so we build a pbvh from that. */
2293         if(grid_pbvh) {
2294                 ccgdm_create_grids(dm);
2295
2296                 gridSize = ccgDM_getGridSize(dm);
2297                 numGrids = ccgDM_getNumGrids(dm);
2298
2299                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2300                 BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
2301                         numGrids, gridSize, (void**)ccgdm->gridFaces);
2302         } else if(ob->type == OB_MESH) {
2303                 Mesh *me= ob->data;
2304                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2305                 BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
2306                                    me->totface, me->totvert);
2307         }
2308
2309         return ccgdm->pbvh;
2310 }
2311
2312 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2313                                                                                  int drawInteriorEdges,
2314                                                                                  int useSubsurfUv,
2315                                                                                  DerivedMesh *dm)
2316 {
2317         CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
2318         CCGVertIterator *vi;
2319         CCGEdgeIterator *ei;
2320         CCGFaceIterator *fi;
2321         int index, totvert, totedge, totface;
2322         int i;
2323         int vertNum, edgeNum, faceNum;
2324         short *edgeFlags;
2325         char *faceFlags;
2326         int edgeSize;
2327         int gridSize;
2328         int gridFaces;
2329         /*int gridSideVerts;*/
2330         int gridSideEdges;
2331         int gridInternalEdges;
2332         MEdge *medge = NULL;
2333         MFace *mface = NULL;
2334         int *orig_indices;
2335         FaceVertWeight *qweight, *tweight;
2336
2337         DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
2338                                          ccgSubSurf_getNumFinalVerts(ss),
2339                                          ccgSubSurf_getNumFinalEdges(ss),
2340                                          ccgSubSurf_getNumFinalFaces(ss));
2341
2342         ccgdm->dm.getMinMax = ccgDM_getMinMax;
2343         ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
2344         ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
2345
2346         ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
2347         ccgdm->dm.getVert = ccgDM_getFinalVert;
2348         ccgdm->dm.getEdge = ccgDM_getFinalEdge;
2349         ccgdm->dm.getFace = ccgDM_getFinalFace;
2350         ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
2351         ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
2352         ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2353         ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2354         ccgdm->dm.copyFaceArray = ccgDM_copyFinalFaceArray;
2355         ccgdm->dm.getVertData = DM_get_vert_data;
2356         ccgdm->dm.getEdgeData = DM_get_edge_data;
2357         ccgdm->dm.getFaceData = DM_get_face_data;
2358         ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
2359         ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
2360         ccgdm->dm.getFaceDataArray = ccgDM_get_face_data_layer;
2361         ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
2362         ccgdm->dm.getGridSize = ccgDM_getGridSize;
2363         ccgdm->dm.getGridData = ccgDM_getGridData;
2364         ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency;
2365         ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
2366         ccgdm->dm.getFaceMap = ccgDM_getFaceMap;
2367         ccgdm->dm.getPBVH = ccgDM_getPBVH;
2368
2369         ccgdm->dm.getVertCos = ccgdm_getVertCos;
2370         ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
2371         ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
2372         ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
2373         
2374         ccgdm->dm.drawVerts = ccgDM_drawVerts;
2375         ccgdm->dm.drawEdges = ccgDM_drawEdges;
2376         ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
2377         ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
2378         ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
2379         ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
2380         ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL;
2381         ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
2382         ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
2383         ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL;
2384         ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
2385
2386         ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
2387         ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
2388         
2389         ccgdm->dm.release = ccgDM_release;
2390         
2391         ccgdm->ss = ss;
2392         ccgdm->drawInteriorEdges = drawInteriorEdges;
2393         ccgdm->useSubsurfUv = useSubsurfUv;
2394
2395         totvert = ccgSubSurf_getNumVerts(ss);
2396         ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
2397         vi = ccgSubSurf_getVertIterator(ss);
2398         for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2399                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2400
2401                 ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
2402         }
2403         ccgVertIterator_free(vi);
2404
2405         totedge = ccgSubSurf_getNumEdges(ss);
2406         ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
2407         ei = ccgSubSurf_getEdgeIterator(ss);
2408         for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2409                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2410
2411                 ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
2412         }
2413
2414         totface = ccgSubSurf_getNumFaces(ss);
2415         ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
2416         fi = ccgSubSurf_getFaceIterator(ss);
2417         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2418                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2419
2420                 ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
2421         }
2422         ccgFaceIterator_free(fi);
2423
2424         edgeSize = ccgSubSurf_getEdgeSize(ss);
2425         gridSize = ccgSubSurf_getGridSize(ss);
2426         gridFaces = gridSize - 1;
2427         /*gridSideVerts = gridSize - 2;*/ /*UNUSED*/
2428         /*gridInternalVerts = gridSideVerts * gridSideVerts; */ /*UNUSED*/
2429         gridSideEdges = gridSize - 1;
2430         gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
2431
2432         calc_ss_weights(gridFaces, &qweight, &tweight);
2433
2434         vertNum = 0;
2435         edgeNum = 0;
2436         faceNum = 0;
2437
2438         /* mvert = dm->getVertArray(dm); - as yet unused */
2439         medge = dm->getEdgeArray(dm);
2440         mface = dm->getFaceArray(dm);
2441
2442         faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags");
2443
2444         orig_indices = (int*)ccgdm->dm.getFaceDataArray(&ccgdm->dm, CD_ORIGINDEX);
2445         for(index = 0; index < totface; ++index) {
2446                 CCGFace *f = ccgdm->faceMap[index].face;
2447                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2448                 int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
2449                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2450                 FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
2451                 int S, x, y;
2452                 int vertIdx[4];
2453
2454                 ccgdm->faceMap[index].startVert = vertNum;
2455                 ccgdm->faceMap[index].startEdge = edgeNum;
2456                 ccgdm->faceMap[index].startFace = faceNum;
2457
2458                 if(orig_indices)
2459                         orig_indices[faceNum] = origIndex;
2460
2461                 /* set the face base vert */
2462                 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
2463
2464                 for(S = 0; S < numVerts; S++) {
2465                         CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
2466
2467                         vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2468                 }
2469
2470                 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, weight[0][0],
2471                                                         numVerts, vertNum);
2472                 ++vertNum;
2473
2474                 for(S = 0; S < numVerts; S++) {
2475                         int prevS = (S - 1 + numVerts) % numVerts;
2476                         int nextS = (S + 1) % numVerts;
2477                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2478                         for(x = 1; x < gridFaces; x++) {
2479                                 float w[4];
2480                                 w[prevS]  = weight[x][0][0];
2481                                 w[S]      = weight[x][0][1];
2482                                 w[nextS]  = weight[x][0][2];
2483                                 w[otherS] = weight[x][0][3];
2484                                 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2485                                                                         numVerts, vertNum);
2486                                 ++vertNum;
2487                         }
2488                 }
2489
2490                 for(S = 0; S < numVerts; S++) {
2491                         int prevS = (S - 1 + numVerts) % numVerts;
2492                         int nextS = (S + 1) % numVerts;
2493                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2494                         for(y = 1; y < gridFaces; y++) {
2495                                 for(x = 1; x < gridFaces; x++) {
2496                                         float w[4];
2497                                         w[prevS]  = weight[y * gridFaces + x][0][0];
2498                                         w[S]      = weight[y * gridFaces + x][0][1];
2499                                         w[nextS]  = weight[y * gridFaces + x][0][2];
2500                                         w[otherS] = weight[y * gridFaces + x][0][3];
2501                                         DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2502                                                                                 numVerts, vertNum);
2503                                         ++vertNum;
2504                                 }
2505                         }
2506                 }
2507
2508                 for(S = 0; S < numVerts; S++) {
2509                         int prevS = (S - 1 + numVerts) % numVerts;
2510                         int nextS = (S + 1) % numVerts;
2511                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2512
2513                         weight = (numVerts == 4) ? qweight : tweight;
2514
2515                         for(y = 0; y < gridFaces; y++) {
2516                                 for(x = 0; x < gridFaces; x++) {
2517                                         FaceVertWeight w;
2518                                         int j;
2519
2520                                         for(j = 0; j < 4; ++j) {
2521                                                 w[j][prevS]  = (*weight)[j][0];
2522                                                 w[j][S]      = (*weight)[j][1];
2523                                                 w[j][nextS]  = (*weight)[j][2];
2524                                                 w[j][otherS] = (*weight)[j][3];
2525                                         }
2526
2527                                         DM_interp_face_data(dm, &ccgdm->dm, &origIndex, NULL,
2528                                                                                 &w, 1, faceNum);
2529                                         weight++;
2530
2531                                         ++faceNum;
2532                                 }
2533                         }
2534                 }
2535
2536                 faceFlags[index*2] = mface[origIndex].flag;
2537                 faceFlags[index*2 + 1] = mface[origIndex].mat_nr;
2538
2539                 edgeNum += numFinalEdges;
2540         }
2541
2542         if(useSubsurfUv) {
2543                 CustomData *fdata = &ccgdm->dm.faceData;
2544                 CustomData *dmfdata = &dm->faceData;
2545                 int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
2546                 int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
2547
2548                 for (i=0; i<numlayer && i<dmnumlayer; i++)
2549                         set_subsurf_uv(ss, dm, &ccgdm->dm, i);
2550         }
2551
2552         edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "edgeFlags");
2553
2554         for(index = 0; index < totedge; ++index) {
2555                 CCGEdge *e = ccgdm->edgeMap[index].edge;
2556                 int numFinalEdges = edgeSize - 1;
2557                 int x;
2558                 int vertIdx[2];
2559                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
2560
2561                 CCGVert *v;
2562                 v = ccgSubSurf_getEdgeVert0(e);
2563                 vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2564                 v = ccgSubSurf_getEdgeVert1(e);
2565                 vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2566
2567                 ccgdm->edgeMap[index].startVert = vertNum;
2568                 ccgdm->edgeMap[index].startEdge = edgeNum;
2569
2570                 /* set the edge base vert */
2571                 *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
2572
2573                 for(x = 1; x < edgeSize - 1; x++) {
2574                         float w[2];
2575                         w[1] = (float) x / (edgeSize - 1);
2576                         w[0] = 1 - w[1];
2577                         DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
2578                         ++vertNum;
2579                 }
2580
2581                 edgeFlags[index]= medge[edgeIdx].flag;
2582
2583                 edgeNum += numFinalEdges;
2584         }
2585
2586         for(index = 0; index < totvert; ++index) {
2587                 CCGVert *v = ccgdm->vertMap[index].vert;
2588                 int vertIdx;
2589
2590                 vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2591
2592                 ccgdm->vertMap[index].startVert = vertNum;
2593
2594                 /* set the vert base vert */
2595                 *((int*) ccgSubSurf_getVertUserData(ss, v)) = vertNum;
2596
2597                 DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
2598
2599                 ++vertNum;
2600         }
2601
2602         MEM_freeN(qweight);
2603         MEM_freeN(tweight);
2604
2605         return ccgdm;
2606 }
2607
2608 /***/
2609
2610 struct DerivedMesh *subsurf_make_derived_from_derived(
2611                                                 struct DerivedMesh *dm,
2612                                                 struct SubsurfModifierData *smd,
2613                                                 int useRenderParams, float (*vertCos)[3],
2614                                                 int isFinalCalc, int forEditMode, int inEditMode)
2615 {
2616         int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF;
2617         int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2618         int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv;
2619         int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
2620         CCGDerivedMesh *result;
2621
2622         if(forEditMode) {
2623                 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
2624
2625                 smd->emCache = _getSubSurf(smd->emCache, levels, useAging, 0,
2626                                                                    useSimple);
2627                 ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
2628
2629                 result = getCCGDerivedMesh(smd->emCache,
2630                                                                    drawInteriorEdges,
2631                                                                    useSubsurfUv, dm);
2632         } else if(useRenderParams) {
2633                 /* Do not use cache in render mode. */
2634                 CCGSubSurf *ss;
2635                 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->renderLevels): smd->renderLevels;
2636
2637                 if(levels == 0)
2638                         return dm;
2639                 
2640                 ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
2641
2642                 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2643
2644                 result = getCCGDerivedMesh(ss,
2645                         drawInteriorEdges, useSubsurfUv, dm);
2646
2647                 result->freeSS = 1;
2648         } else {
2649                 int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
2650                 int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2651                 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
2652                 CCGSubSurf *ss;
2653
2654                 /* It is quite possible there is a much better place to do this. It
2655                  * depends a bit on how rigourously we expect this function to never
2656                  * be called in editmode. In semi-theory we could share a single
2657                  * cache, but the handles used inside and outside editmode are not
2658                  * the same so we would need some way of converting them. Its probably
2659                  * not worth the effort. But then why am I even writing this long
2660                  * comment that no one will read? Hmmm. - zr
2661                  *
2662                  * Addendum: we can't really ensure that this is never called in edit
2663                  * mode, so now we have a parameter to verify it. - brecht
2664                  */
2665                 if(!inEditMode && smd->emCache) {
2666                         ccgSubSurf_free(smd->emCache);
2667                         smd->emCache = NULL;
2668                 }
2669
2670                 if(useIncremental && isFinalCalc) {
2671                         smd->mCache = ss = _getSubSurf(smd->mCache, levels,
2672                                                                                    useAging, 0, useSimple);
2673
2674                         ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2675
2676                         result = getCCGDerivedMesh(smd->mCache,
2677                                                                            drawInteriorEdges,
2678                                                                            useSubsurfUv, dm);
2679                 } else {
2680                         if (smd->mCache && isFinalCalc) {
2681                                 ccgSubSurf_free(smd->mCache);
2682                                 smd->mCache = NULL;
2683                         }
2684
2685                         ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
2686                         ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2687
2688                         result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
2689
2690                         if(isFinalCalc)
2691                                 smd->mCache = ss;
2692                         else
2693                                 result->freeSS = 1;
2694                 }
2695         }
2696
2697         return (DerivedMesh*)result;
2698 }
2699
2700 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 
2701 {
2702         /* Finds the subsurf limit positions for the verts in a mesh 
2703          * and puts them in an array of floats. Please note that the 
2704          * calculated vert positions is incorrect for the verts 
2705          * on the boundary of the mesh.
2706          */
2707         CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0);
2708         float edge_sum[3], face_sum[3];
2709         CCGVertIterator *vi;
2710         DerivedMesh *dm = CDDM_from_mesh(me, NULL);
2711
2712         ss_sync_from_derivedmesh(ss, dm, NULL, 0);
2713
2714         vi = ccgSubSurf_getVertIterator(ss);
2715         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2716                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2717                 int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2718                 int N = ccgSubSurf_getVertNumEdges(v);
2719                 int numFaces = ccgSubSurf_getVertNumFaces(v);
2720                 float *co;
2721                 int i;
2722
2723                 edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0;
2724                 face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
2725
2726                 for (i=0; i<N; i++) {
2727                         CCGEdge *e = ccgSubSurf_getVertEdge(v, i);
2728                         add_v3_v3v3(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
2729                 }
2730                 for (i=0; i<numFaces; i++) {
2731                         CCGFace *f = ccgSubSurf_getVertFace(v, i);
2732                         add_v3_v3(face_sum, ccgSubSurf_getFaceCenterData(f));
2733                 }
2734
2735                 /* ad-hoc correction for boundary vertices, to at least avoid them
2736                    moving completely out of place (brecht) */
2737                 if(numFaces && numFaces != N)
2738                         mul_v3_fl(face_sum, (float)N/(float)numFaces);
2739
2740                 co = ccgSubSurf_getVertData(ss, v);
2741                 positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
2742                 positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
2743                 positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
2744         }
2745         ccgVertIterator_free(vi);
2746
2747         ccgSubSurf_free(ss);
2748
2749         dm->release(dm);
2750 }
2751