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