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