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