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