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