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