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