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