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