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