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