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