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