Sculpt: Specialize a few vertex neighbor iteration cases for BMesh
The start of a transition to remove this API more generally.
This commit is contained in:
@@ -365,7 +365,7 @@ static void grid_hide_update(Depsgraph &depsgraph,
|
||||
|
||||
static void partialvis_update_bmesh_verts(const Set<BMVert *, 0> &verts,
|
||||
const VisAction action,
|
||||
const FunctionRef<bool(const BMVert *v)> should_update,
|
||||
const FunctionRef<bool(BMVert *v)> should_update,
|
||||
bool *any_changed,
|
||||
bool *any_visible)
|
||||
{
|
||||
@@ -401,7 +401,7 @@ static void partialvis_update_bmesh_faces(const Set<BMFace *, 0> &faces)
|
||||
static void partialvis_update_bmesh_nodes(Object &ob,
|
||||
const Span<PBVHNode *> nodes,
|
||||
const VisAction action,
|
||||
const FunctionRef<bool(const BMVert *v)> vert_test_fn)
|
||||
const FunctionRef<bool(BMVert *v)> vert_test_fn)
|
||||
{
|
||||
for (PBVHNode *node : nodes) {
|
||||
bool any_changed = false;
|
||||
@@ -1024,8 +1024,7 @@ static void grow_shrink_visibility_grid(Depsgraph &depsgraph,
|
||||
SubdivCCGNeighbors neighbors;
|
||||
BKE_subdiv_ccg_neighbor_coords_get(subdiv_ccg, coord, true, neighbors);
|
||||
|
||||
for (const int j : neighbors.coords.index_range()) {
|
||||
const SubdivCCGCoord neighbor = neighbors.coords[j];
|
||||
for (const SubdivCCGCoord neighbor : neighbors.coords) {
|
||||
const int neighbor_grid_elem_idx = elem_xy_to_index(
|
||||
neighbor.x, neighbor.y, key.grid_size);
|
||||
|
||||
@@ -1078,32 +1077,21 @@ static Array<bool> duplicate_visibility_bmesh(const Object &object)
|
||||
}
|
||||
|
||||
static void grow_shrink_visibility_bmesh(Object &object,
|
||||
PBVH &pbvh,
|
||||
const Span<PBVHNode *> nodes,
|
||||
const VisAction action,
|
||||
const int iterations)
|
||||
{
|
||||
|
||||
SculptSession &ss = *object.sculpt;
|
||||
|
||||
for (const int i : IndexRange(iterations)) {
|
||||
UNUSED_VARS(i);
|
||||
const Array<bool> prev_visibility = duplicate_visibility_bmesh(object);
|
||||
partialvis_update_bmesh_nodes(object, nodes, action, [&](const BMVert *vert) {
|
||||
int vi = BM_elem_index_get(vert);
|
||||
PBVHVertRef vref = BKE_pbvh_index_to_vertex(pbvh, vi);
|
||||
SculptVertexNeighborIter ni;
|
||||
|
||||
bool should_change = false;
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vref, ni) {
|
||||
if (prev_visibility[ni.index] == action_to_hide(action)) {
|
||||
/* Not returning instantly to avoid leaking memory. */
|
||||
should_change = true;
|
||||
break;
|
||||
partialvis_update_bmesh_nodes(object, nodes, action, [&](BMVert *vert) {
|
||||
Vector<BMVert *, 64> neighbors;
|
||||
for (BMVert *neighbor : vert_neighbors_get_bmesh(*vert, neighbors)) {
|
||||
if (prev_visibility[BM_elem_index_get(neighbor)] == action_to_hide(action)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
||||
return should_change;
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1140,7 +1128,7 @@ static int visibility_filter_exec(bContext *C, wmOperator *op)
|
||||
grow_shrink_visibility_grid(depsgraph, object, pbvh, nodes, mode, iterations);
|
||||
break;
|
||||
case PBVH_BMESH:
|
||||
grow_shrink_visibility_bmesh(object, pbvh, nodes, mode, iterations);
|
||||
grow_shrink_visibility_bmesh(object, nodes, mode, iterations);
|
||||
break;
|
||||
}
|
||||
undo::push_end(object);
|
||||
|
||||
@@ -690,6 +690,20 @@ static void sculpt_vertex_neighbors_get_bmesh(PBVHVertRef vertex, SculptVertexNe
|
||||
}
|
||||
}
|
||||
|
||||
Span<BMVert *> vert_neighbors_get_bmesh(BMVert &vert, Vector<BMVert *, 64> &neighbors)
|
||||
{
|
||||
BMIter liter;
|
||||
BMLoop *l;
|
||||
BM_ITER_ELEM (l, &liter, &vert, BM_LOOPS_OF_VERT) {
|
||||
for (BMVert *other_vert : {l->prev->v, l->next->v}) {
|
||||
if (other_vert != &vert) {
|
||||
neighbors.append(other_vert);
|
||||
}
|
||||
}
|
||||
}
|
||||
return neighbors;
|
||||
}
|
||||
|
||||
static void sculpt_vertex_neighbors_get_faces(const SculptSession &ss,
|
||||
PBVHVertRef vertex,
|
||||
SculptVertexNeighborIter *iter)
|
||||
|
||||
@@ -586,17 +586,14 @@ static void dyntopo_detail_size_sample_from_surface(Object &ob,
|
||||
DyntopoDetailSizeEditCustomData *cd)
|
||||
{
|
||||
SculptSession &ss = *ob.sculpt;
|
||||
const PBVHVertRef active_vertex = SCULPT_active_vertex_get(ss);
|
||||
BMVert *active_vertex = reinterpret_cast<BMVert *>(SCULPT_active_vertex_get(ss).i);
|
||||
|
||||
float len_accum = 0;
|
||||
int num_neighbors = 0;
|
||||
SculptVertexNeighborIter ni;
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, active_vertex, ni) {
|
||||
len_accum += len_v3v3(SCULPT_vertex_co_get(ss, active_vertex),
|
||||
SCULPT_vertex_co_get(ss, ni.vertex));
|
||||
num_neighbors++;
|
||||
Vector<BMVert *, 64> neighbors;
|
||||
for (BMVert *neighbor : vert_neighbors_get_bmesh(*active_vertex, neighbors)) {
|
||||
len_accum += len_v3v3(active_vertex->co, neighbor->co);
|
||||
}
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
||||
const int num_neighbors = neighbors.size();
|
||||
|
||||
if (num_neighbors > 0) {
|
||||
const float avg_edge_len = len_accum / num_neighbors;
|
||||
|
||||
@@ -913,6 +913,12 @@ void SCULPT_vertex_neighbors_get(const SculptSession &ss,
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
namespace blender::ed::sculpt_paint {
|
||||
|
||||
Span<BMVert *> vert_neighbors_get_bmesh(BMVert &vert, Vector<BMVert *, 64> &neighbors);
|
||||
|
||||
}
|
||||
|
||||
PBVHVertRef SCULPT_active_vertex_get(const SculptSession &ss);
|
||||
const float *SCULPT_active_vertex_co_get(const SculptSession &ss);
|
||||
|
||||
|
||||
@@ -136,32 +136,35 @@ float neighbor_mask_average(SculptSession &ss,
|
||||
int total = 0;
|
||||
SculptVertexNeighborIter ni;
|
||||
switch (BKE_pbvh_type(*ss.pbvh)) {
|
||||
case PBVH_FACES:
|
||||
case PBVH_FACES: {
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) {
|
||||
avg += write_info.layer[ni.vertex.i];
|
||||
total++;
|
||||
}
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
||||
break;
|
||||
case PBVH_GRIDS:
|
||||
return avg / total;
|
||||
}
|
||||
case PBVH_GRIDS: {
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) {
|
||||
avg += SCULPT_mask_get_at_grids_vert_index(
|
||||
*ss.subdiv_ccg, *BKE_pbvh_get_grid_key(*ss.pbvh), ni.vertex.i);
|
||||
total++;
|
||||
}
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
||||
break;
|
||||
case PBVH_BMESH:
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) {
|
||||
BMVert *vert = reinterpret_cast<BMVert *>(ni.vertex.i);
|
||||
avg += BM_ELEM_CD_GET_FLOAT(vert, write_info.bm_offset);
|
||||
total++;
|
||||
return avg / total;
|
||||
}
|
||||
case PBVH_BMESH: {
|
||||
Vector<BMVert *, 64> neighbors;
|
||||
for (BMVert *neighbor :
|
||||
vert_neighbors_get_bmesh(*reinterpret_cast<BMVert *>(vertex.i), neighbors))
|
||||
{
|
||||
avg += BM_ELEM_CD_GET_FLOAT(neighbor, write_info.bm_offset);
|
||||
}
|
||||
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
|
||||
break;
|
||||
return avg / neighbors.size();
|
||||
}
|
||||
}
|
||||
BLI_assert(total > 0);
|
||||
return avg / total;
|
||||
BLI_assert_unreachable();
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float4 neighbor_color_average(SculptSession &ss, PBVHVertRef vertex)
|
||||
|
||||
Reference in New Issue
Block a user