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