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