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