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