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