diff --git a/source/blender/bmesh/intern/bmesh_log.cc b/source/blender/bmesh/intern/bmesh_log.cc index 855aa160cc6..c2e779ff1c5 100644 --- a/source/blender/bmesh/intern/bmesh_log.cc +++ b/source/blender/bmesh/intern/bmesh_log.cc @@ -929,6 +929,17 @@ const float *BM_log_find_original_vert_co(BMLog *log, BMVert *v) return lv == nullptr ? nullptr : lv->co; } +const float *BM_log_find_original_vert_mask(BMLog *log, BMVert *v) +{ + BMLogEntry *entry = log->current_entry; + const BMLogVert *lv; + uint v_id = bm_log_vert_id_get(log, v); + void *key = POINTER_FROM_UINT(v_id); + + lv = static_cast(BLI_ghash_lookup(entry->modified_verts, key)); + return lv == nullptr ? nullptr : &lv->mask; +} + const float *BM_log_original_vert_co(BMLog *log, BMVert *v) { BMLogEntry *entry = log->current_entry; diff --git a/source/blender/bmesh/intern/bmesh_log.hh b/source/blender/bmesh/intern/bmesh_log.hh index 302bd8f784e..a27174d06a5 100644 --- a/source/blender/bmesh/intern/bmesh_log.hh +++ b/source/blender/bmesh/intern/bmesh_log.hh @@ -189,6 +189,15 @@ void BM_log_before_all_removed(BMesh *bm, BMLog *log); */ const float *BM_log_find_original_vert_co(BMLog *log, BMVert *v); +/** + * Search the log for the original vertex mask. + * + * Does not modify the log or the vertex. + * + * \return the pointer or nullptr if the vertex isn't found. + */ +const float *BM_log_find_original_vert_mask(BMLog *log, BMVert *v); + /** * Get the logged coordinates of a vertex. * diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index decb7f1f57b..20164647777 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -1180,9 +1180,11 @@ static void restore_mask_from_undo_step(Object &object) bke::SpanAttributeWriter mask = attributes.lookup_or_add_for_write_span( ".sculpt_mask", bke::AttrDomain::Point); node_mask.foreach_index(GrainSize(1), [&](const int i) { - if (const undo::Node *unode = undo::get_node(&nodes[i], undo::Type::Mask)) { + if (const std::optional> orig_data = orig_mask_data_lookup_mesh(object, + nodes[i])) + { const Span verts = bke::pbvh::node_unique_verts(nodes[i]); - array_utils::scatter(unode->mask.as_span(), verts, mask.span); + array_utils::scatter(*orig_data, verts, mask.span); BKE_pbvh_node_mark_update_mask(nodes[i]); } }); @@ -1193,13 +1195,12 @@ static void restore_mask_from_undo_step(Object &object) MutableSpan nodes = ss.pbvh->nodes(); const int offset = CustomData_get_offset_named(&ss.bm->vdata, CD_PROP_FLOAT, ".sculpt_mask"); if (offset != -1) { - node_mask.foreach_index([&](const int i) { - if (undo::get_node(&nodes[i], undo::Type::Mask)) { - for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(&nodes[i])) { - const float orig_mask = BM_log_original_mask(ss.bm_log, vert); - BM_ELEM_CD_SET_FLOAT(vert, offset, orig_mask); + node_mask.foreach_index(GrainSize(1), [&](const int i) { + for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(&nodes[i])) { + if (const float *orig_mask = BM_log_find_original_vert_mask(ss.bm_log, vert)) { + BM_ELEM_CD_SET_FLOAT(vert, offset, *orig_mask); + BKE_pbvh_node_mark_update_mask(nodes[i]); } - BKE_pbvh_node_mark_update_mask(nodes[i]); } }); } @@ -1212,13 +1213,15 @@ static void restore_mask_from_undo_step(Object &object) const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg); const Span grids = subdiv_ccg.grids; node_mask.foreach_index(GrainSize(1), [&](const int i) { - if (const undo::Node *unode = undo::get_node(&nodes[i], undo::Type::Mask)) { + if (const std::optional> orig_data = orig_mask_data_lookup_grids(object, + nodes[i])) + { int index = 0; - for (const int grid : unode->grids) { + for (const int grid : bke::pbvh::node_grid_indices(nodes[i])) { CCGElem *elem = grids[grid]; for (const int i : IndexRange(key.grid_area)) { if (grid_hidden.is_empty() || !grid_hidden[grid][i]) { - CCG_elem_offset_mask(key, elem, i) = unode->mask[index]; + CCG_elem_offset_mask(key, elem, i) = (*orig_data)[index]; } index++; } @@ -1245,7 +1248,9 @@ static void restore_color_from_undo_step(Object &object) const GroupedSpan vert_to_face_map = ss.vert_to_face_map; bke::GSpanAttributeWriter color_attribute = color::active_color_attribute_for_write(mesh); node_mask.foreach_index(GrainSize(1), [&](const int i) { - if (const undo::Node *unode = undo::get_node(&nodes[i], undo::Type::Color)) { + if (const std::optional> orig_data = orig_color_data_lookup_mesh(object, + nodes[i])) + { const Span verts = bke::pbvh::node_unique_verts(nodes[i]); for (const int i : verts.index_range()) { color::color_vert_set(faces, @@ -1253,7 +1258,7 @@ static void restore_color_from_undo_step(Object &object) vert_to_face_map, color_attribute.domain, verts[i], - unode->col[i], + (*orig_data)[i], color_attribute.span); } } @@ -1269,13 +1274,18 @@ static void restore_face_set_from_undo_step(Object &object) switch (ss.pbvh->type()) { case bke::pbvh::Type::Mesh: { + const Mesh &mesh = *static_cast(object.data); + const Span tri_faces = mesh.corner_tri_faces(); MutableSpan nodes = ss.pbvh->nodes(); bke::SpanAttributeWriter attribute = face_set::ensure_face_sets_mesh(object); + threading::EnumerableThreadSpecific> all_tls; node_mask.foreach_index(GrainSize(1), [&](const int i) { - if (const undo::Node *unode = undo::get_node(&nodes[i], undo::Type::FaceSet)) { - const Span faces = unode->face_indices; - const Span face_sets = unode->face_sets; - blender::array_utils::scatter(face_sets, faces, attribute.span); + Vector &tls = all_tls.local(); + if (const std::optional> orig_data = orig_face_set_data_lookup_mesh(object, + nodes[i])) + { + const Span faces = bke::pbvh::node_face_indices_calc_mesh(tri_faces, nodes[i], tls); + scatter_data_mesh(*orig_data, faces, attribute.span); BKE_pbvh_node_mark_update_face_sets(nodes[i]); } }); @@ -1283,13 +1293,18 @@ static void restore_face_set_from_undo_step(Object &object) break; } case bke::pbvh::Type::Grids: { + const SubdivCCG &subdiv_ccg = *ss.subdiv_ccg; MutableSpan nodes = ss.pbvh->nodes(); bke::SpanAttributeWriter attribute = face_set::ensure_face_sets_mesh(object); + threading::EnumerableThreadSpecific> all_tls; node_mask.foreach_index(GrainSize(1), [&](const int i) { - if (const undo::Node *unode = undo::get_node(&nodes[i], undo::Type::FaceSet)) { - const Span faces = unode->face_indices; - const Span face_sets = unode->face_sets; - blender::array_utils::scatter(face_sets, faces, attribute.span); + Vector &tls = all_tls.local(); + if (const std::optional> orig_data = orig_face_set_data_lookup_grids(object, + nodes[i])) + { + const Span faces = bke::pbvh::node_face_indices_calc_grids( + subdiv_ccg, nodes[i], tls); + scatter_data_mesh(*orig_data, faces, attribute.span); BKE_pbvh_node_mark_update_face_sets(nodes[i]); } }); @@ -1325,9 +1340,11 @@ void restore_position_from_undo_step(const Depsgraph &depsgraph, Object &object) threading::parallel_for(node_mask.index_range(), 1, [&](const IndexRange range) { LocalData &tls = all_tls.local(); node_mask.slice(range).foreach_index([&](const int i) { - if (const undo::Node *unode = undo::get_node(&nodes[i], undo::Type::Position)) { + if (const std::optional orig_data = orig_position_data_lookup_mesh( + object, nodes[i])) + { const Span verts = bke::pbvh::node_unique_verts(nodes[i]); - const Span undo_positions = unode->position.as_span().take_front(verts.size()); + const Span undo_positions = orig_data->positions; if (need_translations) { tls.translations.resize(verts.size()); translations_from_new_positions( @@ -1388,13 +1405,15 @@ void restore_position_from_undo_step(const Depsgraph &depsgraph, Object &object) const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg); const Span grids = subdiv_ccg.grids; node_mask.foreach_index(GrainSize(1), [&](const int i) { - if (const undo::Node *unode = undo::get_node(&nodes[i], undo::Type::Position)) { + if (const std::optional orig_data = orig_position_data_lookup_grids( + object, nodes[i])) + { int index = 0; - for (const int grid : unode->grids) { + for (const int grid : bke::pbvh::node_grid_indices(nodes[i])) { CCGElem *elem = grids[grid]; for (const int i : IndexRange(key.grid_area)) { if (grid_hidden.is_empty() || !grid_hidden[grid][i]) { - CCG_elem_offset_co(key, elem, i) = unode->position[index]; + CCG_elem_offset_co(key, elem, i) = orig_data->positions[index]; } index++; } @@ -1693,9 +1712,11 @@ static void calc_area_normal_and_center_node_mesh(const Object &object, const Span verts = bke::pbvh::node_unique_verts(node); if (ss.cache && !ss.cache->accum) { - if (const undo::Node *unode = undo::get_node(&node, undo::Type::Position)) { - const Span orig_positions = unode->position.as_span().take_front(verts.size()); - const Span orig_normals = unode->normal.as_span().take_front(verts.size()); + if (const std::optional orig_data = orig_position_data_get_mesh(object, + node)) + { + const Span orig_positions = orig_data->positions; + const Span orig_normals = orig_data->normals; tls.distances.reinitialize(verts.size()); const MutableSpan distances_sq = tls.distances; @@ -1780,9 +1801,11 @@ static void calc_area_normal_and_center_node_grids(const Object &object, const Span grids = bke::pbvh::node_grid_indices(node); if (ss.cache && !ss.cache->accum) { - if (const undo::Node *unode = undo::get_node(&node, undo::Type::Position)) { - const Span orig_positions = unode->position.as_span(); - const Span orig_normals = unode->normal.as_span(); + if (const std::optional orig_data = orig_position_data_get_grids(object, + node)) + { + const Span orig_positions = orig_data->positions; + const Span orig_normals = orig_data->normals; tls.distances.reinitialize(orig_positions.size()); const MutableSpan distances_sq = tls.distances; @@ -1877,13 +1900,9 @@ static void calc_area_normal_and_center_node_bmesh(const Object &object, const float normal_radius_sq = normal_radius * normal_radius; const float normal_radius_inv = math::rcp(normal_radius); - const undo::Node *unode = nullptr; bool use_original = false; if (ss.cache && !ss.cache->accum) { - unode = undo::get_node(&node, undo::Type::Position); - if (unode) { - use_original = undo::get_bmesh_log_entry() != nullptr; - } + use_original = undo::get_bmesh_log_entry() != nullptr; } /* When the mesh is edited we can't rely on original coords @@ -2904,6 +2923,7 @@ static void sculpt_pbvh_update_pixels(const Depsgraph &depsgraph, * \{ */ struct SculptRaycastData { + const Object *object; SculptSession *ss; const float *ray_start; const float *ray_normal; @@ -2927,6 +2947,7 @@ struct SculptRaycastData { }; struct SculptFindNearestToRayData { + const Object *object; SculptSession *ss; const float *ray_start, *ray_normal; bool hit; @@ -4761,18 +4782,30 @@ static void sculpt_raycast_cb(blender::bke::pbvh::Node &node, SculptRaycastData if (BKE_pbvh_node_get_tmin(&node) >= *tmin) { return; } + bool use_origco = false; Span origco; if (srd.original && srd.ss->cache) { - if (srd.ss->pbvh->type() == bke::pbvh::Type::BMesh) { - use_origco = true; - } - else { - /* Intersect with coordinates from before we started stroke. */ - if (const undo::Node *unode = undo::get_node(&node, undo::Type::Position)) { + switch (srd.ss->pbvh->type()) { + case bke::pbvh::Type::Mesh: + if (const std::optional orig_data = orig_position_data_lookup_mesh( + *srd.object, static_cast(node))) + { + use_origco = true; + origco = orig_data->positions; + } + break; + case bke::pbvh::Type::Grids: + if (const std::optional orig_data = orig_position_data_lookup_grids( + *srd.object, static_cast(node))) + { + use_origco = true; + origco = orig_data->positions; + } + break; + case bke::pbvh::Type::BMesh: use_origco = true; - origco = unode->position.as_span(); - } + break; } } @@ -4808,18 +4841,31 @@ static void sculpt_find_nearest_to_ray_cb(blender::bke::pbvh::Node &node, if (BKE_pbvh_node_get_tmin(&node) >= *tmin) { return; } + bool use_origco = false; Span origco; if (srd.original && srd.ss->cache) { - if (srd.ss->pbvh->type() == bke::pbvh::Type::BMesh) { - use_origco = true; - } - else { - /* Intersect with coordinates from before we started stroke. */ - if (const undo::Node *unode = undo::get_node(&node, undo::Type::Position)) { + switch (srd.ss->pbvh->type()) { + case bke::pbvh::Type::Mesh: + if (const std::optional orig_data = orig_position_data_lookup_mesh( + *srd.object, static_cast(node))) + { + use_origco = true; + origco = orig_data->positions; + } + break; + case bke::pbvh::Type::Grids: + if (const std::optional orig_data = orig_position_data_lookup_grids( + *srd.object, static_cast(node))) + { + use_origco = true; + origco = orig_data->positions; + } + + break; + case bke::pbvh::Type::BMesh: use_origco = true; - origco = unode->position.as_span(); - } + break; } } @@ -4922,6 +4968,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, SculptRaycastData srd{}; srd.original = original; + srd.object = &ob; srd.ss = ob.sculpt; srd.hit = false; if (ss.pbvh->type() == bke::pbvh::Type::Mesh) { @@ -5097,6 +5144,7 @@ bool SCULPT_stroke_get_location_ex(bContext *C, bool hit = false; { SculptRaycastData srd; + srd.object = &ob; srd.ss = ob.sculpt; srd.ray_start = ray_start; srd.ray_normal = ray_normal; @@ -5139,6 +5187,7 @@ bool SCULPT_stroke_get_location_ex(bContext *C, SculptFindNearestToRayData srd{}; srd.original = original; + srd.object = &ob; srd.ss = ob.sculpt; srd.hit = false; if (ss.pbvh->type() == bke::pbvh::Type::Mesh) { @@ -6208,6 +6257,7 @@ bool SCULPT_vertex_is_occluded(const Object &object, const float3 &position, boo SculptRaycastData srd = {nullptr}; srd.original = original; + srd.object = &object; srd.ss = &ss; srd.hit = false; srd.ray_start = ray_start; diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.cc b/source/blender/editors/sculpt_paint/sculpt_automasking.cc index a408cc0aa1c..9e2c283ecf6 100644 --- a/source/blender/editors/sculpt_paint/sculpt_automasking.cc +++ b/source/blender/editors/sculpt_paint/sculpt_automasking.cc @@ -625,8 +625,8 @@ void calc_vert_factors(const Depsgraph &depsgraph, { Span orig_normals; if (cache.settings.flags & (BRUSH_AUTOMASKING_BRUSH_NORMAL | BRUSH_AUTOMASKING_VIEW_NORMAL)) { - if (const undo::Node *unode = undo::get_node(&node, undo::Type::Position)) { - orig_normals = unode->normal.as_span(); + if (std::optional orig_data = orig_position_data_lookup_mesh(object, node)) { + orig_normals = orig_data->normals; } } @@ -672,8 +672,9 @@ void calc_grids_factors(const Depsgraph &depsgraph, Span orig_normals; if (cache.settings.flags & (BRUSH_AUTOMASKING_BRUSH_NORMAL | BRUSH_AUTOMASKING_VIEW_NORMAL)) { - if (const undo::Node *unode = undo::get_node(&node, undo::Type::Position)) { - orig_normals = unode->normal.as_span(); + if (std::optional orig_data = orig_position_data_lookup_grids(object, node)) + { + orig_normals = orig_data->normals; } } diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.hh b/source/blender/editors/sculpt_paint/sculpt_intern.hh index c2b91f5dd38..fbbb86750d4 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -718,16 +718,45 @@ struct OrigPositionData { * Retrieve positions from the latest undo state. This is often used for modal actions that depend * on the initial state of the geometry from before the start of the action. */ -OrigPositionData orig_position_data_get_mesh(const Object &object, - const bke::pbvh::MeshNode &node); -OrigPositionData orig_position_data_get_grids(const Object &object, - const bke::pbvh::GridsNode &node); +std::optional orig_position_data_lookup_mesh(const Object &object, + const bke::pbvh::MeshNode &node); +inline OrigPositionData orig_position_data_get_mesh(const Object &object, + const bke::pbvh::MeshNode &node) +{ + return *orig_position_data_lookup_mesh(object, node); +} + +std::optional orig_position_data_lookup_grids(const Object &object, + const bke::pbvh::GridsNode &node); +inline OrigPositionData orig_position_data_get_grids(const Object &object, + const bke::pbvh::GridsNode &node) +{ + return *orig_position_data_lookup_grids(object, node); +} + void orig_position_data_gather_bmesh(const BMLog &bm_log, const Set &verts, MutableSpan positions, MutableSpan normals); -Span orig_color_data_get_mesh(const Object &object, const bke::pbvh::MeshNode &node); +std::optional> orig_color_data_lookup_mesh(const Object &object, + const bke::pbvh::MeshNode &node); +inline Span orig_color_data_get_mesh(const Object &object, const bke::pbvh::MeshNode &node) +{ + return *orig_color_data_lookup_mesh(object, node); +} + +std::optional> orig_face_set_data_lookup_mesh(const Object &object, + const bke::pbvh::MeshNode &node); + +std::optional> orig_face_set_data_lookup_grids(const Object &object, + const bke::pbvh::GridsNode &node); + +std::optional> orig_mask_data_lookup_mesh(const Object &object, + const bke::pbvh::MeshNode &node); + +std::optional> orig_mask_data_lookup_grids(const Object &object, + const bke::pbvh::GridsNode &node); } diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.cc b/source/blender/editors/sculpt_paint/sculpt_undo.cc index fbd5669f202..e2fb7ab8d37 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -129,6 +129,37 @@ namespace blender::ed::sculpt_paint::undo { #define NO_ACTIVE_LAYER bke::AttrDomain::Auto +struct Node { + Array position; + Array orig_position; + Array normal; + Array col; + Array mask; + + Array loop_col; + + /* Mesh. */ + + Array vert_indices; + int unique_verts_num; + + Array corner_indices; + + BitVector<0> vert_hidden; + BitVector<0> face_hidden; + + /* Multires. */ + + /** Indices of grids in the pbvh::Tree node. */ + Array grids; + BitGroupVector<0> grid_hidden; + + /* Sculpt Face Sets */ + Array face_sets; + + Vector face_indices; +}; + struct SculptAttrRef { bke::AttrDomain domain; eCustomDataType type; @@ -1129,7 +1160,13 @@ static void free_step_data(StepData &step_data) step_data.~StepData(); } -const Node *get_node(const bke::pbvh::Node *node, const Type type) +/** + * Retrieve the undo data of a given type for the active undo step. For example, this is used to + * access "original" data from before the current stroke. + * + * This is only possible when building an undo step, in between #push_begin and #push_end. + */ +static const Node *get_node(const bke::pbvh::Node *node, const Type type) { StepData *step_data = get_step_data(); if (!step_data) { @@ -2124,19 +2161,25 @@ void push_multires_mesh_end(bContext *C, const char *str) namespace blender::ed::sculpt_paint { -OrigPositionData orig_position_data_get_mesh(const Object & /*object*/, - const bke::pbvh::MeshNode &node) +std::optional orig_position_data_lookup_mesh(const Object & /*object*/, + const bke::pbvh::MeshNode &node) { const undo::Node *unode = undo::get_node(&node, undo::Type::Position); - return {unode->position.as_span().take_front(unode->unique_verts_num), - unode->normal.as_span().take_front(unode->unique_verts_num)}; + if (!unode) { + return std::nullopt; + } + return OrigPositionData{unode->position.as_span().take_front(unode->unique_verts_num), + unode->normal.as_span().take_front(unode->unique_verts_num)}; } -OrigPositionData orig_position_data_get_grids(const Object & /*object*/, - const bke::pbvh::GridsNode &node) +std::optional orig_position_data_lookup_grids(const Object & /*object*/, + const bke::pbvh::GridsNode &node) { const undo::Node *unode = undo::get_node(&node, undo::Type::Position); - return {unode->position.as_span(), unode->normal.as_span()}; + if (!unode) { + return std::nullopt; + } + return OrigPositionData{unode->position.as_span(), unode->normal.as_span()}; } void orig_position_data_gather_bmesh(const BMLog &bm_log, @@ -2159,10 +2202,54 @@ void orig_position_data_gather_bmesh(const BMLog &bm_log, } } -Span orig_color_data_get_mesh(const Object & /*object*/, const bke::pbvh::MeshNode &node) +std::optional> orig_color_data_lookup_mesh(const Object & /*object*/, + const bke::pbvh::MeshNode &node) { const undo::Node *unode = undo::get_node(&node, undo::Type::Color); + if (!unode) { + return std::nullopt; + } return unode->col.as_span(); } +std::optional> orig_face_set_data_lookup_mesh(const Object & /*object*/, + const bke::pbvh::MeshNode &node) +{ + const undo::Node *unode = undo::get_node(&node, undo::Type::FaceSet); + if (!unode) { + return std::nullopt; + } + return unode->face_sets.as_span(); +} + +std::optional> orig_face_set_data_lookup_grids(const Object & /*object*/, + const bke::pbvh::GridsNode &node) +{ + const undo::Node *unode = undo::get_node(&node, undo::Type::FaceSet); + if (!unode) { + return std::nullopt; + } + return unode->face_sets.as_span(); +} + +std::optional> orig_mask_data_lookup_mesh(const Object & /*object*/, + const bke::pbvh::MeshNode &node) +{ + const undo::Node *unode = undo::get_node(&node, undo::Type::Mask); + if (!unode) { + return std::nullopt; + } + return unode->mask.as_span(); +} + +std::optional> orig_mask_data_lookup_grids(const Object & /*object*/, + const bke::pbvh::GridsNode &node) +{ + const undo::Node *unode = undo::get_node(&node, undo::Type::Mask); + if (!unode) { + return std::nullopt; + } + return unode->mask.as_span(); +} + } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.hh b/source/blender/editors/sculpt_paint/sculpt_undo.hh index d13643ab023..1b429faeed3 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.hh +++ b/source/blender/editors/sculpt_paint/sculpt_undo.hh @@ -45,37 +45,6 @@ enum class Type : int8_t { Color, }; -struct Node { - Array position; - Array orig_position; - Array normal; - Array col; - Array mask; - - Array loop_col; - - /* Mesh. */ - - Array vert_indices; - int unique_verts_num; - - Array corner_indices; - - BitVector<0> vert_hidden; - BitVector<0> face_hidden; - - /* Multires. */ - - /** Indices of grids in the pbvh::Tree node. */ - Array grids; - BitGroupVector<0> grid_hidden; - - /* Sculpt Face Sets */ - Array face_sets; - - Vector face_indices; -}; - /* Storage of geometry for the undo node. * Is used as a storage for either original or modified geometry. */ struct NodeGeometry { @@ -95,6 +64,8 @@ struct NodeGeometry { int faces_num; }; +struct Node; + struct StepData { /** * The type of data stored in this undo step. For historical reasons this is often set when the @@ -177,14 +148,6 @@ void push_nodes(const Depsgraph &depsgraph, const IndexMask &node_mask, undo::Type type); -/** - * Retrieve the undo data of a given type for the active undo step. For example, this is used to - * access "original" data from before the current stroke. - * - * This is only possible when building an undo step, in between #push_begin and #push_end. - */ -const undo::Node *get_node(const bke::pbvh::Node *node, undo::Type type); - /** * Pushes an undo step using the operator name. This is necessary for * redo panels to work; operators that do not support that may use