1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005 Blender Foundation.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup bke
22  */
23 
24 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
25 #  ifdef __GNUC__
26 #    pragma GCC diagnostic ignored "-Wvla"
27 #  endif
28 #  define USE_DYNSIZE
29 #endif
30 
31 #include <float.h>
32 #include <math.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 
37 #include "atomic_ops.h"
38 
39 #include "MEM_guardedalloc.h"
40 
41 #include "DNA_mesh_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_modifier_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_scene_types.h"
46 
47 #include "BLI_bitmap.h"
48 #include "BLI_blenlib.h"
49 #include "BLI_edgehash.h"
50 #include "BLI_math.h"
51 #include "BLI_memarena.h"
52 #include "BLI_task.h"
53 #include "BLI_threads.h"
54 #include "BLI_utildefines.h"
55 
56 #include "BKE_ccg.h"
57 #include "BKE_cdderivedmesh.h"
58 #include "BKE_mesh.h"
59 #include "BKE_mesh_mapping.h"
60 #include "BKE_modifier.h"
61 #include "BKE_multires.h"
62 #include "BKE_object.h"
63 #include "BKE_paint.h"
64 #include "BKE_pbvh.h"
65 #include "BKE_scene.h"
66 #include "BKE_subsurf.h"
67 
68 #ifndef USE_DYNSIZE
69 #  include "BLI_array.h"
70 #endif
71 
72 #include "CCGSubSurf.h"
73 
74 /* assumes MLoop's are laid out 4 for each poly, in order */
75 #define USE_LOOP_LAYOUT_FAST
76 
77 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
78                                          int drawInteriorEdges,
79                                          int useSubsurfUv,
80                                          DerivedMesh *dm);
81 ///
82 
arena_alloc(CCGAllocatorHDL a,int numBytes)83 static void *arena_alloc(CCGAllocatorHDL a, int numBytes)
84 {
85   return BLI_memarena_alloc(a, numBytes);
86 }
87 
arena_realloc(CCGAllocatorHDL a,void * ptr,int newSize,int oldSize)88 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize)
89 {
90   void *p2 = BLI_memarena_alloc(a, newSize);
91   if (ptr) {
92     memcpy(p2, ptr, oldSize);
93   }
94   return p2;
95 }
96 
arena_free(CCGAllocatorHDL UNUSED (a),void * UNUSED (ptr))97 static void arena_free(CCGAllocatorHDL UNUSED(a), void *UNUSED(ptr))
98 {
99   /* do nothing */
100 }
101 
arena_release(CCGAllocatorHDL a)102 static void arena_release(CCGAllocatorHDL a)
103 {
104   BLI_memarena_free(a);
105 }
106 
107 typedef enum {
108   CCG_USE_AGING = 1,
109   CCG_USE_ARENA = 2,
110   CCG_CALC_NORMALS = 4,
111   /* add an extra four bytes for a mask layer */
112   CCG_ALLOC_MASK = 8,
113   CCG_SIMPLE_SUBDIV = 16,
114 } CCGFlags;
115 
_getSubSurf(CCGSubSurf * prevSS,int subdivLevels,int numLayers,CCGFlags flags)116 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int numLayers, CCGFlags flags)
117 {
118   CCGMeshIFC ifc;
119   CCGSubSurf *ccgSS;
120   int useAging = !!(flags & CCG_USE_AGING);
121   int useArena = flags & CCG_USE_ARENA;
122   int normalOffset = 0;
123 
124   /* (subdivLevels == 0) is not allowed */
125   subdivLevels = MAX2(subdivLevels, 1);
126 
127   if (prevSS) {
128     int oldUseAging;
129 
130     ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
131 
132     if ((oldUseAging != useAging) ||
133         (ccgSubSurf_getSimpleSubdiv(prevSS) != !!(flags & CCG_SIMPLE_SUBDIV))) {
134       ccgSubSurf_free(prevSS);
135     }
136     else {
137       ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
138 
139       return prevSS;
140     }
141   }
142 
143   if (useAging) {
144     ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
145   }
146   else {
147     ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
148   }
149   ifc.numLayers = numLayers;
150   ifc.vertDataSize = sizeof(float) * numLayers;
151   normalOffset += sizeof(float) * numLayers;
152   if (flags & CCG_CALC_NORMALS) {
153     ifc.vertDataSize += sizeof(float[3]);
154   }
155   if (flags & CCG_ALLOC_MASK) {
156     ifc.vertDataSize += sizeof(float);
157   }
158   ifc.simpleSubdiv = !!(flags & CCG_SIMPLE_SUBDIV);
159 
160   if (useArena) {
161     CCGAllocatorIFC allocatorIFC;
162     CCGAllocatorHDL allocator = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "subsurf arena");
163 
164     allocatorIFC.alloc = arena_alloc;
165     allocatorIFC.realloc = arena_realloc;
166     allocatorIFC.free = arena_free;
167     allocatorIFC.release = arena_release;
168 
169     ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
170   }
171   else {
172     ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
173   }
174 
175   if (useAging) {
176     ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
177   }
178 
179   if (flags & CCG_ALLOC_MASK) {
180     normalOffset += sizeof(float);
181     /* mask is allocated after regular layers */
182     ccgSubSurf_setAllocMask(ccgSS, 1, sizeof(float) * numLayers);
183   }
184 
185   if (flags & CCG_CALC_NORMALS) {
186     ccgSubSurf_setCalcVertexNormals(ccgSS, 1, normalOffset);
187   }
188   else {
189     ccgSubSurf_setCalcVertexNormals(ccgSS, 0, 0);
190   }
191 
192   return ccgSS;
193 }
194 
getEdgeIndex(CCGSubSurf * ss,CCGEdge * e,int x,int edgeSize)195 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize)
196 {
197   CCGVert *v0 = ccgSubSurf_getEdgeVert0(e);
198   CCGVert *v1 = ccgSubSurf_getEdgeVert1(e);
199   int v0idx = *((int *)ccgSubSurf_getVertUserData(ss, v0));
200   int v1idx = *((int *)ccgSubSurf_getVertUserData(ss, v1));
201   int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e));
202 
203   if (x == 0) {
204     return v0idx;
205   }
206   if (x == edgeSize - 1) {
207     return v1idx;
208   }
209 
210   return edgeBase + x - 1;
211 }
212 
getFaceIndex(CCGSubSurf * ss,CCGFace * f,int S,int x,int y,int edgeSize,int gridSize)213 static int getFaceIndex(
214     CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize)
215 {
216   int faceBase = *((int *)ccgSubSurf_getFaceUserData(ss, f));
217   int numVerts = ccgSubSurf_getFaceNumVerts(f);
218 
219   if (x == gridSize - 1 && y == gridSize - 1) {
220     CCGVert *v = ccgSubSurf_getFaceVert(f, S);
221     return *((int *)ccgSubSurf_getVertUserData(ss, v));
222   }
223   if (x == gridSize - 1) {
224     CCGVert *v = ccgSubSurf_getFaceVert(f, S);
225     CCGEdge *e = ccgSubSurf_getFaceEdge(f, S);
226     int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e));
227     if (v == ccgSubSurf_getEdgeVert0(e)) {
228       return edgeBase + (gridSize - 1 - y) - 1;
229     }
230 
231     return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - y) - 1);
232   }
233   if (y == gridSize - 1) {
234     CCGVert *v = ccgSubSurf_getFaceVert(f, S);
235     CCGEdge *e = ccgSubSurf_getFaceEdge(f, (S + numVerts - 1) % numVerts);
236     int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e));
237     if (v == ccgSubSurf_getEdgeVert0(e)) {
238       return edgeBase + (gridSize - 1 - x) - 1;
239     }
240 
241     return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - x) - 1);
242   }
243   if (x == 0 && y == 0) {
244     return faceBase;
245   }
246   if (x == 0) {
247     S = (S + numVerts - 1) % numVerts;
248     return faceBase + 1 + (gridSize - 2) * S + (y - 1);
249   }
250   if (y == 0) {
251     return faceBase + 1 + (gridSize - 2) * S + (x - 1);
252   }
253 
254   return faceBase + 1 + (gridSize - 2) * numVerts + S * (gridSize - 2) * (gridSize - 2) +
255          (y - 1) * (gridSize - 2) + (x - 1);
256 }
257 
get_face_uv_map_vert(UvVertMap * vmap,struct MPoly * mpoly,struct MLoop * ml,int fi,CCGVertHDL * fverts)258 static void get_face_uv_map_vert(
259     UvVertMap *vmap, struct MPoly *mpoly, struct MLoop *ml, int fi, CCGVertHDL *fverts)
260 {
261   UvMapVert *v, *nv;
262   int j, nverts = mpoly[fi].totloop;
263 
264   for (j = 0; j < nverts; j++) {
265     for (nv = v = BKE_mesh_uv_vert_map_get_vert(vmap, ml[j].v); v; v = v->next) {
266       if (v->separate) {
267         nv = v;
268       }
269       if (v->poly_index == fi) {
270         break;
271       }
272     }
273 
274     fverts[j] = POINTER_FROM_UINT(mpoly[nv->poly_index].loopstart + nv->loop_of_poly_index);
275   }
276 }
277 
ss_sync_from_uv(CCGSubSurf * ss,CCGSubSurf * origss,DerivedMesh * dm,MLoopUV * mloopuv)278 static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MLoopUV *mloopuv)
279 {
280   MPoly *mpoly = dm->getPolyArray(dm);
281   MLoop *mloop = dm->getLoopArray(dm);
282   int totvert = dm->getNumVerts(dm);
283   int totface = dm->getNumPolys(dm);
284   int i, seam;
285   UvMapVert *v;
286   UvVertMap *vmap;
287   float limit[2];
288 #ifndef USE_DYNSIZE
289   CCGVertHDL *fverts = NULL;
290   BLI_array_declare(fverts);
291 #endif
292   EdgeSet *eset;
293   float uv[3] = {0.0f, 0.0f, 0.0f}; /* only first 2 values are written into */
294 
295   limit[0] = limit[1] = STD_UV_CONNECT_LIMIT;
296   /* previous behavior here is without accounting for winding, however this causes stretching in
297    * UV map in really simple cases with mirror + subsurf, see second part of T44530.
298    * Also, initially intention is to treat merged vertices from mirror modifier as seams.
299    * This fixes a very old regression (2.49 was correct here) */
300   vmap = BKE_mesh_uv_vert_map_create(mpoly, mloop, mloopuv, totface, totvert, limit, false, true);
301   if (!vmap) {
302     return 0;
303   }
304 
305   ccgSubSurf_initFullSync(ss);
306 
307   /* create vertices */
308   for (i = 0; i < totvert; i++) {
309     if (!BKE_mesh_uv_vert_map_get_vert(vmap, i)) {
310       continue;
311     }
312 
313     for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i)->next; v; v = v->next) {
314       if (v->separate) {
315         break;
316       }
317     }
318 
319     seam = (v != NULL);
320 
321     for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i); v; v = v->next) {
322       if (v->separate) {
323         CCGVert *ssv;
324         int loopid = mpoly[v->poly_index].loopstart + v->loop_of_poly_index;
325         CCGVertHDL vhdl = POINTER_FROM_INT(loopid);
326 
327         copy_v2_v2(uv, mloopuv[loopid].uv);
328 
329         ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
330       }
331     }
332   }
333 
334   /* create edges */
335   eset = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totface));
336 
337   for (i = 0; i < totface; i++) {
338     MPoly *mp = &mpoly[i];
339     int nverts = mp->totloop;
340     int j, j_next;
341     CCGFace *origf = ccgSubSurf_getFace(origss, POINTER_FROM_INT(i));
342     /* unsigned int *fv = &mp->v1; */
343     MLoop *ml = mloop + mp->loopstart;
344 
345 #ifdef USE_DYNSIZE
346     CCGVertHDL fverts[nverts];
347 #else
348     BLI_array_clear(fverts);
349     BLI_array_grow_items(fverts, nverts);
350 #endif
351 
352     get_face_uv_map_vert(vmap, mpoly, ml, i, fverts);
353 
354     for (j = 0, j_next = nverts - 1; j < nverts; j_next = j++) {
355       unsigned int v0 = POINTER_AS_UINT(fverts[j_next]);
356       unsigned int v1 = POINTER_AS_UINT(fverts[j]);
357 
358       if (BLI_edgeset_add(eset, v0, v1)) {
359         CCGEdge *e, *orige = ccgSubSurf_getFaceEdge(origf, j_next);
360         CCGEdgeHDL ehdl = POINTER_FROM_INT(mp->loopstart + j_next);
361         float crease = ccgSubSurf_getEdgeCrease(orige);
362 
363         ccgSubSurf_syncEdge(ss, ehdl, fverts[j_next], fverts[j], crease, &e);
364       }
365     }
366   }
367 
368   BLI_edgeset_free(eset);
369 
370   /* create faces */
371   for (i = 0; i < totface; i++) {
372     MPoly *mp = &mpoly[i];
373     MLoop *ml = &mloop[mp->loopstart];
374     int nverts = mp->totloop;
375     CCGFace *f;
376 
377 #ifdef USE_DYNSIZE
378     CCGVertHDL fverts[nverts];
379 #else
380     BLI_array_clear(fverts);
381     BLI_array_grow_items(fverts, nverts);
382 #endif
383 
384     get_face_uv_map_vert(vmap, mpoly, ml, i, fverts);
385     ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), nverts, fverts, &f);
386   }
387 
388 #ifndef USE_DYNSIZE
389   BLI_array_free(fverts);
390 #endif
391 
392   BKE_mesh_uv_vert_map_free(vmap);
393   ccgSubSurf_processSync(ss);
394 
395   return 1;
396 }
397 
set_subsurf_legacy_uv(CCGSubSurf * ss,DerivedMesh * dm,DerivedMesh * result,int n)398 static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
399 {
400   CCGSubSurf *uvss;
401   CCGFace **faceMap;
402   MTFace *tf;
403   MLoopUV *mluv;
404   CCGFaceIterator fi;
405   int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S;
406   MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, n);
407   /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
408    * just tface except applying the modifier then looses subsurf UV */
409   MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
410   MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, n);
411 
412   if (!dmloopuv || (!tface && !mloopuv)) {
413     return;
414   }
415 
416   /* create a CCGSubSurf from uv's */
417   uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 2, CCG_USE_ARENA);
418 
419   if (!ss_sync_from_uv(uvss, ss, dm, dmloopuv)) {
420     ccgSubSurf_free(uvss);
421     return;
422   }
423 
424   /* get some info from CCGSubSurf */
425   totface = ccgSubSurf_getNumFaces(uvss);
426   /* edgeSize = ccgSubSurf_getEdgeSize(uvss); */ /*UNUSED*/
427   gridSize = ccgSubSurf_getGridSize(uvss);
428   gridFaces = gridSize - 1;
429 
430   /* make a map from original faces to CCGFaces */
431   faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv");
432   for (ccgSubSurf_initFaceIterator(uvss, &fi); !ccgFaceIterator_isStopped(&fi);
433        ccgFaceIterator_next(&fi)) {
434     CCGFace *f = ccgFaceIterator_getCurrent(&fi);
435     faceMap[POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f))] = f;
436   }
437 
438   /* load coordinates from uvss into tface */
439   tf = tface;
440   mluv = mloopuv;
441 
442   for (index = 0; index < totface; index++) {
443     CCGFace *f = faceMap[index];
444     int numVerts = ccgSubSurf_getFaceNumVerts(f);
445 
446     for (S = 0; S < numVerts; S++) {
447       float(*faceGridData)[2] = ccgSubSurf_getFaceGridDataArray(uvss, f, S);
448 
449       for (y = 0; y < gridFaces; y++) {
450         for (x = 0; x < gridFaces; x++) {
451           float *a = faceGridData[(y + 0) * gridSize + x + 0];
452           float *b = faceGridData[(y + 0) * gridSize + x + 1];
453           float *c = faceGridData[(y + 1) * gridSize + x + 1];
454           float *d = faceGridData[(y + 1) * gridSize + x + 0];
455 
456           if (tf) {
457             copy_v2_v2(tf->uv[0], a);
458             copy_v2_v2(tf->uv[1], d);
459             copy_v2_v2(tf->uv[2], c);
460             copy_v2_v2(tf->uv[3], b);
461             tf++;
462           }
463 
464           if (mluv) {
465             copy_v2_v2(mluv[0].uv, a);
466             copy_v2_v2(mluv[1].uv, d);
467             copy_v2_v2(mluv[2].uv, c);
468             copy_v2_v2(mluv[3].uv, b);
469             mluv += 4;
470           }
471         }
472       }
473     }
474   }
475 
476   ccgSubSurf_free(uvss);
477   MEM_freeN(faceMap);
478 }
479 
set_subsurf_uv(CCGSubSurf * ss,DerivedMesh * dm,DerivedMesh * result,int layer_index)480 static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int layer_index)
481 {
482   set_subsurf_legacy_uv(ss, dm, result, layer_index);
483 }
484 
485 /* face weighting */
486 #define SUB_ELEMS_FACE 50
487 typedef float FaceVertWeight[SUB_ELEMS_FACE][SUB_ELEMS_FACE];
488 
489 typedef struct FaceVertWeightEntry {
490   FaceVertWeight *weight;
491   float *w;
492   int valid;
493 } FaceVertWeightEntry;
494 
495 typedef struct WeightTable {
496   FaceVertWeightEntry *weight_table;
497   int len;
498 } WeightTable;
499 
get_ss_weights(WeightTable * wtable,int gridCuts,int faceLen)500 static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen)
501 {
502   int x, y, i, j;
503   float *w, w1, w2, w4, fac, fac2, fx, fy;
504 
505   if (wtable->len <= faceLen) {
506     void *tmp = MEM_callocN(sizeof(FaceVertWeightEntry) * (faceLen + 1), "weight table alloc 2");
507 
508     if (wtable->len) {
509       memcpy(tmp, wtable->weight_table, sizeof(FaceVertWeightEntry) * wtable->len);
510       MEM_freeN(wtable->weight_table);
511     }
512 
513     wtable->weight_table = tmp;
514     wtable->len = faceLen + 1;
515   }
516 
517   if (!wtable->weight_table[faceLen].valid) {
518     wtable->weight_table[faceLen].valid = 1;
519     wtable->weight_table[faceLen].w = w = MEM_callocN(
520         sizeof(float) * faceLen * faceLen * (gridCuts + 2) * (gridCuts + 2), "weight table alloc");
521     fac = 1.0f / (float)faceLen;
522 
523     for (i = 0; i < faceLen; i++) {
524       for (x = 0; x < gridCuts + 2; x++) {
525         for (y = 0; y < gridCuts + 2; y++) {
526           fx = 0.5f - (float)x / (float)(gridCuts + 1) / 2.0f;
527           fy = 0.5f - (float)y / (float)(gridCuts + 1) / 2.0f;
528 
529           fac2 = faceLen - 4;
530           w1 = (1.0f - fx) * (1.0f - fy) + (-fac2 * fx * fy * fac);
531           w2 = (1.0f - fx + fac2 * fx * -fac) * (fy);
532           w4 = (fx) * (1.0f - fy + -fac2 * fy * fac);
533 
534           /* these values aren't used for tri's and cause divide by zero */
535           if (faceLen > 3) {
536             fac2 = 1.0f - (w1 + w2 + w4);
537             fac2 = fac2 / (float)(faceLen - 3);
538             for (j = 0; j < faceLen; j++) {
539               w[j] = fac2;
540             }
541           }
542 
543           w[i] = w1;
544           w[(i - 1 + faceLen) % faceLen] = w2;
545           w[(i + 1) % faceLen] = w4;
546 
547           w += faceLen;
548         }
549       }
550     }
551   }
552 
553   return wtable->weight_table[faceLen].w;
554 }
555 
free_ss_weights(WeightTable * wtable)556 static void free_ss_weights(WeightTable *wtable)
557 {
558   int i;
559 
560   for (i = 0; i < wtable->len; i++) {
561     if (wtable->weight_table[i].valid) {
562       MEM_freeN(wtable->weight_table[i].w);
563     }
564   }
565 
566   if (wtable->weight_table) {
567     MEM_freeN(wtable->weight_table);
568   }
569 }
570 
ss_sync_ccg_from_derivedmesh(CCGSubSurf * ss,DerivedMesh * dm,float (* vertexCos)[3],int useFlatSubdiv)571 static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss,
572                                          DerivedMesh *dm,
573                                          float (*vertexCos)[3],
574                                          int useFlatSubdiv)
575 {
576   float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
577 #ifndef USE_DYNSIZE
578   CCGVertHDL *fVerts = NULL;
579   BLI_array_declare(fVerts);
580 #endif
581   MVert *mvert = dm->getVertArray(dm);
582   MEdge *medge = dm->getEdgeArray(dm);
583   /* MFace *mface = dm->getTessFaceArray(dm); */ /* UNUSED */
584   MVert *mv;
585   MEdge *me;
586   MLoop *mloop = dm->getLoopArray(dm), *ml;
587   MPoly *mpoly = dm->getPolyArray(dm), *mp;
588   /*MFace *mf;*/ /*UNUSED*/
589   int totvert = dm->getNumVerts(dm);
590   int totedge = dm->getNumEdges(dm);
591   /*int totface = dm->getNumTessFaces(dm);*/ /*UNUSED*/
592   /*int totpoly = dm->getNumFaces(dm);*/     /*UNUSED*/
593   int i, j;
594   int *index;
595 
596   ccgSubSurf_initFullSync(ss);
597 
598   mv = mvert;
599   index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
600   for (i = 0; i < totvert; i++, mv++) {
601     CCGVert *v;
602 
603     if (vertexCos) {
604       ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), vertexCos[i], 0, &v);
605     }
606     else {
607       ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), mv->co, 0, &v);
608     }
609 
610     ((int *)ccgSubSurf_getVertUserData(ss, v))[1] = (index) ? *index++ : i;
611   }
612 
613   me = medge;
614   index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX);
615   for (i = 0; i < totedge; i++, me++) {
616     CCGEdge *e;
617     float crease;
618 
619     crease = useFlatSubdiv ? creaseFactor : me->crease * creaseFactor / 255.0f;
620 
621     ccgSubSurf_syncEdge(
622         ss, POINTER_FROM_INT(i), POINTER_FROM_UINT(me->v1), POINTER_FROM_UINT(me->v2), crease, &e);
623 
624     ((int *)ccgSubSurf_getEdgeUserData(ss, e))[1] = (index) ? *index++ : i;
625   }
626 
627   mp = mpoly;
628   index = (int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
629   for (i = 0; i < dm->numPolyData; i++, mp++) {
630     CCGFace *f;
631 
632 #ifdef USE_DYNSIZE
633     CCGVertHDL fVerts[mp->totloop];
634 #else
635     BLI_array_clear(fVerts);
636     BLI_array_grow_items(fVerts, mp->totloop);
637 #endif
638 
639     ml = mloop + mp->loopstart;
640     for (j = 0; j < mp->totloop; j++, ml++) {
641       fVerts[j] = POINTER_FROM_UINT(ml->v);
642     }
643 
644     /* this is very bad, means mesh is internally inconsistent.
645      * it is not really possible to continue without modifying
646      * other parts of code significantly to handle missing faces.
647      * since this really shouldn't even be possible we just bail.*/
648     if (ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), mp->totloop, fVerts, &f) ==
649         eCCGError_InvalidValue) {
650       static int hasGivenError = 0;
651 
652       if (!hasGivenError) {
653         // XXX error("Unrecoverable error in SubSurf calculation,"
654         //      " mesh is inconsistent.");
655 
656         hasGivenError = 1;
657       }
658 
659       return;
660     }
661 
662     ((int *)ccgSubSurf_getFaceUserData(ss, f))[1] = (index) ? *index++ : i;
663   }
664 
665   ccgSubSurf_processSync(ss);
666 
667 #ifndef USE_DYNSIZE
668   BLI_array_free(fVerts);
669 #endif
670 }
671 
ss_sync_from_derivedmesh(CCGSubSurf * ss,DerivedMesh * dm,float (* vertexCos)[3],int use_flat_subdiv,bool UNUSED (use_subdiv_uvs))672 static void ss_sync_from_derivedmesh(CCGSubSurf *ss,
673                                      DerivedMesh *dm,
674                                      float (*vertexCos)[3],
675                                      int use_flat_subdiv,
676                                      bool UNUSED(use_subdiv_uvs))
677 {
678   ss_sync_ccg_from_derivedmesh(ss, dm, vertexCos, use_flat_subdiv);
679 }
680 
681 /***/
682 
ccgDM_getVertMapIndex(CCGSubSurf * ss,CCGVert * v)683 static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v)
684 {
685   return ((int *)ccgSubSurf_getVertUserData(ss, v))[1];
686 }
687 
ccgDM_getEdgeMapIndex(CCGSubSurf * ss,CCGEdge * e)688 static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e)
689 {
690   return ((int *)ccgSubSurf_getEdgeUserData(ss, e))[1];
691 }
692 
ccgDM_getFaceMapIndex(CCGSubSurf * ss,CCGFace * f)693 static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f)
694 {
695   return ((int *)ccgSubSurf_getFaceUserData(ss, f))[1];
696 }
697 
minmax_v3_v3v3(const float vec[3],float min[3],float max[3])698 static void minmax_v3_v3v3(const float vec[3], float min[3], float max[3])
699 {
700   if (min[0] > vec[0]) {
701     min[0] = vec[0];
702   }
703   if (min[1] > vec[1]) {
704     min[1] = vec[1];
705   }
706   if (min[2] > vec[2]) {
707     min[2] = vec[2];
708   }
709   if (max[0] < vec[0]) {
710     max[0] = vec[0];
711   }
712   if (max[1] < vec[1]) {
713     max[1] = vec[1];
714   }
715   if (max[2] < vec[2]) {
716     max[2] = vec[2];
717   }
718 }
719 
720 /* UNUSED, keep since this functionality may be useful in the future. */
UNUSED_FUNCTION(ccgDM_getMinMax)721 static void UNUSED_FUNCTION(ccgDM_getMinMax)(DerivedMesh *dm, float r_min[3], float r_max[3])
722 {
723   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
724   CCGSubSurf *ss = ccgdm->ss;
725   CCGVertIterator vi;
726   CCGEdgeIterator ei;
727   CCGFaceIterator fi;
728   CCGKey key;
729   int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
730   int gridSize = ccgSubSurf_getGridSize(ss);
731 
732   CCG_key_top_level(&key, ss);
733 
734   if (!ccgSubSurf_getNumVerts(ss)) {
735     r_min[0] = r_min[1] = r_min[2] = r_max[0] = r_max[1] = r_max[2] = 0.0;
736   }
737 
738   for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi);
739        ccgVertIterator_next(&vi)) {
740     CCGVert *v = ccgVertIterator_getCurrent(&vi);
741     float *co = ccgSubSurf_getVertData(ss, v);
742 
743     minmax_v3_v3v3(co, r_min, r_max);
744   }
745 
746   for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei);
747        ccgEdgeIterator_next(&ei)) {
748     CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
749     CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
750 
751     for (i = 0; i < edgeSize; i++) {
752       minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), r_min, r_max);
753     }
754   }
755 
756   for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi);
757        ccgFaceIterator_next(&fi)) {
758     CCGFace *f = ccgFaceIterator_getCurrent(&fi);
759     int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
760 
761     for (S = 0; S < numVerts; S++) {
762       CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
763 
764       for (y = 0; y < gridSize; y++) {
765         for (x = 0; x < gridSize; x++) {
766           minmax_v3_v3v3(CCG_grid_elem_co(&key, faceGridData, x, y), r_min, r_max);
767         }
768       }
769     }
770   }
771 }
772 
ccgDM_getNumVerts(DerivedMesh * dm)773 static int ccgDM_getNumVerts(DerivedMesh *dm)
774 {
775   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
776 
777   return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
778 }
779 
ccgDM_getNumEdges(DerivedMesh * dm)780 static int ccgDM_getNumEdges(DerivedMesh *dm)
781 {
782   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
783 
784   return ccgSubSurf_getNumFinalEdges(ccgdm->ss);
785 }
786 
ccgDM_getNumPolys(DerivedMesh * dm)787 static int ccgDM_getNumPolys(DerivedMesh *dm)
788 {
789   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
790 
791   return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
792 }
793 
ccgDM_getNumTessFaces(DerivedMesh * dm)794 static int ccgDM_getNumTessFaces(DerivedMesh *dm)
795 {
796   return dm->numTessFaceData;
797 }
798 
ccgDM_getNumLoops(DerivedMesh * dm)799 static int ccgDM_getNumLoops(DerivedMesh *dm)
800 {
801   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
802 
803   /* All subsurf faces are quads */
804   return 4 * ccgSubSurf_getNumFinalFaces(ccgdm->ss);
805 }
806 
ccgDM_getFinalVert(DerivedMesh * dm,int vertNum,MVert * mv)807 static void ccgDM_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
808 {
809   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
810   CCGSubSurf *ss = ccgdm->ss;
811   CCGElem *vd;
812   CCGKey key;
813   int i;
814 
815   CCG_key_top_level(&key, ss);
816   memset(mv, 0, sizeof(*mv));
817 
818   if ((vertNum < ccgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) {
819     /* this vert comes from face data */
820     int lastface = ccgSubSurf_getNumFaces(ss) - 1;
821     CCGFace *f;
822     int x, y, grid, numVerts;
823     int offset;
824     int gridSize = ccgSubSurf_getGridSize(ss);
825     int gridSideVerts;
826     int gridInternalVerts;
827     int gridSideEnd;
828     int gridInternalEnd;
829 
830     i = 0;
831     while (i < lastface && vertNum >= ccgdm->faceMap[i + 1].startVert) {
832       i++;
833     }
834 
835     f = ccgdm->faceMap[i].face;
836     numVerts = ccgSubSurf_getFaceNumVerts(f);
837 
838     gridSideVerts = gridSize - 2;
839     gridInternalVerts = gridSideVerts * gridSideVerts;
840 
841     gridSideEnd = 1 + numVerts * gridSideVerts;
842     gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
843 
844     offset = vertNum - ccgdm->faceMap[i].startVert;
845     if (offset < 1) {
846       vd = ccgSubSurf_getFaceCenterData(f);
847       copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
848       normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
849     }
850     else if (offset < gridSideEnd) {
851       offset -= 1;
852       grid = offset / gridSideVerts;
853       x = offset % gridSideVerts + 1;
854       vd = ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x);
855       copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
856       normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
857     }
858     else if (offset < gridInternalEnd) {
859       offset -= gridSideEnd;
860       grid = offset / gridInternalVerts;
861       offset %= gridInternalVerts;
862       y = offset / gridSideVerts + 1;
863       x = offset % gridSideVerts + 1;
864       vd = ccgSubSurf_getFaceGridData(ss, f, grid, x, y);
865       copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
866       normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
867     }
868   }
869   else if ((vertNum < ccgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
870     /* this vert comes from edge data */
871     CCGEdge *e;
872     int lastedge = ccgSubSurf_getNumEdges(ss) - 1;
873     int x;
874 
875     i = 0;
876     while (i < lastedge && vertNum >= ccgdm->edgeMap[i + 1].startVert) {
877       i++;
878     }
879 
880     e = ccgdm->edgeMap[i].edge;
881 
882     x = vertNum - ccgdm->edgeMap[i].startVert + 1;
883     vd = ccgSubSurf_getEdgeData(ss, e, x);
884     copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
885     normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
886   }
887   else {
888     /* this vert comes from vert data */
889     CCGVert *v;
890     i = vertNum - ccgdm->vertMap[0].startVert;
891 
892     v = ccgdm->vertMap[i].vert;
893     vd = ccgSubSurf_getVertData(ss, v);
894     copy_v3_v3(mv->co, CCG_elem_co(&key, vd));
895     normal_float_to_short_v3(mv->no, CCG_elem_no(&key, vd));
896   }
897 }
898 
ccgDM_getFinalVertCo(DerivedMesh * dm,int vertNum,float r_co[3])899 static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float r_co[3])
900 {
901   MVert mvert;
902 
903   ccgDM_getFinalVert(dm, vertNum, &mvert);
904   copy_v3_v3(r_co, mvert.co);
905 }
906 
ccgDM_getFinalVertNo(DerivedMesh * dm,int vertNum,float r_no[3])907 static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float r_no[3])
908 {
909   MVert mvert;
910 
911   ccgDM_getFinalVert(dm, vertNum, &mvert);
912   normal_short_to_float_v3(r_no, mvert.no);
913 }
914 
ccgDM_getFinalEdge(DerivedMesh * dm,int edgeNum,MEdge * med)915 static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
916 {
917   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
918   CCGSubSurf *ss = ccgdm->ss;
919   int i;
920 
921   memset(med, 0, sizeof(*med));
922 
923   if (edgeNum < ccgdm->edgeMap[0].startEdge) {
924     /* this edge comes from face data */
925     int lastface = ccgSubSurf_getNumFaces(ss) - 1;
926     CCGFace *f;
927     int x, y, grid /*, numVerts*/;
928     int offset;
929     int gridSize = ccgSubSurf_getGridSize(ss);
930     int edgeSize = ccgSubSurf_getEdgeSize(ss);
931     int gridSideEdges;
932     int gridInternalEdges;
933 
934     i = 0;
935     while (i < lastface && edgeNum >= ccgdm->faceMap[i + 1].startEdge) {
936       i++;
937     }
938 
939     f = ccgdm->faceMap[i].face;
940     /* numVerts = ccgSubSurf_getFaceNumVerts(f); */ /*UNUSED*/
941 
942     gridSideEdges = gridSize - 1;
943     gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
944 
945     offset = edgeNum - ccgdm->faceMap[i].startEdge;
946     grid = offset / (gridSideEdges + gridInternalEdges);
947     offset %= (gridSideEdges + gridInternalEdges);
948 
949     if (offset < gridSideEdges) {
950       x = offset;
951       med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, gridSize);
952       med->v2 = getFaceIndex(ss, f, grid, x + 1, 0, edgeSize, gridSize);
953     }
954     else {
955       offset -= gridSideEdges;
956       x = (offset / 2) / gridSideEdges + 1;
957       y = (offset / 2) % gridSideEdges;
958       if (offset % 2 == 0) {
959         med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSize, gridSize);
960         med->v2 = getFaceIndex(ss, f, grid, x, y + 1, edgeSize, gridSize);
961       }
962       else {
963         med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSize, gridSize);
964         med->v2 = getFaceIndex(ss, f, grid, y + 1, x, edgeSize, gridSize);
965       }
966     }
967   }
968   else {
969     /* this vert comes from edge data */
970     CCGEdge *e;
971     int edgeSize = ccgSubSurf_getEdgeSize(ss);
972     int x;
973     short *edgeFlag;
974     unsigned int flags = 0;
975 
976     i = (edgeNum - ccgdm->edgeMap[0].startEdge) / (edgeSize - 1);
977 
978     e = ccgdm->edgeMap[i].edge;
979 
980     if (!ccgSubSurf_getEdgeNumFaces(e)) {
981       flags |= ME_LOOSEEDGE;
982     }
983 
984     x = edgeNum - ccgdm->edgeMap[i].startEdge;
985 
986     med->v1 = getEdgeIndex(ss, e, x, edgeSize);
987     med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
988 
989     edgeFlag = (ccgdm->edgeFlags) ? &ccgdm->edgeFlags[i] : NULL;
990     if (edgeFlag) {
991       flags |= (*edgeFlag & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER;
992     }
993     else {
994       flags |= ME_EDGEDRAW | ME_EDGERENDER;
995     }
996 
997     med->flag = flags;
998   }
999 }
1000 
ccgDM_getFinalFace(DerivedMesh * dm,int faceNum,MFace * mf)1001 static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
1002 {
1003   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1004   CCGSubSurf *ss = ccgdm->ss;
1005   int gridSize = ccgSubSurf_getGridSize(ss);
1006   int edgeSize = ccgSubSurf_getEdgeSize(ss);
1007   int gridSideEdges = gridSize - 1;
1008   int gridFaces = gridSideEdges * gridSideEdges;
1009   int i;
1010   CCGFace *f;
1011   /*int numVerts;*/
1012   int offset;
1013   int grid;
1014   int x, y;
1015   /*int lastface = ccgSubSurf_getNumFaces(ss) - 1;*/ /*UNUSED*/
1016   DMFlagMat *faceFlags = ccgdm->faceFlags;
1017 
1018   memset(mf, 0, sizeof(*mf));
1019   if (faceNum >= ccgdm->dm.numTessFaceData) {
1020     return;
1021   }
1022 
1023   i = ccgdm->reverseFaceMap[faceNum];
1024 
1025   f = ccgdm->faceMap[i].face;
1026   /*numVerts = ccgSubSurf_getFaceNumVerts(f);*/ /*UNUSED*/
1027 
1028   offset = faceNum - ccgdm->faceMap[i].startFace;
1029   grid = offset / gridFaces;
1030   offset %= gridFaces;
1031   y = offset / gridSideEdges;
1032   x = offset % gridSideEdges;
1033 
1034   mf->v1 = getFaceIndex(ss, f, grid, x + 0, y + 0, edgeSize, gridSize);
1035   mf->v2 = getFaceIndex(ss, f, grid, x + 0, y + 1, edgeSize, gridSize);
1036   mf->v3 = getFaceIndex(ss, f, grid, x + 1, y + 1, edgeSize, gridSize);
1037   mf->v4 = getFaceIndex(ss, f, grid, x + 1, y + 0, edgeSize, gridSize);
1038 
1039   if (faceFlags) {
1040     mf->flag = faceFlags[i].flag;
1041     mf->mat_nr = faceFlags[i].mat_nr;
1042   }
1043   else {
1044     mf->flag = ME_SMOOTH;
1045   }
1046 
1047   mf->edcode = 0;
1048 }
1049 
1050 /* Translate GridHidden into the ME_HIDE flag for MVerts. Assumes
1051  * vertices are in the order output by ccgDM_copyFinalVertArray. */
subsurf_copy_grid_hidden(DerivedMesh * dm,const MPoly * mpoly,MVert * mvert,const MDisps * mdisps)1052 void subsurf_copy_grid_hidden(DerivedMesh *dm,
1053                               const MPoly *mpoly,
1054                               MVert *mvert,
1055                               const MDisps *mdisps)
1056 {
1057   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1058   CCGSubSurf *ss = ccgdm->ss;
1059   int level = ccgSubSurf_getSubdivisionLevels(ss);
1060   int gridSize = ccgSubSurf_getGridSize(ss);
1061   int edgeSize = ccgSubSurf_getEdgeSize(ss);
1062   int totface = ccgSubSurf_getNumFaces(ss);
1063   int i, j, x, y;
1064 
1065   for (i = 0; i < totface; i++) {
1066     CCGFace *f = ccgdm->faceMap[i].face;
1067 
1068     for (j = 0; j < mpoly[i].totloop; j++) {
1069       const MDisps *md = &mdisps[mpoly[i].loopstart + j];
1070       int hidden_gridsize = BKE_ccg_gridsize(md->level);
1071       int factor = BKE_ccg_factor(level, md->level);
1072       BLI_bitmap *hidden = md->hidden;
1073 
1074       if (!hidden) {
1075         continue;
1076       }
1077 
1078       for (y = 0; y < gridSize; y++) {
1079         for (x = 0; x < gridSize; x++) {
1080           int vndx, offset;
1081 
1082           vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
1083           offset = (y * factor) * hidden_gridsize + (x * factor);
1084           if (BLI_BITMAP_TEST(hidden, offset)) {
1085             mvert[vndx].flag |= ME_HIDE;
1086           }
1087         }
1088       }
1089     }
1090   }
1091 }
1092 
1093 /* Translate GridPaintMask into vertex paint masks. Assumes vertices
1094  * are in the order output by ccgDM_copyFinalVertArray. */
subsurf_copy_grid_paint_mask(DerivedMesh * dm,const MPoly * mpoly,float * paint_mask,const GridPaintMask * grid_paint_mask)1095 void subsurf_copy_grid_paint_mask(DerivedMesh *dm,
1096                                   const MPoly *mpoly,
1097                                   float *paint_mask,
1098                                   const GridPaintMask *grid_paint_mask)
1099 {
1100   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1101   CCGSubSurf *ss = ccgdm->ss;
1102   int level = ccgSubSurf_getSubdivisionLevels(ss);
1103   int gridSize = ccgSubSurf_getGridSize(ss);
1104   int edgeSize = ccgSubSurf_getEdgeSize(ss);
1105   int totface = ccgSubSurf_getNumFaces(ss);
1106   int i, j, x, y, factor, gpm_gridsize;
1107 
1108   for (i = 0; i < totface; i++) {
1109     CCGFace *f = ccgdm->faceMap[i].face;
1110     const MPoly *p = &mpoly[i];
1111 
1112     for (j = 0; j < p->totloop; j++) {
1113       const GridPaintMask *gpm = &grid_paint_mask[p->loopstart + j];
1114       if (!gpm->data) {
1115         continue;
1116       }
1117 
1118       factor = BKE_ccg_factor(level, gpm->level);
1119       gpm_gridsize = BKE_ccg_gridsize(gpm->level);
1120 
1121       for (y = 0; y < gridSize; y++) {
1122         for (x = 0; x < gridSize; x++) {
1123           int vndx, offset;
1124 
1125           vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize);
1126           offset = y * factor * gpm_gridsize + x * factor;
1127           paint_mask[vndx] = gpm->data[offset];
1128         }
1129       }
1130     }
1131   }
1132 }
1133 
1134 /* utility function */
ccgDM_to_MVert(MVert * mv,const CCGKey * key,CCGElem * elem)1135 BLI_INLINE void ccgDM_to_MVert(MVert *mv, const CCGKey *key, CCGElem *elem)
1136 {
1137   copy_v3_v3(mv->co, CCG_elem_co(key, elem));
1138   normal_float_to_short_v3(mv->no, CCG_elem_no(key, elem));
1139   mv->flag = mv->bweight = 0;
1140 }
1141 
ccgDM_copyFinalVertArray(DerivedMesh * dm,MVert * mvert)1142 static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
1143 {
1144   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1145   CCGSubSurf *ss = ccgdm->ss;
1146   CCGElem *vd;
1147   CCGKey key;
1148   int index;
1149   int totvert, totedge, totface;
1150   int gridSize = ccgSubSurf_getGridSize(ss);
1151   int edgeSize = ccgSubSurf_getEdgeSize(ss);
1152   unsigned int i = 0;
1153 
1154   CCG_key_top_level(&key, ss);
1155 
1156   totface = ccgSubSurf_getNumFaces(ss);
1157   for (index = 0; index < totface; index++) {
1158     CCGFace *f = ccgdm->faceMap[index].face;
1159     int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1160 
1161     vd = ccgSubSurf_getFaceCenterData(f);
1162     ccgDM_to_MVert(&mvert[i++], &key, vd);
1163 
1164     for (S = 0; S < numVerts; S++) {
1165       for (x = 1; x < gridSize - 1; x++) {
1166         vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
1167         ccgDM_to_MVert(&mvert[i++], &key, vd);
1168       }
1169     }
1170 
1171     for (S = 0; S < numVerts; S++) {
1172       for (y = 1; y < gridSize - 1; y++) {
1173         for (x = 1; x < gridSize - 1; x++) {
1174           vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y);
1175           ccgDM_to_MVert(&mvert[i++], &key, vd);
1176         }
1177       }
1178     }
1179   }
1180 
1181   totedge = ccgSubSurf_getNumEdges(ss);
1182   for (index = 0; index < totedge; index++) {
1183     CCGEdge *e = ccgdm->edgeMap[index].edge;
1184     int x;
1185 
1186     for (x = 1; x < edgeSize - 1; x++) {
1187       /* This gives errors with -debug-fpe
1188        * the normals don't seem to be unit length.
1189        * this is most likely caused by edges with no
1190        * faces which are now zerod out, see comment in:
1191        * ccgSubSurf__calcVertNormals(), - campbell */
1192       vd = ccgSubSurf_getEdgeData(ss, e, x);
1193       ccgDM_to_MVert(&mvert[i++], &key, vd);
1194     }
1195   }
1196 
1197   totvert = ccgSubSurf_getNumVerts(ss);
1198   for (index = 0; index < totvert; index++) {
1199     CCGVert *v = ccgdm->vertMap[index].vert;
1200 
1201     vd = ccgSubSurf_getVertData(ss, v);
1202     ccgDM_to_MVert(&mvert[i++], &key, vd);
1203   }
1204 }
1205 
1206 /* utility function */
ccgDM_to_MEdge(MEdge * med,const int v1,const int v2,const short flag)1207 BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2, const short flag)
1208 {
1209   med->v1 = v1;
1210   med->v2 = v2;
1211   med->crease = med->bweight = 0;
1212   med->flag = flag;
1213 }
1214 
ccgDM_copyFinalEdgeArray(DerivedMesh * dm,MEdge * medge)1215 static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
1216 {
1217   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1218   CCGSubSurf *ss = ccgdm->ss;
1219   int index;
1220   int totedge, totface;
1221   int gridSize = ccgSubSurf_getGridSize(ss);
1222   int edgeSize = ccgSubSurf_getEdgeSize(ss);
1223   unsigned int i = 0;
1224   short *edgeFlags = ccgdm->edgeFlags;
1225   const short ed_interior_flag = ccgdm->drawInteriorEdges ? (ME_EDGEDRAW | ME_EDGERENDER) : 0;
1226 
1227   totface = ccgSubSurf_getNumFaces(ss);
1228   for (index = 0; index < totface; index++) {
1229     CCGFace *f = ccgdm->faceMap[index].face;
1230     int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1231 
1232     for (S = 0; S < numVerts; S++) {
1233       for (x = 0; x < gridSize - 1; x++) {
1234         ccgDM_to_MEdge(&medge[i++],
1235                        getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize),
1236                        getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize),
1237                        ed_interior_flag);
1238       }
1239 
1240       for (x = 1; x < gridSize - 1; x++) {
1241         for (y = 0; y < gridSize - 1; y++) {
1242           ccgDM_to_MEdge(&medge[i++],
1243                          getFaceIndex(ss, f, S, x, y, edgeSize, gridSize),
1244                          getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize),
1245                          ed_interior_flag);
1246           ccgDM_to_MEdge(&medge[i++],
1247                          getFaceIndex(ss, f, S, y, x, edgeSize, gridSize),
1248                          getFaceIndex(ss, f, S, y + 1, x, edgeSize, gridSize),
1249                          ed_interior_flag);
1250         }
1251       }
1252     }
1253   }
1254 
1255   totedge = ccgSubSurf_getNumEdges(ss);
1256   for (index = 0; index < totedge; index++) {
1257     CCGEdge *e = ccgdm->edgeMap[index].edge;
1258     short ed_flag = 0;
1259     int x;
1260     int edgeIdx = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e));
1261 
1262     if (!ccgSubSurf_getEdgeNumFaces(e)) {
1263       ed_flag |= ME_LOOSEEDGE;
1264     }
1265 
1266     if (edgeFlags) {
1267       if (edgeIdx != -1) {
1268         ed_flag |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER);
1269       }
1270     }
1271     else {
1272       ed_flag |= ME_EDGEDRAW | ME_EDGERENDER;
1273     }
1274 
1275     for (x = 0; x < edgeSize - 1; x++) {
1276       ccgDM_to_MEdge(&medge[i++],
1277                      getEdgeIndex(ss, e, x, edgeSize),
1278                      getEdgeIndex(ss, e, x + 1, edgeSize),
1279                      ed_flag);
1280     }
1281   }
1282 }
1283 
ccgDM_copyFinalFaceArray(DerivedMesh * dm,MFace * mface)1284 static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
1285 {
1286   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1287   CCGSubSurf *ss = ccgdm->ss;
1288   int index;
1289   int totface;
1290   int gridSize = ccgSubSurf_getGridSize(ss);
1291   int edgeSize = ccgSubSurf_getEdgeSize(ss);
1292   int i = 0;
1293   DMFlagMat *faceFlags = ccgdm->faceFlags;
1294 
1295   totface = dm->getNumTessFaces(dm);
1296   for (index = 0; index < totface; index++) {
1297     CCGFace *f = ccgdm->faceMap[index].face;
1298     int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1299     /* keep types in sync with MFace, avoid many conversions */
1300     char flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH;
1301     short mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0;
1302 
1303     for (S = 0; S < numVerts; S++) {
1304       for (y = 0; y < gridSize - 1; y++) {
1305         for (x = 0; x < gridSize - 1; x++) {
1306           MFace *mf = &mface[i];
1307           mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0, edgeSize, gridSize);
1308           mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1, edgeSize, gridSize);
1309           mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1, edgeSize, gridSize);
1310           mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0, edgeSize, gridSize);
1311           mf->mat_nr = mat_nr;
1312           mf->flag = flag;
1313           mf->edcode = 0;
1314 
1315           i++;
1316         }
1317       }
1318     }
1319   }
1320 }
1321 
1322 typedef struct CopyFinalLoopArrayData {
1323   CCGDerivedMesh *ccgdm;
1324   MLoop *mloop;
1325   int grid_size;
1326   int *grid_offset;
1327   int edge_size;
1328   size_t mloop_index;
1329 } CopyFinalLoopArrayData;
1330 
copyFinalLoopArray_task_cb(void * __restrict userdata,const int iter,const TaskParallelTLS * __restrict UNUSED (tls))1331 static void copyFinalLoopArray_task_cb(void *__restrict userdata,
1332                                        const int iter,
1333                                        const TaskParallelTLS *__restrict UNUSED(tls))
1334 {
1335   CopyFinalLoopArrayData *data = userdata;
1336   CCGDerivedMesh *ccgdm = data->ccgdm;
1337   CCGSubSurf *ss = ccgdm->ss;
1338   const int grid_size = data->grid_size;
1339   const int edge_size = data->edge_size;
1340   CCGFace *f = ccgdm->faceMap[iter].face;
1341   const int num_verts = ccgSubSurf_getFaceNumVerts(f);
1342   const int grid_index = data->grid_offset[iter];
1343   const size_t loop_index = 4 * (size_t)grid_index * (grid_size - 1) * (grid_size - 1);
1344   MLoop *ml = &data->mloop[loop_index];
1345   for (int S = 0; S < num_verts; S++) {
1346     for (int y = 0; y < grid_size - 1; y++) {
1347       for (int x = 0; x < grid_size - 1; x++) {
1348 
1349         uint v1 = getFaceIndex(ss, f, S, x + 0, y + 0, edge_size, grid_size);
1350         uint v2 = getFaceIndex(ss, f, S, x + 0, y + 1, edge_size, grid_size);
1351         uint v3 = getFaceIndex(ss, f, S, x + 1, y + 1, edge_size, grid_size);
1352         uint v4 = getFaceIndex(ss, f, S, x + 1, y + 0, edge_size, grid_size);
1353 
1354         ml->v = v1;
1355         ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v1, v2));
1356         ml++;
1357 
1358         ml->v = v2;
1359         ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v2, v3));
1360         ml++;
1361 
1362         ml->v = v3;
1363         ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v3, v4));
1364         ml++;
1365 
1366         ml->v = v4;
1367         ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v4, v1));
1368         ml++;
1369       }
1370     }
1371   }
1372 }
1373 
ccgDM_copyFinalLoopArray(DerivedMesh * dm,MLoop * mloop)1374 static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
1375 {
1376   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1377   CCGSubSurf *ss = ccgdm->ss;
1378 
1379   if (!ccgdm->ehash) {
1380     BLI_mutex_lock(&ccgdm->loops_cache_lock);
1381     if (!ccgdm->ehash) {
1382       MEdge *medge;
1383       EdgeHash *ehash;
1384 
1385       ehash = BLI_edgehash_new_ex(__func__, ccgdm->dm.numEdgeData);
1386       medge = ccgdm->dm.getEdgeArray((DerivedMesh *)ccgdm);
1387 
1388       for (int i = 0; i < ccgdm->dm.numEdgeData; i++) {
1389         BLI_edgehash_insert(ehash, medge[i].v1, medge[i].v2, POINTER_FROM_INT(i));
1390       }
1391 
1392       atomic_cas_ptr((void **)&ccgdm->ehash, ccgdm->ehash, ehash);
1393     }
1394     BLI_mutex_unlock(&ccgdm->loops_cache_lock);
1395   }
1396 
1397   CopyFinalLoopArrayData data;
1398   data.ccgdm = ccgdm;
1399   data.mloop = mloop;
1400   data.grid_size = ccgSubSurf_getGridSize(ss);
1401   data.grid_offset = dm->getGridOffset(dm);
1402   data.edge_size = ccgSubSurf_getEdgeSize(ss);
1403 
1404   /* NOTE: For a dense subdivision we've got enough work for each face and
1405    * hence can dedicate whole thread to single face. For less dense
1406    * subdivision we handle multiple faces per thread.
1407    */
1408   data.mloop_index = data.grid_size >= 5 ? 1 : 8;
1409 
1410   TaskParallelSettings settings;
1411   BLI_parallel_range_settings_defaults(&settings);
1412   settings.min_iter_per_thread = 1;
1413 
1414   BLI_task_parallel_range(
1415       0, ccgSubSurf_getNumFaces(ss), &data, copyFinalLoopArray_task_cb, &settings);
1416 }
1417 
ccgDM_copyFinalPolyArray(DerivedMesh * dm,MPoly * mpoly)1418 static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mpoly)
1419 {
1420   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1421   CCGSubSurf *ss = ccgdm->ss;
1422   int index;
1423   int totface;
1424   int gridSize = ccgSubSurf_getGridSize(ss);
1425   /* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */
1426   int i = 0, k = 0;
1427   DMFlagMat *faceFlags = ccgdm->faceFlags;
1428 
1429   totface = ccgSubSurf_getNumFaces(ss);
1430   for (index = 0; index < totface; index++) {
1431     CCGFace *f = ccgdm->faceMap[index].face;
1432     int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1433     int flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH;
1434     int mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0;
1435 
1436     for (S = 0; S < numVerts; S++) {
1437       for (y = 0; y < gridSize - 1; y++) {
1438         for (x = 0; x < gridSize - 1; x++) {
1439           MPoly *mp = &mpoly[i];
1440 
1441           mp->mat_nr = mat_nr;
1442           mp->flag = flag;
1443           mp->loopstart = k;
1444           mp->totloop = 4;
1445 
1446           k += 4;
1447           i++;
1448         }
1449       }
1450     }
1451   }
1452 }
1453 
ccgDM_release(DerivedMesh * dm)1454 static void ccgDM_release(DerivedMesh *dm)
1455 {
1456   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1457 
1458   if (DM_release(dm)) {
1459     /* Before freeing, need to update the displacement map */
1460     if (ccgdm->multires.modified_flags) {
1461       /* Check that mmd still exists */
1462       if (!ccgdm->multires.local_mmd &&
1463           BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0) {
1464         ccgdm->multires.mmd = NULL;
1465       }
1466 
1467       if (ccgdm->multires.mmd) {
1468         if (ccgdm->multires.modified_flags & MULTIRES_COORDS_MODIFIED) {
1469           multires_modifier_update_mdisps(dm, NULL);
1470         }
1471         if (ccgdm->multires.modified_flags & MULTIRES_HIDDEN_MODIFIED) {
1472           multires_modifier_update_hidden(dm);
1473         }
1474       }
1475     }
1476 
1477     if (ccgdm->ehash) {
1478       BLI_edgehash_free(ccgdm->ehash, NULL);
1479     }
1480 
1481     if (ccgdm->reverseFaceMap) {
1482       MEM_freeN(ccgdm->reverseFaceMap);
1483     }
1484     if (ccgdm->gridFaces) {
1485       MEM_freeN(ccgdm->gridFaces);
1486     }
1487     if (ccgdm->gridData) {
1488       MEM_freeN(ccgdm->gridData);
1489     }
1490     if (ccgdm->gridOffset) {
1491       MEM_freeN(ccgdm->gridOffset);
1492     }
1493     if (ccgdm->gridFlagMats) {
1494       MEM_freeN(ccgdm->gridFlagMats);
1495     }
1496     if (ccgdm->gridHidden) {
1497       /* Using dm->getNumGrids(dm) accesses freed memory */
1498       uint numGrids = ccgdm->numGrid;
1499       for (uint i = 0; i < numGrids; i++) {
1500         if (ccgdm->gridHidden[i]) {
1501           MEM_freeN(ccgdm->gridHidden[i]);
1502         }
1503       }
1504       MEM_freeN(ccgdm->gridHidden);
1505     }
1506     if (ccgdm->freeSS) {
1507       ccgSubSurf_free(ccgdm->ss);
1508     }
1509     if (ccgdm->pmap) {
1510       MEM_freeN(ccgdm->pmap);
1511     }
1512     if (ccgdm->pmap_mem) {
1513       MEM_freeN(ccgdm->pmap_mem);
1514     }
1515     MEM_freeN(ccgdm->edgeFlags);
1516     MEM_freeN(ccgdm->faceFlags);
1517     MEM_freeN(ccgdm->vertMap);
1518     MEM_freeN(ccgdm->edgeMap);
1519     MEM_freeN(ccgdm->faceMap);
1520 
1521     BLI_mutex_end(&ccgdm->loops_cache_lock);
1522     BLI_rw_mutex_end(&ccgdm->origindex_cache_rwlock);
1523 
1524     MEM_freeN(ccgdm);
1525   }
1526 }
1527 
ccgDM_get_vert_data_layer(DerivedMesh * dm,int type)1528 static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
1529 {
1530   if (type == CD_ORIGINDEX) {
1531     /* create origindex on demand to save memory */
1532     CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1533     CCGSubSurf *ss = ccgdm->ss;
1534     int *origindex;
1535     int a, index, totnone, totorig;
1536 
1537     /* Avoid re-creation if the layer exists already */
1538     BLI_rw_mutex_lock(&ccgdm->origindex_cache_rwlock, THREAD_LOCK_READ);
1539     origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1540     BLI_rw_mutex_unlock(&ccgdm->origindex_cache_rwlock);
1541     if (origindex) {
1542       return origindex;
1543     }
1544 
1545     BLI_rw_mutex_lock(&ccgdm->origindex_cache_rwlock, THREAD_LOCK_WRITE);
1546     DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
1547     origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1548 
1549     totorig = ccgSubSurf_getNumVerts(ss);
1550     totnone = dm->numVertData - totorig;
1551 
1552     /* original vertices are at the end */
1553     for (a = 0; a < totnone; a++) {
1554       origindex[a] = ORIGINDEX_NONE;
1555     }
1556 
1557     for (index = 0; index < totorig; index++, a++) {
1558       CCGVert *v = ccgdm->vertMap[index].vert;
1559       origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
1560     }
1561     BLI_rw_mutex_unlock(&ccgdm->origindex_cache_rwlock);
1562 
1563     return origindex;
1564   }
1565 
1566   return DM_get_vert_data_layer(dm, type);
1567 }
1568 
ccgDM_get_edge_data_layer(DerivedMesh * dm,int type)1569 static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
1570 {
1571   if (type == CD_ORIGINDEX) {
1572     /* create origindex on demand to save memory */
1573     CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1574     CCGSubSurf *ss = ccgdm->ss;
1575     int *origindex;
1576     int a, i, index, totnone, totorig, totedge;
1577     int edgeSize = ccgSubSurf_getEdgeSize(ss);
1578 
1579     /* Avoid re-creation if the layer exists already */
1580     origindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1581     if (origindex) {
1582       return origindex;
1583     }
1584 
1585     DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
1586     origindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1587 
1588     totedge = ccgSubSurf_getNumEdges(ss);
1589     totorig = totedge * (edgeSize - 1);
1590     totnone = dm->numEdgeData - totorig;
1591 
1592     /* original edges are at the end */
1593     for (a = 0; a < totnone; a++) {
1594       origindex[a] = ORIGINDEX_NONE;
1595     }
1596 
1597     for (index = 0; index < totedge; index++) {
1598       CCGEdge *e = ccgdm->edgeMap[index].edge;
1599       int mapIndex = ccgDM_getEdgeMapIndex(ss, e);
1600 
1601       for (i = 0; i < edgeSize - 1; i++, a++) {
1602         origindex[a] = mapIndex;
1603       }
1604     }
1605 
1606     return origindex;
1607   }
1608 
1609   return DM_get_edge_data_layer(dm, type);
1610 }
1611 
ccgDM_get_tessface_data_layer(DerivedMesh * dm,int type)1612 static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type)
1613 {
1614   if (type == CD_ORIGINDEX) {
1615     /* create origindex on demand to save memory */
1616     int *origindex;
1617 
1618     /* Avoid re-creation if the layer exists already */
1619     origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
1620     if (origindex) {
1621       return origindex;
1622     }
1623 
1624     DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
1625     origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
1626 
1627     /* silly loop counting up */
1628     range_vn_i(origindex, dm->getNumTessFaces(dm), 0);
1629 
1630     return origindex;
1631   }
1632 
1633   if (type == CD_TESSLOOPNORMAL) {
1634     /* Create tessloopnormal on demand to save memory. */
1635     /* Note that since tessellated face corners are the same a loops in CCGDM,
1636      * and since all faces have four loops/corners, we can simplify the code
1637      * here by converting tessloopnormals from 'short (*)[4][3]' to 'short (*)[3]'. */
1638     short(*tlnors)[3];
1639 
1640     /* Avoid re-creation if the layer exists already */
1641     tlnors = DM_get_tessface_data_layer(dm, CD_TESSLOOPNORMAL);
1642     if (!tlnors) {
1643       float(*lnors)[3];
1644       short(*tlnors_it)[3];
1645       const int numLoops = ccgDM_getNumLoops(dm);
1646       int i;
1647 
1648       lnors = dm->getLoopDataArray(dm, CD_NORMAL);
1649       if (!lnors) {
1650         return NULL;
1651       }
1652 
1653       DM_add_tessface_layer(dm, CD_TESSLOOPNORMAL, CD_CALLOC, NULL);
1654       tlnors = tlnors_it = (short(*)[3])DM_get_tessface_data_layer(dm, CD_TESSLOOPNORMAL);
1655 
1656       /* With ccgdm, we have a simple one to one mapping between loops
1657        * and tessellated face corners. */
1658       for (i = 0; i < numLoops; i++, tlnors_it++, lnors++) {
1659         normal_float_to_short_v3(*tlnors_it, *lnors);
1660       }
1661     }
1662 
1663     return tlnors;
1664   }
1665 
1666   return DM_get_tessface_data_layer(dm, type);
1667 }
1668 
ccgDM_get_poly_data_layer(DerivedMesh * dm,int type)1669 static void *ccgDM_get_poly_data_layer(DerivedMesh *dm, int type)
1670 {
1671   if (type == CD_ORIGINDEX) {
1672     /* create origindex on demand to save memory */
1673     CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1674     CCGSubSurf *ss = ccgdm->ss;
1675     int *origindex;
1676     int a, i, index, totface;
1677     int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
1678 
1679     /* Avoid re-creation if the layer exists already */
1680     origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
1681     if (origindex) {
1682       return origindex;
1683     }
1684 
1685     DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
1686     origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
1687 
1688     totface = ccgSubSurf_getNumFaces(ss);
1689 
1690     for (a = 0, index = 0; index < totface; index++) {
1691       CCGFace *f = ccgdm->faceMap[index].face;
1692       int numVerts = ccgSubSurf_getFaceNumVerts(f);
1693       int mapIndex = ccgDM_getFaceMapIndex(ss, f);
1694 
1695       for (i = 0; i < gridFaces * gridFaces * numVerts; i++, a++) {
1696         origindex[a] = mapIndex;
1697       }
1698     }
1699 
1700     return origindex;
1701   }
1702 
1703   return DM_get_poly_data_layer(dm, type);
1704 }
1705 
ccgDM_get_vert_data(DerivedMesh * dm,int index,int type)1706 static void *ccgDM_get_vert_data(DerivedMesh *dm, int index, int type)
1707 {
1708   if (type == CD_ORIGINDEX) {
1709     /* ensure creation of CD_ORIGINDEX layer */
1710     ccgDM_get_vert_data_layer(dm, type);
1711   }
1712 
1713   return DM_get_vert_data(dm, index, type);
1714 }
1715 
ccgDM_get_edge_data(DerivedMesh * dm,int index,int type)1716 static void *ccgDM_get_edge_data(DerivedMesh *dm, int index, int type)
1717 {
1718   if (type == CD_ORIGINDEX) {
1719     /* ensure creation of CD_ORIGINDEX layer */
1720     ccgDM_get_edge_data_layer(dm, type);
1721   }
1722 
1723   return DM_get_edge_data(dm, index, type);
1724 }
1725 
ccgDM_get_tessface_data(DerivedMesh * dm,int index,int type)1726 static void *ccgDM_get_tessface_data(DerivedMesh *dm, int index, int type)
1727 {
1728   if (ELEM(type, CD_ORIGINDEX, CD_TESSLOOPNORMAL)) {
1729     /* ensure creation of CD_ORIGINDEX/CD_TESSLOOPNORMAL layers */
1730     ccgDM_get_tessface_data_layer(dm, type);
1731   }
1732 
1733   return DM_get_tessface_data(dm, index, type);
1734 }
1735 
ccgDM_get_poly_data(DerivedMesh * dm,int index,int type)1736 static void *ccgDM_get_poly_data(DerivedMesh *dm, int index, int type)
1737 {
1738   if (type == CD_ORIGINDEX) {
1739     /* ensure creation of CD_ORIGINDEX layer */
1740     ccgDM_get_tessface_data_layer(dm, type);
1741   }
1742 
1743   return DM_get_poly_data(dm, index, type);
1744 }
1745 
ccgDM_getNumGrids(DerivedMesh * dm)1746 static int ccgDM_getNumGrids(DerivedMesh *dm)
1747 {
1748   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1749   int index, numFaces, numGrids;
1750 
1751   numFaces = ccgSubSurf_getNumFaces(ccgdm->ss);
1752   numGrids = 0;
1753 
1754   for (index = 0; index < numFaces; index++) {
1755     CCGFace *f = ccgdm->faceMap[index].face;
1756     numGrids += ccgSubSurf_getFaceNumVerts(f);
1757   }
1758 
1759   return numGrids;
1760 }
1761 
ccgDM_getGridSize(DerivedMesh * dm)1762 static int ccgDM_getGridSize(DerivedMesh *dm)
1763 {
1764   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1765   return ccgSubSurf_getGridSize(ccgdm->ss);
1766 }
1767 
ccgdm_create_grids(DerivedMesh * dm)1768 static void ccgdm_create_grids(DerivedMesh *dm)
1769 {
1770   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1771   CCGSubSurf *ss = ccgdm->ss;
1772   CCGElem **gridData;
1773   DMFlagMat *gridFlagMats;
1774   CCGFace **gridFaces;
1775   int *gridOffset;
1776   int index, numFaces, numGrids, S, gIndex /*, gridSize*/;
1777 
1778   if (ccgdm->gridData) {
1779     return;
1780   }
1781 
1782   numGrids = ccgDM_getNumGrids(dm);
1783   numFaces = ccgSubSurf_getNumFaces(ss);
1784   /*gridSize = ccgDM_getGridSize(dm);*/ /*UNUSED*/
1785 
1786   /* compute offset into grid array for each face */
1787   gridOffset = MEM_mallocN(sizeof(int) * numFaces, "ccgdm.gridOffset");
1788 
1789   for (gIndex = 0, index = 0; index < numFaces; index++) {
1790     CCGFace *f = ccgdm->faceMap[index].face;
1791     int numVerts = ccgSubSurf_getFaceNumVerts(f);
1792 
1793     gridOffset[index] = gIndex;
1794     gIndex += numVerts;
1795   }
1796 
1797   /* compute grid data */
1798   gridData = MEM_mallocN(sizeof(CCGElem *) * numGrids, "ccgdm.gridData");
1799   gridFaces = MEM_mallocN(sizeof(CCGFace *) * numGrids, "ccgdm.gridFaces");
1800   gridFlagMats = MEM_mallocN(sizeof(DMFlagMat) * numGrids, "ccgdm.gridFlagMats");
1801 
1802   ccgdm->gridHidden = MEM_callocN(sizeof(*ccgdm->gridHidden) * numGrids, "ccgdm.gridHidden");
1803 
1804   for (gIndex = 0, index = 0; index < numFaces; index++) {
1805     CCGFace *f = ccgdm->faceMap[index].face;
1806     int numVerts = ccgSubSurf_getFaceNumVerts(f);
1807 
1808     for (S = 0; S < numVerts; S++, gIndex++) {
1809       gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1810       gridFaces[gIndex] = f;
1811       gridFlagMats[gIndex] = ccgdm->faceFlags[index];
1812     }
1813   }
1814 
1815   ccgdm->gridData = gridData;
1816   ccgdm->gridFaces = gridFaces;
1817   ccgdm->gridOffset = gridOffset;
1818   ccgdm->gridFlagMats = gridFlagMats;
1819   ccgdm->numGrid = numGrids;
1820 }
1821 
ccgDM_getGridData(DerivedMesh * dm)1822 static CCGElem **ccgDM_getGridData(DerivedMesh *dm)
1823 {
1824   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1825 
1826   ccgdm_create_grids(dm);
1827   return ccgdm->gridData;
1828 }
1829 
ccgDM_getGridOffset(DerivedMesh * dm)1830 static int *ccgDM_getGridOffset(DerivedMesh *dm)
1831 {
1832   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1833 
1834   ccgdm_create_grids(dm);
1835   return ccgdm->gridOffset;
1836 }
1837 
ccgDM_getGridKey(DerivedMesh * dm,CCGKey * key)1838 static void ccgDM_getGridKey(DerivedMesh *dm, CCGKey *key)
1839 {
1840   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1841   CCG_key_top_level(key, ccgdm->ss);
1842 }
1843 
ccgDM_getGridFlagMats(DerivedMesh * dm)1844 static DMFlagMat *ccgDM_getGridFlagMats(DerivedMesh *dm)
1845 {
1846   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1847 
1848   ccgdm_create_grids(dm);
1849   return ccgdm->gridFlagMats;
1850 }
1851 
ccgDM_getGridHidden(DerivedMesh * dm)1852 static BLI_bitmap **ccgDM_getGridHidden(DerivedMesh *dm)
1853 {
1854   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1855 
1856   ccgdm_create_grids(dm);
1857   return ccgdm->gridHidden;
1858 }
1859 
ccgDM_getPolyMap(Object * ob,DerivedMesh * dm)1860 static const MeshElemMap *ccgDM_getPolyMap(Object *ob, DerivedMesh *dm)
1861 {
1862   CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1863 
1864   if (!ccgdm->multires.mmd && !ccgdm->pmap && ob->type == OB_MESH) {
1865     Mesh *me = ob->data;
1866 
1867     BKE_mesh_vert_poly_map_create(&ccgdm->pmap,
1868                                   &ccgdm->pmap_mem,
1869                                   me->mpoly,
1870                                   me->mloop,
1871                                   me->totvert,
1872                                   me->totpoly,
1873                                   me->totloop);
1874   }
1875 
1876   return ccgdm->pmap;
1877 }
1878 
1879 /* WARNING! *MUST* be called in an 'loops_cache_rwlock' protected thread context! */
ccgDM_recalcLoopTri(DerivedMesh * dm)1880 static void ccgDM_recalcLoopTri(DerivedMesh *dm)
1881 {
1882   MLoopTri *mlooptri = dm->looptris.array;
1883   const int tottri = dm->numPolyData * 2;
1884   int i, poly_index;
1885 
1886   DM_ensure_looptri_data(dm);
1887   mlooptri = dm->looptris.array_wip;
1888 
1889   BLI_assert(tottri == 0 || mlooptri != NULL);
1890   BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
1891   BLI_assert(tottri == dm->looptris.num);
1892 
1893   for (i = 0, poly_index = 0; i < tottri; i += 2, poly_index += 1) {
1894     MLoopTri *lt;
1895     lt = &mlooptri[i];
1896     /* quad is (0, 3, 2, 1) */
1897     lt->tri[0] = (poly_index * 4) + 0;
1898     lt->tri[1] = (poly_index * 4) + 2;
1899     lt->tri[2] = (poly_index * 4) + 3;
1900     lt->poly = poly_index;
1901 
1902     lt = &mlooptri[i + 1];
1903     lt->tri[0] = (poly_index * 4) + 0;
1904     lt->tri[1] = (poly_index * 4) + 1;
1905     lt->tri[2] = (poly_index * 4) + 2;
1906     lt->poly = poly_index;
1907   }
1908 
1909   BLI_assert(dm->looptris.array == NULL);
1910   atomic_cas_ptr((void **)&dm->looptris.array, dm->looptris.array, dm->looptris.array_wip);
1911   dm->looptris.array_wip = NULL;
1912 }
1913 
set_default_ccgdm_callbacks(CCGDerivedMesh * ccgdm)1914 static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm)
1915 {
1916   ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
1917   ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
1918   ccgdm->dm.getNumLoops = ccgDM_getNumLoops;
1919   /* reuse of ccgDM_getNumTessFaces is intentional here:
1920    * subsurf polys are just created from tessfaces */
1921   ccgdm->dm.getNumPolys = ccgDM_getNumPolys;
1922   ccgdm->dm.getNumTessFaces = ccgDM_getNumTessFaces;
1923 
1924   ccgdm->dm.getVert = ccgDM_getFinalVert;
1925   ccgdm->dm.getEdge = ccgDM_getFinalEdge;
1926   ccgdm->dm.getTessFace = ccgDM_getFinalFace;
1927 
1928   ccgdm->dm.getVertCo = ccgDM_getFinalVertCo;
1929   ccgdm->dm.getVertNo = ccgDM_getFinalVertNo;
1930 
1931   ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
1932   ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
1933   ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray;
1934   ccgdm->dm.copyLoopArray = ccgDM_copyFinalLoopArray;
1935   ccgdm->dm.copyPolyArray = ccgDM_copyFinalPolyArray;
1936 
1937   ccgdm->dm.getVertData = ccgDM_get_vert_data;
1938   ccgdm->dm.getEdgeData = ccgDM_get_edge_data;
1939   ccgdm->dm.getTessFaceData = ccgDM_get_tessface_data;
1940   ccgdm->dm.getPolyData = ccgDM_get_poly_data;
1941   ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;
1942   ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer;
1943   ccgdm->dm.getTessFaceDataArray = ccgDM_get_tessface_data_layer;
1944   ccgdm->dm.getPolyDataArray = ccgDM_get_poly_data_layer;
1945   ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
1946   ccgdm->dm.getGridSize = ccgDM_getGridSize;
1947   ccgdm->dm.getGridData = ccgDM_getGridData;
1948   ccgdm->dm.getGridOffset = ccgDM_getGridOffset;
1949   ccgdm->dm.getGridKey = ccgDM_getGridKey;
1950   ccgdm->dm.getGridFlagMats = ccgDM_getGridFlagMats;
1951   ccgdm->dm.getGridHidden = ccgDM_getGridHidden;
1952   ccgdm->dm.getPolyMap = ccgDM_getPolyMap;
1953 
1954   ccgdm->dm.recalcLoopTri = ccgDM_recalcLoopTri;
1955 
1956   ccgdm->dm.release = ccgDM_release;
1957 }
1958 
create_ccgdm_maps(CCGDerivedMesh * ccgdm,CCGSubSurf * ss)1959 static void create_ccgdm_maps(CCGDerivedMesh *ccgdm, CCGSubSurf *ss)
1960 {
1961   CCGVertIterator vi;
1962   CCGEdgeIterator ei;
1963   CCGFaceIterator fi;
1964   int totvert, totedge, totface;
1965 
1966   totvert = ccgSubSurf_getNumVerts(ss);
1967   ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
1968   for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi);
1969        ccgVertIterator_next(&vi)) {
1970     CCGVert *v = ccgVertIterator_getCurrent(&vi);
1971 
1972     ccgdm->vertMap[POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v))].vert = v;
1973   }
1974 
1975   totedge = ccgSubSurf_getNumEdges(ss);
1976   ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
1977   for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei);
1978        ccgEdgeIterator_next(&ei)) {
1979     CCGEdge *e = ccgEdgeIterator_getCurrent(&ei);
1980 
1981     ccgdm->edgeMap[POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e;
1982   }
1983 
1984   totface = ccgSubSurf_getNumFaces(ss);
1985   ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
1986   for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi);
1987        ccgFaceIterator_next(&fi)) {
1988     CCGFace *f = ccgFaceIterator_getCurrent(&fi);
1989 
1990     ccgdm->faceMap[POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f))].face = f;
1991   }
1992 }
1993 
1994 /* Fill in all geometry arrays making it possible to access any
1995  * hires data from the CPU.
1996  */
set_ccgdm_all_geometry(CCGDerivedMesh * ccgdm,CCGSubSurf * ss,DerivedMesh * dm,bool useSubsurfUv)1997 static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
1998                                    CCGSubSurf *ss,
1999                                    DerivedMesh *dm,
2000                                    bool useSubsurfUv)
2001 {
2002   const int totvert = ccgSubSurf_getNumVerts(ss);
2003   const int totedge = ccgSubSurf_getNumEdges(ss);
2004   const int totface = ccgSubSurf_getNumFaces(ss);
2005   int index;
2006   int i;
2007   int vertNum = 0, edgeNum = 0, faceNum = 0;
2008   int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex, *edgeOrigIndex;
2009   short *edgeFlags = ccgdm->edgeFlags;
2010   DMFlagMat *faceFlags = ccgdm->faceFlags;
2011   int *polyidx = NULL;
2012 #ifndef USE_DYNSIZE
2013   int *loopidx = NULL, *vertidx = NULL;
2014   BLI_array_declare(loopidx);
2015   BLI_array_declare(vertidx);
2016 #endif
2017   int loopindex, loopindex2;
2018   int edgeSize;
2019   int gridSize;
2020   int gridFaces, gridCuts;
2021   int gridSideEdges;
2022   int gridInternalEdges;
2023   WeightTable wtable = {NULL};
2024   MEdge *medge = NULL;
2025   MPoly *mpoly = NULL;
2026   bool has_edge_cd;
2027 
2028   edgeSize = ccgSubSurf_getEdgeSize(ss);
2029   gridSize = ccgSubSurf_getGridSize(ss);
2030   gridFaces = gridSize - 1;
2031   gridCuts = gridSize - 2;
2032   /*gridInternalVerts = gridSideVerts * gridSideVerts; - as yet, unused */
2033   gridSideEdges = gridSize - 1;
2034   gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
2035 
2036   /* mvert = dm->getVertArray(dm); */ /* UNUSED */
2037   medge = dm->getEdgeArray(dm);
2038   /* mface = dm->getTessFaceArray(dm); */ /* UNUSED */
2039 
2040   mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2041   base_polyOrigIndex = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
2042 
2043   vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2044   edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2045 
2046   faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2047   polyOrigIndex = DM_get_poly_data_layer(&ccgdm->dm, CD_ORIGINDEX);
2048 
2049   has_edge_cd = ((ccgdm->dm.edgeData.totlayer - (edgeOrigIndex ? 1 : 0)) != 0);
2050 
2051   loopindex = loopindex2 = 0; /* current loop index */
2052   for (index = 0; index < totface; index++) {
2053     CCGFace *f = ccgdm->faceMap[index].face;
2054     int numVerts = ccgSubSurf_getFaceNumVerts(f);
2055     int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
2056     int origIndex = POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f));
2057     int g2_wid = gridCuts + 2;
2058     float *w, *w2;
2059     int s, x, y;
2060 #ifdef USE_DYNSIZE
2061     int loopidx[numVerts], vertidx[numVerts];
2062 #endif
2063     w = get_ss_weights(&wtable, gridCuts, numVerts);
2064 
2065     ccgdm->faceMap[index].startVert = vertNum;
2066     ccgdm->faceMap[index].startEdge = edgeNum;
2067     ccgdm->faceMap[index].startFace = faceNum;
2068 
2069     faceFlags->flag = mpoly ? mpoly[origIndex].flag : 0;
2070     faceFlags->mat_nr = mpoly ? mpoly[origIndex].mat_nr : 0;
2071     faceFlags++;
2072 
2073     /* set the face base vert */
2074     *((int *)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
2075 
2076 #ifndef USE_DYNSIZE
2077     BLI_array_clear(loopidx);
2078     BLI_array_grow_items(loopidx, numVerts);
2079 #endif
2080     for (s = 0; s < numVerts; s++) {
2081       loopidx[s] = loopindex++;
2082     }
2083 
2084 #ifndef USE_DYNSIZE
2085     BLI_array_clear(vertidx);
2086     BLI_array_grow_items(vertidx, numVerts);
2087 #endif
2088     for (s = 0; s < numVerts; s++) {
2089       CCGVert *v = ccgSubSurf_getFaceVert(f, s);
2090       vertidx[s] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
2091     }
2092 
2093     /*I think this is for interpolating the center vert?*/
2094     w2 = w;  // + numVerts*(g2_wid-1) * (g2_wid-1); //numVerts*((g2_wid-1) * g2_wid+g2_wid-1);
2095     DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum);
2096     if (vertOrigIndex) {
2097       *vertOrigIndex = ORIGINDEX_NONE;
2098       vertOrigIndex++;
2099     }
2100 
2101     vertNum++;
2102 
2103     /*interpolate per-vert data*/
2104     for (s = 0; s < numVerts; s++) {
2105       for (x = 1; x < gridFaces; x++) {
2106         w2 = w + s * numVerts * g2_wid * g2_wid + x * numVerts;
2107         DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum);
2108 
2109         if (vertOrigIndex) {
2110           *vertOrigIndex = ORIGINDEX_NONE;
2111           vertOrigIndex++;
2112         }
2113 
2114         vertNum++;
2115       }
2116     }
2117 
2118     /*interpolate per-vert data*/
2119     for (s = 0; s < numVerts; s++) {
2120       for (y = 1; y < gridFaces; y++) {
2121         for (x = 1; x < gridFaces; x++) {
2122           w2 = w + s * numVerts * g2_wid * g2_wid + (y * g2_wid + x) * numVerts;
2123           DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum);
2124 
2125           if (vertOrigIndex) {
2126             *vertOrigIndex = ORIGINDEX_NONE;
2127             vertOrigIndex++;
2128           }
2129 
2130           vertNum++;
2131         }
2132       }
2133     }
2134 
2135     if (edgeOrigIndex) {
2136       for (i = 0; i < numFinalEdges; i++) {
2137         edgeOrigIndex[edgeNum + i] = ORIGINDEX_NONE;
2138       }
2139     }
2140 
2141     for (s = 0; s < numVerts; s++) {
2142       /*interpolate per-face data*/
2143       for (y = 0; y < gridFaces; y++) {
2144         for (x = 0; x < gridFaces; x++) {
2145           w2 = w + s * numVerts * g2_wid * g2_wid + (y * g2_wid + x) * numVerts;
2146           CustomData_interp(
2147               &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
2148           loopindex2++;
2149 
2150           w2 = w + s * numVerts * g2_wid * g2_wid + ((y + 1) * g2_wid + (x)) * numVerts;
2151           CustomData_interp(
2152               &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
2153           loopindex2++;
2154 
2155           w2 = w + s * numVerts * g2_wid * g2_wid + ((y + 1) * g2_wid + (x + 1)) * numVerts;
2156           CustomData_interp(
2157               &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
2158           loopindex2++;
2159 
2160           w2 = w + s * numVerts * g2_wid * g2_wid + ((y)*g2_wid + (x + 1)) * numVerts;
2161           CustomData_interp(
2162               &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
2163           loopindex2++;
2164 
2165           /*copy over poly data, e.g. mtexpoly*/
2166           CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, origIndex, faceNum, 1);
2167 
2168           /*set original index data*/
2169           if (faceOrigIndex) {
2170             /* reference the index in 'polyOrigIndex' */
2171             *faceOrigIndex = faceNum;
2172             faceOrigIndex++;
2173           }
2174           if (polyOrigIndex) {
2175             *polyOrigIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
2176             polyOrigIndex++;
2177           }
2178 
2179           ccgdm->reverseFaceMap[faceNum] = index;
2180 
2181           /* This is a simple one to one mapping, here... */
2182           if (polyidx) {
2183             polyidx[faceNum] = faceNum;
2184           }
2185 
2186           faceNum++;
2187         }
2188       }
2189     }
2190 
2191     edgeNum += numFinalEdges;
2192   }
2193 
2194   for (index = 0; index < totedge; index++) {
2195     CCGEdge *e = ccgdm->edgeMap[index].edge;
2196     int numFinalEdges = edgeSize - 1;
2197     int mapIndex = ccgDM_getEdgeMapIndex(ss, e);
2198     int x;
2199     int vertIdx[2];
2200     int edgeIdx = POINTER_AS_INT(ccgSubSurf_getEdgeEdgeHandle(e));
2201 
2202     CCGVert *v;
2203     v = ccgSubSurf_getEdgeVert0(e);
2204     vertIdx[0] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
2205     v = ccgSubSurf_getEdgeVert1(e);
2206     vertIdx[1] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
2207 
2208     ccgdm->edgeMap[index].startVert = vertNum;
2209     ccgdm->edgeMap[index].startEdge = edgeNum;
2210 
2211     if (edgeIdx >= 0 && edgeFlags) {
2212       edgeFlags[edgeIdx] = medge[edgeIdx].flag;
2213     }
2214 
2215     /* set the edge base vert */
2216     *((int *)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
2217 
2218     for (x = 1; x < edgeSize - 1; x++) {
2219       float w[2];
2220       w[1] = (float)x / (edgeSize - 1);
2221       w[0] = 1 - w[1];
2222       DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
2223       if (vertOrigIndex) {
2224         *vertOrigIndex = ORIGINDEX_NONE;
2225         vertOrigIndex++;
2226       }
2227       vertNum++;
2228     }
2229 
2230     if (has_edge_cd) {
2231       BLI_assert(edgeIdx >= 0 && edgeIdx < dm->getNumEdges(dm));
2232       for (i = 0; i < numFinalEdges; i++) {
2233         CustomData_copy_data(&dm->edgeData, &ccgdm->dm.edgeData, edgeIdx, edgeNum + i, 1);
2234       }
2235     }
2236 
2237     if (edgeOrigIndex) {
2238       for (i = 0; i < numFinalEdges; i++) {
2239         edgeOrigIndex[edgeNum + i] = mapIndex;
2240       }
2241     }
2242 
2243     edgeNum += numFinalEdges;
2244   }
2245 
2246   if (useSubsurfUv) {
2247     CustomData *ldata = &ccgdm->dm.loopData;
2248     CustomData *dmldata = &dm->loopData;
2249     int numlayer = CustomData_number_of_layers(ldata, CD_MLOOPUV);
2250     int dmnumlayer = CustomData_number_of_layers(dmldata, CD_MLOOPUV);
2251 
2252     for (i = 0; i < numlayer && i < dmnumlayer; i++) {
2253       set_subsurf_uv(ss, dm, &ccgdm->dm, i);
2254     }
2255   }
2256 
2257   for (index = 0; index < totvert; index++) {
2258     CCGVert *v = ccgdm->vertMap[index].vert;
2259     int mapIndex = ccgDM_getVertMapIndex(ccgdm->ss, v);
2260     int vertIdx;
2261 
2262     vertIdx = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
2263 
2264     ccgdm->vertMap[index].startVert = vertNum;
2265 
2266     /* set the vert base vert */
2267     *((int *)ccgSubSurf_getVertUserData(ss, v)) = vertNum;
2268 
2269     DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
2270 
2271     if (vertOrigIndex) {
2272       *vertOrigIndex = mapIndex;
2273       vertOrigIndex++;
2274     }
2275     vertNum++;
2276   }
2277 
2278 #ifndef USE_DYNSIZE
2279   BLI_array_free(vertidx);
2280   BLI_array_free(loopidx);
2281 #endif
2282   free_ss_weights(&wtable);
2283 
2284   BLI_assert(vertNum == ccgSubSurf_getNumFinalVerts(ss));
2285   BLI_assert(edgeNum == ccgSubSurf_getNumFinalEdges(ss));
2286   BLI_assert(loopindex2 == ccgSubSurf_getNumFinalFaces(ss) * 4);
2287   BLI_assert(faceNum == ccgSubSurf_getNumFinalFaces(ss));
2288 }
2289 
getCCGDerivedMesh(CCGSubSurf * ss,int drawInteriorEdges,int useSubsurfUv,DerivedMesh * dm)2290 static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
2291                                          int drawInteriorEdges,
2292                                          int useSubsurfUv,
2293                                          DerivedMesh *dm)
2294 {
2295   const int totedge = ccgSubSurf_getNumEdges(ss);
2296   const int totface = ccgSubSurf_getNumFaces(ss);
2297   CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
2298 
2299   BLI_assert(totedge == ccgSubSurf_getNumEdges(ss));
2300   BLI_assert(totface == ccgSubSurf_getNumFaces(ss));
2301   DM_from_template(&ccgdm->dm,
2302                    dm,
2303                    DM_TYPE_CCGDM,
2304                    ccgSubSurf_getNumFinalVerts(ss),
2305                    ccgSubSurf_getNumFinalEdges(ss),
2306                    0,
2307                    ccgSubSurf_getNumFinalFaces(ss) * 4,
2308                    ccgSubSurf_getNumFinalFaces(ss));
2309 
2310   CustomData_free_layer_active(&ccgdm->dm.polyData, CD_NORMAL, ccgdm->dm.numPolyData);
2311 
2312   ccgdm->reverseFaceMap = MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss),
2313                                       "reverseFaceMap");
2314 
2315   create_ccgdm_maps(ccgdm, ss);
2316 
2317   set_default_ccgdm_callbacks(ccgdm);
2318 
2319   ccgdm->ss = ss;
2320   ccgdm->drawInteriorEdges = drawInteriorEdges;
2321   ccgdm->useSubsurfUv = useSubsurfUv;
2322 
2323   /* CDDM hack. */
2324   ccgdm->edgeFlags = MEM_callocN(sizeof(short) * totedge, "edgeFlags");
2325   ccgdm->faceFlags = MEM_callocN(sizeof(DMFlagMat) * totface, "faceFlags");
2326 
2327   set_ccgdm_all_geometry(ccgdm, ss, dm, useSubsurfUv != 0);
2328 
2329   ccgdm->dm.numVertData = ccgSubSurf_getNumFinalVerts(ss);
2330   ccgdm->dm.numEdgeData = ccgSubSurf_getNumFinalEdges(ss);
2331   ccgdm->dm.numPolyData = ccgSubSurf_getNumFinalFaces(ss);
2332   ccgdm->dm.numLoopData = ccgdm->dm.numPolyData * 4;
2333   ccgdm->dm.numTessFaceData = 0;
2334 
2335   BLI_mutex_init(&ccgdm->loops_cache_lock);
2336   BLI_rw_mutex_init(&ccgdm->origindex_cache_rwlock);
2337 
2338   return ccgdm;
2339 }
2340 
2341 /***/
2342 
subsurf_make_derived_from_derived(struct DerivedMesh * dm,struct SubsurfModifierData * smd,const struct Scene * scene,float (* vertCos)[3],SubsurfFlags flags)2343 struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm,
2344                                                       struct SubsurfModifierData *smd,
2345                                                       const struct Scene *scene,
2346                                                       float (*vertCos)[3],
2347                                                       SubsurfFlags flags)
2348 {
2349   const int useSimple = (smd->subdivType == ME_SIMPLE_SUBSURF) ? CCG_SIMPLE_SUBDIV : 0;
2350   const CCGFlags useAging = (smd->flags & eSubsurfModifierFlag_DebugIncr) ? CCG_USE_AGING : 0;
2351   const int useSubsurfUv = (smd->uv_smooth != SUBSURF_UV_SMOOTH_NONE);
2352   const int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
2353   const bool ignore_simplify = (flags & SUBSURF_IGNORE_SIMPLIFY);
2354   CCGDerivedMesh *result;
2355 
2356   /* note: editmode calculation can only run once per
2357    * modifier stack evaluation (uses freed cache) T36299. */
2358   if (flags & SUBSURF_FOR_EDIT_MODE) {
2359     int levels = (scene != NULL && !ignore_simplify) ?
2360                      get_render_subsurf_level(&scene->r, smd->levels, false) :
2361                      smd->levels;
2362 
2363     /* TODO(sergey): Same as emCache below. */
2364     if ((flags & SUBSURF_IN_EDIT_MODE) && smd->mCache) {
2365       ccgSubSurf_free(smd->mCache);
2366       smd->mCache = NULL;
2367     }
2368 
2369     smd->emCache = _getSubSurf(smd->emCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
2370 
2371     ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple, useSubsurfUv);
2372     result = getCCGDerivedMesh(smd->emCache, drawInteriorEdges, useSubsurfUv, dm);
2373   }
2374   else if (flags & SUBSURF_USE_RENDER_PARAMS) {
2375     /* Do not use cache in render mode. */
2376     CCGSubSurf *ss;
2377     int levels = (scene != NULL && !ignore_simplify) ?
2378                      get_render_subsurf_level(&scene->r, smd->renderLevels, true) :
2379                      smd->renderLevels;
2380 
2381     if (levels == 0) {
2382       return dm;
2383     }
2384 
2385     ss = _getSubSurf(NULL, levels, 3, useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS);
2386 
2387     ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
2388 
2389     result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
2390 
2391     result->freeSS = 1;
2392   }
2393   else {
2394     int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
2395     int levels = (scene != NULL && !ignore_simplify) ?
2396                      get_render_subsurf_level(&scene->r, smd->levels, false) :
2397                      smd->levels;
2398     CCGSubSurf *ss;
2399 
2400     /* It is quite possible there is a much better place to do this. It
2401      * depends a bit on how rigorously we expect this function to never
2402      * be called in editmode. In semi-theory we could share a single
2403      * cache, but the handles used inside and outside editmode are not
2404      * the same so we would need some way of converting them. Its probably
2405      * not worth the effort. But then why am I even writing this long
2406      * comment that no one will read? Hmmm. - zr
2407      *
2408      * Addendum: we can't really ensure that this is never called in edit
2409      * mode, so now we have a parameter to verify it. - brecht
2410      */
2411     if (!(flags & SUBSURF_IN_EDIT_MODE) && smd->emCache) {
2412       ccgSubSurf_free(smd->emCache);
2413       smd->emCache = NULL;
2414     }
2415 
2416     if (useIncremental && (flags & SUBSURF_IS_FINAL_CALC)) {
2417       smd->mCache = ss = _getSubSurf(
2418           smd->mCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
2419 
2420       ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
2421 
2422       result = getCCGDerivedMesh(smd->mCache, drawInteriorEdges, useSubsurfUv, dm);
2423     }
2424     else {
2425       CCGFlags ccg_flags = useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS;
2426       CCGSubSurf *prevSS = NULL;
2427 
2428       if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) {
2429         ccgSubSurf_free(smd->mCache);
2430         smd->mCache = NULL;
2431       }
2432 
2433       if (flags & SUBSURF_ALLOC_PAINT_MASK) {
2434         ccg_flags |= CCG_ALLOC_MASK;
2435       }
2436 
2437       ss = _getSubSurf(prevSS, levels, 3, ccg_flags);
2438       ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
2439 
2440       result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
2441 
2442       if (flags & SUBSURF_IS_FINAL_CALC) {
2443         smd->mCache = ss;
2444       }
2445       else {
2446         result->freeSS = 1;
2447       }
2448 
2449       if (flags & SUBSURF_ALLOC_PAINT_MASK) {
2450         ccgSubSurf_setNumLayers(ss, 4);
2451       }
2452     }
2453   }
2454 
2455   return (DerivedMesh *)result;
2456 }
2457 
subsurf_calculate_limit_positions(Mesh * me,float (* r_positions)[3])2458 void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3])
2459 {
2460   /* Finds the subsurf limit positions for the verts in a mesh
2461    * and puts them in an array of floats. Please note that the
2462    * calculated vert positions is incorrect for the verts
2463    * on the boundary of the mesh.
2464    */
2465   CCGSubSurf *ss = _getSubSurf(NULL, 1, 3, CCG_USE_ARENA);
2466   float edge_sum[3], face_sum[3];
2467   CCGVertIterator vi;
2468   DerivedMesh *dm = CDDM_from_mesh(me);
2469 
2470   ss_sync_from_derivedmesh(ss, dm, NULL, 0, 0);
2471 
2472   for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi);
2473        ccgVertIterator_next(&vi)) {
2474     CCGVert *v = ccgVertIterator_getCurrent(&vi);
2475     int idx = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v));
2476     int N = ccgSubSurf_getVertNumEdges(v);
2477     int numFaces = ccgSubSurf_getVertNumFaces(v);
2478     float *co;
2479     int i;
2480 
2481     zero_v3(edge_sum);
2482     zero_v3(face_sum);
2483 
2484     for (i = 0; i < N; i++) {
2485       CCGEdge *e = ccgSubSurf_getVertEdge(v, i);
2486       add_v3_v3v3(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
2487     }
2488     for (i = 0; i < numFaces; i++) {
2489       CCGFace *f = ccgSubSurf_getVertFace(v, i);
2490       add_v3_v3(face_sum, ccgSubSurf_getFaceCenterData(f));
2491     }
2492 
2493     /* ad-hoc correction for boundary vertices, to at least avoid them
2494      * moving completely out of place (brecht) */
2495     if (numFaces && numFaces != N) {
2496       mul_v3_fl(face_sum, (float)N / (float)numFaces);
2497     }
2498 
2499     co = ccgSubSurf_getVertData(ss, v);
2500     r_positions[idx][0] = (co[0] * N * N + edge_sum[0] * 4 + face_sum[0]) / (N * (N + 5));
2501     r_positions[idx][1] = (co[1] * N * N + edge_sum[1] * 4 + face_sum[1]) / (N * (N + 5));
2502     r_positions[idx][2] = (co[2] * N * N + edge_sum[2] * 4 + face_sum[2]) / (N * (N + 5));
2503   }
2504 
2505   ccgSubSurf_free(ss);
2506 
2507   dm->release(dm);
2508 }
2509 
subsurf_has_edges(DerivedMesh * dm)2510 bool subsurf_has_edges(DerivedMesh *dm)
2511 {
2512   return dm->getNumEdges(dm) != 0;
2513 }
2514 
subsurf_has_faces(DerivedMesh * dm)2515 bool subsurf_has_faces(DerivedMesh *dm)
2516 {
2517   return dm->getNumPolys(dm) != 0;
2518 }
2519