Blender  V3.3
subsurf_ccg.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
8 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
9 # ifdef __GNUC__
10 # pragma GCC diagnostic ignored "-Wvla"
11 # endif
12 # define USE_DYNSIZE
13 #endif
14 
15 #include <float.h>
16 #include <math.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 
21 #include "atomic_ops.h"
22 
23 #include "MEM_guardedalloc.h"
24 
25 #include "DNA_mesh_types.h"
26 #include "DNA_meshdata_types.h"
27 #include "DNA_modifier_types.h"
28 #include "DNA_object_types.h"
29 #include "DNA_scene_types.h"
30 
31 #include "BLI_bitmap.h"
32 #include "BLI_blenlib.h"
33 #include "BLI_edgehash.h"
34 #include "BLI_math.h"
35 #include "BLI_memarena.h"
36 #include "BLI_task.h"
37 #include "BLI_threads.h"
38 #include "BLI_utildefines.h"
39 
40 #include "BKE_ccg.h"
41 #include "BKE_cdderivedmesh.h"
42 #include "BKE_mesh.h"
43 #include "BKE_mesh_mapping.h"
44 #include "BKE_modifier.h"
45 #include "BKE_multires.h"
46 #include "BKE_object.h"
47 #include "BKE_paint.h"
48 #include "BKE_pbvh.h"
49 #include "BKE_scene.h"
50 #include "BKE_subsurf.h"
51 
52 #ifndef USE_DYNSIZE
53 # include "BLI_array.h"
54 #endif
55 
56 #include "CCGSubSurf.h"
57 
58 /* assumes MLoop's are laid out 4 for each poly, in order */
59 #define USE_LOOP_LAYOUT_FAST
60 
62  int drawInteriorEdges,
63  int useSubsurfUv,
64  DerivedMesh *dm);
66 
67 static void *arena_alloc(CCGAllocatorHDL a, int numBytes)
68 {
69  return BLI_memarena_alloc(a, numBytes);
70 }
71 
72 static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize)
73 {
74  void *p2 = BLI_memarena_alloc(a, newSize);
75  if (ptr) {
76  memcpy(p2, ptr, oldSize);
77  }
78  return p2;
79 }
80 
82 {
83  /* do nothing */
84 }
85 
87 {
89 }
90 
91 typedef enum {
95  /* add an extra four bytes for a mask layer */
98 } CCGFlags;
99 
100 static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int numLayers, CCGFlags flags)
101 {
102  CCGMeshIFC ifc;
103  CCGSubSurf *ccgSS;
104  int useAging = !!(flags & CCG_USE_AGING);
105  int useArena = flags & CCG_USE_ARENA;
106  int normalOffset = 0;
107 
108  /* (subdivLevels == 0) is not allowed */
109  subdivLevels = MAX2(subdivLevels, 1);
110 
111  if (prevSS) {
112  int oldUseAging;
113 
114  ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
115 
116  if ((oldUseAging != useAging) ||
117  (ccgSubSurf_getSimpleSubdiv(prevSS) != !!(flags & CCG_SIMPLE_SUBDIV))) {
118  ccgSubSurf_free(prevSS);
119  }
120  else {
121  ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
122 
123  return prevSS;
124  }
125  }
126 
127  if (useAging) {
128  ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
129  }
130  else {
131  ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
132  }
133  ifc.numLayers = numLayers;
134  ifc.vertDataSize = sizeof(float) * numLayers;
135  normalOffset += sizeof(float) * numLayers;
136  if (flags & CCG_CALC_NORMALS) {
137  ifc.vertDataSize += sizeof(float[3]);
138  }
139  if (flags & CCG_ALLOC_MASK) {
140  ifc.vertDataSize += sizeof(float);
141  }
142  ifc.simpleSubdiv = !!(flags & CCG_SIMPLE_SUBDIV);
143 
144  if (useArena) {
145  CCGAllocatorIFC allocatorIFC;
146  CCGAllocatorHDL allocator = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "subsurf arena");
147 
148  allocatorIFC.alloc = arena_alloc;
149  allocatorIFC.realloc = arena_realloc;
150  allocatorIFC.free = arena_free;
151  allocatorIFC.release = arena_release;
152 
153  ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
154  }
155  else {
156  ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
157  }
158 
159  if (useAging) {
160  ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
161  }
162 
163  if (flags & CCG_ALLOC_MASK) {
164  normalOffset += sizeof(float);
165  /* mask is allocated after regular layers */
166  ccgSubSurf_setAllocMask(ccgSS, 1, sizeof(float) * numLayers);
167  }
168 
169  if (flags & CCG_CALC_NORMALS) {
170  ccgSubSurf_setCalcVertexNormals(ccgSS, 1, normalOffset);
171  }
172  else {
173  ccgSubSurf_setCalcVertexNormals(ccgSS, 0, 0);
174  }
175 
176  return ccgSS;
177 }
178 
179 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize)
180 {
183  int v0idx = *((int *)ccgSubSurf_getVertUserData(ss, v0));
184  int v1idx = *((int *)ccgSubSurf_getVertUserData(ss, v1));
185  int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e));
186 
187  if (x == 0) {
188  return v0idx;
189  }
190  if (x == edgeSize - 1) {
191  return v1idx;
192  }
193 
194  return edgeBase + x - 1;
195 }
196 
197 static int getFaceIndex(
198  CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize)
199 {
200  int faceBase = *((int *)ccgSubSurf_getFaceUserData(ss, f));
201  int numVerts = ccgSubSurf_getFaceNumVerts(f);
202 
203  if (x == gridSize - 1 && y == gridSize - 1) {
205  return *((int *)ccgSubSurf_getVertUserData(ss, v));
206  }
207  if (x == gridSize - 1) {
210  int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e));
211  if (v == ccgSubSurf_getEdgeVert0(e)) {
212  return edgeBase + (gridSize - 1 - y) - 1;
213  }
214 
215  return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - y) - 1);
216  }
217  if (y == gridSize - 1) {
219  CCGEdge *e = ccgSubSurf_getFaceEdge(f, (S + numVerts - 1) % numVerts);
220  int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e));
221  if (v == ccgSubSurf_getEdgeVert0(e)) {
222  return edgeBase + (gridSize - 1 - x) - 1;
223  }
224 
225  return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - x) - 1);
226  }
227  if (x == 0 && y == 0) {
228  return faceBase;
229  }
230  if (x == 0) {
231  S = (S + numVerts - 1) % numVerts;
232  return faceBase + 1 + (gridSize - 2) * S + (y - 1);
233  }
234  if (y == 0) {
235  return faceBase + 1 + (gridSize - 2) * S + (x - 1);
236  }
237 
238  return faceBase + 1 + (gridSize - 2) * numVerts + S * (gridSize - 2) * (gridSize - 2) +
239  (y - 1) * (gridSize - 2) + (x - 1);
240 }
241 
243  UvVertMap *vmap, struct MPoly *mpoly, struct MLoop *ml, int fi, CCGVertHDL *fverts)
244 {
245  UvMapVert *v, *nv;
246  int j, nverts = mpoly[fi].totloop;
247 
248  for (j = 0; j < nverts; j++) {
249  for (nv = v = BKE_mesh_uv_vert_map_get_vert(vmap, ml[j].v); v; v = v->next) {
250  if (v->separate) {
251  nv = v;
252  }
253  if (v->poly_index == fi) {
254  break;
255  }
256  }
257 
258  fverts[j] = POINTER_FROM_UINT(mpoly[nv->poly_index].loopstart + nv->loop_of_poly_index);
259  }
260 }
261 
263  CCGSubSurf *origss,
264  DerivedMesh *dm,
265  const MLoopUV *mloopuv)
266 {
267  MPoly *mpoly = dm->getPolyArray(dm);
268  MLoop *mloop = dm->getLoopArray(dm);
269  int totvert = dm->getNumVerts(dm);
270  int totface = dm->getNumPolys(dm);
271  int i, seam;
272  UvMapVert *v;
273  UvVertMap *vmap;
274  float limit[2];
275 #ifndef USE_DYNSIZE
276  CCGVertHDL *fverts = NULL;
277  BLI_array_declare(fverts);
278 #endif
279  EdgeSet *eset;
280  float uv[3] = {0.0f, 0.0f, 0.0f}; /* only first 2 values are written into */
281 
282  limit[0] = limit[1] = STD_UV_CONNECT_LIMIT;
283  /* previous behavior here is without accounting for winding, however this causes stretching in
284  * UV map in really simple cases with mirror + subsurf, see second part of T44530.
285  * Also, initially intention is to treat merged vertices from mirror modifier as seams.
286  * This fixes a very old regression (2.49 was correct here) */
287  vmap = BKE_mesh_uv_vert_map_create(mpoly, mloop, mloopuv, totface, totvert, limit, false, true);
288  if (!vmap) {
289  return 0;
290  }
291 
293 
294  /* create vertices */
295  for (i = 0; i < totvert; i++) {
296  if (!BKE_mesh_uv_vert_map_get_vert(vmap, i)) {
297  continue;
298  }
299 
300  for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i)->next; v; v = v->next) {
301  if (v->separate) {
302  break;
303  }
304  }
305 
306  seam = (v != NULL);
307 
308  for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i); v; v = v->next) {
309  if (v->separate) {
310  CCGVert *ssv;
311  int loopid = mpoly[v->poly_index].loopstart + v->loop_of_poly_index;
312  CCGVertHDL vhdl = POINTER_FROM_INT(loopid);
313 
314  copy_v2_v2(uv, mloopuv[loopid].uv);
315 
316  ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
317  }
318  }
319  }
320 
321  /* create edges */
322  eset = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totface));
323 
324  for (i = 0; i < totface; i++) {
325  MPoly *mp = &mpoly[i];
326  int nverts = mp->totloop;
327  int j, j_next;
328  CCGFace *origf = ccgSubSurf_getFace(origss, POINTER_FROM_INT(i));
329  /* unsigned int *fv = &mp->v1; */
330  MLoop *ml = mloop + mp->loopstart;
331 
332 #ifdef USE_DYNSIZE
333  CCGVertHDL fverts[nverts];
334 #else
335  BLI_array_clear(fverts);
336  BLI_array_grow_items(fverts, nverts);
337 #endif
338 
339  get_face_uv_map_vert(vmap, mpoly, ml, i, fverts);
340 
341  for (j = 0, j_next = nverts - 1; j < nverts; j_next = j++) {
342  unsigned int v0 = POINTER_AS_UINT(fverts[j_next]);
343  unsigned int v1 = POINTER_AS_UINT(fverts[j]);
344 
345  if (BLI_edgeset_add(eset, v0, v1)) {
346  CCGEdge *e, *orige = ccgSubSurf_getFaceEdge(origf, j_next);
347  CCGEdgeHDL ehdl = POINTER_FROM_INT(mp->loopstart + j_next);
348  float crease = ccgSubSurf_getEdgeCrease(orige);
349 
350  ccgSubSurf_syncEdge(ss, ehdl, fverts[j_next], fverts[j], crease, &e);
351  }
352  }
353  }
354 
355  BLI_edgeset_free(eset);
356 
357  /* create faces */
358  for (i = 0; i < totface; i++) {
359  MPoly *mp = &mpoly[i];
360  MLoop *ml = &mloop[mp->loopstart];
361  int nverts = mp->totloop;
362  CCGFace *f;
363 
364 #ifdef USE_DYNSIZE
365  CCGVertHDL fverts[nverts];
366 #else
367  BLI_array_clear(fverts);
368  BLI_array_grow_items(fverts, nverts);
369 #endif
370 
371  get_face_uv_map_vert(vmap, mpoly, ml, i, fverts);
372  ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), nverts, fverts, &f);
373  }
374 
375 #ifndef USE_DYNSIZE
376  BLI_array_free(fverts);
377 #endif
378 
381 
382  return 1;
383 }
384 
386 {
387  CCGFaceIterator fi;
388  int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S;
389  const MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, n);
390  /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
391  * just tface except applying the modifier then looses subsurf UV */
392  MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
393  MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, n);
394 
395  if (!dmloopuv || (!tface && !mloopuv)) {
396  return;
397  }
398 
399  /* create a CCGSubSurf from uv's */
401 
402  if (!ss_sync_from_uv(uvss, ss, dm, dmloopuv)) {
403  ccgSubSurf_free(uvss);
404  return;
405  }
406 
407  /* get some info from CCGSubSurf */
408  totface = ccgSubSurf_getNumFaces(uvss);
409  // edgeSize = ccgSubSurf_getEdgeSize(uvss); /* UNUSED */
410  gridSize = ccgSubSurf_getGridSize(uvss);
411  gridFaces = gridSize - 1;
412 
413  /* make a map from original faces to CCGFaces */
414  CCGFace **faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv");
416  ccgFaceIterator_next(&fi)) {
419  }
420 
421  /* load coordinates from uvss into tface */
422  MTFace *tf = tface;
423  MLoopUV *mluv = mloopuv;
424 
425  for (index = 0; index < totface; index++) {
426  CCGFace *f = faceMap[index];
427  int numVerts = ccgSubSurf_getFaceNumVerts(f);
428 
429  for (S = 0; S < numVerts; S++) {
430  float(*faceGridData)[2] = ccgSubSurf_getFaceGridDataArray(uvss, f, S);
431 
432  for (y = 0; y < gridFaces; y++) {
433  for (x = 0; x < gridFaces; x++) {
434  float *a = faceGridData[(y + 0) * gridSize + x + 0];
435  float *b = faceGridData[(y + 0) * gridSize + x + 1];
436  float *c = faceGridData[(y + 1) * gridSize + x + 1];
437  float *d = faceGridData[(y + 1) * gridSize + x + 0];
438 
439  if (tf) {
440  copy_v2_v2(tf->uv[0], a);
441  copy_v2_v2(tf->uv[1], d);
442  copy_v2_v2(tf->uv[2], c);
443  copy_v2_v2(tf->uv[3], b);
444  tf++;
445  }
446 
447  if (mluv) {
448  copy_v2_v2(mluv[0].uv, a);
449  copy_v2_v2(mluv[1].uv, d);
450  copy_v2_v2(mluv[2].uv, c);
451  copy_v2_v2(mluv[3].uv, b);
452  mluv += 4;
453  }
454  }
455  }
456  }
457  }
458 
459  ccgSubSurf_free(uvss);
461 }
462 
463 static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int layer_index)
464 {
465  set_subsurf_legacy_uv(ss, dm, result, layer_index);
466 }
467 
468 /* face weighting */
469 #define SUB_ELEMS_FACE 50
471 
472 typedef struct FaceVertWeightEntry {
474  float *w;
475  int valid;
477 
478 typedef struct WeightTable {
480  int len;
482 
483 static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen)
484 {
485  int x, y, i, j;
486  float *w, w1, w2, w4, fac, fac2, fx, fy;
487 
488  if (wtable->len <= faceLen) {
489  void *tmp = MEM_callocN(sizeof(FaceVertWeightEntry) * (faceLen + 1), "weight table alloc 2");
490 
491  if (wtable->len) {
492  memcpy(tmp, wtable->weight_table, sizeof(FaceVertWeightEntry) * wtable->len);
493  MEM_freeN(wtable->weight_table);
494  }
495 
496  wtable->weight_table = tmp;
497  wtable->len = faceLen + 1;
498  }
499 
500  if (!wtable->weight_table[faceLen].valid) {
501  wtable->weight_table[faceLen].valid = 1;
502  wtable->weight_table[faceLen].w = w = MEM_callocN(
503  sizeof(float) * faceLen * faceLen * (gridCuts + 2) * (gridCuts + 2), "weight table alloc");
504  fac = 1.0f / (float)faceLen;
505 
506  for (i = 0; i < faceLen; i++) {
507  for (x = 0; x < gridCuts + 2; x++) {
508  for (y = 0; y < gridCuts + 2; y++) {
509  fx = 0.5f - (float)x / (float)(gridCuts + 1) / 2.0f;
510  fy = 0.5f - (float)y / (float)(gridCuts + 1) / 2.0f;
511 
512  fac2 = faceLen - 4;
513  w1 = (1.0f - fx) * (1.0f - fy) + (-fac2 * fx * fy * fac);
514  w2 = (1.0f - fx + fac2 * fx * -fac) * (fy);
515  w4 = (fx) * (1.0f - fy + -fac2 * fy * fac);
516 
517  /* these values aren't used for tri's and cause divide by zero */
518  if (faceLen > 3) {
519  fac2 = 1.0f - (w1 + w2 + w4);
520  fac2 = fac2 / (float)(faceLen - 3);
521  for (j = 0; j < faceLen; j++) {
522  w[j] = fac2;
523  }
524  }
525 
526  w[i] = w1;
527  w[(i - 1 + faceLen) % faceLen] = w2;
528  w[(i + 1) % faceLen] = w4;
529 
530  w += faceLen;
531  }
532  }
533  }
534  }
535 
536  return wtable->weight_table[faceLen].w;
537 }
538 
539 static void free_ss_weights(WeightTable *wtable)
540 {
541  int i;
542 
543  for (i = 0; i < wtable->len; i++) {
544  if (wtable->weight_table[i].valid) {
545  MEM_freeN(wtable->weight_table[i].w);
546  }
547  }
548 
549  if (wtable->weight_table) {
550  MEM_freeN(wtable->weight_table);
551  }
552 }
553 
555  DerivedMesh *dm,
556  float (*vertexCos)[3],
557  int useFlatSubdiv)
558 {
559  float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss);
560 #ifndef USE_DYNSIZE
561  CCGVertHDL *fVerts = NULL;
562  BLI_array_declare(fVerts);
563 #endif
564  MVert *mvert = dm->getVertArray(dm);
565  MEdge *medge = dm->getEdgeArray(dm);
566  MVert *mv;
567  MEdge *me;
568  MLoop *mloop = dm->getLoopArray(dm), *ml;
569  MPoly *mpoly = dm->getPolyArray(dm), *mp;
570  int totvert = dm->getNumVerts(dm);
571  int totedge = dm->getNumEdges(dm);
572  int i, j;
573  int *index;
574 
576 
577  mv = mvert;
578  index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
579  for (i = 0; i < totvert; i++, mv++) {
580  CCGVert *v;
581 
582  if (vertexCos) {
583  ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), vertexCos[i], 0, &v);
584  }
585  else {
586  ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), mv->co, 0, &v);
587  }
588 
589  ((int *)ccgSubSurf_getVertUserData(ss, v))[1] = (index) ? *index++ : i;
590  }
591 
592  me = medge;
593  index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX);
594  for (i = 0; i < totedge; i++, me++) {
595  CCGEdge *e;
596  float crease;
597 
598  crease = useFlatSubdiv ? creaseFactor : me->crease * creaseFactor / 255.0f;
599 
601  ss, POINTER_FROM_INT(i), POINTER_FROM_UINT(me->v1), POINTER_FROM_UINT(me->v2), crease, &e);
602 
603  ((int *)ccgSubSurf_getEdgeUserData(ss, e))[1] = (index) ? *index++ : i;
604  }
605 
606  mp = mpoly;
607  index = (int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
608  for (i = 0; i < dm->numPolyData; i++, mp++) {
609  CCGFace *f;
610 
611 #ifdef USE_DYNSIZE
612  CCGVertHDL fVerts[mp->totloop];
613 #else
614  BLI_array_clear(fVerts);
615  BLI_array_grow_items(fVerts, mp->totloop);
616 #endif
617 
618  ml = mloop + mp->loopstart;
619  for (j = 0; j < mp->totloop; j++, ml++) {
620  fVerts[j] = POINTER_FROM_UINT(ml->v);
621  }
622 
623  /* This is very bad, means mesh is internally inconsistent.
624  * it is not really possible to continue without modifying
625  * other parts of code significantly to handle missing faces.
626  * since this really shouldn't even be possible we just bail. */
627  if (ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), mp->totloop, fVerts, &f) ==
629  static int hasGivenError = 0;
630 
631  if (!hasGivenError) {
632  // XXX error("Unrecoverable error in SubSurf calculation,"
633  // " mesh is inconsistent.");
634 
635  hasGivenError = 1;
636  }
637 
638  return;
639  }
640 
641  ((int *)ccgSubSurf_getFaceUserData(ss, f))[1] = (index) ? *index++ : i;
642  }
643 
645 
646 #ifndef USE_DYNSIZE
647  BLI_array_free(fVerts);
648 #endif
649 }
650 
652  DerivedMesh *dm,
653  float (*vertexCos)[3],
654  int use_flat_subdiv,
655  bool UNUSED(use_subdiv_uvs))
656 {
657  ss_sync_ccg_from_derivedmesh(ss, dm, vertexCos, use_flat_subdiv);
658 }
659 
660 /***/
661 
663 {
664  return ((int *)ccgSubSurf_getVertUserData(ss, v))[1];
665 }
666 
668 {
669  return ((int *)ccgSubSurf_getEdgeUserData(ss, e))[1];
670 }
671 
673 {
674  return ((int *)ccgSubSurf_getFaceUserData(ss, f))[1];
675 }
676 
677 static void minmax_v3_v3v3(const float vec[3], float min[3], float max[3])
678 {
679  if (min[0] > vec[0]) {
680  min[0] = vec[0];
681  }
682  if (min[1] > vec[1]) {
683  min[1] = vec[1];
684  }
685  if (min[2] > vec[2]) {
686  min[2] = vec[2];
687  }
688  if (max[0] < vec[0]) {
689  max[0] = vec[0];
690  }
691  if (max[1] < vec[1]) {
692  max[1] = vec[1];
693  }
694  if (max[2] < vec[2]) {
695  max[2] = vec[2];
696  }
697 }
698 
699 static void UNUSED_FUNCTION(ccgDM_getMinMax)(DerivedMesh *dm, float r_min[3], float r_max[3])
700 {
701  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
702  CCGSubSurf *ss = ccgdm->ss;
703  CCGVertIterator vi;
704  CCGEdgeIterator ei;
705  CCGFaceIterator fi;
706  CCGKey key;
707  int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
708  int gridSize = ccgSubSurf_getGridSize(ss);
709 
710  CCG_key_top_level(&key, ss);
711 
712  if (!ccgSubSurf_getNumVerts(ss)) {
713  r_min[0] = r_min[1] = r_min[2] = r_max[0] = r_max[1] = r_max[2] = 0.0;
714  }
715 
717  ccgVertIterator_next(&vi)) {
719  float *co = ccgSubSurf_getVertData(ss, v);
720 
721  minmax_v3_v3v3(co, r_min, r_max);
722  }
723 
725  ccgEdgeIterator_next(&ei)) {
727  CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
728 
729  for (i = 0; i < edgeSize; i++) {
730  minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), r_min, r_max);
731  }
732  }
733 
735  ccgFaceIterator_next(&fi)) {
737  int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
738 
739  for (S = 0; S < numVerts; S++) {
740  CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
741 
742  for (y = 0; y < gridSize; y++) {
743  for (x = 0; x < gridSize; x++) {
744  minmax_v3_v3v3(CCG_grid_elem_co(&key, faceGridData, x, y), r_min, r_max);
745  }
746  }
747  }
748  }
749 }
750 
752 {
753  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
754 
755  return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
756 }
757 
759 {
760  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
761 
762  return ccgSubSurf_getNumFinalEdges(ccgdm->ss);
763 }
764 
766 {
767  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
768 
769  return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
770 }
771 
773 {
774  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
775 
776  /* All subsurf faces are quads */
777  return 4 * ccgSubSurf_getNumFinalFaces(ccgdm->ss);
778 }
779 
780 static CCGElem *get_vertex_elem(CCGDerivedMesh *ccgdm, int vertNum)
781 {
782  CCGSubSurf *ss = ccgdm->ss;
783  int i;
784 
785  if ((vertNum < ccgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) {
786  /* this vert comes from face data */
787  int lastface = ccgSubSurf_getNumFaces(ss) - 1;
788  CCGFace *f;
789  int x, y, grid, numVerts;
790  int offset;
791  int gridSize = ccgSubSurf_getGridSize(ss);
792  int gridSideVerts;
793  int gridInternalVerts;
794  int gridSideEnd;
795  int gridInternalEnd;
796 
797  i = 0;
798  while (i < lastface && vertNum >= ccgdm->faceMap[i + 1].startVert) {
799  i++;
800  }
801 
802  f = ccgdm->faceMap[i].face;
803  numVerts = ccgSubSurf_getFaceNumVerts(f);
804 
805  gridSideVerts = gridSize - 2;
806  gridInternalVerts = gridSideVerts * gridSideVerts;
807 
808  gridSideEnd = 1 + numVerts * gridSideVerts;
809  gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
810 
811  offset = vertNum - ccgdm->faceMap[i].startVert;
812  if (offset < 1) {
814  }
815  if (offset < gridSideEnd) {
816  offset -= 1;
817  grid = offset / gridSideVerts;
818  x = offset % gridSideVerts + 1;
819  return ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x);
820  }
821  if (offset < gridInternalEnd) {
822  offset -= gridSideEnd;
823  grid = offset / gridInternalVerts;
824  offset %= gridInternalVerts;
825  y = offset / gridSideVerts + 1;
826  x = offset % gridSideVerts + 1;
827  return ccgSubSurf_getFaceGridData(ss, f, grid, x, y);
828  }
829  }
830  if ((vertNum < ccgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) {
831  /* this vert comes from edge data */
832  CCGEdge *e;
833  int lastedge = ccgSubSurf_getNumEdges(ss) - 1;
834  int x;
835 
836  i = 0;
837  while (i < lastedge && vertNum >= ccgdm->edgeMap[i + 1].startVert) {
838  i++;
839  }
840 
841  e = ccgdm->edgeMap[i].edge;
842 
843  x = vertNum - ccgdm->edgeMap[i].startVert + 1;
844  return ccgSubSurf_getEdgeData(ss, e, x);
845  }
846 
847  /* this vert comes from vert data */
848  CCGVert *v;
849  i = vertNum - ccgdm->vertMap[0].startVert;
850 
851  v = ccgdm->vertMap[i].vert;
852  return ccgSubSurf_getVertData(ss, v);
853 }
854 
855 static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float r_co[3])
856 {
857  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
858  CCGSubSurf *ss = ccgdm->ss;
859 
860  CCGElem *vd = get_vertex_elem(ccgdm, vertNum);
861  CCGKey key;
862  CCG_key_top_level(&key, ss);
863  copy_v3_v3(r_co, CCG_elem_co(&key, vd));
864 }
865 
866 static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float r_no[3])
867 {
868  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
869  CCGSubSurf *ss = ccgdm->ss;
870 
871  CCGElem *vd = get_vertex_elem(ccgdm, vertNum);
872  CCGKey key;
873  CCG_key_top_level(&key, ss);
874  copy_v3_v3(r_no, CCG_elem_no(&key, vd));
875 }
876 
877 /* utility function */
878 BLI_INLINE void ccgDM_to_MVert(MVert *mv, const CCGKey *key, CCGElem *elem)
879 {
880  copy_v3_v3(mv->co, CCG_elem_co(key, elem));
881  mv->flag = mv->bweight = 0;
882 }
883 
885 {
886  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
887  CCGSubSurf *ss = ccgdm->ss;
888  CCGElem *vd;
889  CCGKey key;
890  int index;
891  int totvert, totedge, totface;
892  int gridSize = ccgSubSurf_getGridSize(ss);
893  int edgeSize = ccgSubSurf_getEdgeSize(ss);
894  unsigned int i = 0;
895 
896  CCG_key_top_level(&key, ss);
897 
898  totface = ccgSubSurf_getNumFaces(ss);
899  for (index = 0; index < totface; index++) {
900  CCGFace *f = ccgdm->faceMap[index].face;
901  int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
902 
904  ccgDM_to_MVert(&mvert[i++], &key, vd);
905 
906  for (S = 0; S < numVerts; S++) {
907  for (x = 1; x < gridSize - 1; x++) {
908  vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x);
909  ccgDM_to_MVert(&mvert[i++], &key, vd);
910  }
911  }
912 
913  for (S = 0; S < numVerts; S++) {
914  for (y = 1; y < gridSize - 1; y++) {
915  for (x = 1; x < gridSize - 1; x++) {
916  vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y);
917  ccgDM_to_MVert(&mvert[i++], &key, vd);
918  }
919  }
920  }
921  }
922 
923  totedge = ccgSubSurf_getNumEdges(ss);
924  for (index = 0; index < totedge; index++) {
925  CCGEdge *e = ccgdm->edgeMap[index].edge;
926  int x;
927 
928  for (x = 1; x < edgeSize - 1; x++) {
929  /* NOTE(@campbellbarton): This gives errors with `--debug-fpe` the normals don't seem to be
930  * unit length. This is most likely caused by edges with no faces which are now zeroed out,
931  * see comment in: `ccgSubSurf__calcVertNormals()`. */
932  vd = ccgSubSurf_getEdgeData(ss, e, x);
933  ccgDM_to_MVert(&mvert[i++], &key, vd);
934  }
935  }
936 
937  totvert = ccgSubSurf_getNumVerts(ss);
938  for (index = 0; index < totvert; index++) {
939  CCGVert *v = ccgdm->vertMap[index].vert;
940 
941  vd = ccgSubSurf_getVertData(ss, v);
942  ccgDM_to_MVert(&mvert[i++], &key, vd);
943  }
944 }
945 
946 /* utility function */
947 BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2, const short flag)
948 {
949  med->v1 = v1;
950  med->v2 = v2;
951  med->crease = med->bweight = 0;
952  med->flag = flag;
953 }
954 
956 {
957  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
958  CCGSubSurf *ss = ccgdm->ss;
959  int index;
960  int totedge, totface;
961  int gridSize = ccgSubSurf_getGridSize(ss);
962  int edgeSize = ccgSubSurf_getEdgeSize(ss);
963  unsigned int i = 0;
964  short *edgeFlags = ccgdm->edgeFlags;
965  const short ed_interior_flag = ccgdm->drawInteriorEdges ? (ME_EDGEDRAW | ME_EDGERENDER) : 0;
966 
967  totface = ccgSubSurf_getNumFaces(ss);
968  for (index = 0; index < totface; index++) {
969  CCGFace *f = ccgdm->faceMap[index].face;
970  int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
971 
972  for (S = 0; S < numVerts; S++) {
973  for (x = 0; x < gridSize - 1; x++) {
974  ccgDM_to_MEdge(&medge[i++],
975  getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize),
976  getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize),
977  ed_interior_flag);
978  }
979 
980  for (x = 1; x < gridSize - 1; x++) {
981  for (y = 0; y < gridSize - 1; y++) {
982  ccgDM_to_MEdge(&medge[i++],
983  getFaceIndex(ss, f, S, x, y, edgeSize, gridSize),
984  getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize),
985  ed_interior_flag);
986  ccgDM_to_MEdge(&medge[i++],
987  getFaceIndex(ss, f, S, y, x, edgeSize, gridSize),
988  getFaceIndex(ss, f, S, y + 1, x, edgeSize, gridSize),
989  ed_interior_flag);
990  }
991  }
992  }
993  }
994 
995  totedge = ccgSubSurf_getNumEdges(ss);
996  for (index = 0; index < totedge; index++) {
997  CCGEdge *e = ccgdm->edgeMap[index].edge;
998  short ed_flag = 0;
999  int x;
1001 
1002  if (!ccgSubSurf_getEdgeNumFaces(e)) {
1003  ed_flag |= ME_LOOSEEDGE;
1004  }
1005 
1006  if (edgeFlags) {
1007  if (edgeIdx != -1) {
1008  ed_flag |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER);
1009  }
1010  }
1011  else {
1012  ed_flag |= ME_EDGEDRAW | ME_EDGERENDER;
1013  }
1014 
1015  for (x = 0; x < edgeSize - 1; x++) {
1016  ccgDM_to_MEdge(&medge[i++],
1017  getEdgeIndex(ss, e, x, edgeSize),
1018  getEdgeIndex(ss, e, x + 1, edgeSize),
1019  ed_flag);
1020  }
1021  }
1022 }
1023 
1024 typedef struct CopyFinalLoopArrayData {
1030  size_t mloop_index;
1032 
1033 static void copyFinalLoopArray_task_cb(void *__restrict userdata,
1034  const int iter,
1035  const TaskParallelTLS *__restrict UNUSED(tls))
1036 {
1037  CopyFinalLoopArrayData *data = userdata;
1038  CCGDerivedMesh *ccgdm = data->ccgdm;
1039  CCGSubSurf *ss = ccgdm->ss;
1040  const int grid_size = data->grid_size;
1041  const int edge_size = data->edge_size;
1042  CCGFace *f = ccgdm->faceMap[iter].face;
1043  const int num_verts = ccgSubSurf_getFaceNumVerts(f);
1044  const int grid_index = data->grid_offset[iter];
1045  const size_t loop_index = 4 * (size_t)grid_index * (grid_size - 1) * (grid_size - 1);
1046  MLoop *ml = &data->mloop[loop_index];
1047  for (int S = 0; S < num_verts; S++) {
1048  for (int y = 0; y < grid_size - 1; y++) {
1049  for (int x = 0; x < grid_size - 1; x++) {
1050 
1051  uint v1 = getFaceIndex(ss, f, S, x + 0, y + 0, edge_size, grid_size);
1052  uint v2 = getFaceIndex(ss, f, S, x + 0, y + 1, edge_size, grid_size);
1053  uint v3 = getFaceIndex(ss, f, S, x + 1, y + 1, edge_size, grid_size);
1054  uint v4 = getFaceIndex(ss, f, S, x + 1, y + 0, edge_size, grid_size);
1055 
1056  ml->v = v1;
1057  ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v1, v2));
1058  ml++;
1059 
1060  ml->v = v2;
1061  ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v2, v3));
1062  ml++;
1063 
1064  ml->v = v3;
1065  ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v3, v4));
1066  ml++;
1067 
1068  ml->v = v4;
1069  ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v4, v1));
1070  ml++;
1071  }
1072  }
1073  }
1074 }
1075 
1077 {
1078  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1079  CCGSubSurf *ss = ccgdm->ss;
1080 
1081  if (!ccgdm->ehash) {
1083  if (!ccgdm->ehash) {
1084  MEdge *medge;
1085  EdgeHash *ehash;
1086 
1087  ehash = BLI_edgehash_new_ex(__func__, ccgdm->dm.numEdgeData);
1088  medge = ccgdm->dm.getEdgeArray((DerivedMesh *)ccgdm);
1089 
1090  for (int i = 0; i < ccgdm->dm.numEdgeData; i++) {
1091  BLI_edgehash_insert(ehash, medge[i].v1, medge[i].v2, POINTER_FROM_INT(i));
1092  }
1093 
1094  atomic_cas_ptr((void **)&ccgdm->ehash, ccgdm->ehash, ehash);
1095  }
1097  }
1098 
1100  data.ccgdm = ccgdm;
1101  data.mloop = mloop;
1102  data.grid_size = ccgSubSurf_getGridSize(ss);
1103  data.grid_offset = dm->getGridOffset(dm);
1104  data.edge_size = ccgSubSurf_getEdgeSize(ss);
1105 
1106  /* NOTE: For a dense subdivision we've got enough work for each face and
1107  * hence can dedicate whole thread to single face. For less dense
1108  * subdivision we handle multiple faces per thread.
1109  */
1110  data.mloop_index = data.grid_size >= 5 ? 1 : 8;
1111 
1112  TaskParallelSettings settings;
1114  settings.min_iter_per_thread = 1;
1115 
1118 }
1119 
1121 {
1122  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1123  CCGSubSurf *ss = ccgdm->ss;
1124  int index;
1125  int totface;
1126  int gridSize = ccgSubSurf_getGridSize(ss);
1127  /* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */
1128  int i = 0, k = 0;
1129  DMFlagMat *faceFlags = ccgdm->faceFlags;
1130 
1131  totface = ccgSubSurf_getNumFaces(ss);
1132  for (index = 0; index < totface; index++) {
1133  CCGFace *f = ccgdm->faceMap[index].face;
1134  int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f);
1135  int flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH;
1136  int mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0;
1137 
1138  for (S = 0; S < numVerts; S++) {
1139  for (y = 0; y < gridSize - 1; y++) {
1140  for (x = 0; x < gridSize - 1; x++) {
1141  MPoly *mp = &mpoly[i];
1142 
1143  mp->mat_nr = mat_nr;
1144  mp->flag = flag;
1145  mp->loopstart = k;
1146  mp->totloop = 4;
1147 
1148  k += 4;
1149  i++;
1150  }
1151  }
1152  }
1153  }
1154 }
1155 
1156 static void ccgDM_release(DerivedMesh *dm)
1157 {
1158  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1159 
1160  if (DM_release(dm)) {
1161  /* Before freeing, need to update the displacement map */
1162  if (ccgdm->multires.modified_flags) {
1163  /* Check that mmd still exists */
1164  if (!ccgdm->multires.local_mmd &&
1165  BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0) {
1166  ccgdm->multires.mmd = NULL;
1167  }
1168 
1169  if (ccgdm->multires.mmd) {
1172  }
1175  }
1176  }
1177  }
1178 
1179  if (ccgdm->ehash) {
1180  BLI_edgehash_free(ccgdm->ehash, NULL);
1181  }
1182 
1183  if (ccgdm->reverseFaceMap) {
1184  MEM_freeN(ccgdm->reverseFaceMap);
1185  }
1186  if (ccgdm->gridFaces) {
1187  MEM_freeN(ccgdm->gridFaces);
1188  }
1189  if (ccgdm->gridData) {
1190  MEM_freeN(ccgdm->gridData);
1191  }
1192  if (ccgdm->gridOffset) {
1193  MEM_freeN(ccgdm->gridOffset);
1194  }
1195  if (ccgdm->gridFlagMats) {
1196  MEM_freeN(ccgdm->gridFlagMats);
1197  }
1198  if (ccgdm->gridHidden) {
1199  /* Using dm->getNumGrids(dm) accesses freed memory */
1200  uint numGrids = ccgdm->numGrid;
1201  for (uint i = 0; i < numGrids; i++) {
1202  if (ccgdm->gridHidden[i]) {
1203  MEM_freeN(ccgdm->gridHidden[i]);
1204  }
1205  }
1206  MEM_freeN(ccgdm->gridHidden);
1207  }
1208  if (ccgdm->freeSS) {
1209  ccgSubSurf_free(ccgdm->ss);
1210  }
1211  if (ccgdm->pmap) {
1212  MEM_freeN(ccgdm->pmap);
1213  }
1214  if (ccgdm->pmap_mem) {
1215  MEM_freeN(ccgdm->pmap_mem);
1216  }
1217  MEM_freeN(ccgdm->edgeFlags);
1218  MEM_freeN(ccgdm->faceFlags);
1219  MEM_freeN(ccgdm->vertMap);
1220  MEM_freeN(ccgdm->edgeMap);
1221  MEM_freeN(ccgdm->faceMap);
1222 
1225 
1226  MEM_freeN(ccgdm);
1227  }
1228 }
1229 
1231 {
1232  if (type == CD_ORIGINDEX) {
1233  /* create origindex on demand to save memory */
1234  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1235  CCGSubSurf *ss = ccgdm->ss;
1236  int *origindex;
1237  int a, index, totnone, totorig;
1238 
1239  /* Avoid re-creation if the layer exists already */
1241  origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1243  if (origindex) {
1244  return origindex;
1245  }
1246 
1248 
1249  origindex = CustomData_add_layer(
1251 
1252  totorig = ccgSubSurf_getNumVerts(ss);
1253  totnone = dm->numVertData - totorig;
1254 
1255  /* original vertices are at the end */
1256  for (a = 0; a < totnone; a++) {
1257  origindex[a] = ORIGINDEX_NONE;
1258  }
1259 
1260  for (index = 0; index < totorig; index++, a++) {
1261  CCGVert *v = ccgdm->vertMap[index].vert;
1262  origindex[a] = ccgDM_getVertMapIndex(ccgdm->ss, v);
1263  }
1265 
1266  return origindex;
1267  }
1268 
1269  return DM_get_vert_data_layer(dm, type);
1270 }
1271 
1273 {
1274  if (type == CD_ORIGINDEX) {
1275  /* create origindex on demand to save memory */
1276  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1277  CCGSubSurf *ss = ccgdm->ss;
1278  int *origindex;
1279  int a, i, index, totnone, totorig, totedge;
1280  int edgeSize = ccgSubSurf_getEdgeSize(ss);
1281 
1282  /* Avoid re-creation if the layer exists already */
1283  origindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1284  if (origindex) {
1285  return origindex;
1286  }
1287 
1288  origindex = CustomData_add_layer(
1290 
1291  totedge = ccgSubSurf_getNumEdges(ss);
1292  totorig = totedge * (edgeSize - 1);
1293  totnone = dm->numEdgeData - totorig;
1294 
1295  /* original edges are at the end */
1296  for (a = 0; a < totnone; a++) {
1297  origindex[a] = ORIGINDEX_NONE;
1298  }
1299 
1300  for (index = 0; index < totedge; index++) {
1301  CCGEdge *e = ccgdm->edgeMap[index].edge;
1302  int mapIndex = ccgDM_getEdgeMapIndex(ss, e);
1303 
1304  for (i = 0; i < edgeSize - 1; i++, a++) {
1305  origindex[a] = mapIndex;
1306  }
1307  }
1308 
1309  return origindex;
1310  }
1311 
1312  return DM_get_edge_data_layer(dm, type);
1313 }
1314 
1316 {
1317  if (type == CD_ORIGINDEX) {
1318  /* create origindex on demand to save memory */
1319  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1320  CCGSubSurf *ss = ccgdm->ss;
1321  int *origindex;
1322  int a, i, index, totface;
1323  int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
1324 
1325  /* Avoid re-creation if the layer exists already */
1326  origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
1327  if (origindex) {
1328  return origindex;
1329  }
1330 
1331  origindex = CustomData_add_layer(
1333 
1334  totface = ccgSubSurf_getNumFaces(ss);
1335 
1336  for (a = 0, index = 0; index < totface; index++) {
1337  CCGFace *f = ccgdm->faceMap[index].face;
1338  int numVerts = ccgSubSurf_getFaceNumVerts(f);
1339  int mapIndex = ccgDM_getFaceMapIndex(ss, f);
1340 
1341  for (i = 0; i < gridFaces * gridFaces * numVerts; i++, a++) {
1342  origindex[a] = mapIndex;
1343  }
1344  }
1345 
1346  return origindex;
1347  }
1348 
1349  return DM_get_poly_data_layer(dm, type);
1350 }
1351 
1353 {
1354  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1355  int index, numFaces, numGrids;
1356 
1357  numFaces = ccgSubSurf_getNumFaces(ccgdm->ss);
1358  numGrids = 0;
1359 
1360  for (index = 0; index < numFaces; index++) {
1361  CCGFace *f = ccgdm->faceMap[index].face;
1362  numGrids += ccgSubSurf_getFaceNumVerts(f);
1363  }
1364 
1365  return numGrids;
1366 }
1367 
1369 {
1370  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1371  return ccgSubSurf_getGridSize(ccgdm->ss);
1372 }
1373 
1375 {
1376  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1377  CCGSubSurf *ss = ccgdm->ss;
1378  CCGElem **gridData;
1379  DMFlagMat *gridFlagMats;
1380  CCGFace **gridFaces;
1381  int *gridOffset;
1382  int index, numFaces, numGrids, S, gIndex /*, gridSize */;
1383 
1384  if (ccgdm->gridData) {
1385  return;
1386  }
1387 
1388  numGrids = ccgDM_getNumGrids(dm);
1389  numFaces = ccgSubSurf_getNumFaces(ss);
1390  // gridSize = ccgDM_getGridSize(dm); /* UNUSED */
1391 
1392  /* compute offset into grid array for each face */
1393  gridOffset = MEM_mallocN(sizeof(int) * numFaces, "ccgdm.gridOffset");
1394 
1395  for (gIndex = 0, index = 0; index < numFaces; index++) {
1396  CCGFace *f = ccgdm->faceMap[index].face;
1397  int numVerts = ccgSubSurf_getFaceNumVerts(f);
1398 
1399  gridOffset[index] = gIndex;
1400  gIndex += numVerts;
1401  }
1402 
1403  /* compute grid data */
1404  gridData = MEM_mallocN(sizeof(CCGElem *) * numGrids, "ccgdm.gridData");
1405  gridFaces = MEM_mallocN(sizeof(CCGFace *) * numGrids, "ccgdm.gridFaces");
1406  gridFlagMats = MEM_mallocN(sizeof(DMFlagMat) * numGrids, "ccgdm.gridFlagMats");
1407 
1408  ccgdm->gridHidden = MEM_callocN(sizeof(*ccgdm->gridHidden) * numGrids, "ccgdm.gridHidden");
1409 
1410  for (gIndex = 0, index = 0; index < numFaces; index++) {
1411  CCGFace *f = ccgdm->faceMap[index].face;
1412  int numVerts = ccgSubSurf_getFaceNumVerts(f);
1413 
1414  for (S = 0; S < numVerts; S++, gIndex++) {
1415  gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S);
1416  gridFaces[gIndex] = f;
1417  gridFlagMats[gIndex] = ccgdm->faceFlags[index];
1418  }
1419  }
1420 
1421  ccgdm->gridData = gridData;
1422  ccgdm->gridFaces = gridFaces;
1423  ccgdm->gridOffset = gridOffset;
1424  ccgdm->gridFlagMats = gridFlagMats;
1425  ccgdm->numGrid = numGrids;
1426 }
1427 
1429 {
1430  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1431 
1432  ccgdm_create_grids(dm);
1433  return ccgdm->gridData;
1434 }
1435 
1437 {
1438  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1439 
1440  ccgdm_create_grids(dm);
1441  return ccgdm->gridOffset;
1442 }
1443 
1444 static void ccgDM_getGridKey(DerivedMesh *dm, CCGKey *key)
1445 {
1446  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1447  CCG_key_top_level(key, ccgdm->ss);
1448 }
1449 
1451 {
1452  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1453 
1454  ccgdm_create_grids(dm);
1455  return ccgdm->gridFlagMats;
1456 }
1457 
1459 {
1460  CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
1461 
1462  ccgdm_create_grids(dm);
1463  return ccgdm->gridHidden;
1464 }
1465 
1466 /* WARNING! *MUST* be called in an 'loops_cache_rwlock' protected thread context! */
1468 {
1469  const int tottri = dm->numPolyData * 2;
1470  int i, poly_index;
1471 
1473  MLoopTri *mlooptri = dm->looptris.array_wip;
1474 
1475  BLI_assert(tottri == 0 || mlooptri != NULL);
1477  BLI_assert(tottri == dm->looptris.num);
1478 
1479  for (i = 0, poly_index = 0; i < tottri; i += 2, poly_index += 1) {
1480  MLoopTri *lt;
1481  lt = &mlooptri[i];
1482  /* quad is (0, 3, 2, 1) */
1483  lt->tri[0] = (poly_index * 4) + 0;
1484  lt->tri[1] = (poly_index * 4) + 2;
1485  lt->tri[2] = (poly_index * 4) + 3;
1486  lt->poly = poly_index;
1487 
1488  lt = &mlooptri[i + 1];
1489  lt->tri[0] = (poly_index * 4) + 0;
1490  lt->tri[1] = (poly_index * 4) + 1;
1491  lt->tri[2] = (poly_index * 4) + 2;
1492  lt->poly = poly_index;
1493  }
1494 
1495  BLI_assert(dm->looptris.array == NULL);
1496  atomic_cas_ptr((void **)&dm->looptris.array, dm->looptris.array, dm->looptris.array_wip);
1497  dm->looptris.array_wip = NULL;
1498 }
1499 
1501 {
1502  ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
1503  ccgdm->dm.getNumEdges = ccgDM_getNumEdges;
1504  ccgdm->dm.getNumLoops = ccgDM_getNumLoops;
1505  ccgdm->dm.getNumPolys = ccgDM_getNumPolys;
1506 
1509 
1514 
1518  ccgdm->dm.getNumGrids = ccgDM_getNumGrids;
1519  ccgdm->dm.getGridSize = ccgDM_getGridSize;
1520  ccgdm->dm.getGridData = ccgDM_getGridData;
1522  ccgdm->dm.getGridKey = ccgDM_getGridKey;
1525 
1527 
1528  ccgdm->dm.release = ccgDM_release;
1529 }
1530 
1532 {
1533  CCGVertIterator vi;
1534  CCGEdgeIterator ei;
1535  CCGFaceIterator fi;
1536  int totvert, totedge, totface;
1537 
1538  totvert = ccgSubSurf_getNumVerts(ss);
1539  ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap");
1541  ccgVertIterator_next(&vi)) {
1543 
1545  }
1546 
1547  totedge = ccgSubSurf_getNumEdges(ss);
1548  ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap");
1550  ccgEdgeIterator_next(&ei)) {
1552 
1554  }
1555 
1556  totface = ccgSubSurf_getNumFaces(ss);
1557  ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap");
1559  ccgFaceIterator_next(&fi)) {
1561 
1563  }
1564 }
1565 
1566 /* Fill in all geometry arrays making it possible to access any
1567  * hires data from the CPU.
1568  */
1570  CCGSubSurf *ss,
1571  DerivedMesh *dm,
1572  bool useSubsurfUv)
1573 {
1574  const int totvert = ccgSubSurf_getNumVerts(ss);
1575  const int totedge = ccgSubSurf_getNumEdges(ss);
1576  const int totface = ccgSubSurf_getNumFaces(ss);
1577  int index;
1578  int i;
1579  int vertNum = 0, edgeNum = 0, faceNum = 0;
1580  short *edgeFlags = ccgdm->edgeFlags;
1581  DMFlagMat *faceFlags = ccgdm->faceFlags;
1582  int *polyidx = NULL;
1583 #ifndef USE_DYNSIZE
1584  int *loopidx = NULL, *vertidx = NULL;
1585  BLI_array_declare(loopidx);
1586  BLI_array_declare(vertidx);
1587 #endif
1588  int loopindex, loopindex2;
1589  int edgeSize;
1590  int gridSize;
1591  int gridFaces, gridCuts;
1592  int gridSideEdges;
1593  int gridInternalEdges;
1594  WeightTable wtable = {NULL};
1595  MEdge *medge = NULL;
1596  bool has_edge_cd;
1597 
1598  edgeSize = ccgSubSurf_getEdgeSize(ss);
1599  gridSize = ccgSubSurf_getGridSize(ss);
1600  gridFaces = gridSize - 1;
1601  gridCuts = gridSize - 2;
1602  /*gridInternalVerts = gridSideVerts * gridSideVerts; - as yet, unused */
1603  gridSideEdges = gridSize - 1;
1604  gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
1605 
1606  medge = dm->getEdgeArray(dm);
1607 
1608  const MPoly *mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1609  const int *base_polyOrigIndex = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1610 
1611  int *vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX);
1612  int *edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);
1613 
1614  int *polyOrigIndex = DM_get_poly_data_layer(&ccgdm->dm, CD_ORIGINDEX);
1615 
1616  has_edge_cd = ((ccgdm->dm.edgeData.totlayer - (edgeOrigIndex ? 1 : 0)) != 0);
1617 
1618  loopindex = loopindex2 = 0; /* current loop index */
1619  for (index = 0; index < totface; index++) {
1620  CCGFace *f = ccgdm->faceMap[index].face;
1621  int numVerts = ccgSubSurf_getFaceNumVerts(f);
1622  int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
1623  int origIndex = POINTER_AS_INT(ccgSubSurf_getFaceFaceHandle(f));
1624  int g2_wid = gridCuts + 2;
1625  float *w, *w2;
1626  int s, x, y;
1627 #ifdef USE_DYNSIZE
1628  int loopidx[numVerts], vertidx[numVerts];
1629 #endif
1630  w = get_ss_weights(&wtable, gridCuts, numVerts);
1631 
1632  ccgdm->faceMap[index].startVert = vertNum;
1633  ccgdm->faceMap[index].startEdge = edgeNum;
1634  ccgdm->faceMap[index].startFace = faceNum;
1635 
1636  faceFlags->flag = mpoly ? mpoly[origIndex].flag : 0;
1637  faceFlags->mat_nr = mpoly ? mpoly[origIndex].mat_nr : 0;
1638  faceFlags++;
1639 
1640  /* set the face base vert */
1641  *((int *)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
1642 
1643 #ifndef USE_DYNSIZE
1644  BLI_array_clear(loopidx);
1645  BLI_array_grow_items(loopidx, numVerts);
1646 #endif
1647  for (s = 0; s < numVerts; s++) {
1648  loopidx[s] = loopindex++;
1649  }
1650 
1651 #ifndef USE_DYNSIZE
1652  BLI_array_clear(vertidx);
1653  BLI_array_grow_items(vertidx, numVerts);
1654 #endif
1655  for (s = 0; s < numVerts; s++) {
1656  CCGVert *v = ccgSubSurf_getFaceVert(f, s);
1658  }
1659 
1660  /* I think this is for interpolating the center vert? */
1661  w2 = w; // + numVerts*(g2_wid-1) * (g2_wid-1); //numVerts*((g2_wid-1) * g2_wid+g2_wid-1);
1662  DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum);
1663  if (vertOrigIndex) {
1664  *vertOrigIndex = ORIGINDEX_NONE;
1665  vertOrigIndex++;
1666  }
1667 
1668  vertNum++;
1669 
1670  /* Interpolate per-vert data. */
1671  for (s = 0; s < numVerts; s++) {
1672  for (x = 1; x < gridFaces; x++) {
1673  w2 = w + s * numVerts * g2_wid * g2_wid + x * numVerts;
1674  DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum);
1675 
1676  if (vertOrigIndex) {
1677  *vertOrigIndex = ORIGINDEX_NONE;
1678  vertOrigIndex++;
1679  }
1680 
1681  vertNum++;
1682  }
1683  }
1684 
1685  /* Interpolate per-vert data. */
1686  for (s = 0; s < numVerts; s++) {
1687  for (y = 1; y < gridFaces; y++) {
1688  for (x = 1; x < gridFaces; x++) {
1689  w2 = w + s * numVerts * g2_wid * g2_wid + (y * g2_wid + x) * numVerts;
1690  DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum);
1691 
1692  if (vertOrigIndex) {
1693  *vertOrigIndex = ORIGINDEX_NONE;
1694  vertOrigIndex++;
1695  }
1696 
1697  vertNum++;
1698  }
1699  }
1700  }
1701 
1702  if (edgeOrigIndex) {
1703  for (i = 0; i < numFinalEdges; i++) {
1704  edgeOrigIndex[edgeNum + i] = ORIGINDEX_NONE;
1705  }
1706  }
1707 
1708  for (s = 0; s < numVerts; s++) {
1709  /* Interpolate per-face data. */
1710  for (y = 0; y < gridFaces; y++) {
1711  for (x = 0; x < gridFaces; x++) {
1712  w2 = w + s * numVerts * g2_wid * g2_wid + (y * g2_wid + x) * numVerts;
1714  &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
1715  loopindex2++;
1716 
1717  w2 = w + s * numVerts * g2_wid * g2_wid + ((y + 1) * g2_wid + (x)) * numVerts;
1719  &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
1720  loopindex2++;
1721 
1722  w2 = w + s * numVerts * g2_wid * g2_wid + ((y + 1) * g2_wid + (x + 1)) * numVerts;
1724  &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
1725  loopindex2++;
1726 
1727  w2 = w + s * numVerts * g2_wid * g2_wid + ((y)*g2_wid + (x + 1)) * numVerts;
1729  &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2);
1730  loopindex2++;
1731 
1732  /* Copy over poly data, e.g. #CD_FACEMAP. */
1733  CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, origIndex, faceNum, 1);
1734 
1735  if (polyOrigIndex) {
1736  *polyOrigIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
1737  polyOrigIndex++;
1738  }
1739 
1740  ccgdm->reverseFaceMap[faceNum] = index;
1741 
1742  /* This is a simple one to one mapping, here... */
1743  if (polyidx) {
1744  polyidx[faceNum] = faceNum;
1745  }
1746 
1747  faceNum++;
1748  }
1749  }
1750  }
1751 
1752  edgeNum += numFinalEdges;
1753  }
1754 
1755  for (index = 0; index < totedge; index++) {
1756  CCGEdge *e = ccgdm->edgeMap[index].edge;
1757  int numFinalEdges = edgeSize - 1;
1758  int mapIndex = ccgDM_getEdgeMapIndex(ss, e);
1759  int x;
1760  int vertIdx[2];
1762 
1763  CCGVert *v;
1768 
1769  ccgdm->edgeMap[index].startVert = vertNum;
1770  ccgdm->edgeMap[index].startEdge = edgeNum;
1771 
1772  if (edgeIdx >= 0 && edgeFlags) {
1773  edgeFlags[edgeIdx] = medge[edgeIdx].flag;
1774  }
1775 
1776  /* set the edge base vert */
1777  *((int *)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum;
1778 
1779  for (x = 1; x < edgeSize - 1; x++) {
1780  float w[2];
1781  w[1] = (float)x / (edgeSize - 1);
1782  w[0] = 1 - w[1];
1783  DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum);
1784  if (vertOrigIndex) {
1785  *vertOrigIndex = ORIGINDEX_NONE;
1786  vertOrigIndex++;
1787  }
1788  vertNum++;
1789  }
1790 
1791  if (has_edge_cd) {
1792  BLI_assert(edgeIdx >= 0 && edgeIdx < dm->getNumEdges(dm));
1793  for (i = 0; i < numFinalEdges; i++) {
1794  CustomData_copy_data(&dm->edgeData, &ccgdm->dm.edgeData, edgeIdx, edgeNum + i, 1);
1795  }
1796  }
1797 
1798  if (edgeOrigIndex) {
1799  for (i = 0; i < numFinalEdges; i++) {
1800  edgeOrigIndex[edgeNum + i] = mapIndex;
1801  }
1802  }
1803 
1804  edgeNum += numFinalEdges;
1805  }
1806 
1807  if (useSubsurfUv) {
1808  CustomData *ldata = &ccgdm->dm.loopData;
1809  CustomData *dmldata = &dm->loopData;
1810  int numlayer = CustomData_number_of_layers(ldata, CD_MLOOPUV);
1811  int dmnumlayer = CustomData_number_of_layers(dmldata, CD_MLOOPUV);
1812 
1813  for (i = 0; i < numlayer && i < dmnumlayer; i++) {
1814  set_subsurf_uv(ss, dm, &ccgdm->dm, i);
1815  }
1816  }
1817 
1818  for (index = 0; index < totvert; index++) {
1819  CCGVert *v = ccgdm->vertMap[index].vert;
1820  int mapIndex = ccgDM_getVertMapIndex(ccgdm->ss, v);
1821  int vertIdx;
1822 
1824 
1825  ccgdm->vertMap[index].startVert = vertNum;
1826 
1827  /* set the vert base vert */
1828  *((int *)ccgSubSurf_getVertUserData(ss, v)) = vertNum;
1829 
1830  DM_copy_vert_data(dm, &ccgdm->dm, vertIdx, vertNum, 1);
1831 
1832  if (vertOrigIndex) {
1833  *vertOrigIndex = mapIndex;
1834  vertOrigIndex++;
1835  }
1836  vertNum++;
1837  }
1838 
1839 #ifndef USE_DYNSIZE
1840  BLI_array_free(vertidx);
1841  BLI_array_free(loopidx);
1842 #endif
1843  free_ss_weights(&wtable);
1844 
1845  BLI_assert(vertNum == ccgSubSurf_getNumFinalVerts(ss));
1846  BLI_assert(edgeNum == ccgSubSurf_getNumFinalEdges(ss));
1847  BLI_assert(loopindex2 == ccgSubSurf_getNumFinalFaces(ss) * 4);
1848  BLI_assert(faceNum == ccgSubSurf_getNumFinalFaces(ss));
1849 }
1850 
1852  int drawInteriorEdges,
1853  int useSubsurfUv,
1854  DerivedMesh *dm)
1855 {
1856  const int totedge = ccgSubSurf_getNumEdges(ss);
1857  const int totface = ccgSubSurf_getNumFaces(ss);
1858  CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
1859 
1860  BLI_assert(totedge == ccgSubSurf_getNumEdges(ss));
1861  BLI_assert(totface == ccgSubSurf_getNumFaces(ss));
1862  DM_from_template(&ccgdm->dm,
1863  dm,
1864  DM_TYPE_CCGDM,
1867  0,
1870 
1871  ccgdm->reverseFaceMap = MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss),
1872  "reverseFaceMap");
1873 
1874  create_ccgdm_maps(ccgdm, ss);
1875 
1877 
1878  ccgdm->ss = ss;
1879  ccgdm->drawInteriorEdges = drawInteriorEdges;
1880  ccgdm->useSubsurfUv = useSubsurfUv;
1881 
1882  /* CDDM hack. */
1883  ccgdm->edgeFlags = MEM_callocN(sizeof(short) * totedge, "edgeFlags");
1884  ccgdm->faceFlags = MEM_callocN(sizeof(DMFlagMat) * totface, "faceFlags");
1885 
1886  set_ccgdm_all_geometry(ccgdm, ss, dm, useSubsurfUv != 0);
1887 
1891  ccgdm->dm.numLoopData = ccgdm->dm.numPolyData * 4;
1892  ccgdm->dm.numTessFaceData = 0;
1893 
1896 
1897  return ccgdm;
1898 }
1899 
1900 /***/
1901 
1903  struct SubsurfModifierData *smd,
1904  const struct Scene *scene,
1905  float (*vertCos)[3],
1906  SubsurfFlags flags)
1907 {
1908  const int useSimple = (smd->subdivType == ME_SIMPLE_SUBSURF) ? CCG_SIMPLE_SUBDIV : 0;
1909  const CCGFlags useAging = (smd->flags & eSubsurfModifierFlag_DebugIncr) ? CCG_USE_AGING : 0;
1910  const int useSubsurfUv = (smd->uv_smooth != SUBSURF_UV_SMOOTH_NONE);
1911  const int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
1912  const bool ignore_simplify = (flags & SUBSURF_IGNORE_SIMPLIFY);
1914 
1915  /* NOTE: editmode calculation can only run once per
1916  * modifier stack evaluation (uses freed cache) T36299. */
1917  if (flags & SUBSURF_FOR_EDIT_MODE) {
1918  int levels = (scene != NULL && !ignore_simplify) ?
1919  get_render_subsurf_level(&scene->r, smd->levels, false) :
1920  smd->levels;
1921 
1922  /* TODO(sergey): Same as emCache below. */
1923  if ((flags & SUBSURF_IN_EDIT_MODE) && smd->mCache) {
1924  ccgSubSurf_free(smd->mCache);
1925  smd->mCache = NULL;
1926  }
1927 
1928  smd->emCache = _getSubSurf(smd->emCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
1929 
1930  ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple, useSubsurfUv);
1931  result = getCCGDerivedMesh(smd->emCache, drawInteriorEdges, useSubsurfUv, dm);
1932  }
1933  else if (flags & SUBSURF_USE_RENDER_PARAMS) {
1934  /* Do not use cache in render mode. */
1935  CCGSubSurf *ss;
1936  int levels = (scene != NULL && !ignore_simplify) ?
1937  get_render_subsurf_level(&scene->r, smd->renderLevels, true) :
1938  smd->renderLevels;
1939 
1940  if (levels == 0) {
1941  return dm;
1942  }
1943 
1944  ss = _getSubSurf(NULL, levels, 3, useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS);
1945 
1946  ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
1947 
1948  result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
1949 
1950  result->freeSS = 1;
1951  }
1952  else {
1953  int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental);
1954  int levels = (scene != NULL && !ignore_simplify) ?
1955  get_render_subsurf_level(&scene->r, smd->levels, false) :
1956  smd->levels;
1957  CCGSubSurf *ss;
1958 
1959  /* It is quite possible there is a much better place to do this. It
1960  * depends a bit on how rigorously we expect this function to never
1961  * be called in editmode. In semi-theory we could share a single
1962  * cache, but the handles used inside and outside editmode are not
1963  * the same so we would need some way of converting them. Its probably
1964  * not worth the effort. But then why am I even writing this long
1965  * comment that no one will read? Hmmm. - zr
1966  *
1967  * Addendum: we can't really ensure that this is never called in edit
1968  * mode, so now we have a parameter to verify it. - brecht
1969  */
1970  if (!(flags & SUBSURF_IN_EDIT_MODE) && smd->emCache) {
1971  ccgSubSurf_free(smd->emCache);
1972  smd->emCache = NULL;
1973  }
1974 
1975  if (useIncremental && (flags & SUBSURF_IS_FINAL_CALC)) {
1976  smd->mCache = ss = _getSubSurf(
1977  smd->mCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
1978 
1979  ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
1980 
1981  result = getCCGDerivedMesh(smd->mCache, drawInteriorEdges, useSubsurfUv, dm);
1982  }
1983  else {
1984  CCGFlags ccg_flags = useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS;
1985  CCGSubSurf *prevSS = NULL;
1986 
1987  if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) {
1988  ccgSubSurf_free(smd->mCache);
1989  smd->mCache = NULL;
1990  }
1991 
1992  if (flags & SUBSURF_ALLOC_PAINT_MASK) {
1993  ccg_flags |= CCG_ALLOC_MASK;
1994  }
1995 
1996  ss = _getSubSurf(prevSS, levels, 3, ccg_flags);
1997  ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
1998 
1999  result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
2000 
2001  if (flags & SUBSURF_IS_FINAL_CALC) {
2002  smd->mCache = ss;
2003  }
2004  else {
2005  result->freeSS = 1;
2006  }
2007 
2008  if (flags & SUBSURF_ALLOC_PAINT_MASK) {
2009  ccgSubSurf_setNumLayers(ss, 4);
2010  }
2011  }
2012  }
2013 
2014  return (DerivedMesh *)result;
2015 }
2016 
2017 void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3])
2018 {
2019  /* Finds the subsurf limit positions for the verts in a mesh
2020  * and puts them in an array of floats. Please note that the
2021  * calculated vert positions is incorrect for the verts
2022  * on the boundary of the mesh.
2023  */
2024  CCGSubSurf *ss = _getSubSurf(NULL, 1, 3, CCG_USE_ARENA);
2025  float edge_sum[3], face_sum[3];
2026  CCGVertIterator vi;
2027  DerivedMesh *dm = CDDM_from_mesh(me);
2028 
2029  ss_sync_from_derivedmesh(ss, dm, NULL, 0, 0);
2030 
2032  ccgVertIterator_next(&vi)) {
2036  int numFaces = ccgSubSurf_getVertNumFaces(v);
2037  float *co;
2038  int i;
2039 
2040  zero_v3(edge_sum);
2041  zero_v3(face_sum);
2042 
2043  for (i = 0; i < N; i++) {
2045  add_v3_v3v3(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
2046  }
2047  for (i = 0; i < numFaces; i++) {
2048  CCGFace *f = ccgSubSurf_getVertFace(v, i);
2050  }
2051 
2052  /* ad-hoc correction for boundary vertices, to at least avoid them
2053  * moving completely out of place (brecht) */
2054  if (numFaces && numFaces != N) {
2055  mul_v3_fl(face_sum, (float)N / (float)numFaces);
2056  }
2057 
2058  co = ccgSubSurf_getVertData(ss, v);
2059  r_positions[idx][0] = (co[0] * N * N + edge_sum[0] * 4 + face_sum[0]) / (N * (N + 5));
2060  r_positions[idx][1] = (co[1] * N * N + edge_sum[1] * 4 + face_sum[1]) / (N * (N + 5));
2061  r_positions[idx][2] = (co[2] * N * N + edge_sum[2] * 4 + face_sum[2]) / (N * (N + 5));
2062  }
2063 
2064  ccgSubSurf_free(ss);
2065 
2066  dm->release(dm);
2067 }
typedef float(TangentPoint)[2]
void * DM_get_edge_data_layer(struct DerivedMesh *dm, int type)
Definition: DerivedMesh.cc:441
void DM_interp_vert_data(struct DerivedMesh *source, struct DerivedMesh *dest, int *src_indices, float *weights, int count, int dest_index)
Definition: DerivedMesh.cc:466
void DM_copy_vert_data(struct DerivedMesh *source, struct DerivedMesh *dest, int source_index, int dest_index, int count)
Definition: DerivedMesh.cc:460
void * DM_get_poly_data_layer(struct DerivedMesh *dm, int type)
Definition: DerivedMesh.cc:450
bool DM_release(DerivedMesh *dm)
Definition: DerivedMesh.cc:307
void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys)
Definition: DerivedMesh.cc:277
void DM_ensure_looptri_data(DerivedMesh *dm)
Definition: DerivedMesh.cc:362
void * DM_get_vert_data_layer(struct DerivedMesh *dm, int type)
Definition: DerivedMesh.cc:432
@ DM_TYPE_CCGDM
void CCG_key_top_level(CCGKey *key, const struct CCGSubSurf *ss)
BLI_INLINE float * CCG_grid_elem_co(const CCGKey *key, CCGElem *elem, int x, int y)
Definition: BKE_ccg.h:114
BLI_INLINE float * CCG_elem_no(const CCGKey *key, CCGElem *elem)
Definition: BKE_ccg.h:91
struct CCGElem CCGElem
Definition: BKE_ccg.h:30
BLI_INLINE float * CCG_elem_offset_co(const CCGKey *key, CCGElem *elem, int offset)
Definition: BKE_ccg.h:129
BLI_INLINE float * CCG_elem_co(const CCGKey *key, CCGElem *elem)
struct DerivedMesh * CDDM_from_mesh(struct Mesh *mesh)
int CustomData_number_of_layers(const struct CustomData *data, int type)
@ CD_CALLOC
void CustomData_interp(const struct CustomData *source, struct CustomData *dest, const int *src_indices, const float *weights, const float *sub_weights, int count, int dest_index)
#define ORIGINDEX_NONE
void * CustomData_get_layer_n(const struct CustomData *data, int type, int n)
void * CustomData_get_layer(const struct CustomData *data, int type)
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.cc:2776
void CustomData_copy_data(const struct CustomData *source, struct CustomData *dest, int source_index, int dest_index, int count)
UvMapVert * BKE_mesh_uv_vert_map_get_vert(UvVertMap *vmap, unsigned int v)
Definition: mesh_mapping.c:162
UvVertMap * BKE_mesh_uv_vert_map_create(const struct MPoly *mpoly, const struct MLoop *mloop, const struct MLoopUV *mloopuv, unsigned int totpoly, unsigned int totvert, const float limit[2], bool selected, bool use_winding)
void BKE_mesh_uv_vert_map_free(UvVertMap *vmap)
Definition: mesh_mapping.c:167
#define STD_UV_CONNECT_LIMIT
void multires_modifier_update_mdisps(struct DerivedMesh *dm, struct Scene *scene)
Definition: multires.c:1019
void multires_modifier_update_hidden(struct DerivedMesh *dm)
Definition: multires.c:1146
General operations, lookup, etc. for blender objects.
A BVH for high poly meshes.
int get_render_subsurf_level(const struct RenderData *r, int lvl, bool for_render)
@ MULTIRES_HIDDEN_MODIFIED
Definition: BKE_subsurf.h:69
@ MULTIRES_COORDS_MODIFIED
Definition: BKE_subsurf.h:67
SubsurfFlags
Definition: BKE_subsurf.h:35
@ SUBSURF_FOR_EDIT_MODE
Definition: BKE_subsurf.h:38
@ SUBSURF_IN_EDIT_MODE
Definition: BKE_subsurf.h:39
@ SUBSURF_ALLOC_PAINT_MASK
Definition: BKE_subsurf.h:40
@ SUBSURF_USE_RENDER_PARAMS
Definition: BKE_subsurf.h:36
@ SUBSURF_IS_FINAL_CALC
Definition: BKE_subsurf.h:37
@ SUBSURF_IGNORE_SIMPLIFY
Definition: BKE_subsurf.h:42
A (mainly) macro array library.
#define BLI_array_grow_items(arr, num)
Definition: BLI_array.h:91
#define BLI_array_declare(arr)
Definition: BLI_array.h:50
#define BLI_array_clear(arr)
Definition: BLI_array.h:128
#define BLI_array_free(arr)
Definition: BLI_array.h:113
#define BLI_assert(a)
Definition: BLI_assert.h:46
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:16
#define BLI_INLINE
void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP free_value)
Definition: edgehash.c:230
void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val)
Definition: edgehash.c:261
bool BLI_edgeset_add(EdgeSet *es, unsigned int v0, unsigned int v1)
Definition: edgehash.c:484
EdgeSet * BLI_edgeset_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:424
void BLI_edgeset_free(EdgeSet *es)
Definition: edgehash.c:441
#define BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totpoly)
Definition: BLI_edgehash.h:183
EdgeHash * BLI_edgehash_new_ex(const char *info, unsigned int nentries_reserve)
Definition: edgehash.c:212
void * BLI_edgehash_lookup(const EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT
Definition: edgehash.c:295
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
Definition: BLI_memarena.c:94
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
Definition: BLI_memarena.c:64
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
Definition: BLI_memarena.c:116
unsigned int uint
Definition: BLI_sys_types.h:67
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:94
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:293
void BLI_rw_mutex_end(ThreadRWMutex *mutex)
Definition: threads.cc:503
void BLI_mutex_end(ThreadMutex *mutex)
Definition: threads.cc:388
#define THREAD_LOCK_READ
Definition: BLI_threads.h:120
void BLI_mutex_init(ThreadMutex *mutex)
Definition: threads.cc:368
#define THREAD_LOCK_WRITE
Definition: BLI_threads.h:121
void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode)
Definition: threads.cc:488
void BLI_mutex_lock(ThreadMutex *mutex)
Definition: threads.cc:373
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition: threads.cc:378
void BLI_rw_mutex_init(ThreadRWMutex *mutex)
Definition: threads.cc:483
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex)
Definition: threads.cc:498
#define UNUSED_FUNCTION(x)
#define POINTER_FROM_INT(i)
#define POINTER_AS_UINT(i)
#define UNUSED(x)
#define POINTER_AS_INT(i)
#define MAX2(a, b)
#define POINTER_FROM_UINT(i)
void ccgSubSurf_initFaceIterator(CCGSubSurf *ss, CCGFaceIterator *fiter)
Definition: CCGSubSurf.c:1438
int ccgSubSurf_getNumFinalEdges(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1494
int ccgSubSurf_getNumFaces(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1198
CCGVert * ccgVertIterator_getCurrent(CCGVertIterator *vi)
Definition: CCGSubSurf.c:1443
void ccgVertIterator_next(CCGVertIterator *vi)
Definition: CCGSubSurf.c:1451
int ccgSubSurf_getVertNumFaces(CCGVert *v)
Definition: CCGSubSurf.c:1266
CCGFace * ccgSubSurf_getVertFace(CCGVert *v, int index)
Definition: CCGSubSurf.c:1270
int ccgSubSurf_getNumFinalFaces(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1502
int ccgFaceIterator_isStopped(CCGFaceIterator *fi)
Definition: CCGSubSurf.c:1473
CCGSubSurf * ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator)
Definition: CCGSubSurf.c:227
int ccgEdgeIterator_isStopped(CCGEdgeIterator *ei)
Definition: CCGSubSurf.c:1460
void * ccgSubSurf_getVertData(CCGSubSurf *ss, CCGVert *v)
Definition: CCGSubSurf.c:1288
void ccgSubSurf_initEdgeIterator(CCGSubSurf *ss, CCGEdgeIterator *eiter)
Definition: CCGSubSurf.c:1434
void ccgSubSurf_setNumLayers(CCGSubSurf *ss, int numLayers)
Definition: CCGSubSurf.c:435
int ccgSubSurf_getNumVerts(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1190
void * ccgSubSurf_getFaceUserData(CCGSubSurf *ss, CCGFace *f)
Definition: CCGSubSurf.c:1371
CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r)
Definition: CCGSubSurf.c:672
int ccgSubSurf_getSubdivisionLevels(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1216
CCGVert * ccgSubSurf_getEdgeVert0(CCGEdge *e)
Definition: CCGSubSurf.c:1329
CCGVert * ccgSubSurf_getFaceVert(CCGFace *f, int index)
Definition: CCGSubSurf.c:1382
void * ccgSubSurf_getFaceGridData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x, int y)
Definition: CCGSubSurf.c:1422
CCGError ccgSubSurf_processSync(CCGSubSurf *ss)
Definition: CCGSubSurf.c:811
int ccgSubSurf_getVertNumEdges(CCGVert *v)
Definition: CCGSubSurf.c:1277
CCGError ccgSubSurf_setCalcVertexNormals(CCGSubSurf *ss, int useVertNormals, int normalDataOffset)
Definition: CCGSubSurf.c:412
CCGFace * ccgSubSurf_getFace(CCGSubSurf *ss, CCGFaceHDL f)
Definition: CCGSubSurf.c:1211
CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, const void *vertData, int seam, CCGVert **v_r)
Definition: CCGSubSurf.c:539
int ccgSubSurf_getSimpleSubdiv(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1243
int ccgSubSurf_getGridSize(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1231
void * ccgSubSurf_getEdgeDataArray(CCGSubSurf *ss, CCGEdge *e)
Definition: CCGSubSurf.c:1337
float ccgSubSurf_getEdgeCrease(CCGEdge *e)
Definition: CCGSubSurf.c:1352
void * ccgSubSurf_getFaceGridEdgeData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x)
Definition: CCGSubSurf.c:1413
CCGEdgeHDL ccgSubSurf_getEdgeEdgeHandle(CCGEdge *e)
Definition: CCGSubSurf.c:1302
void * ccgSubSurf_getFaceCenterData(CCGFace *f)
Definition: CCGSubSurf.c:1405
CCGVert * ccgSubSurf_getEdgeVert1(CCGEdge *e)
Definition: CCGSubSurf.c:1333
void ccgEdgeIterator_next(CCGEdgeIterator *ei)
Definition: CCGSubSurf.c:1464
void ccgSubSurf_initVertIterator(CCGSubSurf *ss, CCGVertIterator *viter)
Definition: CCGSubSurf.c:1430
void ccgSubSurf_getUseAgeCounts(CCGSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r)
Definition: CCGSubSurf.c:371
CCGFaceHDL ccgSubSurf_getFaceFaceHandle(CCGFace *f)
Definition: CCGSubSurf.c:1359
void * ccgSubSurf_getVertUserData(CCGSubSurf *ss, CCGVert *v)
Definition: CCGSubSurf.c:1262
void ccgSubSurf_setAllocMask(CCGSubSurf *ss, int allocMask, int maskOffset)
Definition: CCGSubSurf.c:429
void ccgSubSurf_free(CCGSubSurf *ss)
Definition: CCGSubSurf.c:281
CCGError ccgSubSurf_initFullSync(CCGSubSurf *ss)
Definition: CCGSubSurf.c:442
CCGError ccgSubSurf_setUseAgeCounts(CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset)
Definition: CCGSubSurf.c:390
CCGEdge * ccgEdgeIterator_getCurrent(CCGEdgeIterator *ei)
Definition: CCGSubSurf.c:1456
int ccgSubSurf_getNumEdges(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1194
int ccgSubSurf_getNumFinalVerts(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1484
CCGEdge * ccgSubSurf_getVertEdge(CCGVert *v, int index)
Definition: CCGSubSurf.c:1281
void * ccgSubSurf_getEdgeData(CCGSubSurf *ss, CCGEdge *e, int x)
Definition: CCGSubSurf.c:1341
void ccgFaceIterator_next(CCGFaceIterator *fi)
Definition: CCGSubSurf.c:1477
int ccgVertIterator_isStopped(CCGVertIterator *vi)
Definition: CCGSubSurf.c:1447
int ccgSubSurf_getEdgeNumFaces(CCGEdge *e)
Definition: CCGSubSurf.c:1318
CCGEdge * ccgSubSurf_getFaceEdge(CCGFace *f, int index)
Definition: CCGSubSurf.c:1389
int ccgSubSurf_getEdgeSize(const CCGSubSurf *ss)
Definition: CCGSubSurf.c:1220
void * ccgSubSurf_getEdgeUserData(CCGSubSurf *ss, CCGEdge *e)
Definition: CCGSubSurf.c:1314
CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels)
Definition: CCGSubSurf.c:352
CCGVertHDL ccgSubSurf_getVertVertHandle(CCGVert *v)
Definition: CCGSubSurf.c:1250
void * ccgSubSurf_getFaceGridDataArray(CCGSubSurf *ss, CCGFace *f, int gridIndex)
Definition: CCGSubSurf.c:1418
CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r)
Definition: CCGSubSurf.c:606
CCGFace * ccgFaceIterator_getCurrent(CCGFaceIterator *fi)
Definition: CCGSubSurf.c:1469
int ccgSubSurf_getFaceNumVerts(CCGFace *f)
Definition: CCGSubSurf.c:1378
void * CCGEdgeHDL
Definition: CCGSubSurf.h:11
void * CCGVertHDL
Definition: CCGSubSurf.h:10
@ eCCGError_InvalidValue
Definition: CCGSubSurf.h:50
void * CCGAllocatorHDL
Definition: CCGSubSurf.h:28
@ CD_MTFACE
@ CD_ORIGINDEX
@ CD_MLOOPUV
@ ME_SIMPLE_SUBSURF
@ ME_SMOOTH
@ ME_EDGEDRAW
@ ME_SEAM
@ ME_EDGERENDER
@ ME_LOOSEEDGE
@ ME_SHARP
@ eSubsurfModifierFlag_Incremental
@ eSubsurfModifierFlag_DebugIncr
@ eSubsurfModifierFlag_ControlEdges
@ SUBSURF_UV_SMOOTH_NONE
Object is a sort of wrapper for general info.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Read Guarded memory(de)allocation.
#define MEM_SIZE_OPTIMAL(size)
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE void * atomic_cas_ptr(void **v, void *old, void *_new)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
virtual int getNumEdges() const
Definition: btBox2dShape.h:174
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
Scene scene
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static ulong * next
#define N
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
const int faceMap[6][4]
Definition: octree.cpp:2817
#define min(a, b)
Definition: sort.c:35
void(* free)(CCGAllocatorHDL a, void *ptr)
Definition: CCGSubSurf.h:33
void(* release)(CCGAllocatorHDL a)
Definition: CCGSubSurf.h:34
void *(* realloc)(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize)
Definition: CCGSubSurf.h:32
void *(* alloc)(CCGAllocatorHDL a, int numBytes)
Definition: CCGSubSurf.h:31
struct MeshElemMap * pmap
Definition: BKE_subsurf.h:104
struct CCGFace ** gridFaces
Definition: BKE_subsurf.h:109
int drawInteriorEdges
Definition: BKE_subsurf.h:79
struct DMFlagMat * faceFlags
Definition: BKE_subsurf.h:98
struct CCGVert * vert
Definition: BKE_subsurf.h:83
struct CCGDerivedMesh::@72 * edgeMap
struct CCGDerivedMesh::@74 multires
struct CCGSubSurf * ss
Definition: BKE_subsurf.h:77
struct MultiresModifierData * mmd
Definition: BKE_subsurf.h:116
unsigned int numGrid
Definition: BKE_subsurf.h:113
struct EdgeHash * ehash
Definition: BKE_subsurf.h:126
MultiresModifiedFlags modified_flags
Definition: BKE_subsurf.h:123
ThreadMutex loops_cache_lock
Definition: BKE_subsurf.h:128
int * reverseFaceMap
Definition: BKE_subsurf.h:100
unsigned int ** gridHidden
Definition: BKE_subsurf.h:111
DerivedMesh dm
Definition: BKE_subsurf.h:75
struct CCGEdge * edge
Definition: BKE_subsurf.h:88
struct CCGDerivedMesh::@71 * vertMap
struct Object * ob
Definition: BKE_subsurf.h:122
struct CCGElem ** gridData
Definition: BKE_subsurf.h:107
struct CCGFace * face
Definition: BKE_subsurf.h:94
short * edgeFlags
Definition: BKE_subsurf.h:97
struct CCGDerivedMesh::@73 * faceMap
struct DMFlagMat * gridFlagMats
Definition: BKE_subsurf.h:110
ThreadRWMutex origindex_cache_rwlock
Definition: BKE_subsurf.h:129
Definition: BKE_ccg.h:32
int numLayers
Definition: CCGSubSurf.h:21
int vertDataSize
Definition: CCGSubSurf.h:22
int simpleSubdiv
Definition: CCGSubSurf.h:23
int edgeUserSize
Definition: CCGSubSurf.h:20
int faceUserSize
Definition: CCGSubSurf.h:20
int vertUserSize
Definition: CCGSubSurf.h:20
CCGDerivedMesh * ccgdm
Definition: subsurf_ccg.c:1025
int(* getGridSize)(DerivedMesh *dm)
struct MLoop *(* getLoopArray)(DerivedMesh *dm)
void(* getVertNo)(DerivedMesh *dm, int index, float r_no[3])
void *(* getVertDataArray)(DerivedMesh *dm, int type)
CustomData vertData
DMFlagMat *(* getGridFlagMats)(DerivedMesh *dm)
struct MVert *(* getVertArray)(DerivedMesh *dm)
void(* copyLoopArray)(DerivedMesh *dm, struct MLoop *r_loop)
void(* copyEdgeArray)(DerivedMesh *dm, struct MEdge *r_edge)
int(* getNumVerts)(DerivedMesh *dm)
void(* copyPolyArray)(DerivedMesh *dm, struct MPoly *r_poly)
int(* getNumPolys)(DerivedMesh *dm)
int(* getNumEdges)(DerivedMesh *dm)
struct DerivedMesh::@16 looptris
struct CCGElem **(* getGridData)(DerivedMesh *dm)
int(* getNumGrids)(DerivedMesh *dm)
CustomData polyData
struct MLoopTri * array_wip
void(* copyVertArray)(DerivedMesh *dm, struct MVert *r_vert)
void *(* getPolyDataArray)(DerivedMesh *dm, int type)
unsigned int **(* getGridHidden)(DerivedMesh *dm)
void *(* getEdgeDataArray)(DerivedMesh *dm, int type)
struct MEdge *(* getEdgeArray)(DerivedMesh *dm)
void(* getGridKey)(DerivedMesh *dm, struct CCGKey *key)
CustomData edgeData
struct MPoly *(* getPolyArray)(DerivedMesh *dm)
CustomData loopData
void(* recalcLoopTri)(DerivedMesh *dm)
struct MLoopTri * array
void(* release)(DerivedMesh *dm)
void(* getVertCo)(DerivedMesh *dm, int index, float r_co[3])
int(* getNumLoops)(DerivedMesh *dm)
int *(* getGridOffset)(DerivedMesh *dm)
FaceVertWeight * weight
Definition: subsurf_ccg.c:473
unsigned int v1
unsigned int v2
unsigned int poly
unsigned int tri[3]
unsigned int e
unsigned int v
short mat_nr
float uv[4][2]
ListBase modifiers
struct RenderData r
unsigned short loop_of_poly_index
unsigned int poly_index
FaceVertWeightEntry * weight_table
Definition: subsurf_ccg.c:479
static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize)
Definition: subsurf_ccg.c:197
static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float r_co[3])
Definition: subsurf_ccg.c:855
static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, DerivedMesh *dm, bool useSubsurfUv)
Definition: subsurf_ccg.c:1569
static CCGSubSurf * _getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int numLayers, CCGFlags flags)
Definition: subsurf_ccg.c:100
struct FaceVertWeightEntry FaceVertWeightEntry
static void * arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize)
Definition: subsurf_ccg.c:72
float FaceVertWeight[SUB_ELEMS_FACE][SUB_ELEMS_FACE]
Definition: subsurf_ccg.c:470
static float * get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen)
Definition: subsurf_ccg.c:483
static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm)
Definition: subsurf_ccg.c:1500
static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, const MLoopUV *mloopuv)
Definition: subsurf_ccg.c:262
static CCGElem ** ccgDM_getGridData(DerivedMesh *dm)
Definition: subsurf_ccg.c:1428
static void ccgdm_create_grids(DerivedMesh *dm)
Definition: subsurf_ccg.c:1374
static void copyFinalLoopArray_task_cb(void *__restrict userdata, const int iter, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: subsurf_ccg.c:1033
static void * ccgDM_get_vert_data_layer(DerivedMesh *dm, int type)
Definition: subsurf_ccg.c:1230
BLI_INLINE void ccgDM_to_MVert(MVert *mv, const CCGKey *key, CCGElem *elem)
Definition: subsurf_ccg.c:878
static void UNUSED_FUNCTION() ccgDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
Definition: subsurf_ccg.c:699
static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mpoly)
Definition: subsurf_ccg.c:1120
static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize)
Definition: subsurf_ccg.c:179
static void free_ss_weights(WeightTable *wtable)
Definition: subsurf_ccg.c:539
static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f)
Definition: subsurf_ccg.c:672
static int ccgDM_getNumEdges(DerivedMesh *dm)
Definition: subsurf_ccg.c:758
static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v)
Definition: subsurf_ccg.c:662
static void minmax_v3_v3v3(const float vec[3], float min[3], float max[3])
Definition: subsurf_ccg.c:677
static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e)
Definition: subsurf_ccg.c:667
static void * ccgDM_get_poly_data_layer(DerivedMesh *dm, int type)
Definition: subsurf_ccg.c:1315
static int ccgDM_getNumVerts(DerivedMesh *dm)
Definition: subsurf_ccg.c:751
static DMFlagMat * ccgDM_getGridFlagMats(DerivedMesh *dm)
Definition: subsurf_ccg.c:1450
struct DerivedMesh * subsurf_make_derived_from_derived(struct DerivedMesh *dm, struct SubsurfModifierData *smd, const struct Scene *scene, float(*vertCos)[3], SubsurfFlags flags)
Definition: subsurf_ccg.c:1902
static int ccgDM_getNumGrids(DerivedMesh *dm)
Definition: subsurf_ccg.c:1352
static int * ccgDM_getGridOffset(DerivedMesh *dm)
Definition: subsurf_ccg.c:1436
static int ccgDM_getNumLoops(DerivedMesh *dm)
Definition: subsurf_ccg.c:772
void subsurf_calculate_limit_positions(Mesh *me, float(*r_positions)[3])
Definition: subsurf_ccg.c:2017
static void ccgDM_release(DerivedMesh *dm)
Definition: subsurf_ccg.c:1156
#define SUB_ELEMS_FACE
Definition: subsurf_ccg.c:469
static void get_face_uv_map_vert(UvVertMap *vmap, struct MPoly *mpoly, struct MLoop *ml, int fi, CCGVertHDL *fverts)
Definition: subsurf_ccg.c:242
static void ccgDM_recalcLoopTri(DerivedMesh *dm)
Definition: subsurf_ccg.c:1467
static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm, float(*vertexCos)[3], int useFlatSubdiv)
Definition: subsurf_ccg.c:554
static int ccgDM_getGridSize(DerivedMesh *dm)
Definition: subsurf_ccg.c:1368
BLI_INLINE void ccgDM_to_MEdge(MEdge *med, const int v1, const int v2, const short flag)
Definition: subsurf_ccg.c:947
static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float r_no[3])
Definition: subsurf_ccg.c:866
static void arena_free(CCGAllocatorHDL UNUSED(a), void *UNUSED(ptr))
Definition: subsurf_ccg.c:81
static void * arena_alloc(CCGAllocatorHDL a, int numBytes)
Definition: subsurf_ccg.c:67
static void arena_release(CCGAllocatorHDL a)
Definition: subsurf_ccg.c:86
static int ccgDM_getNumPolys(DerivedMesh *dm)
Definition: subsurf_ccg.c:765
static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm, float(*vertexCos)[3], int use_flat_subdiv, bool UNUSED(use_subdiv_uvs))
Definition: subsurf_ccg.c:651
static BLI_bitmap ** ccgDM_getGridHidden(DerivedMesh *dm)
Definition: subsurf_ccg.c:1458
static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
Definition: subsurf_ccg.c:385
struct CopyFinalLoopArrayData CopyFinalLoopArrayData
static CCGElem * get_vertex_elem(CCGDerivedMesh *ccgdm, int vertNum)
Definition: subsurf_ccg.c:780
static void * ccgDM_get_edge_data_layer(DerivedMesh *dm, int type)
Definition: subsurf_ccg.c:1272
static void create_ccgdm_maps(CCGDerivedMesh *ccgdm, CCGSubSurf *ss)
Definition: subsurf_ccg.c:1531
static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
Definition: subsurf_ccg.c:1076
static CCGDerivedMesh * getCCGDerivedMesh(CCGSubSurf *ss, int drawInteriorEdges, int useSubsurfUv, DerivedMesh *dm)
Definition: subsurf_ccg.c:1851
static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int layer_index)
Definition: subsurf_ccg.c:463
static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
Definition: subsurf_ccg.c:884
CCGFlags
Definition: subsurf_ccg.c:91
@ CCG_ALLOC_MASK
Definition: subsurf_ccg.c:96
@ CCG_CALC_NORMALS
Definition: subsurf_ccg.c:94
@ CCG_USE_ARENA
Definition: subsurf_ccg.c:93
@ CCG_SIMPLE_SUBDIV
Definition: subsurf_ccg.c:97
@ CCG_USE_AGING
Definition: subsurf_ccg.c:92
static void ccgDM_getGridKey(DerivedMesh *dm, CCGKey *key)
Definition: subsurf_ccg.c:1444
static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
Definition: subsurf_ccg.c:955
struct WeightTable WeightTable
float max
PointerRNA * ptr
Definition: wm_files.c:3480