From 8b7293eb4168908945d562fdd1c3f8cd4d4944e5 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 24 Aug 2022 17:07:43 +0200 Subject: LibOverride: Fix (unreported) crashes in some cases, preserve active object on Clear, general cleanup. Inconsistencies in update/tagging code between different code doing the same 'Clear. liboverride operation lead to crashes in some cases. Unify deg tagging and WM notifiers accross the three editor-level codepaths performing the common Make/Reset/Clear operations. Preserve if possible the active object accross Clear operation. Several cleanup/rename/re-arangement of code to make it more consistent. --- source/blender/editors/object/object_relations.c | 34 +++++++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'source/blender/editors/object') diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 972912e8863..71dfaefe6a3 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2420,6 +2420,8 @@ static int make_override_library_exec(bContext *C, wmOperator *op) DEG_id_tag_update(&CTX_data_scene(C)->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE); WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); return success ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } @@ -2546,7 +2548,8 @@ static int reset_override_library_exec(bContext *C, wmOperator *UNUSED(op)) } FOREACH_SELECTED_OBJECT_END; - WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, NULL); + WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); return OPERATOR_FINISHED; @@ -2570,26 +2573,49 @@ void OBJECT_OT_reset_override_library(wmOperatorType *ot) static int clear_override_library_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + Scene *scene = CTX_data_scene(C); + LinkNode *todo_objects = NULL, *todo_object_iter; /* Make already existing selected liboverrides editable. */ - FOREACH_SELECTED_OBJECT_BEGIN (CTX_data_view_layer(C), CTX_wm_view3d(C), ob_iter) { + FOREACH_SELECTED_OBJECT_BEGIN (view_layer, CTX_wm_view3d(C), ob_iter) { if (ID_IS_LINKED(ob_iter)) { continue; } + BLI_linklist_prepend_alloca(&todo_objects, ob_iter); + } + FOREACH_SELECTED_OBJECT_END; + + for (todo_object_iter = todo_objects; todo_object_iter != NULL; + todo_object_iter = todo_object_iter->next) { + Object *ob_iter = todo_object_iter->link; if (BKE_lib_override_library_is_hierarchy_leaf(bmain, &ob_iter->id)) { + bool do_remap_active = false; + if (OBACT(view_layer) == ob_iter) { + do_remap_active = true; + } BKE_libblock_remap(bmain, &ob_iter->id, ob_iter->id.override_library->reference, ID_REMAP_SKIP_INDIRECT_USAGE); + if (do_remap_active) { + Object *ref_object = ob_iter->id.override_library->reference; + Base *basact = BKE_view_layer_base_find(view_layer, ref_object); + if (basact != NULL) { + view_layer->basact = basact; + } + DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); + } BKE_id_delete(bmain, &ob_iter->id); } else { BKE_lib_override_library_id_reset(bmain, &ob_iter->id, true); } } - FOREACH_SELECTED_OBJECT_END; - WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, NULL); + DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); return OPERATOR_FINISHED; -- cgit v1.2.3