Workaround #29205: Crash while using Edge Split modifier (while rotating vertices...
[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                                 for (S=0; S<numVerts; S++) {
1969                                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1970                                         if (drawSmooth) {
1971                                                 glShadeModel(GL_SMOOTH);
1972                                                 for (y=0; y<gridFaces; y++) {
1973                                                         DMGridData *a, *b;
1974                                                         glBegin(GL_QUAD_STRIP);
1975                                                         for (x=0; x<gridFaces; x++) {
1976                                                                 a = &faceGridData[(y+0)*gridSize + x];
1977                                                                 b = &faceGridData[(y+1)*gridSize + x];
1978         
1979                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1980                                                                 glNormal3fv(a->no);
1981                                                                 glVertex3fv(a->co);
1982                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1983                                                                 glNormal3fv(b->no);
1984                                                                 glVertex3fv(b->co);
1985
1986                                                                 if(x != gridFaces-1) {
1987                                                                         if(cp) cp += 16;
1988                                                                 }
1989                                                         }
1990
1991                                                         a = &faceGridData[(y+0)*gridSize + x];
1992                                                         b = &faceGridData[(y+1)*gridSize + x];
1993
1994                                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1995                                                         glNormal3fv(a->no);
1996                                                         glVertex3fv(a->co);
1997                                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1998                                                         glNormal3fv(b->no);
1999                                                         glVertex3fv(b->co);
2000
2001                                                         if(cp) cp += 16;
2002
2003                                                         glEnd();
2004                                                 }
2005                                         } else {
2006                                                 glShadeModel(GL_FLAT);
2007                                                 glBegin(GL_QUADS);
2008                                                 for (y=0; y<gridFaces; y++) {
2009                                                         for (x=0; x<gridFaces; x++) {
2010                                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
2011                                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
2012                                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
2013                                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
2014
2015                                                                 ccgDM_glNormalFast(a, b, c, d);
2016         
2017                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2018                                                                 glVertex3fv(d);
2019                                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2020                                                                 glVertex3fv(c);
2021                                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2022                                                                 glVertex3fv(b);
2023                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2024                                                                 glVertex3fv(a);
2025
2026                                                                 if(cp) cp += 16;
2027                                                         }
2028                                                 }
2029                                                 glEnd();
2030                                         }
2031                                 }
2032                                 if (draw==2)
2033                                         glDisable(GL_POLYGON_STIPPLE);
2034                         }
2035                 }
2036         }
2037 }
2038 static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
2039         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2040         CCGSubSurf *ss = ccgdm->ss;
2041         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2042         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2043
2044         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2045
2046         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2047                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2048                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2049                 int index = ccgDM_getEdgeMapIndex(ss, e);
2050
2051                 glBegin(GL_LINE_STRIP);
2052                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2053                         if (useAging && !(G.f&G_BACKBUFSEL)) {
2054                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2055                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
2056                         }
2057
2058                         for (i=0; i<edgeSize-1; i++) {
2059                                 glVertex3fv(edgeData[i].co);
2060                                 glVertex3fv(edgeData[i+1].co);
2061                         }
2062                 }
2063                 glEnd();
2064         }
2065
2066         ccgEdgeIterator_free(ei);
2067 }
2068 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
2069         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2070         CCGSubSurf *ss = ccgdm->ss;
2071         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2072         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2073
2074         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2075
2076         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2077                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2078                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2079                 int index = ccgDM_getEdgeMapIndex(ss, e);
2080
2081                 glBegin(GL_LINE_STRIP);
2082                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2083                         for (i=0; i<edgeSize; i++) {
2084                                 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
2085
2086                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
2087                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2088                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
2089                                 }
2090
2091                                 glVertex3fv(edgeData[i].co);
2092                         }
2093                 }
2094                 glEnd();
2095         }
2096
2097         ccgEdgeIterator_free(ei);
2098 }
2099 static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
2100         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2101         CCGSubSurf *ss = ccgdm->ss;
2102         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
2103
2104         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2105                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2106                 int index = ccgDM_getFaceMapIndex(ss, f);
2107
2108                 if (index!=-1) {
2109                                 /* Face center data normal isn't updated atm. */
2110                         DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
2111
2112                         func(userData, index, vd->co, vd->no);
2113                 }
2114         }
2115
2116         ccgFaceIterator_free(fi);
2117 }
2118
2119 static void ccgDM_release(DerivedMesh *dm) {
2120         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2121
2122         if (DM_release(dm)) {
2123                 /* Before freeing, need to update the displacement map */
2124                 if(ccgdm->multires.modified) {
2125                         /* Check that mmd still exists */
2126                         if(!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
2127                                 ccgdm->multires.mmd = NULL;
2128                         if(ccgdm->multires.mmd)
2129                                 ccgdm->multires.update(dm);
2130                 }
2131
2132                 if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
2133                 if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
2134                 if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
2135                 if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
2136                 if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
2137                 if(ccgdm->fmap) MEM_freeN(ccgdm->fmap);
2138                 if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem);
2139                 MEM_freeN(ccgdm->edgeFlags);
2140                 MEM_freeN(ccgdm->faceFlags);
2141                 MEM_freeN(ccgdm->vertMap);
2142                 MEM_freeN(ccgdm->edgeMap);
2143                 MEM_freeN(ccgdm->faceMap);
2144                 MEM_freeN(ccgdm);
2145         }
2146 }
2147
2148 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
2149 {
2150         if(type == CD_ORIGINDEX) {
2151                 /* create origindex on demand to save memory */
2152                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2153                 CCGSubSurf *ss= ccgdm->ss;
2154                 int *origindex;
2155                 int a, index, totnone, totorig;
2156
2157                 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2158                 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
2159
2160                 totorig = ccgSubSurf_getNumVerts(ss);
2161                 totnone= dm->numVertData - totorig;
2162
2163                 /* original vertices are at the end */
2164                 for(a=0; a<totnone; a++)
2165                         origindex[a]= ORIGINDEX_NONE;
2166
2167                 for(index=0; index<totorig; index++, a++) {
2168                         CCGVert *v = ccgdm->vertMap[index].vert;
2169                         origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
2170                 }
2171
2172                 return origindex;
2173         }
2174
2175         return DM_get_vert_data_layer(dm, type);
2176 }
2177
2178 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
2179 {
2180         if(type == CD_ORIGINDEX) {
2181                 /* create origindex on demand to save memory */
2182                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2183                 CCGSubSurf *ss= ccgdm->ss;
2184                 int *origindex;
2185                 int a, i, index, totnone, totorig, totedge;
2186                 int edgeSize= ccgSubSurf_getEdgeSize(ss);
2187
2188                 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2189                 origindex= DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2190
2191                 totedge= ccgSubSurf_getNumEdges(ss);
2192                 totorig= totedge*(edgeSize - 1);
2193                 totnone= dm->numEdgeData - totorig;
2194
2195                 /* original edges are at the end */
2196                 for(a=0; a<totnone; a++)
2197                         origindex[a]= ORIGINDEX_NONE;
2198
2199                 for(index=0; index<totedge; index++) {
2200                         CCGEdge *e= ccgdm->edgeMap[index].edge;
2201                         int mapIndex= ccgDM_getEdgeMapIndex(ss, e);
2202
2203                         for(i = 0; i < edgeSize - 1; i++, a++)
2204                                 origindex[a]= mapIndex;
2205                 }
2206
2207                 return origindex;
2208         }
2209
2210         return DM_get_edge_data_layer(dm, type);
2211 }
2212
2213 static void *ccgDM_get_face_data_layer(DerivedMesh *dm, int type)
2214 {
2215         if(type == CD_ORIGINDEX) {
2216                 /* create origindex on demand to save memory */
2217                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2218                 CCGSubSurf *ss= ccgdm->ss;
2219                 int *origindex;
2220                 int a, i, index, totface;
2221                 int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
2222
2223                 DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2224                 origindex= DM_get_face_data_layer(dm, CD_ORIGINDEX);
2225
2226                 totface= ccgSubSurf_getNumFaces(ss);
2227
2228                 for(a=0, index=0; index<totface; index++) {
2229                         CCGFace *f = ccgdm->faceMap[index].face;
2230                         int numVerts = ccgSubSurf_getFaceNumVerts(f);
2231                         int mapIndex = ccgDM_getFaceMapIndex(ss, f);
2232
2233                         for(i=0; i<gridFaces*gridFaces*numVerts; i++, a++)
2234                                 origindex[a]= mapIndex;
2235                 }
2236
2237                 return origindex;
2238         }
2239
2240         return DM_get_face_data_layer(dm, type);
2241 }
2242
2243 static int ccgDM_getNumGrids(DerivedMesh *dm)
2244 {
2245         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2246         int index, numFaces, numGrids;
2247
2248         numFaces= ccgSubSurf_getNumFaces(ccgdm->ss);
2249         numGrids= 0;
2250
2251         for(index=0; index<numFaces; index++) {
2252                 CCGFace *f = ccgdm->faceMap[index].face;
2253                 numGrids += ccgSubSurf_getFaceNumVerts(f);
2254         }
2255
2256         return numGrids;
2257 }
2258
2259 static int ccgDM_getGridSize(DerivedMesh *dm)
2260 {
2261         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2262         return ccgSubSurf_getGridSize(ccgdm->ss);
2263 }
2264
2265 static int ccgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset)
2266 {
2267         CCGFace *adjf;
2268         CCGEdge *e;
2269         int i, j= 0, numFaces, fIndex, numEdges= 0;
2270
2271         e = ccgSubSurf_getFaceEdge(ss, f, S);
2272         numFaces = ccgSubSurf_getEdgeNumFaces(e);
2273
2274         if(numFaces != 2)
2275                 return -1;
2276
2277         for(i = 0; i < numFaces; i++) {
2278                 adjf = ccgSubSurf_getEdgeFace(e, i);
2279
2280                 if(adjf != f) {
2281                         numEdges = ccgSubSurf_getFaceNumVerts(adjf);
2282                         for(j = 0; j < numEdges; j++)
2283                                 if(ccgSubSurf_getFaceEdge(ss, adjf, j) == e)
2284                                         break;
2285
2286                         if(j != numEdges)
2287                                 break;
2288                 }
2289         }
2290         
2291         fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, adjf));
2292
2293         return gridOffset[fIndex] + (j + offset)%numEdges;
2294 }
2295
2296 static void ccgdm_create_grids(DerivedMesh *dm)
2297 {
2298         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2299         CCGSubSurf *ss= ccgdm->ss;
2300         DMGridData **gridData;
2301         DMGridAdjacency *gridAdjacency, *adj;
2302         CCGFace **gridFaces;
2303         int *gridOffset;
2304         int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
2305
2306         if(ccgdm->gridData)
2307                 return;
2308         
2309         numGrids = ccgDM_getNumGrids(dm);
2310         numFaces = ccgSubSurf_getNumFaces(ss);
2311         /*gridSize = ccgDM_getGridSize(dm);*/  /*UNUSED*/
2312
2313         /* compute offset into grid array for each face */
2314         gridOffset = MEM_mallocN(sizeof(int)*numFaces, "ccgdm.gridOffset");
2315
2316         for(gIndex = 0, index = 0; index < numFaces; index++) {
2317                 CCGFace *f = ccgdm->faceMap[index].face;
2318                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2319
2320                 gridOffset[index] = gIndex;
2321                 gIndex += numVerts;
2322         }
2323
2324         /* compute grid data */
2325         gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "ccgdm.gridData");
2326         gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "ccgdm.gridAdjacency");
2327         gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "ccgdm.gridFaces");
2328
2329         for(gIndex = 0, index = 0; index < numFaces; index++) {
2330                 CCGFace *f = ccgdm->faceMap[index].face;
2331                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2332
2333                 for(S = 0; S < numVerts; S++, gIndex++) {
2334                         int prevS = (S - 1 + numVerts) % numVerts;
2335                         int nextS = (S + 1 + numVerts) % numVerts;
2336
2337                         gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2338                         gridFaces[gIndex] = f;
2339
2340                         adj = &gridAdjacency[gIndex];
2341
2342                         adj->index[0] = gIndex - S + nextS;
2343                         adj->rotation[0] = 3;
2344                         adj->index[1] = ccgdm_adjacent_grid(ss, gridOffset, f, prevS, 0);
2345                         adj->rotation[1] = 1;
2346                         adj->index[2] = ccgdm_adjacent_grid(ss, gridOffset, f, S, 1);
2347                         adj->rotation[2] = 3;
2348                         adj->index[3] = gIndex - S + prevS;
2349                         adj->rotation[3] = 1;
2350                 }
2351         }
2352
2353         ccgdm->gridData = gridData;
2354         ccgdm->gridFaces = gridFaces;
2355         ccgdm->gridAdjacency = gridAdjacency;
2356         ccgdm->gridOffset = gridOffset;
2357 }
2358
2359 static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
2360 {
2361         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2362
2363         ccgdm_create_grids(dm);
2364         return ccgdm->gridData;
2365 }
2366
2367 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm)
2368 {
2369         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2370
2371         ccgdm_create_grids(dm);
2372         return ccgdm->gridAdjacency;
2373 }
2374
2375 static int *ccgDM_getGridOffset(DerivedMesh *dm)
2376 {
2377         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2378
2379         ccgdm_create_grids(dm);
2380         return ccgdm->gridOffset;
2381 }
2382
2383 static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
2384 {
2385         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2386
2387         if(!ccgdm->multires.mmd && !ccgdm->fmap && ob->type == OB_MESH) {
2388                 Mesh *me= ob->data;
2389
2390                 create_vert_face_map(&ccgdm->fmap, &ccgdm->fmap_mem, me->mface,
2391                                      me->totvert, me->totface);
2392         }
2393
2394         return ccgdm->fmap;
2395 }
2396
2397 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
2398 {
2399         MultiresModifierData *mmd= ccgdm->multires.mmd;
2400
2401         /* both of multires and subsurm modifiers are CCG, but
2402            grids should only be used when sculpting on multires */
2403         if(!mmd)
2404                 return 0;
2405
2406         return 1;
2407 }
2408
2409 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
2410 {
2411         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2412         int gridSize, numGrids, grid_pbvh;
2413
2414         if(!ob) {
2415                 ccgdm->pbvh= NULL;
2416                 return NULL;
2417         }
2418
2419         if(!ob->sculpt)
2420                 return NULL;
2421
2422         grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
2423
2424         if(ob->sculpt->pbvh) {
2425                 if(grid_pbvh) {
2426                         /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
2427                            but this can be freed on ccgdm release, this updates the pointers
2428                            when the ccgdm gets remade, the assumption is that the topology
2429                            does not change. */
2430                         ccgdm_create_grids(dm);
2431                         BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
2432                 }
2433
2434                 ccgdm->pbvh = ob->sculpt->pbvh;
2435         }
2436
2437         if(ccgdm->pbvh)
2438                 return ccgdm->pbvh;
2439
2440         /* no pbvh exists yet, we need to create one. only in case of multires
2441            we build a pbvh over the modified mesh, in other cases the base mesh
2442            is being sculpted, so we build a pbvh from that. */
2443         if(grid_pbvh) {
2444                 ccgdm_create_grids(dm);
2445
2446                 gridSize = ccgDM_getGridSize(dm);
2447                 numGrids = ccgDM_getNumGrids(dm);
2448
2449                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2450                 BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
2451                         numGrids, gridSize, (void**)ccgdm->gridFaces);
2452         } else if(ob->type == OB_MESH) {
2453                 Mesh *me= ob->data;
2454                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2455                 BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
2456                                    me->totface, me->totvert);
2457         }
2458
2459         return ccgdm->pbvh;
2460 }
2461
2462 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2463                                                                                  int drawInteriorEdges,
2464                                                                                  int useSubsurfUv,
2465                                                                                  DerivedMesh *dm)
2466 {
2467         CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
2468         CCGVertIterator *vi;
2469         CCGEdgeIterator *ei;
2470         CCGFaceIterator *fi;
2471         int index, totvert, totedge, totface;
2472         int i;
2473         int vertNum, edgeNum, faceNum;
2474         short *edgeFlags;
2475         char *faceFlags;
2476         int edgeSize;
2477         int gridSize;
2478         int gridFaces;
2479         /*int gridSideVerts;*/
2480         int gridSideEdges;
2481         int gridInternalEdges;
2482         MEdge *medge = NULL;
2483         MFace *mface = NULL;
2484         int *orig_indices;
2485         FaceVertWeight *qweight, *tweight;
2486
2487         DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
2488                                          ccgSubSurf_getNumFinalVerts(ss),
2489                                          ccgSubSurf_getNumFinalEdges(ss),
2490                                          ccgSubSurf_getNumFinalFaces(ss));
2491
2492         ccgdm->dm.getMinMax = ccgDM_getMinMax;
2493         ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
2494         ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
2495
2496         ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
2497         ccgdm->dm.getVert = ccgDM_getFinalVert;
2498         ccgdm->dm.getEdge = ccgDM_getFinalEdge;
2499         ccgdm->dm.getFace = ccgDM_getFinalFace;
2500         ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
2501         ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
2502         ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2503         ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2504         ccgdm->dm.copyFaceArray = ccgDM_copyFinalFaceArray;
2505         ccgdm->dm.getVertData = DM_get_vert_data;
2506         ccgdm->dm.getEdgeData = DM_get_edge_data;
2507         ccgdm->dm.getFaceData = DM_get_face_data;
2508         ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
2509         ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
2510         ccgdm->dm.getFaceDataArray = ccgDM_get_face_data_layer;
2511         ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
2512         ccgdm->dm.getGridSize = ccgDM_getGridSize;
2513         ccgdm->dm.getGridData = ccgDM_getGridData;
2514         ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency;
2515         ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
2516         ccgdm->dm.getFaceMap = ccgDM_getFaceMap;
2517         ccgdm->dm.getPBVH = ccgDM_getPBVH;
2518
2519         ccgdm->dm.getVertCos = ccgdm_getVertCos;
2520         ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
2521         ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
2522         ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
2523         
2524         ccgdm->dm.drawVerts = ccgDM_drawVerts;
2525         ccgdm->dm.drawEdges = ccgDM_drawEdges;
2526         ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
2527         ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
2528         ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
2529         ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
2530         ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL;
2531         ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
2532         ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
2533         ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL;
2534         ccgdm->dm.drawMappedFacesMat = ccgDM_drawMappedFacesMat;
2535         ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
2536
2537         ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
2538         ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
2539         
2540         ccgdm->dm.release = ccgDM_release;
2541         
2542         ccgdm->ss = ss;
2543         ccgdm->drawInteriorEdges = drawInteriorEdges;
2544         ccgdm->useSubsurfUv = useSubsurfUv;
2545
2546         totvert = ccgSubSurf_getNumVerts(ss);
2547         ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
2548         vi = ccgSubSurf_getVertIterator(ss);
2549         for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2550                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2551
2552                 ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
2553         }
2554         ccgVertIterator_free(vi);
2555
2556         totedge = ccgSubSurf_getNumEdges(ss);
2557         ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
2558         ei = ccgSubSurf_getEdgeIterator(ss);
2559         for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2560                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2561
2562                 ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
2563         }
2564
2565         totface = ccgSubSurf_getNumFaces(ss);
2566         ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
2567         fi = ccgSubSurf_getFaceIterator(ss);
2568         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2569                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2570
2571                 ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
2572         }
2573         ccgFaceIterator_free(fi);
2574
2575         edgeSize = ccgSubSurf_getEdgeSize(ss);
2576         gridSize = ccgSubSurf_getGridSize(ss);
2577         gridFaces = gridSize - 1;
2578         /*gridSideVerts = gridSize - 2;*/ /*UNUSED*/
2579         /*gridInternalVerts = gridSideVerts * gridSideVerts; */ /*UNUSED*/
2580         gridSideEdges = gridSize - 1;
2581         gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
2582
2583         calc_ss_weights(gridFaces, &qweight, &tweight);
2584
2585         vertNum = 0;
2586         edgeNum = 0;
2587         faceNum = 0;
2588
2589         /* mvert = dm->getVertArray(dm); - as yet unused */
2590         medge = dm->getEdgeArray(dm);
2591         mface = dm->getFaceArray(dm);
2592
2593         faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags");
2594
2595         orig_indices = (int*)ccgdm->dm.getFaceDataArray(&ccgdm->dm, CD_ORIGINDEX);
2596         for(index = 0; index < totface; ++index) {
2597                 CCGFace *f = ccgdm->faceMap[index].face;
2598                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2599                 int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
2600                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2601                 FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
2602                 int S, x, y;
2603                 int vertIdx[4];
2604
2605                 ccgdm->faceMap[index].startVert = vertNum;
2606                 ccgdm->faceMap[index].startEdge = edgeNum;
2607                 ccgdm->faceMap[index].startFace = faceNum;
2608
2609                 if(orig_indices)
2610                         orig_indices[faceNum] = origIndex;
2611
2612                 /* set the face base vert */
2613                 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
2614
2615                 for(S = 0; S < numVerts; S++) {
2616                         CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
2617
2618                         vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2619                 }
2620
2621                 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, weight[0][0],
2622                                                         numVerts, vertNum);
2623                 ++vertNum;
2624
2625                 for(S = 0; S < numVerts; S++) {
2626                         int prevS = (S - 1 + numVerts) % numVerts;
2627                         int nextS = (S + 1) % numVerts;
2628                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2629                         for(x = 1; x < gridFaces; x++) {
2630                                 float w[4];
2631                                 w[prevS]  = weight[x][0][0];
2632                                 w[S]      = weight[x][0][1];
2633                                 w[nextS]  = weight[x][0][2];
2634                                 w[otherS] = weight[x][0][3];
2635                                 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2636                                                                         numVerts, vertNum);
2637                                 ++vertNum;
2638                         }
2639                 }
2640
2641                 for(S = 0; S < numVerts; S++) {
2642                         int prevS = (S - 1 + numVerts) % numVerts;
2643                         int nextS = (S + 1) % numVerts;
2644                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2645                         for(y = 1; y < gridFaces; y++) {
2646                                 for(x = 1; x < gridFaces; x++) {
2647                                         float w[4];
2648                                         w[prevS]  = weight[y * gridFaces + x][0][0];
2649                                         w[S]      = weight[y * gridFaces + x][0][1];
2650                                         w[nextS]  = weight[y * gridFaces + x][0][2];
2651                                         w[otherS] = weight[y * gridFaces + x][0][3];
2652                                         DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2653                                                                                 numVerts, vertNum);
2654                                         ++vertNum;
2655                                 }
2656                         }
2657                 }
2658
2659                 for(S = 0; S < numVerts; S++) {
2660                         int prevS = (S - 1 + numVerts) % numVerts;
2661                         int nextS = (S + 1) % numVerts;
2662                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2663
2664                         weight = (numVerts == 4) ? qweight : tweight;
2665
2666                         for(y = 0; y < gridFaces; y++) {
2667                                 for(x = 0; x < gridFaces; x++) {
2668                                         FaceVertWeight w;
2669                                         int j;
2670
2671                                         for(j = 0; j < 4; ++j) {
2672                                                 w[j][prevS]  = (*weight)[j][0];
2673                                                 w[j][S]      = (*weight)[j][1];
2674                                                 w[j][nextS]  = (*weight)[j][2];
2675                                                 w[j][otherS] = (*weight)[j][3];
2676                                         }
2677
2678                                         DM_interp_face_data(dm, &ccgdm->dm, &origIndex, NULL,
2679                                                                                 &w, 1, faceNum);
2680                                         weight++;
2681
2682                                         ++faceNum;
2683                                 }
2684                         }
2685                 }
2686
2687                 faceFlags[index*2] = mface[origIndex].flag;
2688                 faceFlags[index*2 + 1] = mface[origIndex].mat_nr;
2689
2690                 edgeNum += numFinalEdges;
2691         }
2692
2693         if(useSubsurfUv) {
2694                 CustomData *fdata = &ccgdm->dm.faceData;
2695                 CustomData *dmfdata = &dm->faceData;
2696                 int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
2697                 int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
2698
2699                 for (i=0; i<numlayer && i<dmnumlayer; i++)
2700                         set_subsurf_uv(ss, dm, &ccgdm->dm, i);
2701         }
2702
2703         edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "edgeFlags");
2704
2705         for(index = 0; index < totedge; ++index) {
2706                 CCGEdge *e = ccgdm->edgeMap[index].edge;
2707                 int numFinalEdges = edgeSize - 1;
2708                 int x;
2709                 int vertIdx[2];
2710                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
2711
2712                 CCGVert *v;
2713                 v = ccgSubSurf_getEdgeVert0(e);
2714                 vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2715                 v = ccgSubSurf_getEdgeVert1(e);
2716                 vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2717
2718                 ccgdm->edgeMap[index].startVert = vertNum;
2719                 ccgdm->edgeMap[index].startEdge = edgeNum;
2720
2721                 /* set the edge base vert */
2722                 *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
2723
2724                 for(x = 1; x < edgeSize - 1; x++) {
2725                         float w[2];
2726                         w[1] = (float) x / (edgeSize - 1);
2727                         w[0] = 1 - w[1];
2728                         DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
2729                         ++vertNum;
2730                 }
2731
2732                 edgeFlags[index]= medge[edgeIdx].flag;
2733
2734                 edgeNum += numFinalEdges;
2735         }
2736
2737         for(index = 0; index < totvert; ++index) {
2738                 CCGVert *v = ccgdm->vertMap[index].vert;
2739                 int vertIdx;
2740
2741                 vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2742
2743                 ccgdm->vertMap[index].startVert = vertNum;
2744
2745                 /* set the vert base vert */
2746                 *((int*) ccgSubSurf_getVertUserData(ss, v)) = vertNum;
2747
2748                 DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
2749
2750                 ++vertNum;
2751         }
2752
2753         MEM_freeN(qweight);
2754         MEM_freeN(tweight);
2755
2756         return ccgdm;
2757 }
2758
2759 /***/
2760
2761 struct DerivedMesh *subsurf_make_derived_from_derived(
2762                                                 struct DerivedMesh *dm,
2763                                                 struct SubsurfModifierData *smd,
2764                                                 int useRenderParams, float (*vertCos)[3],
2765                                                 int isFinalCalc, int forEditMode, int inEditMode)
2766 {
2767         int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF;
2768         int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2769         int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv;
2770         int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
2771         CCGDerivedMesh *result;
2772
2773         if(forEditMode) {
2774                 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
2775
2776                 smd->emCache = _getSubSurf(smd->emCache, levels, useAging, 0,
2777                                                                    useSimple);
2778                 ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
2779
2780                 result = getCCGDerivedMesh(smd->emCache,
2781                                                                    drawInteriorEdges,
2782                                                                    useSubsurfUv, dm);
2783         } else if(useRenderParams) {
2784                 /* Do not use cache in render mode. */
2785                 CCGSubSurf *ss;
2786                 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->renderLevels): smd->renderLevels;
2787
2788                 if(levels == 0)
2789                         return dm;
2790                 
2791                 ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
2792
2793                 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2794
2795                 result = getCCGDerivedMesh(ss,
2796                         drawInteriorEdges, useSubsurfUv, dm);
2797
2798                 result->freeSS = 1;
2799         } else {
2800                 int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
2801                 int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2802                 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
2803                 CCGSubSurf *ss;
2804
2805                 /* It is quite possible there is a much better place to do this. It
2806                  * depends a bit on how rigourously we expect this function to never
2807                  * be called in editmode. In semi-theory we could share a single
2808                  * cache, but the handles used inside and outside editmode are not
2809                  * the same so we would need some way of converting them. Its probably
2810                  * not worth the effort. But then why am I even writing this long
2811                  * comment that no one will read? Hmmm. - zr
2812                  *
2813                  * Addendum: we can't really ensure that this is never called in edit
2814                  * mode, so now we have a parameter to verify it. - brecht
2815                  */
2816                 if(!inEditMode && smd->emCache) {
2817                         ccgSubSurf_free(smd->emCache);
2818                         smd->emCache = NULL;
2819                 }
2820
2821                 if(useIncremental && isFinalCalc) {
2822                         smd->mCache = ss = _getSubSurf(smd->mCache, levels,
2823                                                                                    useAging, 0, useSimple);
2824
2825                         ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2826
2827                         result = getCCGDerivedMesh(smd->mCache,
2828                                                                            drawInteriorEdges,
2829                                                                            useSubsurfUv, dm);
2830                 } else {
2831                         if (smd->mCache && isFinalCalc) {
2832                                 ccgSubSurf_free(smd->mCache);
2833                                 smd->mCache = NULL;
2834                         }
2835
2836                         ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
2837                         ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2838
2839                         result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
2840
2841                         if(isFinalCalc)
2842                                 smd->mCache = ss;
2843                         else
2844                                 result->freeSS = 1;
2845                 }
2846         }
2847
2848         return (DerivedMesh*)result;
2849 }
2850
2851 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 
2852 {
2853         /* Finds the subsurf limit positions for the verts in a mesh 
2854          * and puts them in an array of floats. Please note that the 
2855          * calculated vert positions is incorrect for the verts 
2856          * on the boundary of the mesh.
2857          */
2858         CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0);
2859         float edge_sum[3], face_sum[3];
2860         CCGVertIterator *vi;
2861         DerivedMesh *dm = CDDM_from_mesh(me, NULL);
2862
2863         ss_sync_from_derivedmesh(ss, dm, NULL, 0);
2864
2865         vi = ccgSubSurf_getVertIterator(ss);
2866         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2867                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2868                 int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2869                 int N = ccgSubSurf_getVertNumEdges(v);
2870                 int numFaces = ccgSubSurf_getVertNumFaces(v);
2871                 float *co;
2872                 int i;
2873
2874                 edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0;
2875                 face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
2876
2877                 for (i=0; i<N; i++) {
2878                         CCGEdge *e = ccgSubSurf_getVertEdge(v, i);
2879                         add_v3_v3v3(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
2880                 }
2881                 for (i=0; i<numFaces; i++) {
2882                         CCGFace *f = ccgSubSurf_getVertFace(v, i);
2883                         add_v3_v3(face_sum, ccgSubSurf_getFaceCenterData(f));
2884                 }
2885
2886                 /* ad-hoc correction for boundary vertices, to at least avoid them
2887                    moving completely out of place (brecht) */
2888                 if(numFaces && numFaces != N)
2889                         mul_v3_fl(face_sum, (float)N/(float)numFaces);
2890
2891                 co = ccgSubSurf_getVertData(ss, v);
2892                 positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
2893                 positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
2894                 positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
2895         }
2896         ccgVertIterator_free(vi);
2897
2898         ccgSubSurf_free(ss);
2899
2900         dm->release(dm);
2901 }
2902