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