bmesh py api:
[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 /* Translate GridHidden into the ME_HIDE flag for MVerts. Assumes
955    vertices are in the order output by ccgDM_copyFinalVertArray. */
956 void subsurf_copy_grid_hidden(DerivedMesh *dm, const MPoly *mpoly,
957                                                           MVert *mvert, const MDisps *mdisps)
958 {
959         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)dm;
960         CCGSubSurf *ss = ccgdm->ss;
961         int level = ccgSubSurf_getSubdivisionLevels(ss);
962         int gridSize = ccgSubSurf_getGridSize(ss);
963         int edgeSize = ccgSubSurf_getEdgeSize(ss);
964         int totface = ccgSubSurf_getNumFaces(ss);
965         int i, j, x, y;
966         
967         for(i = 0; i < totface; i++) {
968                 CCGFace *f = ccgdm->faceMap[i].face;
969
970                 for(j = 0; j < mpoly[i].totloop; j++) {
971                         const MDisps *md = &mdisps[mpoly[i].loopstart + j];
972                         int hidden_gridsize = ccg_gridsize(md->level);
973                         int factor = ccg_factor(level, md->level);
974                         
975                         if(!md->hidden)
976                                 continue;
977                         
978                         for(y = 0; y < gridSize; y++) {
979                                 for(x = 0; x < gridSize; x++) {
980                                         int vndx, offset;
981                                         
982                                         vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
983                                         offset = (y*factor) * hidden_gridsize + (x*factor);
984                                         if(BLI_BITMAP_GET(md->hidden, offset))
985                                                 mvert[vndx].flag |= ME_HIDE;
986                                 }
987                         }
988                 }
989         }
990 }
991
992 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
993 {
994         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
995         CCGSubSurf *ss = ccgdm->ss;
996         DMGridData *vd;
997         int index;
998         int totvert, totedge, totface;
999         int gridSize = ccgSubSurf_getGridSize(ss);
1000         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1001         int i = 0;
1002
1003         totface = ccgSubSurf_getNumFaces(ss);
1004         for(index = 0; index < totface; index++) {
1005                 CCGFace *f = ccgdm->faceMap[index].face;
1006                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1007
1008                 vd= ccgSubSurf_getFaceCenterData(f);
1009                 copy_v3_v3(mvert[i].co, vd->co);
1010                 normal_float_to_short_v3(mvert[i].no, vd->no);
1011                 i++;
1012                 
1013                 for(S = 0; S < numVerts; S++) {
1014                         for(x = 1; x < gridSize - 1; x++, i++) {
1015                                 vd= ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
1016                                 copy_v3_v3(mvert[i].co, vd->co);
1017                                 normal_float_to_short_v3(mvert[i].no, vd->no);
1018                         }
1019                 }
1020
1021                 for(S = 0; S < numVerts; S++) {
1022                         for(y = 1; y < gridSize - 1; y++) {
1023                                 for(x = 1; x < gridSize - 1; x++, i++) {
1024                                         vd= ccgSubSurf_getFaceGridData(ss, f, S, x, y);
1025                                         copy_v3_v3(mvert[i].co, vd->co);
1026                                         normal_float_to_short_v3(mvert[i].no, vd->no);
1027                                 }
1028                         }
1029                 }
1030         }
1031
1032         totedge = ccgSubSurf_getNumEdges(ss);
1033         for(index = 0; index < totedge; index++) {
1034                 CCGEdge *e = ccgdm->edgeMap[index].edge;
1035                 int x;
1036
1037                 for(x = 1; x < edgeSize - 1; x++, i++) {
1038                         vd= ccgSubSurf_getEdgeData(ss, e, x);
1039                         copy_v3_v3(mvert[i].co, vd->co);
1040                         /* This gives errors with -debug-fpe
1041                          * the normals dont seem to be unit length.
1042                          * this is most likely caused by edges with no
1043                          * faces which are now zerod out, see comment in:
1044                          * ccgSubSurf__calcVertNormals(), - campbell */
1045                         normal_float_to_short_v3(mvert[i].no, vd->no);
1046                 }
1047         }
1048
1049         totvert = ccgSubSurf_getNumVerts(ss);
1050         for(index = 0; index < totvert; index++) {
1051                 CCGVert *v = ccgdm->vertMap[index].vert;
1052
1053                 vd= ccgSubSurf_getVertData(ss, v);
1054                 copy_v3_v3(mvert[i].co, vd->co);
1055                 normal_float_to_short_v3(mvert[i].no, vd->no);
1056                 i++;
1057         }
1058 }
1059
1060 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
1061 {
1062         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1063         CCGSubSurf *ss = ccgdm->ss;
1064         int index;
1065         int totedge, totface;
1066         int gridSize = ccgSubSurf_getGridSize(ss);
1067         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1068         int i = 0;
1069         short *edgeFlags = ccgdm->edgeFlags;
1070
1071         totface = ccgSubSurf_getNumFaces(ss);
1072         for(index = 0; index < totface; index++) {
1073                 CCGFace *f = ccgdm->faceMap[index].face;
1074                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1075
1076                 for(S = 0; S < numVerts; S++) {
1077                         for(x = 0; x < gridSize - 1; x++) {
1078                                 MEdge *med = &medge[i];
1079
1080                                 if(ccgdm->drawInteriorEdges)
1081                                         med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1082                                 med->v1 = getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize);
1083                                 med->v2 = getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize);
1084                                 i++;
1085                         }
1086
1087                         for(x = 1; x < gridSize - 1; x++) {
1088                                 for(y = 0; y < gridSize - 1; y++) {
1089                                         MEdge *med;
1090
1091                                         med = &medge[i];
1092                                         if(ccgdm->drawInteriorEdges)
1093                                                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1094                                         med->v1 = getFaceIndex(ss, f, S, x, y,
1095                                                                                    edgeSize, gridSize);
1096                                         med->v2 = getFaceIndex(ss, f, S, x, y + 1,
1097                                                                                    edgeSize, gridSize);
1098                                         i++;
1099
1100                                         med = &medge[i];
1101                                         if(ccgdm->drawInteriorEdges)
1102                                                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
1103                                         med->v1 = getFaceIndex(ss, f, S, y, x,
1104                                                                                    edgeSize, gridSize);
1105                                         med->v2 = getFaceIndex(ss, f, S, y + 1, x,
1106                                                                                    edgeSize, gridSize);
1107                                         i++;
1108                                 }
1109                         }
1110                 }
1111         }
1112
1113         totedge = ccgSubSurf_getNumEdges(ss);
1114         for(index = 0; index < totedge; index++) {
1115                 CCGEdge *e = ccgdm->edgeMap[index].edge;
1116                 unsigned int flags = 0;
1117                 int x;
1118                 int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e));
1119
1120                 if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
1121
1122                 if(edgeFlags) {
1123                         if(edgeIdx != -1) {
1124                                 flags |= (edgeFlags[index] & (ME_SEAM | ME_SHARP))
1125                                                  | ME_EDGEDRAW | ME_EDGERENDER;
1126                         }
1127                 } else {
1128                         flags |= ME_EDGEDRAW | ME_EDGERENDER;
1129                 }
1130
1131                 for(x = 0; x < edgeSize - 1; x++) {
1132                         MEdge *med = &medge[i];
1133                         med->v1 = getEdgeIndex(ss, e, x, edgeSize);
1134                         med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
1135                         med->flag = flags;
1136                         i++;
1137                 }
1138         }
1139 }
1140
1141 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
1142 {
1143         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1144         CCGSubSurf *ss = ccgdm->ss;
1145         int index;
1146         int totface;
1147         int gridSize = ccgSubSurf_getGridSize(ss);
1148         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1149         int i = 0;
1150         DMFlagMat *faceFlags = ccgdm->faceFlags;
1151
1152         totface = ccgSubSurf_getNumFaces(ss);
1153         for(index = 0; index < totface; index++) {
1154                 CCGFace *f = ccgdm->faceMap[index].face;
1155                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1156                 /* keep types in sync with MFace, avoid many conversions */
1157                 char flag = (faceFlags)? faceFlags[index].flag: ME_SMOOTH;
1158                 short mat_nr = (faceFlags)? faceFlags[index].mat_nr: 0;
1159
1160                 for(S = 0; S < numVerts; S++) {
1161                         for(y = 0; y < gridSize - 1; y++) {
1162                                 for(x = 0; x < gridSize - 1; x++) {
1163                                         MFace *mf = &mface[i];
1164                                         mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1165                                                                                   edgeSize, gridSize);
1166                                         mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1167                                                                                   edgeSize, gridSize);
1168                                         mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1169                                                                                   edgeSize, gridSize);
1170                                         mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1171                                                                                   edgeSize, gridSize);
1172                                         mf->mat_nr = mat_nr;
1173                                         mf->flag = flag;
1174
1175                                         i++;
1176                                 }
1177                         }
1178                 }
1179         }
1180 }
1181
1182 static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
1183 {
1184         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1185         CCGSubSurf *ss = ccgdm->ss;
1186         int index;
1187         int totface;
1188         int gridSize = ccgSubSurf_getGridSize(ss);
1189         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1190         int i = 0;
1191         MLoop *mv;
1192         /* DMFlagMat *faceFlags = ccgdm->faceFlags; */ /* UNUSED */
1193
1194         if (!ccgdm->ehash) {
1195                 MEdge *medge;
1196
1197                 ccgdm->ehash = BLI_edgehash_new();
1198                 medge = ccgdm->dm.getEdgeArray((DerivedMesh*)ccgdm);
1199
1200                 for (i=0; i<ccgdm->dm.numEdgeData; i++) {
1201                         BLI_edgehash_insert(ccgdm->ehash, medge[i].v1, medge[i].v2, SET_INT_IN_POINTER(i));
1202                 }
1203         }
1204
1205         totface = ccgSubSurf_getNumFaces(ss);
1206         mv = mloop;
1207         for(index = 0; index < totface; index++) {
1208                 CCGFace *f = ccgdm->faceMap[index].face;
1209                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1210                 /* int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; */ /* UNUSED */
1211                 /* int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; */ /* UNUSED */
1212
1213                 for(S = 0; S < numVerts; S++) {
1214                         for(y = 0; y < gridSize - 1; y++) {
1215                                 for(x = 0; x < gridSize - 1; x++) {
1216                                         int v1, v2, v3, v4;
1217
1218                                         v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
1219                                                                                   edgeSize, gridSize);
1220
1221                                         v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
1222                                                                                   edgeSize, gridSize);
1223                                         v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
1224                                                                                   edgeSize, gridSize);
1225                                         v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
1226                                                                                   edgeSize, gridSize);
1227
1228                                         mv->v = v1;
1229                                         mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(ccgdm->ehash, v1, v2));
1230                                         mv++, i++;
1231
1232                                         mv->v = v2;
1233                                         mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(ccgdm->ehash, v2, v3));
1234                                         mv++, i++;
1235
1236                                         mv->v = v3;
1237                                         mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(ccgdm->ehash, v3, v4));
1238                                         mv++, i++;
1239
1240                                         mv->v = v4;
1241                                         mv->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(ccgdm->ehash, v4, v1));
1242                                         mv++, i++;
1243                                 }
1244                         }
1245                 }
1246         }
1247 }
1248
1249 static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mface)
1250 {
1251         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1252         CCGSubSurf *ss = ccgdm->ss;
1253         int index;
1254         int totface;
1255         int gridSize = ccgSubSurf_getGridSize(ss);
1256         /* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */
1257         int i = 0, k = 0;
1258         DMFlagMat *faceFlags = ccgdm->faceFlags;
1259
1260         totface = ccgSubSurf_getNumFaces(ss);
1261         for(index = 0; index < totface; index++) {
1262                 CCGFace *f = ccgdm->faceMap[index].face;
1263                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1264                 int flag = (faceFlags)? faceFlags[index].flag: ME_SMOOTH;
1265                 int mat_nr = (faceFlags)? faceFlags[index].mat_nr: 0;
1266
1267                 for(S = 0; S < numVerts; S++) {
1268                         for(y = 0; y < gridSize - 1; y++) {
1269                                 for(x = 0; x < gridSize - 1; x++) {
1270                                         MPoly *mf = &mface[i];
1271
1272                                         mf->mat_nr = mat_nr;
1273                                         mf->flag = flag;
1274                                         mf->loopstart = k;
1275                                         mf->totloop = 4;
1276
1277                                         k += 4;
1278                                         i++;
1279                                 }
1280                         }
1281                 }
1282         }
1283 }
1284
1285 static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3])
1286 {
1287         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1288         CCGSubSurf *ss = ccgdm->ss;
1289         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1290         int gridSize = ccgSubSurf_getGridSize(ss);
1291         int i;
1292         CCGVertIterator *vi;
1293         CCGEdgeIterator *ei;
1294         CCGFaceIterator *fi;
1295         CCGFace **faceMap2;
1296         CCGEdge **edgeMap2;
1297         CCGVert **vertMap2;
1298         int index, totvert, totedge, totface;
1299         
1300         totvert = ccgSubSurf_getNumVerts(ss);
1301         vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
1302         vi = ccgSubSurf_getVertIterator(ss);
1303         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1304                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1305
1306                 vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v;
1307         }
1308         ccgVertIterator_free(vi);
1309
1310         totedge = ccgSubSurf_getNumEdges(ss);
1311         edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
1312         ei = ccgSubSurf_getEdgeIterator(ss);
1313         for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
1314                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1315
1316                 edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e;
1317         }
1318
1319         totface = ccgSubSurf_getNumFaces(ss);
1320         faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
1321         fi = ccgSubSurf_getFaceIterator(ss);
1322         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1323                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1324
1325                 faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f))] = f;
1326         }
1327         ccgFaceIterator_free(fi);
1328
1329         i = 0;
1330         for (index=0; index<totface; index++) {
1331                 CCGFace *f = faceMap2[index];
1332                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1333
1334                 copy_v3_v3(cos[i++], ccgSubSurf_getFaceCenterData(f));
1335                 
1336                 for (S=0; S<numVerts; S++) {
1337                         for (x=1; x<gridSize-1; x++) {
1338                                 copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1339                         }
1340                 }
1341
1342                 for (S=0; S<numVerts; S++) {
1343                         for (y=1; y<gridSize-1; y++) {
1344                                 for (x=1; x<gridSize-1; x++) {
1345                                         copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1346                                 }
1347                         }
1348                 }
1349         }
1350
1351         for (index=0; index<totedge; index++) {
1352                 CCGEdge *e= edgeMap2[index];
1353                 int x;
1354
1355                 for (x=1; x<edgeSize-1; x++) {
1356                         copy_v3_v3(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
1357                 }
1358         }
1359
1360         for (index=0; index<totvert; index++) {
1361                 CCGVert *v = vertMap2[index];
1362                 copy_v3_v3(cos[i++], ccgSubSurf_getVertData(ss, v));
1363         }
1364
1365         MEM_freeN(vertMap2);
1366         MEM_freeN(edgeMap2);
1367         MEM_freeN(faceMap2);
1368 }
1369
1370 static void ccgDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
1371 {
1372         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1373         CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
1374
1375         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1376                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1377                 DMGridData *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
1378                 int index = ccgDM_getVertMapIndex(ccgdm->ss, v);
1379
1380                 if (index!=-1)
1381                         func(userData, index, vd->co, vd->no, NULL);
1382         }
1383
1384         ccgVertIterator_free(vi);
1385 }
1386
1387 static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
1388 {
1389         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1390         CCGSubSurf *ss = ccgdm->ss;
1391         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
1392         int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
1393
1394         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1395                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1396                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1397                 int index = ccgDM_getEdgeMapIndex(ss, e);
1398
1399                 if (index!=-1) {
1400                         for (i=0; i<edgeSize-1; i++)
1401                                 func(userData, index, edgeData[i].co, edgeData[i+1].co);
1402                 }
1403         }
1404
1405         ccgEdgeIterator_free(ei);
1406 }
1407
1408 static void ccgDM_drawVerts(DerivedMesh *dm)
1409 {
1410         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1411         CCGSubSurf *ss = ccgdm->ss;
1412         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1413         int gridSize = ccgSubSurf_getGridSize(ss);
1414         CCGVertIterator *vi;
1415         CCGEdgeIterator *ei;
1416         CCGFaceIterator *fi;
1417
1418         glBegin(GL_POINTS);
1419         vi = ccgSubSurf_getVertIterator(ss);
1420         for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
1421                 CCGVert *v = ccgVertIterator_getCurrent(vi);
1422                 glVertex3fv(ccgSubSurf_getVertData(ss, v));
1423         }
1424         ccgVertIterator_free(vi);
1425
1426         ei = ccgSubSurf_getEdgeIterator(ss);
1427         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
1428                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
1429                 int x;
1430
1431                 for (x=1; x<edgeSize-1; x++)
1432                         glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
1433         }
1434         ccgEdgeIterator_free(ei);
1435
1436         fi = ccgSubSurf_getFaceIterator(ss);
1437         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
1438                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
1439                 int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1440
1441                 glVertex3fv(ccgSubSurf_getFaceCenterData(f));
1442                 for (S=0; S<numVerts; S++)
1443                         for (x=1; x<gridSize-1; x++)
1444                                 glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
1445                 for (S=0; S<numVerts; S++)
1446                         for (y=1; y<gridSize-1; y++)
1447                                 for (x=1; x<gridSize-1; x++)
1448                                         glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
1449         }
1450         ccgFaceIterator_free(fi);
1451         glEnd();
1452 }
1453
1454 static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
1455 {
1456         if(ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
1457                 CCGFace **faces;
1458                 int totface;
1459
1460                 BLI_pbvh_get_grid_updates(ccgdm->pbvh, 1, (void***)&faces, &totface);
1461                 if(totface) {
1462                         ccgSubSurf_updateFromFaces(ccgdm->ss, 0, faces, totface);
1463                         ccgSubSurf_updateNormals(ccgdm->ss, faces, totface);
1464                         MEM_freeN(faces);
1465                 }
1466         }
1467 }
1468
1469 static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int UNUSED(drawAllEdges))
1470 {
1471         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1472         CCGSubSurf *ss = ccgdm->ss;
1473         int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1474         int totedge = ccgSubSurf_getNumEdges(ss);
1475         int gridSize = ccgSubSurf_getGridSize(ss);
1476         int useAging;
1477
1478         ccgdm_pbvh_update(ccgdm);
1479
1480         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
1481
1482         for (j=0; j< totedge; j++) {
1483                 CCGEdge *e = ccgdm->edgeMap[j].edge;
1484                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1485
1486                 if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e))
1487                         continue;
1488
1489                 if(ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW))
1490                         continue;
1491
1492                 if (useAging && !(G.f&G_BACKBUFSEL)) {
1493                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
1494                         glColor3ub(0, ageCol>0?ageCol:0, 0);
1495                 }
1496
1497                 glBegin(GL_LINE_STRIP);
1498                 for (i=0; i<edgeSize-1; i++) {
1499                         glVertex3fv(edgeData[i].co);
1500                         glVertex3fv(edgeData[i+1].co);
1501                 }
1502                 glEnd();
1503         }
1504
1505         if (useAging && !(G.f&G_BACKBUFSEL)) {
1506                 glColor3ub(0, 0, 0);
1507         }
1508
1509         if (ccgdm->drawInteriorEdges) {
1510                 int totface = ccgSubSurf_getNumFaces(ss);
1511
1512                 for(j = 0; j < totface; j++) {
1513                         CCGFace *f = ccgdm->faceMap[j].face;
1514                         int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1515
1516                         for (S=0; S<numVerts; S++) {
1517                                 DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1518
1519                                 glBegin(GL_LINE_STRIP);
1520                                 for (x=0; x<gridSize; x++)
1521                                         glVertex3fv(faceGridData[x].co);
1522                                 glEnd();
1523                                 for (y=1; y<gridSize-1; y++) {
1524                                         glBegin(GL_LINE_STRIP);
1525                                         for (x=0; x<gridSize; x++)
1526                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1527                                         glEnd();
1528                                 }
1529                                 for (x=1; x<gridSize-1; x++) {
1530                                         glBegin(GL_LINE_STRIP);
1531                                         for (y=0; y<gridSize; y++)
1532                                                 glVertex3fv(faceGridData[y*gridSize + x].co);
1533                                         glEnd();
1534                                 }
1535                         }
1536                 }
1537         }
1538 }
1539
1540 static void ccgDM_drawLooseEdges(DerivedMesh *dm)
1541 {
1542         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1543         CCGSubSurf *ss = ccgdm->ss;
1544         int totedge = ccgSubSurf_getNumEdges(ss);
1545         int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss);
1546
1547         for (j=0; j< totedge; j++) {
1548                 CCGEdge *e = ccgdm->edgeMap[j].edge;
1549                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
1550
1551                 if (!ccgSubSurf_getEdgeNumFaces(e)) {
1552                         glBegin(GL_LINE_STRIP);
1553                         for (i=0; i<edgeSize-1; i++) {
1554                                 glVertex3fv(edgeData[i].co);
1555                                 glVertex3fv(edgeData[i+1].co);
1556                         }
1557                         glEnd();
1558                 }
1559         }
1560 }
1561
1562 static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d)
1563 {
1564         float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
1565         float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
1566         float no[3];
1567
1568         no[0] = b_dY*a_cZ - b_dZ*a_cY;
1569         no[1] = b_dZ*a_cX - b_dX*a_cZ;
1570         no[2] = b_dX*a_cY - b_dY*a_cX;
1571
1572         /* don't normalize, GL_NORMALIZE is enabled */
1573         glNormal3fv(no);
1574 }
1575
1576         /* Only used by non-editmesh types */
1577 static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int fast, DMSetMaterial setMaterial)
1578 {
1579         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1580         CCGSubSurf *ss = ccgdm->ss;
1581         int gridSize = ccgSubSurf_getGridSize(ss);
1582         DMFlagMat *faceFlags = ccgdm->faceFlags;
1583         int step = (fast)? gridSize-1: 1;
1584         int i, totface = ccgSubSurf_getNumFaces(ss);
1585         int drawcurrent = 0, matnr = -1, shademodel = -1;
1586
1587         ccgdm_pbvh_update(ccgdm);
1588
1589         if(ccgdm->pbvh && ccgdm->multires.mmd && !fast) {
1590                 if(dm->numTessFaceData) {
1591                         BLI_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, setMaterial);
1592                         glShadeModel(GL_FLAT);
1593                 }
1594
1595                 return;
1596         }
1597
1598         for(i = 0; i < totface; i++) {
1599                 CCGFace *f = ccgdm->faceMap[i].face;
1600                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1601                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
1602                 int new_matnr, new_shademodel;
1603
1604                 if(faceFlags) {
1605                         new_shademodel = (faceFlags[index].flag & ME_SMOOTH)? GL_SMOOTH: GL_FLAT;
1606                         new_matnr= faceFlags[index].mat_nr;
1607                 }
1608                 else {
1609                         new_shademodel = GL_SMOOTH;
1610                         new_matnr= 0;
1611                 }
1612                 
1613                 if(shademodel != new_shademodel || matnr != new_matnr) {
1614                         matnr= new_matnr;
1615                         shademodel= new_shademodel;
1616
1617                         drawcurrent= setMaterial(matnr+1, NULL);
1618
1619                         glShadeModel(shademodel);
1620                 }
1621
1622                 if(!drawcurrent)
1623                         continue;
1624
1625                 for (S=0; S<numVerts; S++) {
1626                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1627
1628                         if (shademodel == GL_SMOOTH) {
1629                                 for (y=0; y<gridSize-1; y+=step) {
1630                                         glBegin(GL_QUAD_STRIP);
1631                                         for (x=0; x<gridSize; x+=step) {
1632                                                 DMGridData *a = &faceGridData[(y+0)*gridSize + x];
1633                                                 DMGridData *b = &faceGridData[(y+step)*gridSize + x];
1634
1635                                                 glNormal3fv(a->no);
1636                                                 glVertex3fv(a->co);
1637                                                 glNormal3fv(b->no);
1638                                                 glVertex3fv(b->co);
1639                                         }
1640                                         glEnd();
1641                                 }
1642                         } else {
1643                                 glBegin(GL_QUADS);
1644                                 for (y=0; y<gridSize-1; y+=step) {
1645                                         for (x=0; x<gridSize-1; x+=step) {
1646                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
1647                                                 float *b = faceGridData[(y+0)*gridSize + x + step].co;
1648                                                 float *c = faceGridData[(y+step)*gridSize + x + step].co;
1649                                                 float *d = faceGridData[(y+step)*gridSize + x].co;
1650
1651                                                 ccgDM_glNormalFast(a, b, c, d);
1652
1653                                                 glVertex3fv(d);
1654                                                 glVertex3fv(c);
1655                                                 glVertex3fv(b);
1656                                                 glVertex3fv(a);
1657                                         }
1658                                 }
1659                                 glEnd();
1660                         }
1661                 }
1662         }
1663 }
1664
1665         /* Only used by non-editmesh types */
1666 static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
1667                         DMSetMaterial setMaterial,
1668                         DMSetDrawOptions setDrawOptions,
1669                         void *userData)
1670 {
1671         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1672         CCGSubSurf *ss = ccgdm->ss;
1673         GPUVertexAttribs gattribs;
1674         DMVertexAttribs attribs= {{{NULL}}};
1675         /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1676         int gridSize = ccgSubSurf_getGridSize(ss);
1677         int gridFaces = gridSize - 1;
1678         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1679         DMFlagMat *faceFlags = ccgdm->faceFlags;
1680         int a, b, i, doDraw, numVerts, matnr, new_matnr, totface;
1681
1682         ccgdm_pbvh_update(ccgdm);
1683
1684         doDraw = 0;
1685         matnr = -1;
1686
1687 #define PASSATTRIB(dx, dy, vert) {                                                                                              \
1688         if(attribs.totorco) {                                                                                                           \
1689                 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize);                 \
1690                 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
1691         }                                                                                                                                                       \
1692         for(b = 0; b < attribs.tottface; b++) {                                                                         \
1693                 MTFace *tf = &attribs.tface[b].array[a];                                                                \
1694                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);                   \
1695         }                                                                                                                                                       \
1696         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
1697                 MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
1698                 GLubyte col[4];                                                                                                                 \
1699                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
1700                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
1701         }                                                                                                                                                       \
1702         if(attribs.tottang) {                                                                                                           \
1703                 float *tang = attribs.tang.array[a*4 + vert];                                                   \
1704                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
1705         }                                                                                                                                                       \
1706 }
1707
1708         totface = ccgSubSurf_getNumFaces(ss);
1709         for(a = 0, i = 0; i < totface; i++) {
1710                 CCGFace *f = ccgdm->faceMap[i].face;
1711                 int S, x, y, drawSmooth;
1712                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
1713                 int origIndex = ccgDM_getFaceMapIndex(ss, f);
1714                 
1715                 numVerts = ccgSubSurf_getFaceNumVerts(f);
1716
1717                 if(faceFlags) {
1718                         drawSmooth = (faceFlags[index].flag & ME_SMOOTH);
1719                         new_matnr= faceFlags[index].mat_nr + 1;
1720                 }
1721                 else {
1722                         drawSmooth = 1;
1723                         new_matnr= 1;
1724                 }
1725
1726                 if(new_matnr != matnr) {
1727                         doDraw = setMaterial(matnr = new_matnr, &gattribs);
1728                         if(doDraw)
1729                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1730                 }
1731
1732                 if(!doDraw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) &&
1733                                            (setDrawOptions(userData, origIndex) == DM_DRAW_OPTION_SKIP))) {
1734                         a += gridFaces*gridFaces*numVerts;
1735                         continue;
1736                 }
1737
1738                 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1739                 for (S=0; S<numVerts; S++) {
1740                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1741                         DMGridData *vda, *vdb;
1742
1743                         if (drawSmooth) {
1744                                 for (y=0; y<gridFaces; y++) {
1745                                         glBegin(GL_QUAD_STRIP);
1746                                         for (x=0; x<gridFaces; x++) {
1747                                                 vda = &faceGridData[(y+0)*gridSize + x];
1748                                                 vdb = &faceGridData[(y+1)*gridSize + x];
1749                                                 
1750                                                 PASSATTRIB(0, 0, 0);
1751                                                 glNormal3fv(vda->no);
1752                                                 glVertex3fv(vda->co);
1753
1754                                                 PASSATTRIB(0, 1, 1);
1755                                                 glNormal3fv(vdb->no);
1756                                                 glVertex3fv(vdb->co);
1757
1758                                                 if(x != gridFaces-1)
1759                                                         a++;
1760                                         }
1761
1762                                         vda = &faceGridData[(y+0)*gridSize + x];
1763                                         vdb = &faceGridData[(y+1)*gridSize + x];
1764
1765                                         PASSATTRIB(0, 0, 3);
1766                                         glNormal3fv(vda->no);
1767                                         glVertex3fv(vda->co);
1768
1769                                         PASSATTRIB(0, 1, 2);
1770                                         glNormal3fv(vdb->no);
1771                                         glVertex3fv(vdb->co);
1772
1773                                         glEnd();
1774
1775                                         a++;
1776                                 }
1777                         } else {
1778                                 glBegin(GL_QUADS);
1779                                 for (y=0; y<gridFaces; y++) {
1780                                         for (x=0; x<gridFaces; x++) {
1781                                                 float *aco = faceGridData[(y+0)*gridSize + x].co;
1782                                                 float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
1783                                                 float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
1784                                                 float *dco = faceGridData[(y+1)*gridSize + x].co;
1785
1786                                                 ccgDM_glNormalFast(aco, bco, cco, dco);
1787
1788                                                 PASSATTRIB(0, 1, 1);
1789                                                 glVertex3fv(dco);
1790                                                 PASSATTRIB(1, 1, 2);
1791                                                 glVertex3fv(cco);
1792                                                 PASSATTRIB(1, 0, 3);
1793                                                 glVertex3fv(bco);
1794                                                 PASSATTRIB(0, 0, 0);
1795                                                 glVertex3fv(aco);
1796                                                 
1797                                                 a++;
1798                                         }
1799                                 }
1800                                 glEnd();
1801                         }
1802                 }
1803         }
1804
1805 #undef PASSATTRIB
1806 }
1807
1808 static void ccgDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial)
1809 {
1810         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1811 }
1812
1813         /* Only used by non-editmesh types */
1814 static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *userData, int, void *attribs), int (*setFace)(void *userData, int index), void *userData)
1815 {
1816         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1817         CCGSubSurf *ss = ccgdm->ss;
1818         GPUVertexAttribs gattribs;
1819         DMVertexAttribs attribs= {{{NULL}}};
1820         int gridSize = ccgSubSurf_getGridSize(ss);
1821         int gridFaces = gridSize - 1;
1822         int edgeSize = ccgSubSurf_getEdgeSize(ss);
1823         DMFlagMat *faceFlags = ccgdm->faceFlags;
1824         int a, b, i, numVerts, matnr, new_matnr, totface;
1825
1826         ccgdm_pbvh_update(ccgdm);
1827
1828         matnr = -1;
1829
1830 #define PASSATTRIB(dx, dy, vert) {                                                                                              \
1831         if(attribs.totorco) {                                                                                                           \
1832                 index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize);                 \
1833                 if(attribs.orco.glTexco)                                                                                                \
1834                         glTexCoord3fv(attribs.orco.array[index]);                                                       \
1835                 else                                                                                                                                    \
1836                         glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
1837         }                                                                                                                                                       \
1838         for(b = 0; b < attribs.tottface; b++) {                                                                         \
1839                 MTFace *tf = &attribs.tface[b].array[a];                                                                \
1840                 if(attribs.tface[b].glTexco)                                                                                    \
1841                         glTexCoord2fv(tf->uv[vert]);                                                                            \
1842                 else                                                                                                                                    \
1843                         glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);           \
1844         }                                                                                                                                                       \
1845         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
1846                 MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
1847                 GLubyte col[4];                                                                                                                 \
1848                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
1849                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
1850         }                                                                                                                                                       \
1851         if(attribs.tottang) {                                                                                                           \
1852                 float *tang = attribs.tang.array[a*4 + vert];                                                   \
1853                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
1854         }                                                                                                                                                       \
1855 }
1856
1857         totface = ccgSubSurf_getNumFaces(ss);
1858         for(a = 0, i = 0; i < totface; i++) {
1859                 CCGFace *f = ccgdm->faceMap[i].face;
1860                 int S, x, y, drawSmooth;
1861                 int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
1862                 int origIndex = ccgDM_getFaceMapIndex(ss, f);
1863                 
1864                 numVerts = ccgSubSurf_getFaceNumVerts(f);
1865
1866                 /* get flags */
1867                 if(faceFlags) {
1868                         drawSmooth = (faceFlags[index].flag & ME_SMOOTH);
1869                         new_matnr= faceFlags[index].mat_nr + 1;
1870                 }
1871                 else {
1872                         drawSmooth = 1;
1873                         new_matnr= 1;
1874                 }
1875
1876                 /* material */
1877                 if(new_matnr != matnr) {
1878                         setMaterial(userData, matnr = new_matnr, &gattribs);
1879                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1880                 }
1881
1882                 /* face hiding */
1883                 if((setFace && (origIndex != ORIGINDEX_NONE) && !setFace(userData, origIndex))) {
1884                         a += gridFaces*gridFaces*numVerts;
1885                         continue;
1886                 }
1887
1888                 /* draw face*/
1889                 glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
1890                 for (S=0; S<numVerts; S++) {
1891                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1892                         DMGridData *vda, *vdb;
1893
1894                         if (drawSmooth) {
1895                                 for (y=0; y<gridFaces; y++) {
1896                                         glBegin(GL_QUAD_STRIP);
1897                                         for (x=0; x<gridFaces; x++) {
1898                                                 vda = &faceGridData[(y+0)*gridSize + x];
1899                                                 vdb = &faceGridData[(y+1)*gridSize + x];
1900                                                 
1901                                                 PASSATTRIB(0, 0, 0);
1902                                                 glNormal3fv(vda->no);
1903                                                 glVertex3fv(vda->co);
1904
1905                                                 PASSATTRIB(0, 1, 1);
1906                                                 glNormal3fv(vdb->no);
1907                                                 glVertex3fv(vdb->co);
1908
1909                                                 if(x != gridFaces-1)
1910                                                         a++;
1911                                         }
1912
1913                                         vda = &faceGridData[(y+0)*gridSize + x];
1914                                         vdb = &faceGridData[(y+1)*gridSize + x];
1915
1916                                         PASSATTRIB(0, 0, 3);
1917                                         glNormal3fv(vda->no);
1918                                         glVertex3fv(vda->co);
1919
1920                                         PASSATTRIB(0, 1, 2);
1921                                         glNormal3fv(vdb->no);
1922                                         glVertex3fv(vdb->co);
1923
1924                                         glEnd();
1925
1926                                         a++;
1927                                 }
1928                         } else {
1929                                 glBegin(GL_QUADS);
1930                                 for (y=0; y<gridFaces; y++) {
1931                                         for (x=0; x<gridFaces; x++) {
1932                                                 float *aco = faceGridData[(y+0)*gridSize + x].co;
1933                                                 float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
1934                                                 float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
1935                                                 float *dco = faceGridData[(y+1)*gridSize + x].co;
1936
1937                                                 ccgDM_glNormalFast(aco, bco, cco, dco);
1938
1939                                                 PASSATTRIB(0, 1, 1);
1940                                                 glVertex3fv(dco);
1941                                                 PASSATTRIB(1, 1, 2);
1942                                                 glVertex3fv(cco);
1943                                                 PASSATTRIB(1, 0, 3);
1944                                                 glVertex3fv(bco);
1945                                                 PASSATTRIB(0, 0, 0);
1946                                                 glVertex3fv(aco);
1947                                                 
1948                                                 a++;
1949                                         }
1950                                 }
1951                                 glEnd();
1952                         }
1953                 }
1954         }
1955
1956 #undef PASSATTRIB
1957 }
1958
1959 static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
1960         DMSetDrawOptionsTex drawParams,
1961         DMSetDrawOptions drawParamsMapped,
1962         DMCompareDrawOptions compareDrawOptions,
1963         void *userData) 
1964 {
1965         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
1966         CCGSubSurf *ss = ccgdm->ss;
1967         MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
1968         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
1969         DMFlagMat *faceFlags = ccgdm->faceFlags;
1970         DMDrawOption draw_option;
1971         int i, totface, gridSize = ccgSubSurf_getGridSize(ss);
1972         int gridFaces = gridSize - 1;
1973
1974         (void) compareDrawOptions;
1975
1976         ccgdm_pbvh_update(ccgdm);
1977
1978         if(!mcol)
1979                 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
1980
1981         if(!mcol)
1982                 mcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL);
1983
1984         totface = ccgSubSurf_getNumFaces(ss);
1985         for(i = 0; i < totface; i++) {
1986                 CCGFace *f = ccgdm->faceMap[i].face;
1987                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
1988                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
1989                 int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
1990                 unsigned char *cp= NULL;
1991                 int mat_nr;
1992
1993                 if(faceFlags) {
1994                         drawSmooth = (faceFlags[origIndex].flag & ME_SMOOTH);
1995                         mat_nr= faceFlags[origIndex].mat_nr;
1996                 }
1997                 else {
1998                         drawSmooth = 1;
1999                         mat_nr= 0;
2000                 }
2001
2002                 if(drawParams)
2003                         draw_option = drawParams(tf, (mcol != NULL), mat_nr);
2004                 else if (index != ORIGINDEX_NONE)
2005                         draw_option= (drawParamsMapped)? drawParamsMapped(userData, index): DM_DRAW_OPTION_NORMAL;
2006                 else
2007                         draw_option= GPU_enable_material(mat_nr, NULL) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP;
2008
2009
2010                 if (draw_option == DM_DRAW_OPTION_SKIP) {
2011                         if(tf) tf += gridFaces*gridFaces*numVerts;
2012                         if(mcol) mcol += gridFaces*gridFaces*numVerts*4;
2013                         continue;
2014                 }
2015
2016                 /* flag 1 == use vertex colors */
2017                 if(mcol) {
2018                         if(draw_option != DM_DRAW_OPTION_NO_MCOL)
2019                                 cp= (unsigned char*)mcol;
2020                         mcol += gridFaces*gridFaces*numVerts*4;
2021                 }
2022
2023                 for (S=0; S<numVerts; S++) {
2024                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2025                         DMGridData *a, *b;
2026
2027                         if (drawSmooth) {
2028                                 glShadeModel(GL_SMOOTH);
2029                                 for (y=0; y<gridFaces; y++) {
2030                                         glBegin(GL_QUAD_STRIP);
2031                                         for (x=0; x<gridFaces; x++) {
2032                                                 a = &faceGridData[(y+0)*gridSize + x];
2033                                                 b = &faceGridData[(y+1)*gridSize + x];
2034
2035                                                 if(tf) glTexCoord2fv(tf->uv[0]);
2036                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2037                                                 glNormal3fv(a->no);
2038                                                 glVertex3fv(a->co);
2039
2040                                                 if(tf) glTexCoord2fv(tf->uv[1]);
2041                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2042                                                 glNormal3fv(b->no);
2043                                                 glVertex3fv(b->co);
2044                                                 
2045                                                 if(x != gridFaces-1) {
2046                                                         if(tf) tf++;
2047                                                         if(cp) cp += 16;
2048                                                 }
2049                                         }
2050
2051                                         a = &faceGridData[(y+0)*gridSize + x];
2052                                         b = &faceGridData[(y+1)*gridSize + x];
2053
2054                                         if(tf) glTexCoord2fv(tf->uv[3]);
2055                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2056                                         glNormal3fv(a->no);
2057                                         glVertex3fv(a->co);
2058
2059                                         if(tf) glTexCoord2fv(tf->uv[2]);
2060                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2061                                         glNormal3fv(b->no);
2062                                         glVertex3fv(b->co);
2063
2064                                         if(tf) tf++;
2065                                         if(cp) cp += 16;
2066
2067                                         glEnd();
2068                                 }
2069                         } else {
2070                                 glShadeModel(GL_FLAT);
2071                                 glBegin(GL_QUADS);
2072                                 for (y=0; y<gridFaces; y++) {
2073                                         for (x=0; x<gridFaces; x++) {
2074                                                 float *a_co = faceGridData[(y+0)*gridSize + x].co;
2075                                                 float *b_co = faceGridData[(y+0)*gridSize + x + 1].co;
2076                                                 float *c_co = faceGridData[(y+1)*gridSize + x + 1].co;
2077                                                 float *d_co = faceGridData[(y+1)*gridSize + x].co;
2078
2079                                                 ccgDM_glNormalFast(a_co, b_co, c_co, d_co);
2080
2081                                                 if(tf) glTexCoord2fv(tf->uv[1]);
2082                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2083                                                 glVertex3fv(d_co);
2084
2085                                                 if(tf) glTexCoord2fv(tf->uv[2]);
2086                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2087                                                 glVertex3fv(c_co);
2088
2089                                                 if(tf) glTexCoord2fv(tf->uv[3]);
2090                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2091                                                 glVertex3fv(b_co);
2092
2093                                                 if(tf) glTexCoord2fv(tf->uv[0]);
2094                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2095                                                 glVertex3fv(a_co);
2096
2097                                                 if(tf) tf++;
2098                                                 if(cp) cp += 16;
2099                                         }
2100                                 }
2101                                 glEnd();
2102                         }
2103                 }
2104         }
2105 }
2106
2107 static void ccgDM_drawFacesTex(DerivedMesh *dm,
2108                            DMSetDrawOptionsTex setDrawOptions,
2109                            DMCompareDrawOptions compareDrawOptions,
2110                            void *userData)
2111 {
2112         ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
2113 }
2114
2115 static void ccgDM_drawMappedFacesTex(DerivedMesh *dm,
2116     DMSetDrawOptions setDrawOptions,
2117     DMCompareDrawOptions compareDrawOptions,
2118     void *userData)
2119 {
2120         ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
2121 }
2122
2123 static void ccgDM_drawUVEdges(DerivedMesh *dm)
2124 {
2125
2126         MFace *mf = dm->getTessFaceArray(dm);
2127         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
2128         int i;
2129         
2130         if (tf) {
2131                 glBegin(GL_LINES);
2132                 for(i = 0; i < dm->numTessFaceData; i++, mf++, tf++) {
2133                         if(!(mf->flag&ME_HIDE)) {
2134                                 glVertex2fv(tf->uv[0]);
2135                                 glVertex2fv(tf->uv[1]);
2136         
2137                                 glVertex2fv(tf->uv[1]);
2138                                 glVertex2fv(tf->uv[2]);
2139         
2140                                 if(!mf->v4) {
2141                                         glVertex2fv(tf->uv[2]);
2142                                         glVertex2fv(tf->uv[0]);
2143                                 } else {
2144                                         glVertex2fv(tf->uv[2]);
2145                                         glVertex2fv(tf->uv[3]);
2146         
2147                                         glVertex2fv(tf->uv[3]);
2148                                         glVertex2fv(tf->uv[0]);
2149                                 }
2150                         }
2151                 }
2152                 glEnd();
2153         }
2154 }
2155
2156 static void ccgDM_drawMappedFaces(DerivedMesh *dm,
2157                         DMSetDrawOptions setDrawOptions,
2158                         DMSetMaterial setMaterial,
2159                         DMCompareDrawOptions compareDrawOptions,
2160                         void *userData, DMDrawFlag flag)
2161 {
2162         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2163         CCGSubSurf *ss = ccgdm->ss;
2164         MCol *mcol= NULL;
2165         int i, gridSize = ccgSubSurf_getGridSize(ss);
2166         DMFlagMat *faceFlags = ccgdm->faceFlags;
2167         int useColors = flag & DM_DRAW_USE_COLORS;
2168         int gridFaces = gridSize - 1, totface;
2169
2170         /* currently unused -- each original face is handled separately */
2171         (void)compareDrawOptions;
2172
2173         if(useColors) {
2174                 mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
2175                 if(!mcol)
2176                         mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
2177         }
2178
2179         totface = ccgSubSurf_getNumFaces(ss);
2180         for(i = 0; i < totface; i++) {
2181                 CCGFace *f = ccgdm->faceMap[i].face;
2182                 int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
2183                 int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
2184                 int origIndex;
2185                 unsigned char *cp= NULL;
2186
2187                 origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
2188
2189                 if(flag & DM_DRAW_ALWAYS_SMOOTH) drawSmooth = 1;
2190                 else if(faceFlags) drawSmooth = (faceFlags[origIndex].flag & ME_SMOOTH);
2191                 else drawSmooth = 1;
2192
2193                 if(mcol) {
2194                         cp= (unsigned char*)mcol;
2195                         mcol += gridFaces*gridFaces*numVerts*4;
2196                 }
2197
2198                 {
2199                         DMDrawOption draw_option= DM_DRAW_OPTION_NORMAL;
2200
2201                         if(index == ORIGINDEX_NONE)
2202                                 draw_option= setMaterial(faceFlags ? faceFlags[origIndex].mat_nr + 1: 1, NULL); /* XXX, no faceFlags no material */
2203                         else if (setDrawOptions)
2204                                 draw_option= setDrawOptions(userData, index);
2205
2206                         if (draw_option != DM_DRAW_OPTION_SKIP) {
2207                                 if (draw_option == DM_DRAW_OPTION_STIPPLE) {
2208                                           glEnable(GL_POLYGON_STIPPLE);
2209                                           glPolygonStipple(stipple_quarttone);
2210                                 }
2211
2212                                 /* no need to set shading mode to flat because
2213                                  *  normals are already used to change shading */
2214                                 glShadeModel(GL_SMOOTH);
2215                                 
2216                                 for (S=0; S<numVerts; S++) {
2217                                         DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2218                                         if (drawSmooth) {
2219                                                 for (y=0; y<gridFaces; y++) {
2220                                                         DMGridData *a, *b;
2221                                                         glBegin(GL_QUAD_STRIP);
2222                                                         for (x=0; x<gridFaces; x++) {
2223                                                                 a = &faceGridData[(y+0)*gridSize + x];
2224                                                                 b = &faceGridData[(y+1)*gridSize + x];
2225         
2226                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2227                                                                 glNormal3fv(a->no);
2228                                                                 glVertex3fv(a->co);
2229                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2230                                                                 glNormal3fv(b->no);
2231                                                                 glVertex3fv(b->co);
2232
2233                                                                 if(x != gridFaces-1) {
2234                                                                         if(cp) cp += 16;
2235                                                                 }
2236                                                         }
2237
2238                                                         a = &faceGridData[(y+0)*gridSize + x];
2239                                                         b = &faceGridData[(y+1)*gridSize + x];
2240
2241                                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2242                                                         glNormal3fv(a->no);
2243                                                         glVertex3fv(a->co);
2244                                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2245                                                         glNormal3fv(b->no);
2246                                                         glVertex3fv(b->co);
2247
2248                                                         if(cp) cp += 16;
2249
2250                                                         glEnd();
2251                                                 }
2252                                         } else {
2253                                                 glBegin(GL_QUADS);
2254                                                 for (y=0; y<gridFaces; y++) {
2255                                                         for (x=0; x<gridFaces; x++) {
2256                                                                 float *a = faceGridData[(y+0)*gridSize + x].co;
2257                                                                 float *b = faceGridData[(y+0)*gridSize + x + 1].co;
2258                                                                 float *c = faceGridData[(y+1)*gridSize + x + 1].co;
2259                                                                 float *d = faceGridData[(y+1)*gridSize + x].co;
2260
2261                                                                 ccgDM_glNormalFast(a, b, c, d);
2262         
2263                                                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
2264                                                                 glVertex3fv(d);
2265                                                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
2266                                                                 glVertex3fv(c);
2267                                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
2268                                                                 glVertex3fv(b);
2269                                                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
2270                                                                 glVertex3fv(a);
2271
2272                                                                 if(cp) cp += 16;
2273                                                         }
2274                                                 }
2275                                                 glEnd();
2276                                         }
2277                                 }
2278                                 if (draw_option == DM_DRAW_OPTION_STIPPLE)
2279                                         glDisable(GL_POLYGON_STIPPLE);
2280                         }
2281                 }
2282         }
2283 }
2284
2285 static void ccgDM_drawMappedEdges(DerivedMesh *dm,
2286                                                                   DMSetDrawOptions setDrawOptions,
2287                                                                   void *userData)
2288 {
2289         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2290         CCGSubSurf *ss = ccgdm->ss;
2291         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2292         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2293
2294         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2295
2296         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2297                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2298                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2299                 int index = ccgDM_getEdgeMapIndex(ss, e);
2300
2301                 glBegin(GL_LINE_STRIP);
2302                 if (index!=-1 && (!setDrawOptions || (setDrawOptions(userData, index) != DM_DRAW_OPTION_SKIP))) {
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                         for (i=0; i<edgeSize-1; i++) {
2309                                 glVertex3fv(edgeData[i].co);
2310                                 glVertex3fv(edgeData[i+1].co);
2311                         }
2312                 }
2313                 glEnd();
2314         }
2315
2316         ccgEdgeIterator_free(ei);
2317 }
2318
2319 static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm,
2320                                                                                 DMSetDrawOptions setDrawOptions,
2321                                                                                 DMSetDrawInterpOptions setDrawInterpOptions,
2322                                                                                 void *userData)
2323 {
2324         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2325         CCGSubSurf *ss = ccgdm->ss;
2326         CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
2327         int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
2328
2329         ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
2330
2331         for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
2332                 CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
2333                 DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
2334                 int index = ccgDM_getEdgeMapIndex(ss, e);
2335
2336                 glBegin(GL_LINE_STRIP);
2337                 if (index!=-1 && (!setDrawOptions || (setDrawOptions(userData, index) != DM_DRAW_OPTION_SKIP))) {
2338                         for (i=0; i<edgeSize; i++) {
2339                                 setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
2340
2341                                 if (useAging && !(G.f&G_BACKBUFSEL)) {
2342                                         int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
2343                                         glColor3ub(0, ageCol>0?ageCol:0, 0);
2344                                 }
2345
2346                                 glVertex3fv(edgeData[i].co);
2347                         }
2348                 }
2349                 glEnd();
2350         }
2351
2352         ccgEdgeIterator_free(ei);
2353 }
2354
2355 static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
2356 {
2357         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2358         CCGSubSurf *ss = ccgdm->ss;
2359         CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
2360
2361         for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
2362                 CCGFace *f = ccgFaceIterator_getCurrent(fi);
2363                 int index = ccgDM_getFaceMapIndex(ss, f);
2364
2365                 if (index!=-1) {
2366                                 /* Face center data normal isn't updated atm. */
2367                         DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
2368
2369                         func(userData, index, vd->co, vd->no);
2370                 }
2371         }
2372
2373         ccgFaceIterator_free(fi);
2374 }
2375
2376 static void ccgDM_release(DerivedMesh *dm)
2377 {
2378         CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
2379
2380         if (DM_release(dm)) {
2381                 /* Before freeing, need to update the displacement map */
2382                 if(ccgdm->multires.modified_flags) {
2383                         /* Check that mmd still exists */
2384                         if(!ccgdm->multires.local_mmd &&
2385                            BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0)
2386                                 ccgdm->multires.mmd = NULL;
2387                         
2388                         if(ccgdm->multires.mmd) {
2389                                 if(ccgdm->multires.modified_flags & MULTIRES_COORDS_MODIFIED)
2390                                         multires_modifier_update_mdisps(dm);
2391                                 if(ccgdm->multires.modified_flags & MULTIRES_HIDDEN_MODIFIED)
2392                                         multires_modifier_update_hidden(dm);
2393                         }
2394                 }
2395
2396                 if (ccgdm->ehash)
2397                         BLI_edgehash_free(ccgdm->ehash, NULL);
2398
2399                 if(ccgdm->reverseFaceMap) MEM_freeN(ccgdm->reverseFaceMap);
2400                 if(ccgdm->gridFaces) MEM_freeN(ccgdm->gridFaces);
2401                 if(ccgdm->gridData) MEM_freeN(ccgdm->gridData);
2402                 if(ccgdm->gridAdjacency) MEM_freeN(ccgdm->gridAdjacency);
2403                 if(ccgdm->gridOffset) MEM_freeN(ccgdm->gridOffset);
2404                 if(ccgdm->gridFlagMats) MEM_freeN(ccgdm->gridFlagMats);
2405                 if(ccgdm->gridHidden) {
2406                         int i, numGrids = dm->getNumGrids(dm);
2407                         for(i = 0; i < numGrids; i++) {
2408                                 if(ccgdm->gridHidden[i])
2409                                         MEM_freeN(ccgdm->gridHidden[i]);
2410                         }
2411                         MEM_freeN(ccgdm->gridHidden);
2412                 }
2413                 if(ccgdm->freeSS) ccgSubSurf_free(ccgdm->ss);
2414                 if(ccgdm->pmap) MEM_freeN(ccgdm->pmap);
2415                 if(ccgdm->pmap_mem) MEM_freeN(ccgdm->pmap_mem);
2416                 MEM_freeN(ccgdm->edgeFlags);
2417                 MEM_freeN(ccgdm->faceFlags);
2418                 MEM_freeN(ccgdm->vertMap);
2419                 MEM_freeN(ccgdm->edgeMap);
2420                 MEM_freeN(ccgdm->faceMap);
2421                 MEM_freeN(ccgdm);
2422         }
2423 }
2424
2425 static void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata, 
2426                                  CustomData *pdata, int loopstart, int findex,  int polyindex,
2427                                  const int numTex, const int numCol, const int hasWCol, const int hasOrigSpace)
2428 {
2429         MTFace *texface;
2430         MTexPoly *texpoly;
2431         MCol *mcol;
2432         MLoopCol *mloopcol;
2433         MLoopUV *mloopuv;
2434         int i, j;
2435
2436         for(i=0; i < numTex; i++) {
2437                 texface = CustomData_get_n(fdata, CD_MTFACE, findex, i);
2438                 texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i);
2439                 
2440                 ME_MTEXFACE_CPY(texface, texpoly);
2441
2442                 mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i);
2443                 for (j=0; j<4; j++, mloopuv++) {
2444                         copy_v2_v2(texface->uv[j], mloopuv->uv);
2445                 }
2446         }
2447
2448         for(i=0; i < numCol; i++) {
2449                 mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i);
2450                 mcol = CustomData_get_n(fdata, CD_MCOL, findex, i);
2451
2452                 for (j=0; j<4; j++, mloopcol++) {
2453                         mcol[j].r = mloopcol->r;
2454                         mcol[j].g = mloopcol->g;
2455                         mcol[j].b = mloopcol->b;
2456                         mcol[j].a = mloopcol->a;
2457                 }
2458         }
2459         
2460         if (hasWCol) {
2461                 mloopcol = CustomData_get(ldata, loopstart, CD_WEIGHT_MLOOPCOL);
2462                 mcol = CustomData_get(fdata, findex, CD_WEIGHT_MCOL);
2463
2464                 for (j=0; j<4; j++, mloopcol++) {
2465                         mcol[j].r = mloopcol->r;
2466                         mcol[j].g = mloopcol->g;
2467                         mcol[j].b = mloopcol->b;
2468                         mcol[j].a = mloopcol->a;
2469                 }
2470         }
2471
2472         if (hasOrigSpace) {
2473                 OrigSpaceFace *of = CustomData_get(fdata, findex, CD_ORIGSPACE);
2474                 OrigSpaceLoop *lof;
2475
2476                 lof = CustomData_get(ldata, loopstart, CD_ORIGSPACE_MLOOP);
2477                 for (j=0; j<4; j++, lof++) {
2478                         copy_v2_v2(of->uv[j], lof->uv);
2479                 }
2480         }
2481 }
2482
2483 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
2484 {
2485         if(type == CD_ORIGINDEX) {
2486                 /* create origindex on demand to save memory */
2487                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2488                 CCGSubSurf *ss= ccgdm->ss;
2489                 int *origindex;
2490                 int a, index, totnone, totorig;
2491
2492                 /* Avoid re-creation if the layer exists already */
2493                 origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
2494                 if (origindex) {
2495                         return origindex;
2496                 }
2497
2498                 DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2499                 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
2500
2501                 totorig = ccgSubSurf_getNumVerts(ss);
2502                 totnone= dm->numVertData - totorig;
2503
2504                 /* original vertices are at the end */
2505                 for(a=0; a<totnone; a++)
2506                         origindex[a]= ORIGINDEX_NONE;
2507
2508                 for(index=0; index<totorig; index++, a++) {
2509                         CCGVert *v = ccgdm->vertMap[index].vert;
2510                         origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
2511                 }
2512
2513                 return origindex;
2514         }
2515
2516         return DM_get_vert_data_layer(dm, type);
2517 }
2518
2519 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
2520 {
2521         if(type == CD_ORIGINDEX) {
2522                 /* create origindex on demand to save memory */
2523                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2524                 CCGSubSurf *ss= ccgdm->ss;
2525                 int *origindex;
2526                 int a, i, index, totnone, totorig, totedge;
2527                 int edgeSize= ccgSubSurf_getEdgeSize(ss);
2528
2529                 /* Avoid re-creation if the layer exists already */
2530                 origindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2531                 if (origindex) {
2532                         return origindex;
2533                 }
2534
2535                 DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2536                 origindex= DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2537
2538                 totedge= ccgSubSurf_getNumEdges(ss);
2539                 totorig= totedge*(edgeSize - 1);
2540                 totnone= dm->numEdgeData - totorig;
2541
2542                 /* original edges are at the end */
2543                 for(a=0; a<totnone; a++)
2544                         origindex[a]= ORIGINDEX_NONE;
2545
2546                 for(index=0; index<totedge; index++) {
2547                         CCGEdge *e= ccgdm->edgeMap[index].edge;
2548                         int mapIndex= ccgDM_getEdgeMapIndex(ss, e);
2549
2550                         for(i = 0; i < edgeSize - 1; i++, a++)
2551                                 origindex[a]= mapIndex;
2552                 }
2553
2554                 return origindex;
2555         }
2556
2557         return DM_get_edge_data_layer(dm, type);
2558 }
2559
2560 static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type)
2561 {
2562         if(type == CD_ORIGINDEX) {
2563                 /* create origindex on demand to save memory */
2564                 CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2565                 CCGSubSurf *ss= ccgdm->ss;
2566                 int *origindex;
2567                 int a, i, index, totface;
2568                 int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
2569
2570                 /* Avoid re-creation if the layer exists already */
2571                 origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
2572                 if (origindex) {
2573                         return origindex;
2574                 }
2575
2576                 DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
2577                 origindex= DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
2578
2579                 totface= ccgSubSurf_getNumFaces(ss);
2580
2581                 for(a=0, index=0; index<totface; index++) {
2582                         CCGFace *f = ccgdm->faceMap[index].face;
2583                         int numVerts = ccgSubSurf_getFaceNumVerts(f);
2584                         int mapIndex = ccgDM_getFaceMapIndex(ss, f);
2585
2586                         for(i=0; i<gridFaces*gridFaces*numVerts; i++, a++)
2587                                 origindex[a]= mapIndex;
2588                 }
2589
2590                 return origindex;
2591         }
2592
2593         return DM_get_tessface_data_layer(dm, type);
2594 }
2595
2596 static void *ccgDM_get_vert_data(DerivedMesh *dm, int index, int type)
2597 {
2598         if (type == CD_ORIGINDEX) {
2599                 /* ensure creation of CD_ORIGINDEX layer */
2600                 ccgDM_get_vert_data_layer(dm, type);
2601         }
2602
2603         return DM_get_vert_data(dm, index, type);
2604 }
2605
2606 static void *ccgDM_get_edge_data(DerivedMesh *dm, int index, int type)
2607 {
2608         if (type == CD_ORIGINDEX) {
2609                 /* ensure creation of CD_ORIGINDEX layer */
2610                 ccgDM_get_edge_data_layer(dm, type);
2611         }
2612
2613         return DM_get_edge_data(dm, index, type);
2614 }
2615
2616 static void *ccgDM_get_tessface_data(DerivedMesh *dm, int index, int type)
2617 {
2618         if (type == CD_ORIGINDEX) {
2619                 /* ensure creation of CD_ORIGINDEX layer */
2620                 ccgDM_get_tessface_data_layer(dm, type);
2621         }
2622
2623         return DM_get_tessface_data(dm, index, type);
2624 }
2625
2626 static int ccgDM_getNumGrids(DerivedMesh *dm)
2627 {
2628         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2629         int index, numFaces, numGrids;
2630
2631         numFaces= ccgSubSurf_getNumFaces(ccgdm->ss);
2632         numGrids= 0;
2633
2634         for(index=0; index<numFaces; index++) {
2635                 CCGFace *f = ccgdm->faceMap[index].face;
2636                 numGrids += ccgSubSurf_getFaceNumVerts(f);
2637         }
2638
2639         return numGrids;
2640 }
2641
2642 static int ccgDM_getGridSize(DerivedMesh *dm)
2643 {
2644         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2645         return ccgSubSurf_getGridSize(ccgdm->ss);
2646 }
2647
2648 static int ccgdm_adjacent_grid(int *gridOffset, CCGFace *f, int S, int offset)
2649 {
2650         CCGFace *adjf;
2651         CCGEdge *e;
2652         int i, j= 0, numFaces, fIndex, numEdges= 0;
2653
2654         e = ccgSubSurf_getFaceEdge(f, S);
2655         numFaces = ccgSubSurf_getEdgeNumFaces(e);
2656
2657         if(numFaces != 2)
2658                 return -1;
2659
2660         for(i = 0; i < numFaces; i++) {
2661                 adjf = ccgSubSurf_getEdgeFace(e, i);
2662
2663                 if(adjf != f) {
2664                         numEdges = ccgSubSurf_getFaceNumVerts(adjf);
2665                         for(j = 0; j < numEdges; j++)
2666                                 if(ccgSubSurf_getFaceEdge(adjf, j) == e)
2667                                         break;
2668
2669                         if(j != numEdges)
2670                                 break;
2671                 }
2672         }
2673
2674         if(numEdges == 0)
2675                 return -1;
2676         
2677         fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(adjf));
2678
2679         return gridOffset[fIndex] + (j + offset)%numEdges;
2680 }
2681
2682 static void ccgdm_create_grids(DerivedMesh *dm)
2683 {
2684         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2685         CCGSubSurf *ss= ccgdm->ss;
2686         DMGridData **gridData;
2687         DMGridAdjacency *gridAdjacency, *adj;
2688         DMFlagMat *gridFlagMats;
2689         CCGFace **gridFaces;
2690         int *gridOffset;
2691         int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
2692
2693         if(ccgdm->gridData)
2694                 return;
2695         
2696         numGrids = ccgDM_getNumGrids(dm);
2697         numFaces = ccgSubSurf_getNumFaces(ss);
2698         /*gridSize = ccgDM_getGridSize(dm);*/  /*UNUSED*/
2699
2700         /* compute offset into grid array for each face */
2701         gridOffset = MEM_mallocN(sizeof(int)*numFaces, "ccgdm.gridOffset");
2702
2703         for(gIndex = 0, index = 0; index < numFaces; index++) {
2704                 CCGFace *f = ccgdm->faceMap[index].face;
2705                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2706
2707                 gridOffset[index] = gIndex;
2708                 gIndex += numVerts;
2709         }
2710
2711         /* compute grid data */
2712         gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "ccgdm.gridData");
2713         gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "ccgdm.gridAdjacency");
2714         gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "ccgdm.gridFaces");
2715         gridFlagMats = MEM_mallocN(sizeof(DMFlagMat)*numGrids, "ccgdm.gridFlagMats");
2716
2717         ccgdm->gridHidden = MEM_callocN(sizeof(BLI_bitmap)*numGrids, "ccgdm.gridHidden");
2718
2719         for(gIndex = 0, index = 0; index < numFaces; index++) {
2720                 CCGFace *f = ccgdm->faceMap[index].face;
2721                 int numVerts = ccgSubSurf_getFaceNumVerts(f);
2722
2723                 for(S = 0; S < numVerts; S++, gIndex++) {
2724                         int prevS = (S - 1 + numVerts) % numVerts;
2725                         int nextS = (S + 1 + numVerts) % numVerts;
2726
2727                         gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
2728                         gridFaces[gIndex] = f;
2729                         gridFlagMats[gIndex] = ccgdm->faceFlags[index];
2730
2731                         adj = &gridAdjacency[gIndex];
2732
2733                         adj->index[0] = gIndex - S + nextS;
2734                         adj->rotation[0] = 3;
2735                         adj->index[1] = ccgdm_adjacent_grid(gridOffset, f, prevS, 0);
2736                         adj->rotation[1] = 1;
2737                         adj->index[2] = ccgdm_adjacent_grid(gridOffset, f, S, 1);
2738                         adj->rotation[2] = 3;
2739                         adj->index[3] = gIndex - S + prevS;
2740                         adj->rotation[3] = 1;
2741                 }
2742         }
2743
2744         ccgdm->gridData = gridData;
2745         ccgdm->gridFaces = gridFaces;
2746         ccgdm->gridAdjacency = gridAdjacency;
2747         ccgdm->gridOffset = gridOffset;
2748         ccgdm->gridFlagMats = gridFlagMats;
2749 }
2750
2751 static DMGridData **ccgDM_getGridData(DerivedMesh *dm)
2752 {
2753         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2754
2755         ccgdm_create_grids(dm);
2756         return ccgdm->gridData;
2757 }
2758
2759 static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm)
2760 {
2761         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2762
2763         ccgdm_create_grids(dm);
2764         return ccgdm->gridAdjacency;
2765 }
2766
2767 static int *ccgDM_getGridOffset(DerivedMesh *dm)
2768 {
2769         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2770
2771         ccgdm_create_grids(dm);
2772         return ccgdm->gridOffset;
2773 }
2774
2775 static DMFlagMat *ccgDM_getGridFlagMats(DerivedMesh *dm)
2776 {
2777         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2778         
2779         ccgdm_create_grids(dm);
2780         return ccgdm->gridFlagMats;
2781 }
2782
2783 static BLI_bitmap *ccgDM_getGridHidden(DerivedMesh *dm)
2784 {
2785         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2786         
2787         ccgdm_create_grids(dm);
2788         return ccgdm->gridHidden;
2789 }
2790
2791 static const MeshElemMap *ccgDM_getPolyMap(Object *ob, DerivedMesh *dm)
2792 {
2793         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2794
2795         if(!ccgdm->multires.mmd && !ccgdm->pmap && ob->type == OB_MESH) {
2796                 Mesh *me= ob->data;
2797
2798                 create_vert_poly_map(&ccgdm->pmap, &ccgdm->pmap_mem,
2799                                      me->mpoly, me->mloop,
2800                                      me->totvert, me->totpoly, me->totloop);
2801         }
2802
2803         return ccgdm->pmap;
2804 }
2805
2806 static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
2807 {
2808         MultiresModifierData *mmd= ccgdm->multires.mmd;
2809
2810         /* both of multires and subsurf modifiers are CCG, but
2811          * grids should only be used when sculpting on multires */
2812         if(!mmd)
2813                 return 0;
2814
2815         return 1;
2816 }
2817
2818 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
2819 {
2820         CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
2821         int gridSize, numGrids, grid_pbvh;
2822
2823         if(!ob) {
2824                 ccgdm->pbvh= NULL;
2825                 return NULL;
2826         }
2827
2828         if(!ob->sculpt)
2829                 return NULL;
2830
2831         grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
2832
2833         if(ob->sculpt->pbvh) {
2834                 if(grid_pbvh) {
2835                         /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
2836                          * but this can be freed on ccgdm release, this updates the pointers
2837                          * when the ccgdm gets remade, the assumption is that the topology
2838                          * does not change. */
2839                         ccgdm_create_grids(dm);
2840                         BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
2841                 }
2842
2843                 ccgdm->pbvh = ob->sculpt->pbvh;
2844         }
2845
2846         if(ccgdm->pbvh)
2847                 return ccgdm->pbvh;
2848
2849         /* no pbvh exists yet, we need to create one. only in case of multires
2850          * we build a pbvh over the modified mesh, in other cases the base mesh
2851          * is being sculpted, so we build a pbvh from that. */
2852         if(grid_pbvh) {
2853                 ccgdm_create_grids(dm);
2854
2855                 gridSize = ccgDM_getGridSize(dm);
2856                 numGrids = ccgDM_getNumGrids(dm);
2857
2858                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2859                 BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
2860                         numGrids, gridSize, (void**)ccgdm->gridFaces, ccgdm->gridFlagMats, ccgdm->gridHidden);
2861         } else if(ob->type == OB_MESH) {
2862                 Mesh *me= ob->data;
2863                 ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
2864                 BLI_assert(!(me->mface == NULL && me->mpoly != NULL)); /* BMESH ONLY complain if mpoly is valid but not mface */
2865                 BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
2866                                    me->totface, me->totvert);
2867         }
2868
2869         return ccgdm->pbvh;
2870 }
2871
2872 static void ccgDM_recalcTessellation(DerivedMesh *UNUSED(dm))
2873 {
2874         /* Nothing to do: CCG handles creating its own tessfaces */
2875 }
2876
2877 static void ccgDM_calcNormals(DerivedMesh *UNUSED(dm))
2878 {
2879         /* Nothing to do: CCG calculates normals during drawing */
2880 }
2881
2882 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2883                                                                                  int drawInteriorEdges,
2884                                                                                  int useSubsurfUv,
2885                                                                                  DerivedMesh *dm)
2886 {
2887         CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
2888         CCGVertIterator *vi;
2889         CCGEdgeIterator *ei;
2890         CCGFaceIterator *fi;
2891         int index, totvert, totedge, totface;
2892         int i;
2893         int vertNum, edgeNum, faceNum;
2894         int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex; /* *edgeOrigIndex - as yet, unused  */
2895         short *edgeFlags;
2896         DMFlagMat *faceFlags;
2897         int *loopidx = NULL, *vertidx = NULL;
2898         BLI_array_declare(loopidx);
2899         BLI_array_declare(vertidx);
2900         int loopindex, loopindex2;
2901         int edgeSize, has_edge_origindex;
2902         int gridSize;
2903         int gridFaces, gridCuts;
2904         /*int gridSideVerts;*/
2905         int gridSideEdges;
2906         int numTex, numCol;
2907         int hasWCol, hasOrigSpace;
2908         int gridInternalEdges;
2909         float *w = NULL;
2910         WeightTable wtable = {0};
2911         /* MCol *mcol; */ /* UNUSED */
2912         MEdge *medge = NULL;
2913         /* MFace *mface = NULL; */
2914         MPoly *mpoly = NULL;
2915
2916         DM_from_template(&ccgdm->dm, dm, DM_TYPE_CCGDM,
2917                                          ccgSubSurf_getNumFinalVerts(ss),
2918                                          ccgSubSurf_getNumFinalEdges(ss),
2919                                          ccgSubSurf_getNumFinalFaces(ss),
2920                                          ccgSubSurf_getNumFinalFaces(ss)*4,