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