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