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