svn merge ^/trunk/blender -r42009:42053
[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         int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1416         int totedge = ccgSubSurf_getNumEdges(ss);
1417         int gridSize = ccgSubSurf_getGridSize(ss);
1418         int useAging;
1419
1420         ccgdm_pbvh_update(ccgdm);
1421
1422         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1423
1424         for (j=0; j< totedge; j++) {
1425                 CCGEdge *e = ccgdm->edgeMap[j].edge;
1426                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1427
1428                 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e))
1429                         continue;
1430
1431                 if(ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW))
1432                         continue;
1433
1434                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1435                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1436                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1437                 }
1438
1439                 glBegin(GL_LINE_STRIP);
1440                 for (i=0; i<edgeSize-1; i++) {
1441                         glVertex3fv(edgeData[i].co);
1442                         glVertex3fv(edgeData[i+1].co);
1443                 }
1444                 glEnd();
1445         }
1446
1447         if (useAging && !(G.f&G_BACKBUFSEL)) {
1448                 glColor3ub(0, 0, 0);
1449         }
1450
1451         if (ccgdm->drawInteriorEdges) {
1452                 int totface = ccgSubSurf_getNumFaces(ss);
1453
1454                 for(j = 0; j < totface; j++) {
1455                         CCGFace *f = ccgdm->faceMap[j].face;
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 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
1482         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1483         CCGSubSurf *ss = cgdm->ss;
1484         int totedge = ccgSubSurf_getNumEdges(ss);
1485         int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1486
1487         for (j=0; j< totedge; j++) {
1488                 CCGEdge *e = ccgdm->edgeMap[j].edge;
1489                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1490
1491                 if (!ccgSubSurf_getEdgeNumFaces(e)) {
1492                         glBegin(GL_LINE_STRIP);
1493                         for (i=0; i<edgeSize-1; i++) {
1494                                 glVertex3fv(edgeData[i].co);
1495                                 glVertex3fv(edgeData[i+1].co);
1496                         }
1497                         glEnd();
1498                 }
1499         }
1500 }
1501
1502 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
1503 {
1504         float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1505         float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1506         float no[3];
1507
1508         no[0] = b_dY*a_cZ - b_dZ*a_cY;
1509         no[1] = b_dZ*a_cX - b_dX*a_cZ;
1510         no[2] = b_dX*a_cY - b_dY*a_cX;
1511
1512         /* don't normalize, GL_NORMALIZE is enabled */
1513         glNormal3fv(no);
1514 }
1515
1516         /* Only used by non-editmesh types */
1517 static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int fast, int (*setMaterial)(int, void *attribs)) {
1518         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1519         CCGSubSurf *ss = ccgdm->ss;
1520         int gridSize = ccgSubSurf_getGridSize(ss);
1521         char *faceFlags = ccgdm->faceFlags;
1522         int step = (fast)? gridSize-1: 1;
1523         int i, totface = ccgSubSurf_getNumFaces(ss);
1524         int drawcurrent = 0, matnr = -1, shademodel = -1;
1525
1526         ccgdm_pbvh_update(ccgdm);
1527
1528         if(ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
1529                 if(dm->numFaceData) {
1530                         /* should be per face */
1531                         if(!setMaterial(faceFlags[1]+1, NULL))
1532                                 return;
1533
1534                         glShadeModel((faceFlags[0] & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
1535                         BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, (faceFlags[0] & ME_SMOOTH));
1536                         glShadeModel(GL_FLAT);
1537                 }
1538
1539                 return;
1540         }
1541
1542         for(i = 0; i < totface; i++) {
1543                 CCGFace *f = ccgdm->faceMap[i].face;
1544                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1545                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1546                 int new_matnr, new_shademodel;
1547
1548                 if(faceFlags) {
1549                         new_shademodel = (faceFlags[index*2] & ME_SMOOTH)? GL_SMOOTH: GL_FLAT;
1550                         new_matnr= faceFlags[index*2 + 1];
1551                 }
1552                 else {
1553                         new_shademodel = GL_SMOOTH;
1554                         new_matnr= 0;
1555                 }
1556                 
1557                 if(shademodel != new_shademodel || matnr != new_matnr) {
1558                         matnr= new_matnr;
1559                         shademodel= new_shademodel;
1560
1561                         drawcurrent= setMaterial(matnr+1, NULL);
1562
1563                         glShadeModel(shademodel);
1564                 }
1565
1566                 if(!drawcurrent)
1567                         continue;
1568
1569                 for (S=0; S<numVerts; S++) {
1570                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1571
1572                         if (shademodel == GL_SMOOTH) {
1573                                 for (y=0; y<gridSize-1; y+=step) {
1574                                         glBegin(GL_QUAD_STRIP);
1575                                         for (x=0; x<gridSize; x+=step) {
1576                                                 DMGridData *a = &faceGridData[(y+0)*gridSize + x];
1577                                                 DMGridData *b = &faceGridData[(y+step)*gridSize + x];
1578
1579                                                 glNormal3fv(a->no);
1580                                                 glVertex3fv(a->co);
1581                                                 glNormal3fv(b->no);
1582                                                 glVertex3fv(b->co);
1583                                         }
1584                                         glEnd();
1585                                 }
1586                         } else {
1587                                 glBegin(GL_QUADS);
1588                                 for (y=0; y<gridSize-1; y+=step) {
1589                                         for (x=0; x<gridSize-1; x+=step) {
1590                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
1591                                                 float *b = faceGridData[(y+0)*gridSize + x + step].co;
1592                                                 float *c = faceGridData[(y+step)*gridSize + x + step].co;
1593                                                 float *d = faceGridData[(y+step)*gridSize + x].co;
1594
1595                                                 ccgDM_glNormalFast(a, b, c, d);
1596
1597                                                 glVertex3fv(d);
1598                                                 glVertex3fv(c);
1599                                                 glVertex3fv(b);
1600                                                 glVertex3fv(a);
1601                                         }
1602                                 }
1603                                 glEnd();
1604                         }
1605                 }
1606         }
1607 }
1608
1609         /* Only used by non-editmesh types */
1610 static void cgdm_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) {
1611         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1612         CCGSubSurf *ss = cgdm->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
1747 static void cgdm_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
1748         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1749 }
1750
1751         /* Only used by non-editmesh types */
1752 static void cgdm_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *userData, int, void *attribs), int (*setFace)(void *userData, int index), void *userData) {
1753         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1754         CCGSubSurf *ss = ccgdm->ss;
1755         GPUVertexAttribs gattribs;
1756         DMVertexAttribs attribs= {{{NULL}}};
1757         int gridSize = ccgSubSurf_getGridSize(ss);
1758         int gridFaces = gridSize - 1;
1759         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1760         char *faceFlags = ccgdm->faceFlags;
1761         int a, b, i, numVerts, matnr, new_matnr, totface;
1762
1763         ccgdm_pbvh_update(ccgdm);
1764
1765         matnr = -1;
1766
1767 #define PASSATTRIB(dx, dy, vert) {                                                                                              \
1768         if(attribs.totorco) {                                                                                                           \
1769                 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize);                 \
1770                 if(attribs.orco.glTexco)                                                                                                \
1771                         glTexCoord3fv(attribs.orco.array[index]);                                                       \
1772                 else                                                                                                                                    \
1773                         glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
1774         }                                                                                                                                                       \
1775         for(b = 0; b < attribs.tottface; b++) {                                                                         \
1776                 MTFace *tf = &attribs.tface[b].array[a];                                                                \
1777                 if(attribs.tface[b].glTexco)                                                                                    \
1778                         glTexCoord2fv(tf->uv[vert]);                                                                            \
1779                 else                                                                                                                                    \
1780                         glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);           \
1781         }                                                                                                                                                       \
1782         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
1783                 MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
1784                 GLubyte col[4];                                                                                                                 \
1785                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
1786                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
1787         }                                                                                                                                                       \
1788         if(attribs.tottang) {                                                                                                           \
1789                 float *tang = attribs.tang.array[a*4 + vert];                                                   \
1790                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
1791         }                                                                                                                                                       \
1792 }
1793
1794         totface = ccgSubSurf_getNumFaces(ss);
1795         for(a = 0, i = 0; i < totface; i++) {
1796                 CCGFace *f = ccgdm->faceMap[i].face;
1797                 int S, x, y, drawSmooth;
1798                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1799                 int origIndex = ccgDM_getFaceMapIndex(ss, f);
1800                 
1801                 numVerts = ccgSubSurf_getFaceNumVerts(f);
1802
1803                 /* get flags */
1804                 if(faceFlags) {
1805                         drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
1806                         new_matnr= faceFlags[index*2 + 1] + 1;
1807                 }
1808                 else {
1809                         drawSmooth = 1;
1810                         new_matnr= 1;
1811                 }
1812
1813                 /* material */
1814                 if(new_matnr != matnr) {
1815                         setMaterial(userData, matnr = new_matnr, &gattribs);
1816                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1817                 }
1818
1819                 /* face hiding */
1820                 if((setFace && (origIndex != ORIGINDEX_NONE) && !setFace(userData, origIndex))) {
1821                         a += gridFaces*gridFaces*numVerts;
1822                         continue;
1823                 }
1824
1825                 /* draw face*/
1826                 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1827                 for (S=0; S<numVerts; S++) {
1828                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1829                         DMGridData *vda, *vdb;
1830
1831                         if (drawSmooth) {
1832                                 for (y=0; y<gridFaces; y++) {
1833                                         glBegin(GL_QUAD_STRIP);
1834                                         for (x=0; x<gridFaces; x++) {
1835                                                 vda = &faceGridData[(y+0)*gridSize + x];
1836                                                 vdb = &faceGridData[(y+1)*gridSize + x];
1837                                                 
1838                                                 PASSATTRIB(0, 0, 0);
1839                                                 glNormal3fv(vda->no);
1840                                                 glVertex3fv(vda->co);
1841
1842                                                 PASSATTRIB(0, 1, 1);
1843                                                 glNormal3fv(vdb->no);
1844                                                 glVertex3fv(vdb->co);
1845
1846                                                 if(x != gridFaces-1)
1847                                                         a++;
1848                                         }
1849
1850                                         vda = &faceGridData[(y+0)*gridSize + x];
1851                                         vdb = &faceGridData[(y+1)*gridSize + x];
1852
1853                                         PASSATTRIB(0, 0, 3);
1854                                         glNormal3fv(vda->no);
1855                                         glVertex3fv(vda->co);
1856
1857                                         PASSATTRIB(0, 1, 2);
1858                                         glNormal3fv(vdb->no);
1859                                         glVertex3fv(vdb->co);
1860
1861                                         glEnd();
1862
1863                                         a++;
1864                                 }
1865                         } else {
1866                                 glBegin(GL_QUADS);
1867                                 for (y=0; y<gridFaces; y++) {
1868                                         for (x=0; x<gridFaces; x++) {
1869                                                 float *aco = faceGridData[(y+0)*gridSize + x].co;
1870                                                 float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
1871                                                 float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
1872                                                 float *dco = faceGridData[(y+1)*gridSize + x].co;
1873
1874                                                 ccgDM_glNormalFast(aco, bco, cco, dco);
1875
1876                                                 PASSATTRIB(0, 1, 1);
1877                                                 glVertex3fv(dco);
1878                                                 PASSATTRIB(1, 1, 2);
1879                                                 glVertex3fv(cco);
1880                                                 PASSATTRIB(1, 0, 3);
1881                                                 glVertex3fv(bco);
1882                                                 PASSATTRIB(0, 0, 0);
1883                                                 glVertex3fv(aco);
1884                                                 
1885                                                 a++;
1886                                         }
1887                                 }
1888                                 glEnd();
1889                         }
1890                 }
1891         }
1892
1893 #undef PASSATTRIB
1894 }
1895
1896
1897 static void cgdm_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) {
1898         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1899         CCGSubSurf *ss = cgdm->ss;
1900         int gridSize = ccgSubSurf_getGridSize(ss);
1901         unsigned char *cp1, *cp2;
1902         int useTwoSide=1, i, totface;
1903
1904         ccgdm_pbvh_update(cgdm);
1905
1906         cp1= col1;
1907         if(col2) {
1908                 cp2= col2;
1909         } else {
1910                 cp2= NULL;
1911                 useTwoSide= 0;
1912         }
1913
1914         glShadeModel(GL_SMOOTH);
1915
1916         if(col2) {
1917                 glEnable(GL_CULL_FACE);
1918         }
1919
1920         glBegin(GL_QUADS);
1921         totface = ccgSubSurf_getNumFaces(ss);
1922         for(i = 0; i < totface; i++) {
1923                 CCGFace *f = ccgdm->faceMap[i].face;
1924                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1925
1926                 for (S=0; S<numVerts; S++) {
1927                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1928                         for (y=0; y<gridSize-1; y++) {
1929                                 for (x=0; x<gridSize-1; x++) {
1930                                         float *a = faceGridData[(y+0)*gridSize + x].co;
1931                                         float *b = faceGridData[(y+0)*gridSize + x + 1].co;
1932                                         float *c = faceGridData[(y+1)*gridSize + x + 1].co;
1933                                         float *d = faceGridData[(y+1)*gridSize + x].co;
1934
1935                                         glColor3ub(cp1[3], cp1[2], cp1[1]);
1936                                         glVertex3fv(d);
1937                                         glColor3ub(cp1[7], cp1[6], cp1[5]);
1938                                         glVertex3fv(c);
1939                                         glColor3ub(cp1[11], cp1[10], cp1[9]);
1940                                         glVertex3fv(b);
1941                                         glColor3ub(cp1[15], cp1[14], cp1[13]);
1942                                         glVertex3fv(a);
1943
1944                                         if (useTwoSide) {
1945                                                 glColor3ub(cp2[15], cp2[14], cp2[13]);
1946                                                 glVertex3fv(a);
1947                                                 glColor3ub(cp2[11], cp2[10], cp2[9]);
1948                                                 glVertex3fv(b);
1949                                                 glColor3ub(cp2[7], cp2[6], cp2[5]);
1950                                                 glVertex3fv(c);
1951                                                 glColor3ub(cp2[3], cp2[2], cp2[1]);
1952                                                 glVertex3fv(d);
1953                                         }
1954
1955                                         if (cp2) cp2+=16;
1956                                         cp1+=16;
1957                                 }
1958                         }
1959                 }
1960         }
1961         glEnd();
1962 }
1963
1964 static void cgdm_drawFacesTex_common(DerivedMesh *dm,
1965         int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
1966         int (*drawParamsMapped)(void *userData, int index),
1967         void *userData) 
1968 {
1969         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
1970         CCGSubSurf *ss = cgdm->ss;
1971         MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
1972         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
1973         char *faceFlags = cgdm->faceFlags;
1974         int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss);
1975         int gridFaces = gridSize - 1;
1976
1977         ccgdm_pbvh_update(cgdm);
1978
1979         if(!mcol)
1980                 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
1981
1982         if(!mcol)
1983                 mcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL);
1984
1985         totface = ccgSubSurf_getNumFaces(ss);
1986         for(i = 0; i < totface; i++) {
1987                 CCGFace *f = cgdm->faceMap[i].face;
1988                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1989                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
1990                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
1991                 unsigned char *cp= NULL;
1992                 int mat_nr;
1993
1994                 if(faceFlags) {
1995                         drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
1996                         mat_nr= faceFlags[origIndex*2 + 1];
1997                 }
1998                 else {
1999                         drawSmooth = 1;
2000                         mat_nr= 0;
2001                 }
2002
2003                 if(drawParams)
2004                         flag = drawParams(tf, (mcol != NULL), mat_nr);
2005                 else if (index != ORIGINDEX_NONE)
2006                         flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1;
2007                 else
2008                         flag= GPU_enable_material(mat_nr, NULL) ? 1:0;
2009
2010
2011                 if (flag == 0) { /* flag 0 == the face is hidden or invisible */
2012                         if(tf) tf += gridFaces*gridFaces*numVerts;
2013                         if(mcol) mcol += gridFaces*gridFaces*numVerts*4;
2014                         continue;
2015                 }
2016
2017                 /* flag 1 == use vertex colors */
2018                 if(mcol) {
2019                         if(flag==1) cp= (unsigned char*)mcol;
2020                         mcol += gridFaces*gridFaces*numVerts*4;
2021                 }
2022
2023                 for (S=0; S<numVerts; S++) {
2024                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2025                         DMGridData *a, *b;
2026
2027                         if (drawSmooth) {
2028                                 glShadeModel(GL_SMOOTH);
2029                                 for (y=0; y<gridFaces; y++) {
2030                                         glBegin(GL_QUAD_STRIP);
2031                                         for (x=0; x<gridFaces; x++) {
2032                                                 a = &faceGridData[(y+0)*gridSize + x];
2033                                                 b = &faceGridData[(y+1)*gridSize + x];
2034
2035                                                 if(tf) glTexCoord2fv(tf->uv[0]);
2036                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2037                                                 glNormal3fv(a->no);
2038                                                 glVertex3fv(a->co);
2039
2040                                                 if(tf) glTexCoord2fv(tf->uv[1]);
2041                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2042                                                 glNormal3fv(b->no);
2043                                                 glVertex3fv(b->co);
2044                                                 
2045                                                 if(x != gridFaces-1) {
2046                                                         if(tf) tf++;
2047                                                         if(cp) cp += 16;
2048                                                 }
2049                                         }
2050
2051                                         a = &faceGridData[(y+0)*gridSize + x];
2052                                         b = &faceGridData[(y+1)*gridSize + x];
2053
2054                                         if(tf) glTexCoord2fv(tf->uv[3]);
2055                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2056                                         glNormal3fv(a->no);
2057                                         glVertex3fv(a->co);
2058
2059                                         if(tf) glTexCoord2fv(tf->uv[2]);
2060                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2061                                         glNormal3fv(b->no);
2062                                         glVertex3fv(b->co);
2063
2064                                         if(tf) tf++;
2065                                         if(cp) cp += 16;
2066
2067                                         glEnd();
2068                                 }
2069                         } else {
2070                                 glShadeModel(GL_FLAT);
2071                                 glBegin(GL_QUADS);
2072                                 for (y=0; y<gridFaces; y++) {
2073                                         for (x=0; x<gridFaces; x++) {
2074                                                 float *a_co = faceGridData[(y+0)*gridSize + x].co;
2075                                                 float *b_co = faceGridData[(y+0)*gridSize + x + 1].co;
2076                                                 float *c_co = faceGridData[(y+1)*gridSize + x + 1].co;
2077                                                 float *d_co = faceGridData[(y+1)*gridSize + x].co;
2078
2079                                                 ccgDM_glNormalFast(a_co, b_co, c_co, d_co);
2080
2081                                                 if(tf) glTexCoord2fv(tf->uv[1]);
2082                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2083                                                 glVertex3fv(d_co);
2084
2085                                                 if(tf) glTexCoord2fv(tf->uv[2]);
2086                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2087                                                 glVertex3fv(c_co);
2088
2089                                                 if(tf) glTexCoord2fv(tf->uv[3]);
2090                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2091                                                 glVertex3fv(b_co);
2092
2093                                                 if(tf) glTexCoord2fv(tf->uv[0]);
2094                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2095                                                 glVertex3fv(a_co);
2096
2097                                                 if(tf) tf++;
2098                                                 if(cp) cp += 16;
2099                                         }
2100                                 }
2101                                 glEnd();
2102                         }
2103                 }
2104         }
2105 }
2106
2107 static void cgdm_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr))
2108 {
2109         cgdm_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
2110 }
2111
2112 static void cgdm_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
2113 {
2114         cgdm_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
2115 }
2116
2117 static void cgdm_drawUVEdges(DerivedMesh *dm)
2118 {
2119
2120         MFace *mf = dm->getTessFaceArray(dm);
2121         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
2122         int i;
2123         
2124         if (tf) {
2125                 glBegin(GL_LINES);
2126                 for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
2127                         if(!(mf->flag&ME_HIDE)) {
2128                                 glVertex2fv(tf->uv[0]);
2129                                 glVertex2fv(tf->uv[1]);
2130         
2131                                 glVertex2fv(tf->uv[1]);
2132                                 glVertex2fv(tf->uv[2]);
2133         
2134                                 if(!mf->v4) {
2135                                         glVertex2fv(tf->uv[2]);
2136                                         glVertex2fv(tf->uv[0]);
2137                                 } else {
2138                                         glVertex2fv(tf->uv[2]);
2139                                         glVertex2fv(tf->uv[3]);
2140         
2141                                         glVertex2fv(tf->uv[3]);
2142                                         glVertex2fv(tf->uv[0]);
2143                                 }
2144                         }
2145                 }
2146                 glEnd();
2147         }
2148 }
2149
2150 static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs),
2151                         int (*compareDrawOptions)(void *userData, int cur_index, int next_index)) {
2152         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2153         CCGSubSurf *ss = cgdm->ss;
2154         MCol *mcol= NULL;
2155         int i, gridSize = ccgSubSurf_getGridSize(ss);
2156         char *faceFlags = cgdm->faceFlags;
2157         int gridFaces = gridSize - 1, totface;
2158
2159         /* currently unused -- each original face is handled separately */
2160         (void)compareDrawOptions;
2161
2162         if(useColors) {
2163                 mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
2164                 if(!mcol)
2165                         mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
2166         }
2167
2168         totface = ccgSubSurf_getNumFaces(ss);
2169         for(i = 0; i < totface; i++) {
2170                 CCGFace *f = cgdm->faceMap[i].face;
2171                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2172                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
2173                 int origIndex;
2174                 unsigned char *cp= NULL;
2175
2176                 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
2177
2178                 if(faceFlags) drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH);
2179                 else drawSmooth = 1;
2180
2181                 if(mcol) {
2182                         cp= (unsigned char*)mcol;
2183                         mcol += gridFaces*gridFaces*numVerts*4;
2184                 }
2185
2186                 {
2187                         int draw= 1;
2188
2189                         if(index == ORIGINDEX_NONE)
2190                                 draw= setMaterial(faceFlags ? faceFlags[origIndex*2 + 1] + 1: 1, NULL); /* XXX, no faceFlags no material */
2191                         else if (setDrawOptions)
2192                                 draw= setDrawOptions(userData, index, &drawSmooth);
2193
2194                         if (draw) {
2195                                 if (draw==2) {
2196                                           glEnable(GL_POLYGON_STIPPLE);
2197                                           glPolygonStipple(stipple_quarttone);
2198                                 }
2199
2200                                 /* no need to set shading mode to flat because
2201                                 *  normals are already used to change shading */
2202                                 glShadeModel(GL_SMOOTH);
2203                                 
2204                                 for (S=0; S<numVerts; S++) {
2205                                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2206                                         if (drawSmooth) {
2207                                                 for (y=0; y<gridFaces; y++) {
2208                                                         DMGridData *a, *b;
2209                                                         glBegin(GL_QUAD_STRIP);
2210                                                         for (x=0; x<gridFaces; x++) {
2211                                                                 a = &faceGridData[(y+0)*gridSize + x];
2212                                                                 b = &faceGridData[(y+1)*gridSize + x];
2213         
2214                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2215                                                                 glNormal3fv(a->no);
2216                                                                 glVertex3fv(a->co);
2217                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2218                                                                 glNormal3fv(b->no);
2219                                                                 glVertex3fv(b->co);
2220
2221                                                                 if(x != gridFaces-1) {
2222                                                                         if(cp) cp += 16;
2223                                                                 }
2224                                                         }
2225
2226                                                         a = &faceGridData[(y+0)*gridSize + x];
2227                                                         b = &faceGridData[(y+1)*gridSize + x];
2228
2229                                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2230                                                         glNormal3fv(a->no);
2231                                                         glVertex3fv(a->co);
2232                                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2233                                                         glNormal3fv(b->no);
2234                                                         glVertex3fv(b->co);
2235
2236                                                         if(cp) cp += 16;
2237
2238                                                         glEnd();
2239                                                 }
2240                                         } else {
2241                                                 glBegin(GL_QUADS);
2242                                                 for (y=0; y<gridFaces; y++) {
2243                                                         for (x=0; x<gridFaces; x++) {
2244                                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
2245                                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
2246                                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
2247                                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
2248
2249                                                                 ccgDM_glNormalFast(a, b, c, d);
2250         
2251                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2252                                                                 glVertex3fv(d);
2253                                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2254                                                                 glVertex3fv(c);
2255                                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2256                                                                 glVertex3fv(b);
2257                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2258                                                                 glVertex3fv(a);
2259
2260                                                                 if(cp) cp += 16;
2261                                                         }
2262                                                 }
2263                                                 glEnd();
2264                                         }
2265                                 }
2266                                 if (draw==2)
2267                                         glDisable(GL_POLYGON_STIPPLE);
2268                         }
2269                 }
2270         }
2271 }
2272 static void cgdm_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
2273         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2274         CCGSubSurf *ss = cgdm->ss;
2275         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2276         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2277
2278         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2279
2280         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2281                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2282                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2283                 int index = ccgDM_getEdgeMapIndex(ss, e);
2284
2285                 glBegin(GL_LINE_STRIP);
2286                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2287                         if (useAging && !(G.f&G_BACKBUFSEL)) {
2288                                 int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2289                                 glColor3ub(0, ageCol>0?ageCol:0, 0);
2290                         }
2291
2292                         for (i=0; i<edgeSize-1; i++) {
2293                                 glVertex3fv(edgeData[i].co);
2294                                 glVertex3fv(edgeData[i+1].co);
2295                         }
2296                 }
2297                 glEnd();
2298         }
2299
2300         ccgEdgeIterator_free(ei);
2301 }
2302 static void cgdm_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
2303         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2304         CCGSubSurf *ss = cgdm->ss;
2305         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2306         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2307
2308         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2309
2310         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2311                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2312                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2313                 int index = ccgDM_getEdgeMapIndex(ss, e);
2314
2315                 glBegin(GL_LINE_STRIP);
2316                 if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
2317                         for (i=0; i<edgeSize; i++) {
2318                                 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
2319
2320                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
2321                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2322                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
2323                                 }
2324
2325                                 glVertex3fv(edgeData[i].co);
2326                         }
2327                 }
2328                 glEnd();
2329         }
2330
2331         ccgEdgeIterator_free(ei);
2332 }
2333 static void cgdm_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
2334         CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
2335         CCGSubSurf *ss = cgdm->ss;
2336         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
2337
2338         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2339                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2340                 int index = ccgDM_getFaceMapIndex(ss, f);
2341
2342                 if (index!=-1) {
2343                                 /* Face center data normal isn't updated atm. */
2344                         DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
2345
2346                         func(userData, index, vd->co, vd->no);
2347                 }
2348         }
2349
2350         ccgFaceIterator_free(fi);
2351 }
2352
2353 static void cgdm_release(DerivedMesh *dm) {
2354         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2355
2356         if (DM_release(dm)) {
2357                 /* Before freeing, need to update the displacement map */
2358                 if(ccgdm->multires.modified) {
2359                         /* Check that mmd still exists */
2360                         if(!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
2361                                 ccgdm->multires.mmd = NULL;
2362                         if(ccgdm->multires.mmd)
2363                                 ccgdm->multires.update(dm);
2364                 }
2365
2366                 if (ccgdm->ehash)
2367                         BLI_edgehash_free(ccgdm->ehash, NULL);
2368
2369                 if(ccgdm->reverseFaceMap) MEM_freeN(ccgdm->reverseFaceMap);
2370                 if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
2371                 if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
2372                 if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
2373                 if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
2374                 if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
2375                 if(ccgdm->fmap) MEM_freeN(ccgdm->fmap);
2376                 if(ccgdm->fmap_mem) MEM_freeN(ccgdm->fmap_mem);
2377                 MEM_freeN(ccgdm->edgeFlags);
2378                 MEM_freeN(ccgdm->faceFlags);
2379                 MEM_freeN(ccgdm->vertMap);
2380                 MEM_freeN(ccgdm->edgeMap);
2381                 MEM_freeN(ccgdm->faceMap);
2382                 MEM_freeN(ccgdm);
2383         }
2384 }
2385
2386 static void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata, 
2387                           CustomData *pdata, int loopstart, int findex, 
2388                           int polyindex, int numTex, int numCol) 
2389 {
2390         MTFace *texface;
2391         MTexPoly *texpoly;
2392         MCol *mcol;
2393         MLoopCol *mloopcol;
2394         MLoopUV *mloopuv;
2395         int i, j, hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL);
2396
2397         for(i=0; i < numTex; i++){
2398                 texface = CustomData_get_n(fdata, CD_MTFACE, findex, i);
2399                 texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i);
2400                 
2401                 texface->tpage = texpoly->tpage;
2402                 texface->flag = texpoly->flag;
2403                 texface->transp = texpoly->transp;
2404                 texface->mode = texpoly->mode;
2405                 texface->tile = texpoly->tile;
2406                 texface->unwrap = texpoly->unwrap;
2407
2408                 mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i);
2409                 for (j=0; j<4; j++, mloopuv++) {
2410                         texface->uv[j][0] = mloopuv->uv[0];
2411                         texface->uv[j][1] = mloopuv->uv[1];
2412                 }
2413         }
2414
2415         for(i=0; i < numCol; i++){
2416                 mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i);
2417                 mcol = CustomData_get_n(fdata, CD_MCOL, findex, i);
2418
2419                 for (j=0; j<4; j++, mloopcol++) {
2420                         mcol[j].r = mloopcol->r;
2421                         mcol[j].g = mloopcol->g;
2422                         mcol[j].b = mloopcol->b;
2423                         mcol[j].a = mloopcol->a;
2424                 }
2425         }
2426         
2427         if (hasWCol) {
2428                 mloopcol = CustomData_get(ldata, loopstart, CD_WEIGHT_MLOOPCOL);
2429                 mcol = CustomData_get(fdata, findex, CD_WEIGHT_MCOL);
2430
2431                 for (j=0; j<4; j++, mloopcol++) {
2432                         mcol[j].r = mloopcol->r;
2433                         mcol[j].g = mloopcol->g;
2434                         mcol[j].b = mloopcol->b;
2435                         mcol[j].a = mloopcol->a;
2436                 }
2437         }
2438 }
2439
2440 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
2441 {
2442         if(type == CD_ORIGINDEX) {
2443                 /* create origindex on demand to save memory */
2444                 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2445                 CCGSubSurf *ss= cgdm->ss;
2446                 int *origindex;
2447                 int a, index, totnone, totorig;
2448
2449                 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2450                 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
2451
2452                 totorig = ccgSubSurf_getNumVerts(ss);
2453                 totnone= dm->numVertData - totorig;
2454
2455                 /* original vertices are at the end */
2456                 for(a=0; a<totnone; a++)
2457                         origindex[a]= ORIGINDEX_NONE;
2458
2459                 for(index=0; index<totorig; index++, a++) {
2460                         CCGVert *v = cgdm->vertMap[index].vert;
2461                         origindex[a] = ccgDM_getVertMapIndex(cgdm->ss, v);
2462                 }
2463
2464                 return origindex;
2465         }
2466
2467         return DM_get_vert_data_layer(dm, type);
2468 }
2469
2470 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
2471 {
2472         if(type == CD_ORIGINDEX) {
2473                 /* create origindex on demand to save memory */
2474                 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2475                 CCGSubSurf *ss= cgdm->ss;
2476                 int *origindex;
2477                 int a, i, index, totnone, totorig, totedge;
2478                 int edgeSize= ccgSubSurf_getEdgeSize(ss);
2479
2480                 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2481                 origindex= DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2482
2483                 totedge= ccgSubSurf_getNumEdges(ss);
2484                 totorig= totedge*(edgeSize - 1);
2485                 totnone= dm->numEdgeData - totorig;
2486
2487                 /* original edges are at the end */
2488                 for(a=0; a<totnone; a++)
2489                         origindex[a]= ORIGINDEX_NONE;
2490
2491                 for(index=0; index<totedge; index++) {
2492                         CCGEdge *e= cgdm->edgeMap[index].edge;
2493                         int mapIndex= ccgDM_getEdgeMapIndex(ss, e);
2494
2495                         for(i = 0; i < edgeSize - 1; i++, a++)
2496                                 origindex[a]= mapIndex;
2497                 }
2498
2499                 return origindex;
2500         }
2501
2502         return DM_get_edge_data_layer(dm, type);
2503 }
2504
2505 static void *ccgDM_get_face_data_layer(DerivedMesh *dm, int type)
2506 {
2507         if(type == CD_ORIGINDEX) {
2508                 /* create origindex on demand to save memory */
2509                 CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2510                 CCGSubSurf *ss= cgdm->ss;
2511                 int *origindex;
2512                 int a, i, index, totface;
2513                 int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
2514
2515                 DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2516                 origindex= DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
2517
2518                 totface= ccgSubSurf_getNumFaces(ss);
2519
2520                 for(a=0, index=0; index<totface; index++) {
2521                         CCGFace *f = cgdm->faceMap[index].face;
2522                         int numVerts = ccgSubSurf_getFaceNumVerts(f);
2523                         int mapIndex = ccgDM_getFaceMapIndex(ss, f);
2524
2525                         for(i=0; i<gridFaces*gridFaces*numVerts; i++, a++)
2526                                 origindex[a]= mapIndex;
2527                 }
2528
2529                 return origindex;
2530         }
2531
2532         return DM_get_tessface_data_layer(dm, type);
2533 }
2534
2535 static int ccgDM_getNumGrids(DerivedMesh *dm)
2536 {
2537         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2538         int index, numFaces, numGrids;
2539
2540         numFaces= ccgSubSurf_getNumFaces(cgdm->ss);
2541         numGrids= 0;
2542
2543         for(index=0; index<numFaces; index++) {
2544                 CCGFace *f = cgdm->faceMap[index].face;
2545                 numGrids += ccgSubSurf_getFaceNumVerts(f);
2546         }
2547
2548         return numGrids;
2549 }
2550
2551 static int ccgDM_getGridSize(DerivedMesh *dm)
2552 {
2553         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2554         return ccgSubSurf_getGridSize(cgdm->ss);
2555 }
2556
2557 static int cgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset)
2558 {
2559         CCGFace *adjf;
2560         CCGEdge *e;
2561         int i, j= 0, numFaces, fIndex, numEdges= 0;
2562
2563         e = ccgSubSurf_getFaceEdge(ss, f, S);
2564         numFaces = ccgSubSurf_getEdgeNumFaces(e);
2565
2566         if(numFaces != 2)
2567                 return -1;
2568
2569         for(i = 0; i < numFaces; i++) {
2570                 adjf = ccgSubSurf_getEdgeFace(e, i);
2571
2572                 if(adjf != f) {
2573                         numEdges = ccgSubSurf_getFaceNumVerts(adjf);
2574                         for(j = 0; j < numEdges; j++)
2575                                 if(ccgSubSurf_getFaceEdge(ss, adjf, j) == e)
2576                                         break;
2577
2578                         if(j != numEdges)
2579                                 break;
2580                 }
2581         }
2582         
2583         fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, adjf));
2584
2585         return gridOffset[fIndex] + (j + offset)%numEdges;
2586 }
2587
2588 static void ccgdm_create_grids(DerivedMesh *dm)
2589 {
2590         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2591         CCGSubSurf *ss= cgdm->ss;
2592         DMGridData **gridData;
2593         DMGridAdjacency *gridAdjacency, *adj;
2594         CCGFace **gridFaces;
2595         int *gridOffset;
2596         int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
2597
2598         if(cgdm->gridData)
2599                 return;
2600         
2601         numGrids = ccgDM_getNumGrids(dm);
2602         numFaces = ccgSubSurf_getNumFaces(ss);
2603         /*gridSize = ccgDM_getGridSize(dm);*/  /*UNUSED*/
2604
2605         /* compute offset into grid array for each face */
2606         gridOffset = MEM_mallocN(sizeof(int)*numFaces, "cgdm.gridOffset");
2607
2608         for(gIndex = 0, index = 0; index < numFaces; index++) {
2609                 CCGFace *f = cgdm->faceMap[index].face;
2610                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2611
2612                 gridOffset[index] = gIndex;
2613                 gIndex += numVerts;
2614         }
2615
2616         /* compute grid data */
2617         gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "cgdm.gridData");
2618         gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "cgdm.gridAdjacency");
2619         gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "cgdm.gridFaces");
2620
2621         for(gIndex = 0, index = 0; index < numFaces; index++) {
2622                 CCGFace *f = cgdm->faceMap[index].face;
2623                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2624
2625                 for(S = 0; S < numVerts; S++, gIndex++) {
2626                         int prevS = (S - 1 + numVerts) % numVerts;
2627                         int nextS = (S + 1 + numVerts) % numVerts;
2628
2629                         gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2630                         gridFaces[gIndex] = f;
2631
2632                         adj = &gridAdjacency[gIndex];
2633
2634                         adj->index[0] = gIndex - S + nextS;
2635                         adj->rotation[0] = 3;
2636                         adj->index[1] = cgdm_adjacent_grid(ss, gridOffset, f, prevS, 0);
2637                         adj->rotation[1] = 1;
2638                         adj->index[2] = cgdm_adjacent_grid(ss, gridOffset, f, S, 1);
2639                         adj->rotation[2] = 3;
2640                         adj->index[3] = gIndex - S + prevS;
2641                         adj->rotation[3] = 1;
2642                 }
2643         }
2644
2645         cgdm->gridData = gridData;
2646         cgdm->gridFaces = gridFaces;
2647         cgdm->gridAdjacency = gridAdjacency;
2648         cgdm->gridOffset = gridOffset;
2649 }
2650
2651 static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
2652 {
2653         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2654
2655         ccgdm_create_grids(dm);
2656         return cgdm->gridData;
2657 }
2658
2659 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm)
2660 {
2661         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2662
2663         ccgdm_create_grids(dm);
2664         return cgdm->gridAdjacency;
2665 }
2666
2667 static int *ccgDM_getGridOffset(DerivedMesh *dm)
2668 {
2669         CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm;
2670
2671         ccgdm_create_grids(dm);
2672         return cgdm->gridOffset;
2673 }
2674
2675 static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
2676 {
2677         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2678
2679         if(!ccgdm->multires.mmd && !ccgdm->fmap && ob->type == OB_MESH) {
2680                 Mesh *me= ob->data;
2681
2682                 create_vert_face_map(&ccgdm->fmap, &ccgdm->fmap_mem, me->mface,
2683                                      me->totvert, me->totface);
2684         }
2685
2686         return ccgdm->fmap;
2687 }
2688
2689 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
2690 {
2691         MultiresModifierData *mmd= ccgdm->multires.mmd;
2692
2693         /* both of multires and subsurm modifiers are CCG, but
2694            grids should only be used when sculpting on multires */
2695         if(!mmd)
2696                 return 0;
2697
2698         return 1;
2699 }
2700
2701 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
2702 {
2703         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2704         int gridSize, numGrids, grid_pbvh;
2705
2706         if(!ob) {
2707                 ccgdm->pbvh= NULL;
2708                 return NULL;
2709         }
2710
2711         if(!ob->sculpt)
2712                 return NULL;
2713
2714         grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
2715
2716         if(ob->sculpt->pbvh) {
2717                 if(grid_pbvh) {
2718                         /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
2719                            but this can be freed on ccgdm release, this updates the pointers
2720                            when the ccgdm gets remade, the assumption is that the topology
2721                            does not change. */
2722                         ccgdm_create_grids(dm);
2723                         BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
2724                 }
2725
2726                 ccgdm->pbvh = ob->sculpt->pbvh;
2727         }
2728
2729         if(ccgdm->pbvh)
2730                 return ccgdm->pbvh;
2731
2732         /* no pbvh exists yet, we need to create one. only in case of multires
2733            we build a pbvh over the modified mesh, in other cases the base mesh
2734            is being sculpted, so we build a pbvh from that. */
2735         if(grid_pbvh) {
2736                 ccgdm_create_grids(dm);
2737
2738                 gridSize = ccgDM_getGridSize(dm);
2739                 numGrids = ccgDM_getNumGrids(dm);
2740
2741                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2742                 BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
2743                         numGrids, gridSize, (void**)ccgdm->gridFaces);
2744         } else if(ob->type == OB_MESH) {
2745                 Mesh *me= ob->data;
2746                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2747                 BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
2748                                    me->totface, me->totvert);
2749         }
2750
2751         return ccgdm->pbvh;
2752 }
2753
2754 static void ccgDM_recalcTesselection(DerivedMesh *UNUSED(dm))
2755 {
2756         /* Nothing to do: CCG handles creating its own tessfaces */
2757 }
2758
2759 static void ccgDM_calcNormals(DerivedMesh *UNUSED(dm))
2760 {
2761         /* Nothing to do: CCG calculates normals during drawing */
2762 }
2763
2764 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2765                                                                                  int drawInteriorEdges,
2766                                                                                  int useSubsurfUv,
2767                                                                                  DerivedMesh *dm)
2768 {
2769         CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "cgdm");
2770         CCGVertIterator *vi;
2771         CCGEdgeIterator *ei;
2772         CCGFaceIterator *fi;
2773         int index, totvert, totedge, totface;
2774         int i;
2775         int vertNum, edgeNum, faceNum;
2776         int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex; /* *edgeOrigIndex - as yet, unused  */
2777         short *edgeFlags;
2778         char *faceFlags;
2779         int *loopidx = NULL, *vertidx = NULL;
2780         BLI_array_declare(loopidx);
2781         BLI_array_declare(vertidx);
2782         int loopindex, loopindex2;
2783         int edgeSize, has_edge_origindex;
2784         int gridSize;
2785         int gridFaces, gridCuts;
2786         /*int gridSideVerts;*/
2787         int gridSideEdges;
2788         int numTex, numCol;
2789         int gridInternalEdges;
2790         float *w = NULL;
2791         WeightTable wtable = {0};
2792         /* MCol *mcol; */ /* UNUSED */
2793         MEdge *medge = NULL;
2794         /* MFace *mface = NULL; */
2795         MPoly *mpoly = NULL;
2796
2797         DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
2798                                          ccgSubSurf_getNumFinalVerts(ss),
2799                                          ccgSubSurf_getNumFinalEdges(ss),
2800                                          ccgSubSurf_getNumFinalFaces(ss),
2801                                          ccgSubSurf_getNumFinalFaces(ss)*4, 
2802                                          ccgSubSurf_getNumFinalFaces(ss));
2803         
2804         numTex = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPUV);
2805         numCol = CustomData_number_of_layers(&ccgdm->dm.loopData, CD_MLOOPCOL);
2806         
2807         if (numTex && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MTFACE) != numTex)
2808                 CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
2809         else if (numCol && CustomData_number_of_layers(&ccgdm->dm.faceData, CD_MCOL) != numCol)
2810                 CustomData_from_bmeshpoly(&ccgdm->dm.faceData, &ccgdm->dm.polyData, &ccgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss));
2811
2812         ccgdm->dm.getMinMax = cgdm_getMinMax;
2813         ccgdm->dm.getNumVerts = cgdm_getNumVerts;
2814         ccgdm->dm.getNumEdges = cgdm_getNumEdges;
2815         ccgdm->dm.getNumTessFaces = cgdm_getNumTessFaces;
2816         ccgdm->dm.getNumFaces = cgdm_getNumTessFaces;
2817
2818         ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
2819         ccgdm->dm.getPBVH = ccgDM_getPBVH;
2820
2821         ccgdm->dm.getVert = ccgDM_getFinalVert;
2822         ccgdm->dm.getEdge = ccgDM_getFinalEdge;
2823         ccgdm->dm.getTessFace = ccgDM_getFinalFace;
2824         ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
2825         ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
2826         ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2827         ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2828         ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
2829         ccgdm->dm.copyLoopArray = ccgDM_copyFinalLoopArray;
2830         ccgdm->dm.copyPolyArray = ccgDM_copyFinalPolyArray;
2831         ccgdm->dm.getVertData = DM_get_vert_data;
2832         ccgdm->dm.getEdgeData = DM_get_edge_data;
2833         ccgdm->dm.getTessFaceData = DM_get_face_data;
2834         ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
2835         ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
2836         ccgdm->dm.getTessFaceDataArray = ccgDM_get_face_data_layer;
2837         ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
2838         ccgdm->dm.getGridSize = ccgDM_getGridSize;
2839         ccgdm->dm.getGridData = ccgDM_getGridData;
2840         ccgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency;
2841         ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
2842         ccgdm->dm.getFaceMap = ccgDM_getFaceMap;
2843         ccgdm->dm.getPBVH = ccgDM_getPBVH;
2844
2845         ccgdm->dm.getTessFace = ccgDM_getFinalFace;
2846         ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
2847         ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
2848         ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
2849         ccgdm->dm.getVertData = DM_get_vert_data;
2850         ccgdm->dm.getEdgeData = DM_get_edge_data;
2851         ccgdm->dm.getTessFaceData = DM_get_face_data;
2852
2853         ccgdm->dm.calcNormals = ccgDM_calcNormals;
2854         ccgdm->dm.recalcTesselation = ccgDM_recalcTesselection;
2855
2856         ccgdm->dm.getVertCos = cgdm_getVertCos;
2857         ccgdm->dm.foreachMappedVert = cgdm_foreachMappedVert;
2858         ccgdm->dm.foreachMappedEdge = cgdm_foreachMappedEdge;
2859         ccgdm->dm.foreachMappedFaceCenter = cgdm_foreachMappedFaceCenter;
2860         
2861         ccgdm->dm.drawVerts = ccgDM_drawVerts;
2862         ccgdm->dm.drawEdges = ccgDM_drawEdges;
2863         ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
2864         ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
2865         ccgdm->dm.drawFacesColored = cgdm_drawFacesColored;
2866         ccgdm->dm.drawFacesTex = cgdm_drawFacesTex;
2867         ccgdm->dm.drawFacesGLSL = cgdm_drawFacesGLSL;
2868         ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
2869         ccgdm->dm.drawMappedFacesTex = cgdm_drawMappedFacesTex;
2870         ccgdm->dm.drawMappedFacesGLSL = cgdm_drawMappedFacesGLSL;
2871         ccgdm->dm.drawMappedFacesMat = cgdm_drawMappedFacesMat;
2872         ccgdm->dm.drawUVEdges = cgdm_drawUVEdges;
2873
2874         ccgdm->dm.drawMappedEdgesInterp = cgdm_drawMappedEdgesInterp;
2875         ccgdm->dm.drawMappedEdges = cgdm_drawMappedEdges;
2876
2877         ccgdm->dm.release = cgdm_release;
2878         
2879         ccgdm->ss = ss;
2880         ccgdm->drawInteriorEdges = drawInteriorEdges;
2881         ccgdm->useSubsurfUv = useSubsurfUv;
2882
2883         totvert = ccgSubSurf_getNumVerts(ss);
2884         ccgdm->vertMap = MEM_callocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
2885         vi = ccgSubSurf_getVertIterator(ss);
2886         for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
2887                 CCGVert *v = ccgVertIterator_getCurrent(vi);
2888
2889                 ccgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v;
2890         }
2891         ccgVertIterator_free(vi);
2892
2893         totedge = ccgSubSurf_getNumEdges(ss);
2894         ccgdm->edgeMap = MEM_callocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
2895         ei = ccgSubSurf_getEdgeIterator(ss);
2896         for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2897                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2898
2899                 ccgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
2900         }