Fix #119384: Update Sharing Objects When Changing Modes #119759

Closed
Harley Acheson wants to merge 2 commits from Harley/blender:FixSharedDataCrash into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
2 changed files with 17 additions and 2 deletions

View File

@ -2178,6 +2178,11 @@ static void outliner_draw_mode_column_toggle(uiBlock *block,
const bool object_data_shared = (ob->data == ob_active->data);
draw_active_icon = draw_active_icon || object_data_shared;
if (!draw_active_icon && BKE_object_is_in_editmode(ob)) {
Harley marked this conversation as resolved
Review

BKE_object_is_in_editmode still seems not right here. Feels like this shouldn't be specific to edit mode here.

Maybe comparing the modes is enough?

`BKE_object_is_in_editmode` still seems not right here. Feels like this shouldn't be specific to edit mode here. Maybe comparing the modes is enough?
Review

I need to call BKE_object_is_in_editmode because it checks the mesh>edit_mesh (and equivalent for other object types) rather than relying on the mode flags.

I need to call `BKE_object_is_in_editmode` because it checks the mesh>edit_mesh (and equivalent for other object types) rather than relying on the mode flags.
/* Object not in edit mode, but its (shared) data is in edit mode. */
draw_active_icon = true;
}
int icon;
const char *tip;
if (draw_active_icon) {

View File

@ -90,14 +90,24 @@ static void do_outliner_item_editmode_toggle(bContext *C, Scene *scene, Base *ba
bool changed = false;
if (BKE_object_is_in_editmode(ob)) {
changed = ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA);
/* Exit edit mode for all objects sharing the same data. */
LISTBASE_FOREACH (Object *, ob_iter, &bmain->objects) {
if (ob_iter->data == ob->data) {
changed |= ED_object_editmode_exit_ex(bmain, scene, ob_iter, EM_FREEDATA);
}
Harley marked this conversation as resolved Outdated

How about trying to call ED_object_editmode_exit_ex for every object with the same data? I think that handles some other important update tags, etc. when exiting the mode.

How about trying to call `ED_object_editmode_exit_ex` for every object with the same data? I think that handles some other important update tags, etc. when exiting the mode.
}
if (changed) {
Harley marked this conversation as resolved Outdated

ob_iter is a more obvious variable name with fewer extra connotations

`ob_iter` is a more obvious variable name with fewer extra connotations
ED_object_base_select(base, BA_DESELECT);
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, nullptr);
}
}
else {
changed = ED_object_editmode_enter_ex(CTX_data_main(C), scene, ob, EM_NO_CONTEXT);
/* Enter edit mode for all objects sharing the same data. */
LISTBASE_FOREACH (Object *, ob_iter, &bmain->objects) {
if (ob_iter->data == ob->data) {
changed |= ED_object_editmode_enter_ex(CTX_data_main(C), scene, ob_iter, EM_NO_CONTEXT);
}
}
if (changed) {
ED_object_base_select(base, BA_SELECT);
WM_event_add_notifier(C, NC_SCENE | ND_MODE, nullptr);