[Bf-blender-cvs] [2090b3e5ac4] master: Cleanup: internal sculpt refactoring related to multires, no user visible changes
Brecht Van Lommel
noreply at git.blender.org
Tue Oct 1 16:15:37 CEST 2019
Commit: 2090b3e5ac41b5f5dffcdbd3d4c4b5ac0b84473d
Author: Brecht Van Lommel
Date: Mon Sep 30 16:33:04 2019 +0200
Branches: master
https://developer.blender.org/rB2090b3e5ac41b5f5dffcdbd3d4c4b5ac0b84473d
Cleanup: internal sculpt refactoring related to multires, no user visible changes
===================================================================
M source/blender/blenkernel/BKE_pbvh.h
M source/blender/blenkernel/intern/pbvh.c
M source/blender/editors/sculpt_paint/sculpt.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index fbf593496cf..dedf76ee839 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -214,7 +214,8 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden,
/* multires level, only valid for type == PBVH_GRIDS */
const struct CCGKey *BKE_pbvh_get_grid_key(const PBVH *pbvh);
-struct CCGElem **BKE_pbvh_get_grids(const PBVH *pbvh, int *num_grids);
+struct CCGElem **BKE_pbvh_get_grids(const PBVH *pbvh);
+int BKE_pbvh_get_grid_num_vertices(const PBVH *pbvh);
/* Only valid for type == PBVH_BMESH */
struct BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh);
@@ -362,6 +363,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo
if (vi.grids) { \
vi.width = vi.gridsize; \
vi.height = vi.gridsize; \
+ vi.index = vi.grid_indices[vi.g] * vi.key.grid_area - 1; \
vi.grid = vi.grids[vi.grid_indices[vi.g]]; \
if (mode == PBVH_ITER_UNIQUE) \
vi.gh = vi.grid_hidden[vi.grid_indices[vi.g]]; \
@@ -378,6 +380,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo
vi.fno = CCG_elem_no(&vi.key, vi.grid); \
vi.mask = vi.key.has_mask ? CCG_elem_mask(&vi.key, vi.grid) : NULL; \
vi.grid = CCG_elem_next(&vi.key, vi.grid); \
+ vi.index++; \
if (vi.gh) { \
if (BLI_BITMAP_TEST(vi.gh, vi.gy * vi.gridsize + vi.gx)) \
continue; \
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index d185ed0d271..7ed986204d5 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1484,13 +1484,18 @@ const CCGKey *BKE_pbvh_get_grid_key(const PBVH *bvh)
return &bvh->gridkey;
}
-struct CCGElem **BKE_pbvh_get_grids(const PBVH *bvh, int *num_grids)
+struct CCGElem **BKE_pbvh_get_grids(const PBVH *bvh)
{
BLI_assert(bvh->type == PBVH_GRIDS);
- *num_grids = bvh->totgrid;
return bvh->grids;
}
+int BKE_pbvh_get_grid_num_vertices(const PBVH *bvh)
+{
+ BLI_assert(bvh->type == PBVH_GRIDS);
+ return bvh->totgrid * bvh->gridkey.grid_area;
+}
+
BMesh *BKE_pbvh_get_bmesh(PBVH *bvh)
{
BLI_assert(bvh->type == PBVH_BMESH);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index e9d4dba937d..ed468a7e41a 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -98,7 +98,8 @@
* This is read-only, for writing use PBVH vertex iterators. There vd.index matches
* the indices used here.
*
- * Do not use these functions while working with PBVH_GRIDS data in SculptSession. */
+ * For multires, the same vertex in multiple grids is counted multiple times, with
+ * different index for each grid. */
static void sculpt_vertex_random_access_init(SculptSession *ss)
{
@@ -114,9 +115,11 @@ static int sculpt_vertex_count_get(SculptSession *ss)
return ss->totvert;
case PBVH_BMESH:
return BM_mesh_elem_count(BKE_pbvh_get_bmesh(ss->pbvh), BM_VERT);
- default:
- return 0;
+ case PBVH_GRIDS:
+ return BKE_pbvh_get_grid_num_vertices(ss->pbvh);
}
+
+ return 0;
}
const float *sculpt_vertex_co_get(SculptSession *ss, int index)
@@ -126,9 +129,13 @@ const float *sculpt_vertex_co_get(SculptSession *ss, int index)
return ss->mvert[index].co;
case PBVH_BMESH:
return BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co;
- case PBVH_GRIDS:
- BLI_assert(!"This fuction is not supposed to be used for PBVH_GRIDS");
- break;
+ case PBVH_GRIDS: {
+ const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
+ const int grid_index = index / key->grid_area;
+ const int vertex_index = index - grid_index * key->grid_area;
+ CCGElem *elem = BKE_pbvh_get_grids(ss->pbvh)[grid_index];
+ return CCG_elem_co(key, CCG_elem_offset(key, elem, vertex_index));
+ }
}
return NULL;
}
@@ -142,11 +149,17 @@ static void sculpt_vertex_normal_get(SculptSession *ss, int index, float no[3])
case PBVH_BMESH:
copy_v3_v3(no, BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->no);
break;
- default:
- zero_v3(no);
- return;
+ case PBVH_GRIDS: {
+ const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
+ const int grid_index = index / key->grid_area;
+ const int vertex_index = index - grid_index * key->grid_area;
+ CCGElem *elem = BKE_pbvh_get_grids(ss->pbvh)[grid_index];
+ copy_v3_v3(no, CCG_elem_no(key, CCG_elem_offset(key, elem, vertex_index)));
+ break;
+ }
}
}
+
static float sculpt_vertex_mask_get(SculptSession *ss, int index)
{
BMVert *v;
@@ -158,9 +171,16 @@ static float sculpt_vertex_mask_get(SculptSession *ss, int index)
v = BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index);
mask = BM_ELEM_CD_GET_VOID_P(v, CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK));
return *mask;
- default:
- return 0;
+ case PBVH_GRIDS: {
+ const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
+ const int grid_index = index / key->grid_area;
+ const int vertex_index = index - grid_index * key->grid_area;
+ CCGElem *elem = BKE_pbvh_get_grids(ss->pbvh)[grid_index];
+ return *CCG_elem_mask(key, CCG_elem_offset(key, elem, vertex_index));
+ }
}
+
+ return 0.0f;
}
static int sculpt_active_vertex_get(SculptSession *ss)
@@ -172,9 +192,9 @@ static int sculpt_active_vertex_get(SculptSession *ss)
case PBVH_BMESH:
return ss->active_vertex_index;
case PBVH_GRIDS:
- BLI_assert(!"This fuction is not supposed to be used for PBVH_GRIDS");
- break;
+ return ss->active_vertex_index;
}
+
return 0;
}
@@ -273,6 +293,18 @@ static void sculpt_vertex_neighbors_get_faces(SculptSession *ss,
}
}
+static void sculpt_vertex_neighbors_get_grids(SculptSession *UNUSED(ss),
+ int UNUSED(index),
+ SculptVertexNeighborIter *iter)
+{
+ /* TODO: implement this for multires. It might also be worth changing this
+ * iterator to provide a coordinate and mask pointer directly for effiency,
+ * rather than converting back and forth between CCGElem and global index. */
+ iter->size = 0;
+ iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY;
+ iter->neighbors = iter->neighbors_fixed;
+}
+
static void sculpt_vertex_neighbors_get(SculptSession *ss,
int index,
SculptVertexNeighborIter *iter)
@@ -284,8 +316,9 @@ static void sculpt_vertex_neighbors_get(SculptSession *ss,
case PBVH_BMESH:
sculpt_vertex_neighbors_get_bmesh(ss, index, iter);
return;
- default:
- break;
+ case PBVH_GRIDS:
+ sculpt_vertex_neighbors_get_grids(ss, index, iter);
+ return;
}
}
@@ -493,6 +526,8 @@ static void sculpt_floodfill_execute(SculptSession *ss,
void *userdata),
void *userdata)
{
+ /* TODO: multires support, taking into account duplicate vertices and
+ * correctly handling them in the pose, automask and mask expand callbacks. */
while (!BLI_gsqueue_is_empty(flood->queue)) {
SculptFloodFillIterator from;
BLI_gsqueue_pop(flood->queue, &from);
@@ -2356,6 +2391,48 @@ static float bmesh_neighbor_average_mask(BMVert *v, const int cd_vert_mask_offse
}
}
+static void grids_neighbor_average(SculptSession *ss, float result[3], int index)
+{
+ float avg[3] = {0.0f, 0.0f, 0.0f};
+ int total = 0;
+
+ SculptVertexNeighborIter ni;
+ sculpt_vertex_neighbors_iter_begin(ss, index, ni)
+ {
+ add_v3_v3(avg, sculpt_vertex_co_get(ss, ni.index));
+ total++;
+ }
+ sculpt_vertex_neighbors_iter_end(ni);
+
+ if (total > 0) {
+ mul_v3_v3fl(result, avg, 1.0f / (float)total);
+ }
+ else {
+ copy_v3_v3(result, sculpt_vertex_co_get(ss, index));
+ }
+}
+
+static float grids_neighbor_average_mask(SculptSession *ss, int index)
+{
+ float avg = 0.0f;
+ int total = 0;
+
+ SculptVertexNeighborIter ni;
+ sculpt_vertex_neighbors_iter_begin(ss, index, ni)
+ {
+ avg += sculpt_vertex_mask_get(ss, ni.index);
+ total++;
+ }
+ sculpt_vertex_neighbors_iter_end(ni);
+
+ if (total > 0) {
+ return avg / (float)total;
+ }
+ else {
+ return sculpt_vertex_mask_get(ss, index);
+ }
+}
+
/* Note: uses after-struct allocated mem to store actual cache... */
typedef struct SculptDoBrushSmoothGridDataChunk {
size_t tmpgrid_size;
@@ -8266,11 +8343,16 @@ static void mesh_filter_task_cb(void *__restrict userdata,
switch (filter_type) {
case MESH_FILTER_SMOOTH:
CLAMP(fade, -1.0f, 1.0f);
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
- neighbor_average(ss, avg, vd.index);
- }
- else if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
- bmesh_neighbor_average(avg, vd.bm_vert);
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_FACES:
+ neighbor_average(ss, avg, vd.index);
+ break;
+ case PBVH_BMESH:
+ bmesh_neighbor_average(avg, vd.bm_vert);
+ break;
+ case PBVH_GRIDS:
+ grids_neighbor_average(ss, avg, vd.index);
+ break;
}
sub_v3_v3v3(val, avg, orig_co);
madd_v3_v3v3fl(val, orig_co, val, fade);
@@ -8309,11 +8391,16 @@ static void mesh_filter_task_cb(void *__restrict userdata,
mid_v3_v3v3(disp, disp, disp2);
break;
- case MESH_FILTER_RANDOM:
+ case MESH_FILTER_RANDOM: {
normal_short_to_float_v3(normal, orig_data.no);
- mul_v3_fl(normal, BLI_hash_int_01(vd.index ^ ss->filter_cache->random_seed) - 0.5f);
+ /* Index is not unique for multires, so hash by vertex coordinates. */
+ const uint *hash_co = (const uint *)orig_co;
+ const uint hash = BLI_hash_int_2d(hash_co[0], hash_co[1]) ^
+ BLI_hash_int_2d(hash_co[2], ss->filter_cache->random_seed);
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list