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