- use cache_ as a prefix for new modifiers.
[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         int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1177         int totedge = ccgSubSurf_getNumEdges(ss);
1178         int gridSize = ccgSubSurf_getGridSize(ss);
1179         int useAging;
1180
1181         ccgdm_pbvh_update(ccgdm);
1182
1183         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1184
1185         for (j=0; j< totedge; j++) {
1186                 CCGEdge *e = ccgdm->edgeMap[j].edge;
1187                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1188
1189                 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e))
1190                         continue;
1191
1192                 if(ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW))
1193                         continue;
1194
1195                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1196                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1197                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1198                 }
1199
1200                 glBegin(GL_LINE_STRIP);
1201                 for (i=0; i<edgeSize-1; i++) {
1202                         glVertex3fv(edgeData[i].co);
1203                         glVertex3fv(edgeData[i+1].co);
1204                 }
1205                 glEnd();
1206         }
1207
1208         if (useAging && !(G.f&G_BACKBUFSEL)) {
1209                 glColor3ub(0, 0, 0);
1210         }
1211
1212         if (ccgdm->drawInteriorEdges) {
1213                 int totface = ccgSubSurf_getNumFaces(ss);
1214
1215                 for(j = 0; j < totface; j++) {
1216                         CCGFace *f = ccgdm->faceMap[j].face;
1217                         int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1218
1219                         for (S=0; S<numVerts; S++) {
1220                                 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1221
1222                                 glBegin(GL_LINE_STRIP);
1223                                 for (x=0; x<gridSize; x++)
1224                                         glVertex3fv(faceGridData[x].co);
1225                                 glEnd();
1226                                 for (y=1; y<gridSize-1; y++) {
1227                                         glBegin(GL_LINE_STRIP);
1228                                         for (x=0; x<gridSize; x++)
1229                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1230                                         glEnd();
1231                                 }
1232                                 for (x=1; x<gridSize-1; x++) {
1233                                         glBegin(GL_LINE_STRIP);
1234                                         for (y=0; y<gridSize; y++)
1235                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1236                                         glEnd();
1237                                 }
1238                         }
1239                 }
1240         }
1241 }
1242 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
1243         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1244         CCGSubSurf *ss = ccgdm->ss;
1245         int totedge = ccgSubSurf_getNumEdges(ss);
1246         int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1247
1248         for (j=0; j< totedge; j++) {
1249                 CCGEdge *e = ccgdm->edgeMap[j].edge;
1250                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1251
1252                 if (!ccgSubSurf_getEdgeNumFaces(e)) {
1253                         glBegin(GL_LINE_STRIP);
1254                         for (i=0; i<edgeSize-1; i++) {
1255                                 glVertex3fv(edgeData[i].co);
1256                                 glVertex3fv(edgeData[i+1].co);
1257                         }
1258                         glEnd();
1259                 }
1260         }
1261 }
1262
1263 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
1264 {
1265         float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1266         float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1267         float no[3];
1268
1269         no[0] = b_dY*a_cZ - b_dZ*a_cY;
1270         no[1] = b_dZ*a_cX - b_dX*a_cZ;
1271         no[2] = b_dX*a_cY - b_dY*a_cX;
1272
1273         /* don't normalize, GL_NORMALIZE is enabled */
1274         glNormal3fv(no);
1275 }
1276
1277         /* Only used by non-editmesh types */
1278 static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int fast, int (*setMaterial)(int, void *attribs)) {
1279         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1280         CCGSubSurf *ss = ccgdm->ss;
1281         int gridSize = ccgSubSurf_getGridSize(ss);
1282         char *faceFlags = ccgdm->faceFlags;
1283         int step = (fast)? gridSize-1: 1;
1284         int i, totface = ccgSubSurf_getNumFaces(ss);
1285         int drawcurrent = 0, matnr = -1, shademodel = -1;
1286
1287         ccgdm_pbvh_update(ccgdm);
1288
1289         if(ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
1290                 if(dm->numFaceData) {
1291                         /* should be per face */
1292                         if(!setMaterial(faceFlags[1]+1, NULL))
1293                                 return;
1294
1295                         glShadeModel((faceFlags[0] & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
1296                         BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, (faceFlags[0] & ME_SMOOTH));
1297                         glShadeModel(GL_FLAT);
1298                 }
1299
1300                 return;
1301         }
1302
1303         for(i = 0; i < totface; i++) {
1304                 CCGFace *f = ccgdm->faceMap[i].face;
1305                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1306                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1307                 int new_matnr, new_shademodel;
1308
1309                 if(faceFlags) {
1310                         new_shademodel = (faceFlags[index*2] & ME_SMOOTH)? GL_SMOOTH: GL_FLAT;
1311                         new_matnr= faceFlags[index*2 + 1];
1312                 }
1313                 else {
1314                         new_shademodel = GL_SMOOTH;
1315                         new_matnr= 0;
1316                 }
1317                 
1318                 if(shademodel != new_shademodel || matnr != new_matnr) {
1319                         matnr= new_matnr;
1320                         shademodel= new_shademodel;
1321
1322                         drawcurrent= setMaterial(matnr+1, NULL);
1323
1324                         glShadeModel(shademodel);
1325                 }
1326
1327                 if(!drawcurrent)
1328                         continue;
1329
1330                 for (S=0; S<numVerts; S++) {
1331                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1332
1333                         if (shademodel == GL_SMOOTH) {
1334                                 for (y=0; y<gridSize-1; y+=step) {
1335                                         glBegin(GL_QUAD_STRIP);
1336                                         for (x=0; x<gridSize; x+=step) {
1337                                                 DMGridData *a = &faceGridData[(y+0)*gridSize + x];
1338                                                 DMGridData *b = &faceGridData[(y+step)*gridSize + x];
1339
1340                                                 glNormal3fv(a->no);
1341                                                 glVertex3fv(a->co);
1342                                                 glNormal3fv(b->no);
1343                                                 glVertex3fv(b->co);
1344                                         }
1345                                         glEnd();
1346                                 }
1347                         } else {
1348                                 glBegin(GL_QUADS);
1349                                 for (y=0; y<gridSize-1; y+=step) {
1350                                         for (x=0; x<gridSize-1; x+=step) {
1351                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
1352                                                 float *b = faceGridData[(y+0)*gridSize + x + step].co;
1353                                                 float *c = faceGridData[(y+step)*gridSize + x + step].co;
1354                                                 float *d = faceGridData[(y+step)*gridSize + x].co;
1355
1356                                                 ccgDM_glNormalFast(a, b, c, d);
1357
1358                                                 glVertex3fv(d);
1359                                                 glVertex3fv(c);
1360                                                 glVertex3fv(b);
1361                                                 glVertex3fv(a);
1362                                         }
1363                                 }
1364                                 glEnd();
1365                         }
1366                 }
1367         }
1368 }
1369
1370         /* Only used by non-editmesh types */
1371 static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) {
1372         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1373         CCGSubSurf *ss = ccgdm->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
1508 static void ccgDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
1509         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1510 }
1511
1512         /* Only used by non-editmesh types */
1513 static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *userData, int, void *attribs), int (*setFace)(void *userData, int index), void *userData) {
1514         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1515         CCGSubSurf *ss = ccgdm->ss;
1516         GPUVertexAttribs gattribs;
1517         DMVertexAttribs attribs= {{{NULL}}};
1518         int gridSize = ccgSubSurf_getGridSize(ss);
1519         int gridFaces = gridSize - 1;
1520         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1521         char *faceFlags = ccgdm->faceFlags;
1522         int a, b, i, numVerts, matnr, new_matnr, totface;
1523
1524         ccgdm_pbvh_update(ccgdm);
1525
1526         matnr = -1;
1527
1528 #define PASSATTRIB(dx, dy, vert) {                                                                                              \
1529         if(attribs.totorco) {                                                                                                           \
1530                 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize);                 \
1531                 if(attribs.orco.glTexco)                                                                                                \
1532                         glTexCoord3fv(attribs.orco.array[index]);                                                       \
1533                 else                                                                                                                                    \
1534                         glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
1535         }                                                                                                                                                       \
1536         for(b = 0; b < attribs.tottface; b++) {                                                                         \
1537                 MTFace *tf = &attribs.tface[b].array[a];                                                                \
1538                 if(attribs.tface[b].glTexco)                                                                                    \
1539                         glTexCoord2fv(tf->uv[vert]);                                                                            \
1540                 else                                                                                                                                    \
1541                         glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);           \
1542         }                                                                                                                                                       \
1543         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
1544                 MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
1545                 GLubyte col[4];                                                                                                                 \
1546                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
1547                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
1548         }                                                                                                                                                       \
1549         if(attribs.tottang) {                                                                                                           \
1550                 float *tang = attribs.tang.array[a*4 + vert];                                                   \
1551                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
1552         }                                                                                                                                                       \
1553 }
1554
1555         totface = ccgSubSurf_getNumFaces(ss);
1556         for(a = 0, i = 0; i < totface; i++) {
1557                 CCGFace *f = ccgdm->faceMap[i].face;
1558                 int S, x, y, drawSmooth;
1559                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1560                 int origIndex = ccgDM_getFaceMapIndex(ss, f);
1561                 
1562                 numVerts = ccgSubSurf_getFaceNumVerts(f);
1563
1564                 /* get flags */
1565                 if(faceFlags) {
1566                         drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1567                         new_matnr= faceFlags[index*2 + 1] + 1;
1568                 }
1569                 else {
1570                         drawSmooth = 1;
1571                         new_matnr= 1;
1572                 }
1573
1574                 /* material */
1575                 if(new_matnr != matnr) {
1576                         setMaterial(userData, matnr = new_matnr, &gattribs);
1577                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1578                 }
1579
1580                 /* face hiding */
1581                 if((setFace && (origIndex != ORIGINDEX_NONE) && !setFace(userData, origIndex))) {
1582                         a += gridFaces*gridFaces*numVerts;
1583                         continue;
1584                 }
1585
1586                 /* draw face*/
1587                 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1588                 for (S=0; S<numVerts; S++) {
1589                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1590                         DMGridData *vda, *vdb;
1591
1592                         if (drawSmooth) {
1593                                 for (y=0; y<gridFaces; y++) {
1594                                         glBegin(GL_QUAD_STRIP);
1595                                         for (x=0; x<gridFaces; x++) {
1596                                                 vda = &faceGridData[(y+0)*gridSize + x];
1597                                                 vdb = &faceGridData[(y+1)*gridSize + x];
1598                                                 
1599                                                 PASSATTRIB(0, 0, 0);
1600                                                 glNormal3fv(vda->no);
1601                                                 glVertex3fv(vda->co);
1602
1603                                                 PASSATTRIB(0, 1, 1);
1604                                                 glNormal3fv(vdb->no);
1605                                                 glVertex3fv(vdb->co);
1606
1607                                                 if(x != gridFaces-1)
1608                                                         a++;
1609                                         }
1610
1611                                         vda = &faceGridData[(y+0)*gridSize + x];
1612                                         vdb = &faceGridData[(y+1)*gridSize + x];
1613
1614                                         PASSATTRIB(0, 0, 3);
1615                                         glNormal3fv(vda->no);
1616                                         glVertex3fv(vda->co);
1617
1618                                         PASSATTRIB(0, 1, 2);
1619                                         glNormal3fv(vdb->no);
1620                                         glVertex3fv(vdb->co);
1621
1622                                         glEnd();
1623
1624                                         a++;
1625                                 }
1626                         } else {
1627                                 glBegin(GL_QUADS);
1628                                 for (y=0; y<gridFaces; y++) {
1629                                         for (x=0; x<gridFaces; x++) {
1630                                                 float *aco = faceGridData[(y+0)*gridSize + x].co;
1631                                                 float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
1632                                                 float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
1633                                                 float *dco = faceGridData[(y+1)*gridSize + x].co;
1634
1635                                                 ccgDM_glNormalFast(aco, bco, cco, dco);
1636
1637                                                 PASSATTRIB(0, 1, 1);
1638                                                 glVertex3fv(dco);
1639                                                 PASSATTRIB(1, 1, 2);
1640                                                 glVertex3fv(cco);
1641                                                 PASSATTRIB(1, 0, 3);
1642                                                 glVertex3fv(bco);
1643                                                 PASSATTRIB(0, 0, 0);
1644                                                 glVertex3fv(aco);
1645                                                 
1646                                                 a++;
1647                                         }
1648                                 }
1649                                 glEnd();
1650                         }
1651                 }
1652         }
1653
1654 #undef PASSATTRIB
1655 }
1656
1657
1658 static void ccgDM_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) {
1659         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1660         CCGSubSurf *ss = ccgdm->ss;
1661         int gridSize = ccgSubSurf_getGridSize(ss);
1662         unsigned char *cp1, *cp2;
1663         int useTwoSide=1, i, totface;
1664
1665         ccgdm_pbvh_update(ccgdm);
1666
1667         cp1= col1;
1668         if(col2) {
1669                 cp2= col2;
1670         } else {
1671                 cp2= NULL;
1672                 useTwoSide= 0;
1673         }
1674
1675         glShadeModel(GL_SMOOTH);
1676
1677         if(col2) {
1678                 glEnable(GL_CULL_FACE);
1679         }
1680
1681         glBegin(GL_QUADS);
1682         totface = ccgSubSurf_getNumFaces(ss);
1683         for(i = 0; i < totface; i++) {
1684                 CCGFace *f = ccgdm->faceMap[i].face;
1685                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1686
1687                 for (S=0; S<numVerts; S++) {
1688                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1689                         for (y=0; y<gridSize-1; y++) {
1690                                 for (x=0; x<gridSize-1; x++) {
1691                                         float *a = faceGridData[(y+0)*gridSize + x].co;
1692                                         float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1693                                         float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1694                                         float *d = faceGridData[(y+1)*gridSize + x].co;
1695
1696                                         glColor3ub(cp1[3], cp1[2], cp1[1]);
1697                                         glVertex3fv(d);
1698                                         glColor3ub(cp1[7], cp1[6], cp1[5]);
1699                                         glVertex3fv(c);
1700                                         glColor3ub(cp1[11], cp1[10], cp1[9]);
1701                                         glVertex3fv(b);
1702                                         glColor3ub(cp1[15], cp1[14], cp1[13]);
1703                                         glVertex3fv(a);
1704
1705                                         if (useTwoSide) {
1706                                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
1707                                                 glVertex3fv(a);
1708                                                 glColor3ub(cp2[11], cp2[10], cp2[9]);
1709                                                 glVertex3fv(b);
1710                                                 glColor3ub(cp2[7], cp2[6], cp2[5]);
1711                                                 glVertex3fv(c);
1712                                                 glColor3ub(cp2[3], cp2[2], cp2[1]);
1713                                                 glVertex3fv(d);
1714                                         }
1715
1716                                         if (cp2) cp2+=16;
1717                                         cp1+=16;
1718                                 }
1719                         }
1720                 }
1721         }
1722         glEnd();
1723 }
1724
1725 static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
1726         int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
1727         int (*drawParamsMapped)(void *userData, int index),
1728         void *userData) 
1729 {
1730         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1731         CCGSubSurf *ss = ccgdm->ss;
1732         MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
1733         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
1734         char *faceFlags = ccgdm->faceFlags;
1735         int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss);
1736         int gridFaces = gridSize - 1;
1737
1738         ccgdm_pbvh_update(ccgdm);
1739
1740         if(!mcol)
1741                 mcol = dm->getFaceDataArray(dm, CD_MCOL);
1742
1743         if(!mcol)
1744                 mcol = dm->getFaceDataArray(dm, CD_TEXTURE_MCOL);
1745
1746         totface = ccgSubSurf_getNumFaces(ss);
1747         for(i = 0; i < totface; i++) {
1748                 CCGFace *f = ccgdm->faceMap[i].face;
1749                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1750                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
1751                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1752                 unsigned char *cp= NULL;
1753                 int mat_nr;
1754
1755                 if(faceFlags) {
1756                         drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
1757                         mat_nr= faceFlags[origIndex*2 + 1];
1758                 }
1759                 else {
1760                         drawSmooth = 1;
1761                         mat_nr= 0;
1762                 }
1763
1764                 if(drawParams)
1765                         flag = drawParams(tf, (mcol != NULL), mat_nr);
1766                 else if (index != ORIGINDEX_NONE)
1767                         flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1;
1768                 else
1769                         flag= GPU_enable_material(mat_nr, NULL) ? 1:0;
1770
1771
1772                 if (flag == 0) { /* flag 0 == the face is hidden or invisible */
1773                         if(tf) tf += gridFaces*gridFaces*numVerts;
1774                         if(mcol) mcol += gridFaces*gridFaces*numVerts*4;
1775                         continue;
1776                 }
1777
1778                 /* flag 1 == use vertex colors */
1779                 if(mcol) {
1780                         if(flag==1) cp= (unsigned char*)mcol;
1781                         mcol += gridFaces*gridFaces*numVerts*4;
1782                 }
1783
1784                 for (S=0; S<numVerts; S++) {
1785                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1786                         DMGridData *a, *b;
1787
1788                         if (drawSmooth) {
1789                                 glShadeModel(GL_SMOOTH);
1790                                 for (y=0; y<gridFaces; y++) {
1791                                         glBegin(GL_QUAD_STRIP);
1792                                         for (x=0; x<gridFaces; x++) {
1793                                                 a = &faceGridData[(y+0)*gridSize + x];
1794                                                 b = &faceGridData[(y+1)*gridSize + x];
1795
1796                                                 if(tf) glTexCoord2fv(tf->uv[0]);
1797                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1798                                                 glNormal3fv(a->no);
1799                                                 glVertex3fv(a->co);
1800
1801                                                 if(tf) glTexCoord2fv(tf->uv[1]);
1802                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1803                                                 glNormal3fv(b->no);
1804                                                 glVertex3fv(b->co);
1805                                                 
1806                                                 if(x != gridFaces-1) {
1807                                                         if(tf) tf++;
1808                                                         if(cp) cp += 16;
1809                                                 }
1810                                         }
1811
1812                                         a = &faceGridData[(y+0)*gridSize + x];
1813                                         b = &faceGridData[(y+1)*gridSize + x];
1814
1815                                         if(tf) glTexCoord2fv(tf->uv[3]);
1816                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1817                                         glNormal3fv(a->no);
1818                                         glVertex3fv(a->co);
1819
1820                                         if(tf) glTexCoord2fv(tf->uv[2]);
1821                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1822                                         glNormal3fv(b->no);
1823                                         glVertex3fv(b->co);
1824
1825                                         if(tf) tf++;
1826                                         if(cp) cp += 16;
1827
1828                                         glEnd();
1829                                 }
1830                         } else {
1831                                 glShadeModel(GL_FLAT);
1832                                 glBegin(GL_QUADS);
1833                                 for (y=0; y<gridFaces; y++) {
1834                                         for (x=0; x<gridFaces; x++) {
1835                                                 float *a_co = faceGridData[(y+0)*gridSize + x].co;
1836                                                 float *b_co = faceGridData[(y+0)*gridSize + x + 1].co;
1837                                                 float *c_co = faceGridData[(y+1)*gridSize + x + 1].co;
1838                                                 float *d_co = faceGridData[(y+1)*gridSize + x].co;
1839
1840                                                 ccgDM_glNormalFast(a_co, b_co, c_co, d_co);
1841
1842                                                 if(tf) glTexCoord2fv(tf->uv[1]);
1843                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1844                                                 glVertex3fv(d_co);
1845
1846                                                 if(tf) glTexCoord2fv(tf->uv[2]);
1847                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1848                                                 glVertex3fv(c_co);
1849
1850                                                 if(tf) glTexCoord2fv(tf->uv[3]);
1851                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1852                                                 glVertex3fv(b_co);
1853
1854                                                 if(tf) glTexCoord2fv(tf->uv[0]);
1855                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1856                                                 glVertex3fv(a_co);
1857
1858                                                 if(tf) tf++;
1859                                                 if(cp) cp += 16;
1860                                         }
1861                                 }
1862                                 glEnd();
1863                         }
1864                 }
1865         }
1866 }
1867
1868 static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr))
1869 {
1870         ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
1871 }
1872
1873 static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1874 {
1875         ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
1876 }
1877
1878 static void ccgDM_drawUVEdges(DerivedMesh *dm)
1879 {
1880
1881         MFace *mf = dm->getFaceArray(dm);
1882         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
1883         int i;
1884         
1885         if (tf) {
1886                 glBegin(GL_LINES);
1887                 for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
1888                         if(!(mf->flag&ME_HIDE)) {
1889                                 glVertex2fv(tf->uv[0]);
1890                                 glVertex2fv(tf->uv[1]);
1891         
1892                                 glVertex2fv(tf->uv[1]);
1893                                 glVertex2fv(tf->uv[2]);
1894         
1895                                 if(!mf->v4) {
1896                                         glVertex2fv(tf->uv[2]);
1897                                         glVertex2fv(tf->uv[0]);
1898                                 } else {
1899                                         glVertex2fv(tf->uv[2]);
1900                                         glVertex2fv(tf->uv[3]);
1901         
1902                                         glVertex2fv(tf->uv[3]);
1903                                         glVertex2fv(tf->uv[0]);
1904                                 }
1905                         }
1906                 }
1907                 glEnd();
1908         }
1909 }
1910
1911 static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs),
1912                         int (*compareDrawOptions)(void *userData, int cur_index, int next_index)) {
1913         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1914         CCGSubSurf *ss = ccgdm->ss;
1915         MCol *mcol= NULL;
1916         int i, gridSize = ccgSubSurf_getGridSize(ss);
1917         char *faceFlags = ccgdm->faceFlags;
1918         int gridFaces = gridSize - 1, totface;
1919
1920         /* currently unused -- each original face is handled separately */
1921         (void)compareDrawOptions;
1922
1923         if(useColors) {
1924                 mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
1925                 if(!mcol)
1926                         mcol = dm->getFaceDataArray(dm, CD_MCOL);
1927         }
1928
1929         totface = ccgSubSurf_getNumFaces(ss);
1930         for(i = 0; i < totface; i++) {
1931                 CCGFace *f = ccgdm->faceMap[i].face;
1932                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1933                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
1934                 int origIndex;
1935                 unsigned char *cp= NULL;
1936
1937                 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1938
1939                 if(faceFlags) drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
1940                 else drawSmooth = 1;
1941
1942                 if(mcol) {
1943                         cp= (unsigned char*)mcol;
1944                         mcol += gridFaces*gridFaces*numVerts*4;
1945                 }
1946
1947                 {
1948                         int draw= 1;
1949
1950                         if(index == ORIGINDEX_NONE)
1951                                 draw= setMaterial(faceFlags ? faceFlags[origIndex*2 + 1] + 1: 1, NULL); /* XXX, no faceFlags no material */
1952                         else if (setDrawOptions)
1953                                 draw= setDrawOptions(userData, index, &drawSmooth);
1954
1955                         if (draw) {
1956                                 if (draw==2) {
1957                                           glEnable(GL_POLYGON_STIPPLE);
1958                                           glPolygonStipple(stipple_quarttone);
1959                                 }
1960
1961                                 /* no need to set shading mode to flat because
1962                                 *  normals are already used to change shading */
1963                                 glShadeModel(GL_SMOOTH);
1964                                 
1965                                 for (S=0; S<numVerts; S++) {
1966                                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1967                                         if (drawSmooth) {
1968                                                 for (y=0; y<gridFaces; y++) {
1969                                                         DMGridData *a, *b;
1970                                                         glBegin(GL_QUAD_STRIP);
1971                                                         for (x=0; x<gridFaces; x++) {
1972                                                                 a = &faceGridData[(y+0)*gridSize + x];
1973                                                                 b = &faceGridData[(y+1)*gridSize + x];
1974         
1975                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
1976                                                                 glNormal3fv(a->no);
1977                                                                 glVertex3fv(a->co);
1978                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
1979                                                                 glNormal3fv(b->no);
1980                                                                 glVertex3fv(b->co);
1981
1982                                                                 if(x != gridFaces-1) {
1983                                                                         if(cp) cp += 16;
1984                                                                 }
1985                                                         }
1986
1987                                                         a = &faceGridData[(y+0)*gridSize + x];
1988                                                         b = &faceGridData[(y+1)*gridSize + x];
1989
1990                                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
1991                                                         glNormal3fv(a->no);
1992                                                         glVertex3fv(a->co);
1993                                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
1994                                                         glNormal3fv(b->no);
1995                                                         glVertex3fv(b->co);
1996
1997                                                         if(cp) cp += 16;
1998
1999                                                         glEnd();
2000                                                 }
2001                                         } else {
2002                                                 glBegin(GL_QUADS);
2003                                                 for (y=0; y<gridFaces; y++) {
2004                                                         for (x=0; x<gridFaces; x++) {
2005                                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
2006                                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
2007                                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
2008                                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
2009
2010                                                                 ccgDM_glNormalFast(a, b, c, d);
2011         
2012                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2013                                                                 glVertex3fv(d);
2014                                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2015                                                                 glVertex3fv(c);
2016                                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2017                                                                 glVertex3fv(b);
2018                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2019                                                                 glVertex3fv(a);
2020
2021                                                                 if(cp) cp += 16;
2022                                                         }
2023                                                 }
2024                                                 glEnd();
2025                                         }
2026                                 }
2027                                 if (draw==2)
2028                                         glDisable(GL_POLYGON_STIPPLE);
2029                         }
2030                 }
2031         }
2032 }
2033 static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
2034         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2035         CCGSubSurf *ss = ccgdm->ss;
2036         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2037         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2038
2039         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2040
2041         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2042                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2043                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2044                 int index = ccgDM_getEdgeMapIndex(ss, e);
2045
2046                 glBegin(GL_LINE_STRIP);
2047                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2048                         if (useAging && !(G.f&G_BACKBUFSEL)) {
2049                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2050                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
2051                         }
2052
2053                         for (i=0; i<edgeSize-1; i++) {
2054                                 glVertex3fv(edgeData[i].co);
2055                                 glVertex3fv(edgeData[i+1].co);
2056                         }
2057                 }
2058                 glEnd();
2059         }
2060
2061         ccgEdgeIterator_free(ei);
2062 }
2063 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
2064         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2065         CCGSubSurf *ss = ccgdm->ss;
2066         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2067         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2068
2069         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2070
2071         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2072                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2073                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2074                 int index = ccgDM_getEdgeMapIndex(ss, e);
2075
2076                 glBegin(GL_LINE_STRIP);
2077                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2078                         for (i=0; i<edgeSize; i++) {
2079                                 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
2080
2081                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
2082                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2083                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
2084                                 }
2085
2086                                 glVertex3fv(edgeData[i].co);
2087                         }
2088                 }
2089                 glEnd();
2090         }
2091
2092         ccgEdgeIterator_free(ei);
2093 }
2094 static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
2095         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2096         CCGSubSurf *ss = ccgdm->ss;
2097         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
2098
2099         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2100                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2101                 int index = ccgDM_getFaceMapIndex(ss, f);
2102
2103                 if (index!=-1) {
2104                                 /* Face center data normal isn't updated atm. */
2105                         DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
2106
2107                         func(userData, index, vd->co, vd->no);
2108                 }
2109         }
2110
2111         ccgFaceIterator_free(fi);
2112 }
2113
2114 static void ccgDM_release(DerivedMesh *dm) {
2115         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2116
2117         if (DM_release(dm)) {
2118                 /* Before freeing, need to update the displacement map */
2119                 if(ccgdm->multires.modified) {
2120                         /* Check that mmd still exists */
2121                         if(!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
2122                                 ccgdm->multires.mmd = NULL;
2123                         if(ccgdm->multires.mmd)
2124                                 ccgdm->multires.update(dm);
2125                 }
2126
2127                 if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
2128                 if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
2129                 if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
2130                 if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
2131                 if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
2132                 if(ccgdm->fmap) MEM_freeN(ccgdm->fmap);
2133                 if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem);
2134                 MEM_freeN(ccgdm->edgeFlags);
2135                 MEM_freeN(ccgdm->faceFlags);
2136                 MEM_freeN(ccgdm->vertMap);
2137                 MEM_freeN(ccgdm->edgeMap);
2138                 MEM_freeN(ccgdm->faceMap);
2139                 MEM_freeN(ccgdm);
2140         }
2141 }
2142
2143 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
2144 {
2145         if(type == CD_ORIGINDEX) {
2146                 /* create origindex on demand to save memory */
2147                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2148                 CCGSubSurf *ss= ccgdm->ss;
2149                 int *origindex;
2150                 int a, index, totnone, totorig;
2151
2152                 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2153                 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
2154
2155                 totorig = ccgSubSurf_getNumVerts(ss);
2156                 totnone= dm->numVertData - totorig;
2157
2158                 /* original vertices are at the end */
2159                 for(a=0; a<totnone; a++)
2160                         origindex[a]= ORIGINDEX_NONE;
2161
2162                 for(index=0; index<totorig; index++, a++) {
2163                         CCGVert *v = ccgdm->vertMap[index].vert;
2164                         origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
2165                 }
2166
2167                 return origindex;
2168         }
2169
2170         return DM_get_vert_data_layer(dm, type);
2171 }
2172
2173 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
2174 {
2175         if(type == CD_ORIGINDEX) {
2176                 /* create origindex on demand to save memory */
2177                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2178                 CCGSubSurf *ss= ccgdm->ss;
2179                 int *origindex;
2180                 int a, i, index, totnone, totorig, totedge;
2181                 int edgeSize= ccgSubSurf_getEdgeSize(ss);
2182
2183                 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2184                 origindex= DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2185
2186                 totedge= ccgSubSurf_getNumEdges(ss);
2187                 totorig= totedge*(edgeSize - 1);
2188                 totnone= dm->numEdgeData - totorig;
2189
2190                 /* original edges are at the end */
2191                 for(a=0; a<totnone; a++)
2192                         origindex[a]= ORIGINDEX_NONE;
2193
2194                 for(index=0; index<totedge; index++) {
2195                         CCGEdge *e= ccgdm->edgeMap[index].edge;
2196                         int mapIndex= ccgDM_getEdgeMapIndex(ss, e);
2197
2198                         for(i = 0; i < edgeSize - 1; i++, a++)
2199                                 origindex[a]= mapIndex;
2200                 }
2201
2202                 return origindex;
2203         }
2204
2205         return DM_get_edge_data_layer(dm, type);
2206 }
2207
2208 static void *ccgDM_get_face_data_layer(DerivedMesh *dm, int type)
2209 {
2210         if(type == CD_ORIGINDEX) {
2211                 /* create origindex on demand to save memory */
2212                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2213                 CCGSubSurf *ss= ccgdm->ss;
2214                 int *origindex;
2215                 int a, i, index, totface;
2216                 int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
2217
2218                 DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2219                 origindex= DM_get_face_data_layer(dm, CD_ORIGINDEX);
2220
2221                 totface= ccgSubSurf_getNumFaces(ss);
2222
2223                 for(a=0, index=0; index<totface; index++) {
2224                         CCGFace *f = ccgdm->faceMap[index].face;
2225                         int numVerts = ccgSubSurf_getFaceNumVerts(f);
2226                         int mapIndex = ccgDM_getFaceMapIndex(ss, f);
2227
2228                         for(i=0; i<gridFaces*gridFaces*numVerts; i++, a++)
2229                                 origindex[a]= mapIndex;
2230                 }
2231
2232                 return origindex;
2233         }
2234
2235         return DM_get_face_data_layer(dm, type);
2236 }
2237
2238 static int ccgDM_getNumGrids(DerivedMesh *dm)
2239 {
2240         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2241         int index, numFaces, numGrids;
2242
2243         numFaces= ccgSubSurf_getNumFaces(ccgdm->ss);
2244         numGrids= 0;
2245
2246         for(index=0; index<numFaces; index++) {
2247                 CCGFace *f = ccgdm->faceMap[index].face;
2248                 numGrids += ccgSubSurf_getFaceNumVerts(f);
2249         }
2250
2251         return numGrids;
2252 }
2253
2254 static int ccgDM_getGridSize(DerivedMesh *dm)
2255 {
2256         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2257         return ccgSubSurf_getGridSize(ccgdm->ss);
2258 }
2259
2260 static int ccgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset)
2261 {
2262         CCGFace *adjf;
2263         CCGEdge *e;
2264         int i, j= 0, numFaces, fIndex, numEdges= 0;
2265
2266         e = ccgSubSurf_getFaceEdge(ss, f, S);
2267         numFaces = ccgSubSurf_getEdgeNumFaces(e);
2268
2269         if(numFaces != 2)
2270                 return -1;
2271
2272         for(i = 0; i < numFaces; i++) {
2273                 adjf = ccgSubSurf_getEdgeFace(e, i);
2274
2275                 if(adjf != f) {
2276                         numEdges = ccgSubSurf_getFaceNumVerts(adjf);
2277                         for(j = 0; j < numEdges; j++)
2278                                 if(ccgSubSurf_getFaceEdge(ss, adjf, j) == e)
2279                                         break;
2280
2281                         if(j != numEdges)
2282                                 break;
2283                 }
2284         }
2285         
2286         fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, adjf));
2287
2288         return gridOffset[fIndex] + (j + offset)%numEdges;
2289 }
2290
2291 static void ccgdm_create_grids(DerivedMesh *dm)
2292 {
2293         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2294         CCGSubSurf *ss= ccgdm->ss;
2295         DMGridData **gridData;
2296         DMGridAdjacency *gridAdjacency, *adj;
2297         CCGFace **gridFaces;
2298         int *gridOffset;
2299         int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
2300
2301         if(ccgdm->gridData)
2302                 return;
2303         
2304         numGrids = ccgDM_getNumGrids(dm);
2305         numFaces = ccgSubSurf_getNumFaces(ss);
2306         /*gridSize = ccgDM_getGridSize(dm);*/  /*UNUSED*/
2307
2308         /* compute offset into grid array for each face */
2309         gridOffset = MEM_mallocN(sizeof(int)*numFaces, "ccgdm.gridOffset");
2310
2311         for(gIndex = 0, index = 0; index < numFaces; index++) {
2312                 CCGFace *f = ccgdm->faceMap[index].face;
2313                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2314
2315                 gridOffset[index] = gIndex;
2316                 gIndex += numVerts;
2317         }
2318
2319         /* compute grid data */
2320         gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "ccgdm.gridData");
2321         gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "ccgdm.gridAdjacency");
2322         gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "ccgdm.gridFaces");
2323
2324         for(gIndex = 0, index = 0; index < numFaces; index++) {
2325                 CCGFace *f = ccgdm->faceMap[index].face;
2326                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2327
2328                 for(S = 0; S < numVerts; S++, gIndex++) {
2329                         int prevS = (S - 1 + numVerts) % numVerts;
2330                         int nextS = (S + 1 + numVerts) % numVerts;
2331
2332                         gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2333                         gridFaces[gIndex] = f;
2334
2335                         adj = &gridAdjacency[gIndex];
2336
2337                         adj->index[0] = gIndex - S + nextS;
2338                         adj->rotation[0] = 3;
2339                         adj->index[1] = ccgdm_adjacent_grid(ss, gridOffset, f, prevS, 0);
2340                         adj->rotation[1] = 1;
2341                         adj->index[2] = ccgdm_adjacent_grid(ss, gridOffset, f, S, 1);
2342                         adj->rotation[2] = 3;
2343                         adj->index[3] = gIndex - S + prevS;
2344                         adj->rotation[3] = 1;
2345                 }
2346         }
2347
2348         ccgdm->gridData = gridData;
2349         ccgdm->gridFaces = gridFaces;
2350         ccgdm->gridAdjacency = gridAdjacency;
2351         ccgdm->gridOffset = gridOffset;
2352 }
2353
2354 static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
2355 {
2356         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2357
2358         ccgdm_create_grids(dm);
2359         return ccgdm->gridData;
2360 }
2361
2362 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm)
2363 {
2364         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2365
2366         ccgdm_create_grids(dm);
2367         return ccgdm->gridAdjacency;
2368 }
2369
2370 static int *ccgDM_getGridOffset(DerivedMesh *dm)
2371 {
2372         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2373
2374         ccgdm_create_grids(dm);
2375         return ccgdm->gridOffset;
2376 }
2377
2378 static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
2379 {
2380         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2381
2382         if(!ccgdm->multires.mmd && !ccgdm->fmap && ob->type == OB_MESH) {
2383                 Mesh *me= ob->data;
2384
2385                 create_vert_face_map(&ccgdm->fmap, &ccgdm->fmap_mem, me->mface,
2386                                      me->totvert, me->totface);
2387         }
2388
2389         return ccgdm->fmap;
2390 }
2391
2392 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
2393 {
2394         MultiresModifierData *mmd= ccgdm->multires.mmd;
2395
2396         /* both of multires and subsurm modifiers are CCG, but
2397            grids should only be used when sculpting on multires */
2398         if(!mmd)
2399                 return 0;
2400
2401         return 1;
2402 }
2403
2404 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
2405 {
2406         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2407         int gridSize, numGrids, grid_pbvh;
2408
2409         if(!ob) {
2410                 ccgdm->pbvh= NULL;
2411                 return NULL;
2412         }
2413
2414         if(!ob->sculpt)
2415                 return NULL;
2416
2417         grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
2418
2419         if(ob->sculpt->pbvh) {
2420                 if(grid_pbvh) {
2421                         /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
2422                            but this can be freed on ccgdm release, this updates the pointers
2423                            when the ccgdm gets remade, the assumption is that the topology
2424                            does not change. */
2425                         ccgdm_create_grids(dm);
2426                         BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
2427                 }
2428
2429                 ccgdm->pbvh = ob->sculpt->pbvh;
2430         }
2431
2432         if(ccgdm->pbvh)
2433                 return ccgdm->pbvh;
2434
2435         /* no pbvh exists yet, we need to create one. only in case of multires
2436            we build a pbvh over the modified mesh, in other cases the base mesh
2437            is being sculpted, so we build a pbvh from that. */
2438         if(grid_pbvh) {
2439                 ccgdm_create_grids(dm);
2440
2441                 gridSize = ccgDM_getGridSize(dm);
2442                 numGrids = ccgDM_getNumGrids(dm);
2443
2444                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2445                 BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
2446                         numGrids, gridSize, (void**)ccgdm->gridFaces);
2447         } else if(ob->type == OB_MESH) {
2448                 Mesh *me= ob->data;
2449                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2450                 BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
2451                                    me->totface, me->totvert);
2452         }
2453
2454         return ccgdm->pbvh;
2455 }
2456
2457 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2458                                                                                  int drawInteriorEdges,
2459                                                                                  int useSubsurfUv,
2460                                                                                  DerivedMesh *dm)
2461 {
2462         CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
2463         CCGVertIterator *vi;
2464         CCGEdgeIterator *ei;
2465         CCGFaceIterator *fi;
2466         int index, totvert, totedge, totface;
2467         int i;
2468         int vertNum, edgeNum, faceNum;
2469         short *edgeFlags;
2470         char *faceFlags;
2471         int edgeSize;
2472         int gridSize;
2473         int gridFaces;
2474         /*int gridSideVerts;*/
2475         int gridSideEdges;
2476         int gridInternalEdges;
2477         MEdge *medge = NULL;
2478         MFace *mface = NULL;
2479         int *orig_indices;
2480         FaceVertWeight *qweight, *tweight;
2481
2482         DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
2483                                          ccgSubSurf_getNumFinalVerts(ss),
2484                                          ccgSubSurf_getNumFinalEdges(ss),
2485                                          ccgSubSurf_getNumFinalFaces(ss));
2486
2487         ccgdm->dm.getMinMax = ccgDM_getMinMax;
2488         ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
2489         ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
2490
2491         ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
2492         ccgdm->dm.getVert = ccgDM_getFinalVert;
2493         ccgdm->dm.getEdge = ccgDM_getFinalEdge;
2494         ccgdm->dm.getFace = ccgDM_getFinalFace;
2495         ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
2496         ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
2497         ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2498         ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2499         ccgdm->dm.copyFaceArray = ccgDM_copyFinalFaceArray;
2500         ccgdm->dm.getVertData = DM_get_vert_data;
2501         ccgdm->dm.getEdgeData = DM_get_edge_data;
2502         ccgdm->dm.getFaceData = DM_get_face_data;
2503         ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
2504         ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
2505         ccgdm->dm.getFaceDataArray = ccgDM_get_face_data_layer;
2506         ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
2507         ccgdm->dm.getGridSize = ccgDM_getGridSize;
2508         ccgdm->dm.getGridData = ccgDM_getGridData;
2509         ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency;
2510         ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
2511         ccgdm->dm.getFaceMap = ccgDM_getFaceMap;
2512         ccgdm->dm.getPBVH = ccgDM_getPBVH;
2513
2514         ccgdm->dm.getVertCos = ccgdm_getVertCos;
2515         ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
2516         ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
2517         ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
2518         
2519         ccgdm->dm.drawVerts = ccgDM_drawVerts;
2520         ccgdm->dm.drawEdges = ccgDM_drawEdges;
2521         ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
2522         ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
2523         ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
2524         ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
2525         ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL;
2526         ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
2527         ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
2528         ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL;
2529         ccgdm->dm.drawMappedFacesMat = ccgDM_drawMappedFacesMat;
2530         ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
2531
2532         ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
2533         ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
2534         
2535         ccgdm->dm.release = ccgDM_release;
2536         
2537         ccgdm->ss = ss;
2538         ccgdm->drawInteriorEdges = drawInteriorEdges;
2539         ccgdm->useSubsurfUv = useSubsurfUv;
2540
2541         totvert = ccgSubSurf_getNumVerts(ss);
2542         ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
2543         vi = ccgSubSurf_getVertIterator(ss);
2544         for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2545                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2546
2547                 ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
2548         }
2549         ccgVertIterator_free(vi);
2550
2551         totedge = ccgSubSurf_getNumEdges(ss);
2552         ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
2553         ei = ccgSubSurf_getEdgeIterator(ss);
2554         for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2555                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2556
2557                 ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
2558         }
2559
2560         totface = ccgSubSurf_getNumFaces(ss);
2561         ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
2562         fi = ccgSubSurf_getFaceIterator(ss);
2563         for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2564                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2565
2566                 ccgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f;
2567         }
2568         ccgFaceIterator_free(fi);
2569
2570         edgeSize = ccgSubSurf_getEdgeSize(ss);
2571         gridSize = ccgSubSurf_getGridSize(ss);
2572         gridFaces = gridSize - 1;
2573         /*gridSideVerts = gridSize - 2;*/ /*UNUSED*/
2574         /*gridInternalVerts = gridSideVerts * gridSideVerts; */ /*UNUSED*/
2575         gridSideEdges = gridSize - 1;
2576         gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; 
2577
2578         calc_ss_weights(gridFaces, &qweight, &tweight);
2579
2580         vertNum = 0;
2581         edgeNum = 0;
2582         faceNum = 0;
2583
2584         /* mvert = dm->getVertArray(dm); - as yet unused */
2585         medge = dm->getEdgeArray(dm);
2586         mface = dm->getFaceArray(dm);
2587
2588         faceFlags = ccgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags");
2589
2590         orig_indices = (int*)ccgdm->dm.getFaceDataArray(&ccgdm->dm, CD_ORIGINDEX);
2591         for(index = 0; index < totface; ++index) {
2592                 CCGFace *f = ccgdm->faceMap[index].face;
2593                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2594                 int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
2595                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2596                 FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
2597                 int S, x, y;
2598                 int vertIdx[4];
2599
2600                 ccgdm->faceMap[index].startVert = vertNum;
2601                 ccgdm->faceMap[index].startEdge = edgeNum;
2602                 ccgdm->faceMap[index].startFace = faceNum;
2603
2604                 if(orig_indices)
2605                         orig_indices[faceNum] = origIndex;
2606
2607                 /* set the face base vert */
2608                 *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
2609
2610                 for(S = 0; S < numVerts; S++) {
2611                         CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S);
2612
2613                         vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2614                 }
2615
2616                 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, weight[0][0],
2617                                                         numVerts, vertNum);
2618                 ++vertNum;
2619
2620                 for(S = 0; S < numVerts; S++) {
2621                         int prevS = (S - 1 + numVerts) % numVerts;
2622                         int nextS = (S + 1) % numVerts;
2623                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2624                         for(x = 1; x < gridFaces; x++) {
2625                                 float w[4];
2626                                 w[prevS]  = weight[x][0][0];
2627                                 w[S]      = weight[x][0][1];
2628                                 w[nextS]  = weight[x][0][2];
2629                                 w[otherS] = weight[x][0][3];
2630                                 DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2631                                                                         numVerts, vertNum);
2632                                 ++vertNum;
2633                         }
2634                 }
2635
2636                 for(S = 0; S < numVerts; S++) {
2637                         int prevS = (S - 1 + numVerts) % numVerts;
2638                         int nextS = (S + 1) % numVerts;
2639                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2640                         for(y = 1; y < gridFaces; y++) {
2641                                 for(x = 1; x < gridFaces; x++) {
2642                                         float w[4];
2643                                         w[prevS]  = weight[y * gridFaces + x][0][0];
2644                                         w[S]      = weight[y * gridFaces + x][0][1];
2645                                         w[nextS]  = weight[y * gridFaces + x][0][2];
2646                                         w[otherS] = weight[y * gridFaces + x][0][3];
2647                                         DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w,
2648                                                                                 numVerts, vertNum);
2649                                         ++vertNum;
2650                                 }
2651                         }
2652                 }
2653
2654                 for(S = 0; S < numVerts; S++) {
2655                         int prevS = (S - 1 + numVerts) % numVerts;
2656                         int nextS = (S + 1) % numVerts;
2657                         int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
2658
2659                         weight = (numVerts == 4) ? qweight : tweight;
2660
2661                         for(y = 0; y < gridFaces; y++) {
2662                                 for(x = 0; x < gridFaces; x++) {
2663                                         FaceVertWeight w;
2664                                         int j;
2665
2666                                         for(j = 0; j < 4; ++j) {
2667                                                 w[j][prevS]  = (*weight)[j][0];
2668                                                 w[j][S]      = (*weight)[j][1];
2669                                                 w[j][nextS]  = (*weight)[j][2];
2670                                                 w[j][otherS] = (*weight)[j][3];
2671                                         }
2672
2673                                         DM_interp_face_data(dm, &ccgdm->dm, &origIndex, NULL,
2674                                                                                 &w, 1, faceNum);
2675                                         weight++;
2676
2677                                         ++faceNum;
2678                                 }
2679                         }
2680                 }
2681
2682                 faceFlags[index*2] = mface[origIndex].flag;
2683                 faceFlags[index*2 + 1] = mface[origIndex].mat_nr;
2684
2685                 edgeNum += numFinalEdges;
2686         }
2687
2688         if(useSubsurfUv) {
2689                 CustomData *fdata = &ccgdm->dm.faceData;
2690                 CustomData *dmfdata = &dm->faceData;
2691                 int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
2692                 int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
2693
2694                 for (i=0; i<numlayer && i<dmnumlayer; i++)
2695                         set_subsurf_uv(ss, dm, &ccgdm->dm, i);
2696         }
2697
2698         edgeFlags = ccgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "edgeFlags");
2699
2700         for(index = 0; index < totedge; ++index) {
2701                 CCGEdge *e = ccgdm->edgeMap[index].edge;
2702                 int numFinalEdges = edgeSize - 1;
2703                 int x;
2704                 int vertIdx[2];
2705                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
2706
2707                 CCGVert *v;
2708                 v = ccgSubSurf_getEdgeVert0(e);
2709                 vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2710                 v = ccgSubSurf_getEdgeVert1(e);
2711                 vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2712
2713                 ccgdm->edgeMap[index].startVert = vertNum;
2714                 ccgdm->edgeMap[index].startEdge = edgeNum;
2715
2716                 /* set the edge base vert */
2717                 *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
2718
2719                 for(x = 1; x < edgeSize - 1; x++) {
2720                         float w[2];
2721                         w[1] = (float) x / (edgeSize - 1);
2722                         w[0] = 1 - w[1];
2723                         DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
2724                         ++vertNum;
2725                 }
2726
2727                 edgeFlags[index]= medge[edgeIdx].flag;
2728
2729                 edgeNum += numFinalEdges;
2730         }
2731
2732         for(index = 0; index < totvert; ++index) {
2733                 CCGVert *v = ccgdm->vertMap[index].vert;
2734                 int vertIdx;
2735
2736                 vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2737
2738                 ccgdm->vertMap[index].startVert = vertNum;
2739
2740                 /* set the vert base vert */
2741                 *((int*) ccgSubSurf_getVertUserData(ss, v)) = vertNum;
2742
2743                 DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
2744
2745                 ++vertNum;
2746         }
2747
2748         MEM_freeN(qweight);
2749         MEM_freeN(tweight);
2750
2751         return ccgdm;
2752 }
2753
2754 /***/
2755
2756 struct DerivedMesh *subsurf_make_derived_from_derived(
2757                                                 struct DerivedMesh *dm,
2758                                                 struct SubsurfModifierData *smd,
2759                                                 int useRenderParams, float (*vertCos)[3],
2760                                                 int isFinalCalc, int forEditMode, int inEditMode)
2761 {
2762         int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF;
2763         int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2764         int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv;
2765         int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
2766         CCGDerivedMesh *result;
2767
2768         if(forEditMode) {
2769                 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
2770
2771                 smd->emCache = _getSubSurf(smd->emCache, levels, useAging, 0,
2772                                                                    useSimple);
2773                 ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
2774
2775                 result = getCCGDerivedMesh(smd->emCache,
2776                                                                    drawInteriorEdges,
2777                                                                    useSubsurfUv, dm);
2778         } else if(useRenderParams) {
2779                 /* Do not use cache in render mode. */
2780                 CCGSubSurf *ss;
2781                 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->renderLevels): smd->renderLevels;
2782
2783                 if(levels == 0)
2784                         return dm;
2785                 
2786                 ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
2787
2788                 ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2789
2790                 result = getCCGDerivedMesh(ss,
2791                         drawInteriorEdges, useSubsurfUv, dm);
2792
2793                 result->freeSS = 1;
2794         } else {
2795                 int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
2796                 int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
2797                 int levels= (smd->modifier.scene)? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels): smd->levels;
2798                 CCGSubSurf *ss;
2799
2800                 /* It is quite possible there is a much better place to do this. It
2801                  * depends a bit on how rigourously we expect this function to never
2802                  * be called in editmode. In semi-theory we could share a single
2803                  * cache, but the handles used inside and outside editmode are not
2804                  * the same so we would need some way of converting them. Its probably
2805                  * not worth the effort. But then why am I even writing this long
2806                  * comment that no one will read? Hmmm. - zr
2807                  *
2808                  * Addendum: we can't really ensure that this is never called in edit
2809                  * mode, so now we have a parameter to verify it. - brecht
2810                  */
2811                 if(!inEditMode && smd->emCache) {
2812                         ccgSubSurf_free(smd->emCache);
2813                         smd->emCache = NULL;
2814                 }
2815
2816                 if(useIncremental && isFinalCalc) {
2817                         smd->mCache = ss = _getSubSurf(smd->mCache, levels,
2818                                                                                    useAging, 0, useSimple);
2819
2820                         ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2821
2822                         result = getCCGDerivedMesh(smd->mCache,
2823                                                                            drawInteriorEdges,
2824                                                                            useSubsurfUv, dm);
2825                 } else {
2826                         if (smd->mCache && isFinalCalc) {
2827                                 ccgSubSurf_free(smd->mCache);
2828                                 smd->mCache = NULL;
2829                         }
2830
2831                         ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
2832                         ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
2833
2834                         result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
2835
2836                         if(isFinalCalc)
2837                                 smd->mCache = ss;
2838                         else
2839                                 result->freeSS = 1;
2840                 }
2841         }
2842
2843         return (DerivedMesh*)result;
2844 }
2845
2846 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 
2847 {
2848         /* Finds the subsurf limit positions for the verts in a mesh 
2849          * and puts them in an array of floats. Please note that the 
2850          * calculated vert positions is incorrect for the verts 
2851          * on the boundary of the mesh.
2852          */
2853         CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0);
2854         float edge_sum[3], face_sum[3];
2855         CCGVertIterator *vi;
2856         DerivedMesh *dm = CDDM_from_mesh(me, NULL);
2857
2858         ss_sync_from_derivedmesh(ss, dm, NULL, 0);
2859
2860         vi = ccgSubSurf_getVertIterator(ss);
2861         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2862                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2863                 int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v));
2864                 int N = ccgSubSurf_getVertNumEdges(v);
2865                 int numFaces = ccgSubSurf_getVertNumFaces(v);
2866                 float *co;
2867                 int i;
2868
2869                 edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0;
2870                 face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
2871
2872                 for (i=0; i<N; i++) {
2873                         CCGEdge *e = ccgSubSurf_getVertEdge(v, i);
2874                         add_v3_v3v3(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
2875                 }
2876                 for (i=0; i<numFaces; i++) {
2877                         CCGFace *f = ccgSubSurf_getVertFace(v, i);
2878                         add_v3_v3(face_sum, ccgSubSurf_getFaceCenterData(f));
2879                 }
2880
2881                 /* ad-hoc correction for boundary vertices, to at least avoid them
2882                    moving completely out of place (brecht) */
2883                 if(numFaces && numFaces != N)
2884                         mul_v3_fl(face_sum, (float)N/(float)numFaces);
2885
2886                 co = ccgSubSurf_getVertData(ss, v);
2887                 positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
2888                 positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
2889                 positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
2890         }
2891         ccgVertIterator_free(vi);
2892
2893         ccgSubSurf_free(ss);
2894
2895         dm->release(dm);
2896 }
2897