From 37382b7c39d5c67cc851d8b464a821dcb64a480b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 8 Oct 2025 02:42:39 +0000 Subject: [PATCH] UV: track select sticky & sync options with edit-mesh undo Since recent UV selection changes (!138197), the meshes UV selection is closely tied to the scenes selection options. Track these settings with edit-mesh undo, to prevent undoing into a state where the selection doesn't match the previous state. Ref !147591 --- source/blender/editors/mesh/editmesh_undo.cc | 41 +++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_undo.cc b/source/blender/editors/mesh/editmesh_undo.cc index 4b94ca6fb7d..b2e04f487af 100644 --- a/source/blender/editors/mesh/editmesh_undo.cc +++ b/source/blender/editors/mesh/editmesh_undo.cc @@ -149,8 +149,7 @@ struct UndoMesh { UndoMesh *local_next, *local_prev; Mesh *mesh; - int selectmode; - char uv_selectmode; + char selectmode; /** * The active shape key associated with this mesh. @@ -1041,10 +1040,23 @@ struct MeshUndoStep_Elem { UndoMesh data; }; +/** + * Scene & tool-setting data. + * Used so edit-mesh selection settings follow the underlying mesh data. + */ +struct MeshUndoStep_SceneData { + char selectmode; + char uv_selectmode; + char uv_sticky; + char uv_flag; +}; + struct MeshUndoStep { UndoStep step; /** See #ED_undo_object_editmode_validate_scene_from_windows code comment for details. */ UndoRefID_Scene scene_ref; + + MeshUndoStep_SceneData scene_data; MeshUndoStep_Elem *elems; uint elems_len; }; @@ -1075,6 +1087,14 @@ static bool mesh_undosys_step_encode(bContext *C, Main *bmain, UndoStep *us_p) um_references = mesh_undostep_reference_elems_from_objects(objects.data(), objects.size()); #endif + { + MeshUndoStep_SceneData &scene_data = us->scene_data; + scene_data.selectmode = ts->selectmode; + scene_data.uv_selectmode = ts->uv_selectmode; + scene_data.uv_sticky = ts->uv_sticky; + scene_data.uv_flag = ts->uv_flag; + } + for (uint i = 0; i < objects.size(); i++) { Object *obedit = objects[i]; MeshUndoStep_Elem *elem = &us->elems[i]; @@ -1091,7 +1111,6 @@ static bool mesh_undosys_step_encode(bContext *C, Main *bmain, UndoStep *us_p) em->needs_flush_to_id = 1; us->step.data_size += elem->data.undo_size; - elem->data.uv_selectmode = ts->uv_selectmode; #ifdef USE_ARRAY_STORE /** As this is only data storage it is safe to set the session ID here. */ @@ -1154,8 +1173,20 @@ static void mesh_undosys_step_decode( /* Check after setting active (unless undoing into another scene). */ BLI_assert(mesh_undosys_poll(C) || (scene != CTX_data_scene(C))); - scene->toolsettings->selectmode = us->elems[0].data.selectmode; - scene->toolsettings->uv_selectmode = us->elems[0].data.uv_selectmode; + { + /* Follow settings related to selection. + * While other flags could be included too: it's important the user doesn't + * undo into a state where the scene settings would show a different selection + * to the selection the user was previously editing. */ + constexpr char uv_flag_undo = UV_FLAG_SELECT_SYNC | UV_FLAG_SELECT_ISLAND; + + ToolSettings *ts = scene->toolsettings; + const MeshUndoStep_SceneData &scene_data = us->scene_data; + ts->selectmode = scene_data.selectmode; + ts->uv_selectmode = scene_data.uv_selectmode; + ts->uv_sticky = scene_data.uv_sticky; + ts->uv_flag = (ts->uv_flag & ~uv_flag_undo) | (scene_data.uv_flag & uv_flag_undo); + } bmain->is_memfile_undo_flush_needed = true;