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