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