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