Fix #114438: wrong undo after running node tool in mesh edit mode

I think the issue is that the run-node-group operator overwrites the data stored in the
`Mesh` while mesh edit mode operations typically only change the `BMEditMesh`. It
seems like that causes issues because the mesh edit mode undo stack does not
keep track of changes to the `Mesh`. When hitting undo, Blender assumes that the
`Mesh` stored in the object has not changed and therefore it does not have to be
read from the undo step again.

The preliminary fix implemented here is to just not change the `Mesh` but only the
`BMEditMesh` like any other edit mode operator. This seems to solve the issue.
I haven't quite figured out yet how to tell the undo system that the `Mesh` has to be
loaded from the undo step when undoing out of mesh edit mode. Doing that might
provide a better solution.

Pull Request: https://projects.blender.org/blender/blender/pulls/119015
This commit is contained in:
Jacques Lucke 2024-03-12 13:28:26 +01:00
parent 40156dfba3
commit b40a9ce60b
3 changed files with 20 additions and 7 deletions

@ -223,18 +223,20 @@ static void store_result_geometry(
new_mesh->attributes_for_write().remove_anonymous();
BKE_object_material_from_eval_data(&bmain, &object, &new_mesh->id);
BKE_mesh_nomain_to_mesh(new_mesh, &mesh, &object);
if (object.mode == OB_MODE_EDIT) {
EDBM_mesh_make_from_mesh(&object, new_mesh, scene.toolsettings->selectmode, true);
BKE_editmesh_looptris_and_normals_calc(mesh.edit_mesh);
}
else {
BKE_mesh_nomain_to_mesh(new_mesh, &mesh, &object);
}
}
if (has_shape_keys && !mesh.key) {
BKE_report(op.reports, RPT_WARNING, "Mesh shape key data removed");
}
if (object.mode == OB_MODE_EDIT) {
EDBM_mesh_make(&object, scene.toolsettings->selectmode, true);
BKE_editmesh_looptris_and_normals_calc(mesh.edit_mesh);
}
else if (object.mode == OB_MODE_SCULPT) {
if (object.mode == OB_MODE_SCULPT) {
sculpt_paint::undo::geometry_end(&object);
}
break;

@ -77,6 +77,8 @@ void EDBM_mesh_clear(BMEditMesh *em);
void EDBM_selectmode_to_scene(bContext *C);
void EDBM_mesh_make(Object *ob, int select_mode, bool add_key_index);
/** Replaces the edit-mesh in the object with a new one based on the given mesh. */
void EDBM_mesh_make_from_mesh(Object *ob, Mesh *src_mesh, int select_mode, bool add_key_index);
/**
* Should only be called on the active edit-mesh, otherwise call #BKE_editmesh_free_data.
*/

@ -265,11 +265,20 @@ bool EDBM_op_call_silentf(BMEditMesh *em, const char *fmt, ...)
* \{ */
void EDBM_mesh_make(Object *ob, const int select_mode, const bool add_key_index)
{
Mesh *mesh = static_cast<Mesh *>(ob->data);
EDBM_mesh_make_from_mesh(ob, mesh, select_mode, add_key_index);
}
void EDBM_mesh_make_from_mesh(Object *ob,
Mesh *src_mesh,
const int select_mode,
const bool add_key_index)
{
Mesh *mesh = static_cast<Mesh *>(ob->data);
BMeshCreateParams create_params{};
create_params.use_toolflags = true;
BMesh *bm = BKE_mesh_to_bmesh(mesh, ob, add_key_index, &create_params);
BMesh *bm = BKE_mesh_to_bmesh(src_mesh, ob, add_key_index, &create_params);
if (mesh->edit_mesh) {
/* this happens when switching shape keys */