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