From 59442dda915f6fdfd75b3be059c5342ef846bdfe Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 10 Jul 2024 11:37:06 -0400 Subject: [PATCH] Refactor: Sculpt: Tweak restore from undo step functions, expose publicly - Put them in the undo namespace, since they're quite tied to the undo system. - Retrieve the nodes inside the functions, since they always need to act on all leaf nodes conceptually anyway. - Expose the position restore function publicly for use in the transform tool. --- source/blender/editors/sculpt_paint/sculpt.cc | 52 +++++++++++-------- .../editors/sculpt_paint/sculpt_intern.hh | 2 + 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 44df93e2b88..aabd9ec9070 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -1305,9 +1305,13 @@ bool stroke_is_dyntopo(const SculptSession &ss, const Brush &brush) /** \name Sculpt Paint Mesh * \{ */ -static void restore_mask(Object &object, const Span nodes) +namespace undo { + +static void restore_mask_from_undo_step(Object &object) { SculptSession &ss = *object.sculpt; + Vector nodes = bke::pbvh::search_gather(*ss.pbvh, {}); + switch (BKE_pbvh_type(*ss.pbvh)) { case PBVH_FACES: { Mesh &mesh = *static_cast(object.data); @@ -1315,7 +1319,7 @@ static void restore_mask(Object &object, const Span nodes) bke::SpanAttributeWriter mask = attributes.lookup_or_add_for_write_span( ".sculpt_mask", bke::AttrDomain::Point); threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) { - for (PBVHNode *node : nodes.slice(range)) { + for (PBVHNode *node : nodes.as_span().slice(range)) { if (const undo::Node *unode = undo::get_node(node, undo::Type::Mask)) { const Span verts = bke::pbvh::node_unique_verts(*node); array_utils::scatter(unode->mask.as_span(), verts, mask.span); @@ -1347,7 +1351,7 @@ static void restore_mask(Object &object, const Span nodes) const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg); const Span grids = subdiv_ccg.grids; threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) { - for (PBVHNode *node : nodes.slice(range)) { + for (PBVHNode *node : nodes.as_span().slice(range)) { if (const undo::Node *unode = undo::get_node(node, undo::Type::Mask)) { int index = 0; for (const int grid : unode->grids) { @@ -1368,9 +1372,11 @@ static void restore_mask(Object &object, const Span nodes) } } -static void restore_color(Object &object, const Span nodes) +static void restore_color_from_undo_step(Object &object) { SculptSession &ss = *object.sculpt; + Vector nodes = bke::pbvh::search_gather(*ss.pbvh, {}); + BLI_assert(BKE_pbvh_type(*ss.pbvh) == PBVH_FACES); Mesh &mesh = *static_cast(object.data); const OffsetIndices faces = mesh.faces(); @@ -1378,7 +1384,7 @@ static void restore_color(Object &object, const Span nodes) const GroupedSpan vert_to_face_map = ss.vert_to_face_map; bke::GSpanAttributeWriter color_attribute = color::active_color_attribute_for_write(mesh); threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) { - for (PBVHNode *node : nodes.slice(range)) { + for (PBVHNode *node : nodes.as_span().slice(range)) { if (const undo::Node *unode = undo::get_node(node, undo::Type::Color)) { const Span verts = bke::pbvh::node_unique_verts(*node); for (const int i : verts.index_range()) { @@ -1396,15 +1402,17 @@ static void restore_color(Object &object, const Span nodes) color_attribute.finish(); } -static void restore_face_set(Object &object, const Span nodes) +static void restore_face_set_from_undo_step(Object &object) { SculptSession &ss = *object.sculpt; + Vector nodes = bke::pbvh::search_gather(*ss.pbvh, {}); + switch (BKE_pbvh_type(*ss.pbvh)) { case PBVH_FACES: case PBVH_GRIDS: { bke::SpanAttributeWriter attribute = face_set::ensure_face_sets_mesh(object); threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) { - for (PBVHNode *node : nodes.slice(range)) { + for (PBVHNode *node : nodes.as_span().slice(range)) { if (const undo::Node *unode = undo::get_node(node, undo::Type::FaceSet)) { const Span faces = unode->face_indices; const Span face_sets = unode->face_sets; @@ -1431,9 +1439,11 @@ static BLI_NOINLINE void translations_to_positions(const Span new_positi } } -static void restore_position(Object &object, const Span nodes) +void restore_position_from_undo_step(Object &object) { SculptSession &ss = *object.sculpt; + Vector nodes = bke::pbvh::search_gather(*ss.pbvh, {}); + switch (BKE_pbvh_type(*ss.pbvh)) { case PBVH_FACES: { Mesh &mesh = *static_cast(object.data); @@ -1450,7 +1460,7 @@ static void restore_position(Object &object, const Span nodes) threading::EnumerableThreadSpecific all_tls; threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); - for (PBVHNode *node : nodes.slice(range)) { + for (PBVHNode *node : nodes.as_span().slice(range)) { if (const undo::Node *unode = undo::get_node(node, undo::Type::Position)) { const Span verts = bke::pbvh::node_unique_verts(*node); const Span undo_positions = unode->position.as_span().take_front(verts.size()); @@ -1491,7 +1501,7 @@ static void restore_position(Object &object, const Span nodes) return; } threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) { - for (PBVHNode *node : nodes.slice(range)) { + for (PBVHNode *node : nodes.as_span().slice(range)) { for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(node)) { if (const float *orig_co = BM_log_find_original_vert_co(ss.bm_log, vert)) { copy_v3_v3(vert->co, orig_co); @@ -1508,7 +1518,7 @@ static void restore_position(Object &object, const Span nodes) const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg); const Span grids = subdiv_ccg.grids; threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) { - for (PBVHNode *node : nodes.slice(range)) { + for (PBVHNode *node : nodes.as_span().slice(range)) { if (const undo::Node *unode = undo::get_node(node, undo::Type::Position)) { int index = 0; for (const int grid : unode->grids) { @@ -1539,26 +1549,24 @@ static void restore_from_undo_step(const Sculpt &sd, Object &object) SculptSession &ss = *object.sculpt; const Brush *brush = BKE_paint_brush_for_read(&sd.paint); - Vector nodes = bke::pbvh::search_gather(*ss.pbvh, {}); - switch (brush->sculpt_tool) { case SCULPT_TOOL_MASK: - restore_mask(object, nodes); + restore_mask_from_undo_step(object); break; case SCULPT_TOOL_PAINT: case SCULPT_TOOL_SMEAR: - restore_color(object, nodes); + restore_color_from_undo_step(object); break; case SCULPT_TOOL_DRAW_FACE_SETS: if (ss.cache->alt_smooth) { - restore_position(object, nodes); + restore_position_from_undo_step(object); } else { - restore_face_set(object, nodes); + restore_face_set_from_undo_step(object); } break; default: - restore_position(object, nodes); + restore_position_from_undo_step(object); break; } /* Disable multi-threading when dynamic-topology is enabled. Otherwise, @@ -1568,6 +1576,8 @@ static void restore_from_undo_step(const Sculpt &sd, Object &object) BKE_pbvh_node_color_buffer_free(*ss.pbvh); } +} // namespace undo + } // namespace blender::ed::sculpt_paint /*** BVH Tree ***/ @@ -5508,7 +5518,7 @@ static void sculpt_restore_mesh(const Sculpt &sd, Object &ob) SCULPT_TOOL_ROTATE, SCULPT_TOOL_ELASTIC_DEFORM)) { - restore_from_undo_step(sd, ob); + undo::restore_from_undo_step(sd, ob); return; } @@ -5525,7 +5535,7 @@ static void sculpt_restore_mesh(const Sculpt &sd, Object &ob) (brush->flag & BRUSH_DRAG_DOT)) { - restore_from_undo_step(sd, ob); + undo::restore_from_undo_step(sd, ob); if (ss.cache) { MEM_SAFE_FREE(ss.cache->layer_displacement_factor); @@ -6089,7 +6099,7 @@ static void sculpt_brush_stroke_cancel(bContext *C, wmOperator *op) /* XXX Canceling strokes that way does not work with dynamic topology, * user will have to do real undo for now. See #46456. */ if (ss.cache && !dyntopo::stroke_is_dyntopo(ss, brush)) { - restore_from_undo_step(sd, ob); + undo::restore_from_undo_step(sd, ob); } paint_stroke_cancel(C, op, static_cast(op->customdata)); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.hh b/source/blender/editors/sculpt_paint/sculpt_intern.hh index c124b76ed21..4f772e0c07e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -1651,6 +1651,8 @@ void push_end_ex(Object &ob, const bool use_nested_undo); void restore_from_bmesh_enter_geometry(const StepData &step_data, Mesh &mesh); BMLogEntry *get_bmesh_log_entry(); +void restore_position_from_undo_step(Object &object); + } namespace blender::ed::sculpt_paint {