Refactor: Sculpt: Simplify access to BVH nodes in undo code
Use the same method for retrieving "all nodes" that we do elsewhere. Even though this requires a temporary vector, it makes it an easier target for optimization later and makes the sculpt BVH iteration easier to refactor in the meantime.
This commit is contained in:
@@ -277,15 +277,6 @@ std::unique_ptr<Tree> build_bmesh(BMesh *bm);
|
||||
void build_pixels(const Depsgraph &depsgraph, Object &object, Image &image, ImageUser &image_user);
|
||||
void free(std::unique_ptr<Tree> &pbvh);
|
||||
|
||||
/* Hierarchical Search in the BVH, two methods:
|
||||
* - For each hit calling a callback.
|
||||
* - Gather nodes in an array (easy to multi-thread) see search_gather.
|
||||
*/
|
||||
|
||||
void search_callback(Tree &pbvh,
|
||||
FunctionRef<bool(Node &)> filter_fn,
|
||||
FunctionRef<void(Node &)> hit_fn);
|
||||
|
||||
/* Ray-cast
|
||||
* the hit callback is called for all leaf nodes intersecting the ray;
|
||||
* it's up to the callback to find the primitive within the leaves that is
|
||||
|
||||
@@ -796,25 +796,6 @@ float BKE_pbvh_node_get_tmin(const blender::bke::pbvh::Node *node)
|
||||
|
||||
namespace blender::bke::pbvh {
|
||||
|
||||
void search_callback(Tree &pbvh,
|
||||
FunctionRef<bool(Node &)> filter_fn,
|
||||
FunctionRef<void(Node &)> hit_fn)
|
||||
{
|
||||
if (pbvh.nodes_.is_empty()) {
|
||||
return;
|
||||
}
|
||||
PBVHIter iter;
|
||||
Node *node;
|
||||
|
||||
pbvh_iter_begin(&iter, pbvh, filter_fn);
|
||||
|
||||
while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) {
|
||||
if (node->flag_ & PBVH_Leaf) {
|
||||
hit_fn(*node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void search_callback_occluded(Tree &pbvh,
|
||||
const FunctionRef<bool(Node &)> scb,
|
||||
const FunctionRef<void(Node &node, float *tmin)> hit_fn)
|
||||
|
||||
@@ -856,6 +856,8 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
||||
break;
|
||||
}
|
||||
case Type::Position: {
|
||||
const Span<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
|
||||
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, &object, false);
|
||||
if (!topology_matches(step_data, object)) {
|
||||
return;
|
||||
@@ -870,12 +872,12 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
||||
for (std::unique_ptr<Node> &unode : step_data.nodes) {
|
||||
restore_position_grids(grids, key, *unode, modified_grids);
|
||||
}
|
||||
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
|
||||
const Span<int> grids = bke::pbvh::node_grid_indices(node);
|
||||
for (bke::pbvh::Node *node : nodes) {
|
||||
const Span<int> grids = bke::pbvh::node_grid_indices(*node);
|
||||
if (indices_contain_true(modified_grids, grids)) {
|
||||
BKE_pbvh_node_mark_positions_update(&node);
|
||||
BKE_pbvh_node_mark_positions_update(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
multires_mark_as_modified(depsgraph, &object, MULTIRES_COORDS_MODIFIED);
|
||||
}
|
||||
else {
|
||||
@@ -884,11 +886,11 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
||||
}
|
||||
Array<bool> modified_verts(ss.totvert, false);
|
||||
restore_position_mesh(object, step_data.nodes, modified_verts);
|
||||
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
|
||||
if (indices_contain_true(modified_verts, bke::pbvh::node_verts(node))) {
|
||||
BKE_pbvh_node_mark_positions_update(&node);
|
||||
for (bke::pbvh::Node *node : nodes) {
|
||||
if (indices_contain_true(modified_verts, bke::pbvh::node_verts(*node))) {
|
||||
BKE_pbvh_node_mark_positions_update(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (tag_update) {
|
||||
@@ -901,6 +903,8 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
||||
break;
|
||||
}
|
||||
case Type::HideVert: {
|
||||
const Span<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
|
||||
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, &object, false);
|
||||
if (!topology_matches(step_data, object)) {
|
||||
return;
|
||||
@@ -912,22 +916,22 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
||||
for (std::unique_ptr<Node> &unode : step_data.nodes) {
|
||||
restore_vert_visibility_grids(subdiv_ccg, *unode, modified_grids);
|
||||
}
|
||||
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
|
||||
if (indices_contain_true(modified_grids, bke::pbvh::node_grid_indices(node))) {
|
||||
BKE_pbvh_node_mark_update_visibility(&node);
|
||||
for (bke::pbvh::Node *node : nodes) {
|
||||
if (indices_contain_true(modified_grids, bke::pbvh::node_grid_indices(*node))) {
|
||||
BKE_pbvh_node_mark_update_visibility(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
Array<bool> modified_verts(ss.totvert, false);
|
||||
for (std::unique_ptr<Node> &unode : step_data.nodes) {
|
||||
restore_vert_visibility_mesh(object, *unode, modified_verts);
|
||||
}
|
||||
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
|
||||
if (indices_contain_true(modified_verts, bke::pbvh::node_verts(node))) {
|
||||
BKE_pbvh_node_mark_update_visibility(&node);
|
||||
for (bke::pbvh::Node *node : nodes) {
|
||||
if (indices_contain_true(modified_verts, bke::pbvh::node_verts(*node))) {
|
||||
BKE_pbvh_node_mark_update_visibility(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
BKE_pbvh_sync_visibility_from_verts(object);
|
||||
@@ -938,6 +942,8 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
||||
break;
|
||||
}
|
||||
case Type::HideFace: {
|
||||
const Span<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
|
||||
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, &object, false);
|
||||
if (!topology_matches(step_data, object)) {
|
||||
return;
|
||||
@@ -950,26 +956,26 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
||||
|
||||
if (use_multires_undo(step_data, ss)) {
|
||||
Vector<int> faces_vector;
|
||||
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
|
||||
for (bke::pbvh::Node *node : nodes) {
|
||||
faces_vector.clear();
|
||||
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
|
||||
*ss.pbvh, node, faces_vector);
|
||||
*ss.pbvh, *node, faces_vector);
|
||||
if (indices_contain_true(modified_faces, faces)) {
|
||||
BKE_pbvh_node_mark_update_visibility(&node);
|
||||
BKE_pbvh_node_mark_update_visibility(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
const Span<int> tri_faces = mesh.corner_tri_faces();
|
||||
Vector<int> faces_vector;
|
||||
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
|
||||
for (bke::pbvh::Node *node : nodes) {
|
||||
faces_vector.clear();
|
||||
const Span<int> faces = bke::pbvh::node_face_indices_calc_mesh(
|
||||
tri_faces, node, faces_vector);
|
||||
tri_faces, *node, faces_vector);
|
||||
if (indices_contain_true(modified_faces, faces)) {
|
||||
BKE_pbvh_node_mark_update_visibility(&node);
|
||||
BKE_pbvh_node_mark_update_visibility(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
hide::sync_all_from_faces(object);
|
||||
@@ -977,6 +983,8 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
||||
break;
|
||||
}
|
||||
case Type::Mask: {
|
||||
const Span<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
|
||||
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, &object, false);
|
||||
if (!topology_matches(step_data, object)) {
|
||||
return;
|
||||
@@ -987,28 +995,30 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
||||
for (std::unique_ptr<Node> &unode : step_data.nodes) {
|
||||
restore_mask_grids(object, *unode, modified_grids);
|
||||
}
|
||||
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
|
||||
if (indices_contain_true(modified_grids, bke::pbvh::node_grid_indices(node))) {
|
||||
BKE_pbvh_node_mark_update_mask(&node);
|
||||
for (bke::pbvh::Node *node : nodes) {
|
||||
if (indices_contain_true(modified_grids, bke::pbvh::node_grid_indices(*node))) {
|
||||
BKE_pbvh_node_mark_update_mask(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
Array<bool> modified_verts(ss.totvert, false);
|
||||
for (std::unique_ptr<Node> &unode : step_data.nodes) {
|
||||
restore_mask_mesh(object, *unode, modified_verts);
|
||||
}
|
||||
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
|
||||
if (indices_contain_true(modified_verts, bke::pbvh::node_verts(node))) {
|
||||
BKE_pbvh_node_mark_update_mask(&node);
|
||||
for (bke::pbvh::Node *node : nodes) {
|
||||
if (indices_contain_true(modified_verts, bke::pbvh::node_verts(*node))) {
|
||||
BKE_pbvh_node_mark_update_mask(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bke::pbvh::update_mask(object, *ss.pbvh);
|
||||
break;
|
||||
}
|
||||
case Type::FaceSet: {
|
||||
const Span<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
|
||||
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, &object, false);
|
||||
if (!topology_matches(step_data, object)) {
|
||||
return;
|
||||
@@ -1020,30 +1030,32 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
||||
}
|
||||
if (use_multires_undo(step_data, ss)) {
|
||||
Vector<int> faces_vector;
|
||||
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
|
||||
for (bke::pbvh::Node *node : nodes) {
|
||||
faces_vector.clear();
|
||||
const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
|
||||
*ss.pbvh, node, faces_vector);
|
||||
*ss.pbvh, *node, faces_vector);
|
||||
if (indices_contain_true(modified_faces, faces)) {
|
||||
BKE_pbvh_node_mark_update_face_sets(&node);
|
||||
BKE_pbvh_node_mark_update_face_sets(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
const Span<int> tri_faces = mesh.corner_tri_faces();
|
||||
Vector<int> faces_vector;
|
||||
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
|
||||
for (bke::pbvh::Node *node : nodes) {
|
||||
faces_vector.clear();
|
||||
const Span<int> faces = bke::pbvh::node_face_indices_calc_mesh(
|
||||
tri_faces, node, faces_vector);
|
||||
tri_faces, *node, faces_vector);
|
||||
if (indices_contain_true(modified_faces, faces)) {
|
||||
BKE_pbvh_node_mark_update_face_sets(&node);
|
||||
BKE_pbvh_node_mark_update_face_sets(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Type::Color: {
|
||||
const Span<bke::pbvh::Node *> nodes = bke::pbvh::search_gather(*ss.pbvh, {});
|
||||
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, &object, false);
|
||||
if (!topology_matches(step_data, object)) {
|
||||
return;
|
||||
@@ -1051,11 +1063,11 @@ static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
|
||||
|
||||
Array<bool> modified_verts(ss.totvert, false);
|
||||
restore_color(object, step_data, modified_verts);
|
||||
bke::pbvh::search_callback(*ss.pbvh, {}, [&](bke::pbvh::Node &node) {
|
||||
if (indices_contain_true(modified_verts, bke::pbvh::node_verts(node))) {
|
||||
BKE_pbvh_node_mark_update_color(&node);
|
||||
for (bke::pbvh::Node *node : nodes) {
|
||||
if (indices_contain_true(modified_verts, bke::pbvh::node_verts(*node))) {
|
||||
BKE_pbvh_node_mark_update_color(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Type::Geometry: {
|
||||
|
||||
Reference in New Issue
Block a user