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