Refactor: Sculpt: Avoid storing extra undo data on geometry_push
Currently, Sculpt Mode's UndoStep stores two main categories of data, the first category is valid for undo pushes where individual nodes of a mesh are modified, the second category is when the entire mesh is changed. To avoid extra processing of data and move towards reducing and simplifying the amount of data each of these types of undo operations need, this commit strips down the data stored when a geometry_push step is called. Additionally, there are some areas in the code which called `BKE_sculpt_update_object_for_edit` as a requirement for the undo step data, these calls have been removed. --- Testing: * Undo / Redo on mesh with color attributes and performing remesh operations * Undo / Redo with shape key data * Undo / Redo with trim tools * Base Mesh * Deform Modifier Pull Request: https://projects.blender.org/blender/blender/pulls/129828
This commit is contained in:
@@ -133,8 +133,6 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
if (ob->mode == OB_MODE_SCULPT) {
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, false);
|
||||
sculpt_paint::undo::geometry_begin(scene, *ob, op);
|
||||
}
|
||||
|
||||
|
||||
@@ -521,10 +521,8 @@ static void gesture_begin(bContext &C, wmOperator &op, gesture::GestureData &ges
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
|
||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(&C);
|
||||
generate_geometry(gesture_data);
|
||||
islands::invalidate(ss);
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, gesture_data.vc.obact, false);
|
||||
undo::geometry_begin(scene, *gesture_data.vc.obact, &op);
|
||||
}
|
||||
|
||||
|
||||
@@ -1649,20 +1649,11 @@ static void save_active_attribute(Object &object, SculptAttrRef *attr)
|
||||
attr->type = meta_data->data_type;
|
||||
}
|
||||
|
||||
void push_begin_ex(const Scene & /*scene*/, Object &ob, const char *name)
|
||||
/**
|
||||
* Does not save topology counts, as that data is unneded for full geometry pushes and
|
||||
* requires the PBVH to exist. */
|
||||
static void save_common_data(Object &ob, SculptUndoStep *us)
|
||||
{
|
||||
UndoStack *ustack = ED_undo_stack_get();
|
||||
|
||||
/* If possible, we need to tag the object and its geometry data as 'changed in the future' in
|
||||
* the previous undo step if it's a memfile one. */
|
||||
ED_undosys_stack_memfile_id_changed_tag(ustack, &ob.id);
|
||||
ED_undosys_stack_memfile_id_changed_tag(ustack, static_cast<ID *>(ob.data));
|
||||
|
||||
/* Special case, we never read from this. */
|
||||
bContext *C = nullptr;
|
||||
|
||||
SculptUndoStep *us = reinterpret_cast<SculptUndoStep *>(
|
||||
BKE_undosys_step_push_init_with_type(ustack, C, name, BKE_UNDOSYS_TYPE_SCULPT));
|
||||
us->data.object_name = ob.id.name;
|
||||
|
||||
if (!us->active_color_start.was_set) {
|
||||
@@ -1677,9 +1668,36 @@ void push_begin_ex(const Scene & /*scene*/, Object &ob, const char *name)
|
||||
us->active_color_end.was_set = false;
|
||||
}
|
||||
|
||||
const SculptSession &ss = *ob.sculpt;
|
||||
|
||||
us->data.pivot_pos = ss.pivot_pos;
|
||||
us->data.pivot_rot = ss.pivot_rot;
|
||||
|
||||
if (const KeyBlock *key = BKE_keyblock_from_object(&ob)) {
|
||||
us->data.active_shape_key_name = key->name;
|
||||
}
|
||||
}
|
||||
|
||||
void push_begin_ex(const Scene & /*scene*/, Object &ob, const char *name)
|
||||
{
|
||||
UndoStack *ustack = ED_undo_stack_get();
|
||||
|
||||
/* If possible, we need to tag the object and its geometry data as 'changed in the future' in
|
||||
* the previous undo step if it's a memfile one. */
|
||||
ED_undosys_stack_memfile_id_changed_tag(ustack, &ob.id);
|
||||
ED_undosys_stack_memfile_id_changed_tag(ustack, static_cast<ID *>(ob.data));
|
||||
|
||||
/* Special case, we never read from this. */
|
||||
bContext *C = nullptr;
|
||||
|
||||
SculptUndoStep *us = reinterpret_cast<SculptUndoStep *>(
|
||||
BKE_undosys_step_push_init_with_type(ustack, C, name, BKE_UNDOSYS_TYPE_SCULPT));
|
||||
|
||||
const SculptSession &ss = *ob.sculpt;
|
||||
const bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(ob);
|
||||
|
||||
save_common_data(ob, us);
|
||||
|
||||
switch (pbvh.type()) {
|
||||
case bke::pbvh::Type::Mesh: {
|
||||
const Mesh &mesh = *static_cast<const Mesh *>(ob.data);
|
||||
@@ -1696,14 +1714,6 @@ void push_begin_ex(const Scene & /*scene*/, Object &ob, const char *name)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store sculpt pivot. */
|
||||
us->data.pivot_pos = ss.pivot_pos;
|
||||
us->data.pivot_rot = ss.pivot_rot;
|
||||
|
||||
if (const KeyBlock *key = BKE_keyblock_from_object(&ob)) {
|
||||
us->data.active_shape_key_name = key->name;
|
||||
}
|
||||
}
|
||||
|
||||
void push_begin(const Scene &scene, Object &ob, const wmOperator *op)
|
||||
@@ -1995,20 +2005,41 @@ static void step_free(UndoStep *us_p)
|
||||
|
||||
void geometry_begin(const Scene &scene, Object &ob, const wmOperator *op)
|
||||
{
|
||||
push_begin(scene, ob, op);
|
||||
geometry_push(ob);
|
||||
geometry_begin_ex(scene, ob, op->type->name);
|
||||
}
|
||||
|
||||
void geometry_begin_ex(const Scene &scene, Object &ob, const char *name)
|
||||
void geometry_begin_ex(const Scene & /*scene*/, Object &ob, const char *name)
|
||||
{
|
||||
push_begin_ex(scene, ob, name);
|
||||
UndoStack *ustack = ED_undo_stack_get();
|
||||
|
||||
/* If possible, we need to tag the object and its geometry data as 'changed in the future' in
|
||||
* the previous undo step if it's a memfile one. */
|
||||
ED_undosys_stack_memfile_id_changed_tag(ustack, &ob.id);
|
||||
ED_undosys_stack_memfile_id_changed_tag(ustack, static_cast<ID *>(ob.data));
|
||||
|
||||
/* Special case, we never read from this. */
|
||||
bContext *C = nullptr;
|
||||
|
||||
SculptUndoStep *us = reinterpret_cast<SculptUndoStep *>(
|
||||
BKE_undosys_step_push_init_with_type(ustack, C, name, BKE_UNDOSYS_TYPE_SCULPT));
|
||||
save_common_data(ob, us);
|
||||
geometry_push(ob);
|
||||
}
|
||||
|
||||
void geometry_end(Object &ob)
|
||||
{
|
||||
geometry_push(ob);
|
||||
push_end(ob);
|
||||
|
||||
/* We could remove this and enforce all callers run in an operator using 'OPTYPE_UNDO'. */
|
||||
wmWindowManager *wm = static_cast<wmWindowManager *>(G_MAIN->wm.first);
|
||||
if (wm->op_undo_depth == 0) {
|
||||
UndoStack *ustack = ED_undo_stack_get();
|
||||
BKE_undosys_step_push(ustack, nullptr, nullptr);
|
||||
if (wm->op_undo_depth == 0) {
|
||||
BKE_undosys_stack_limit_steps_and_memory_defaults(ustack);
|
||||
}
|
||||
WM_file_tag_modified();
|
||||
}
|
||||
}
|
||||
|
||||
void register_type(UndoType *ut)
|
||||
|
||||
Reference in New Issue
Block a user