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