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