Fix #119384: Outliner mode column crash with shared object data #119745
|
@ -2158,10 +2158,11 @@ static void outliner_mode_toggle_fn(bContext *C, void *tselem_poin, void * /*arg
|
|||
BLI_assert(tselem->id != nullptr && GS(tselem->id->name) == ID_OB);
|
||||
|
||||
Object *ob = (Object *)tselem->id;
|
||||
const bool object_data_shared = (ob->data == tvc.obact->data);
|
||||
const bool object_data_in_mode = tvc.object_data_in_mode.contains(
|
||||
static_cast<const ID *>(ob->data));
|
||||
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
const bool do_extend = (win->eventstate->modifier & KM_CTRL) && !object_data_shared;
|
||||
const bool do_extend = (win->eventstate->modifier & KM_CTRL) && !object_data_in_mode;
|
||||
outliner_item_mode_toggle(C, &tvc, te, do_extend);
|
||||
}
|
||||
|
||||
|
@ -2199,15 +2200,16 @@ static void outliner_draw_mode_column_toggle(uiBlock *block,
|
|||
draw_active_icon = false;
|
||||
}
|
||||
|
||||
const bool object_data_shared = (ob->data == ob_active->data);
|
||||
draw_active_icon = draw_active_icon || object_data_shared;
|
||||
const bool object_data_in_mode = tvc->object_data_in_mode.contains(
|
||||
static_cast<const ID *>(ob->data));
|
||||
draw_active_icon = draw_active_icon || object_data_in_mode;
|
||||
|
||||
int icon;
|
||||
const char *tip;
|
||||
if (draw_active_icon) {
|
||||
icon = UI_icon_from_object_mode(ob_active->mode);
|
||||
tip = object_data_shared ? TIP_("Change the object in the current mode") :
|
||||
TIP_("Remove from the current mode");
|
||||
tip = object_data_in_mode ? TIP_("Change the object in the current mode") :
|
||||
TIP_("Remove from the current mode");
|
||||
}
|
||||
else {
|
||||
icon = ICON_DOT;
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include "BLI_set.hh"
|
||||
|
||||
#include "RNA_types.hh"
|
||||
|
||||
/* Needed for `tree_element_cast()`. */
|
||||
|
@ -253,6 +255,8 @@ struct TreeViewContext {
|
|||
* The pose object may not be the active object (when in weight paint mode).
|
||||
* Checking this in draw loops isn't efficient, so set only once. */
|
||||
Object *ob_pose;
|
||||
|
||||
Set<const ID *> object_data_in_mode;
|
||||
};
|
||||
|
||||
enum TreeItemSelectAction {
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace blender::ed::outliner {
|
|||
|
||||
void outliner_viewcontext_init(const bContext *C, TreeViewContext *tvc)
|
||||
{
|
||||
memset(tvc, 0, sizeof(*tvc));
|
||||
*tvc = {};
|
||||
|
||||
/* Scene level. */
|
||||
tvc->scene = CTX_data_scene(C);
|
||||
|
@ -59,6 +59,13 @@ void outliner_viewcontext_init(const bContext *C, TreeViewContext *tvc)
|
|||
tvc->ob_pose = BKE_object_pose_armature_get(tvc->obact);
|
||||
}
|
||||
}
|
||||
if (tvc->obact && tvc->obact->mode != OB_MODE_OBJECT) {
|
||||
for (const Object *object : BKE_view_layer_array_from_objects_in_mode_unique_data(
|
||||
tvc->scene, tvc->view_layer, nullptr, eObjectMode(tvc->obact->mode)))
|
||||
{
|
||||
tvc->object_data_in_mode.add_new(static_cast<const ID *>(object->data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
Loading…
Reference in New Issue