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