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