From a42896a8a14212fc568fbb147e02dfacb8822f11 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 16 Aug 2022 15:42:04 +0200 Subject: LibOverride: Refactor of menu entries in the View3D. Move override creation into their own menu, add entries for reset and clear operations. --- release/scripts/startup/bl_ui/space_view3d.py | 13 +++ source/blender/editors/object/object_intern.h | 6 +- source/blender/editors/object/object_ops.c | 5 +- source/blender/editors/object/object_relations.c | 111 ++++++++++++++++++++- .../editors/space_outliner/outliner_tools.cc | 2 +- 5 files changed, 129 insertions(+), 8 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 2f9050ba638..5dcfa60665a 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2360,6 +2360,17 @@ class VIEW3D_MT_object_relations(Menu): layout.menu("VIEW3D_MT_make_single_user") +class VIEW3D_MT_object_liboverride(Menu): + bl_label = "Library Override" + + def draw(self, _context): + layout = self.layout + + layout.operator("object.make_override_library", text="Make") + layout.operator("object.reset_override_library", text="Reset") + layout.operator("object.clear_override_library", text="Clear") + + class VIEW3D_MT_object(Menu): bl_context = "objectmode" bl_label = "Object" @@ -2391,6 +2402,7 @@ class VIEW3D_MT_object(Menu): layout.menu("VIEW3D_MT_object_parent") layout.menu("VIEW3D_MT_object_collection") layout.menu("VIEW3D_MT_object_relations") + layout.menu("VIEW3D_MT_object_liboverride") layout.menu("VIEW3D_MT_object_constraints") layout.menu("VIEW3D_MT_object_track") layout.menu("VIEW3D_MT_make_links") @@ -7836,6 +7848,7 @@ classes = ( VIEW3D_MT_object_shading, VIEW3D_MT_object_apply, VIEW3D_MT_object_relations, + VIEW3D_MT_object_liboverride, VIEW3D_MT_object_parent, VIEW3D_MT_object_track, VIEW3D_MT_object_collection, diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index b5862d4d957..d4dd465142e 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -49,10 +49,14 @@ void OBJECT_OT_vertex_parent_set(struct wmOperatorType *ot); void OBJECT_OT_track_set(struct wmOperatorType *ot); void OBJECT_OT_track_clear(struct wmOperatorType *ot); void OBJECT_OT_make_local(struct wmOperatorType *ot); -void OBJECT_OT_make_override_library(struct wmOperatorType *ot); void OBJECT_OT_make_single_user(struct wmOperatorType *ot); void OBJECT_OT_make_links_scene(struct wmOperatorType *ot); void OBJECT_OT_make_links_data(struct wmOperatorType *ot); + +void OBJECT_OT_make_override_library(struct wmOperatorType *ot); +void OBJECT_OT_reset_override_library(struct wmOperatorType *ot); +void OBJECT_OT_clear_override_library(struct wmOperatorType *ot); + /** * Used for drop-box. * Assigns to object under cursor, only first material slot. diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 8a0d380ff2f..24a4556b075 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -58,11 +58,14 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_track_set); WM_operatortype_append(OBJECT_OT_track_clear); WM_operatortype_append(OBJECT_OT_make_local); - WM_operatortype_append(OBJECT_OT_make_override_library); WM_operatortype_append(OBJECT_OT_make_single_user); WM_operatortype_append(OBJECT_OT_make_links_scene); WM_operatortype_append(OBJECT_OT_make_links_data); + WM_operatortype_append(OBJECT_OT_make_override_library); + WM_operatortype_append(OBJECT_OT_reset_override_library); + WM_operatortype_append(OBJECT_OT_clear_override_library); + WM_operatortype_append(OBJECT_OT_select_random); WM_operatortype_append(OBJECT_OT_select_all); WM_operatortype_append(OBJECT_OT_select_same_collection); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index f136d3302df..052b243d893 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2325,6 +2325,14 @@ static int make_override_library_exec(bContext *C, wmOperator *op) user_overrides_from_selected_objects = true; } + /* Make already existing selected liboverrides editable. */ + FOREACH_SELECTED_OBJECT_BEGIN (view_layer, CTX_wm_view3d(C), ob_iter) { + if (ID_IS_OVERRIDE_LIBRARY_REAL(ob_iter) && !ID_IS_LINKED(ob_iter)) { + ob_iter->id.override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED; + } + } + FOREACH_SELECTED_OBJECT_END; + if (do_fully_editable) { /* Pass. */ } @@ -2435,6 +2443,9 @@ static int make_override_library_invoke(bContext *C, wmOperator *op, const wmEve } if (!ID_IS_LINKED(obact)) { + if (ID_IS_OVERRIDE_LIBRARY_REAL(obact)) { + return make_override_library_exec(C, op); + } BKE_report(op->reports, RPT_ERROR, "Cannot make library override from a local object"); return OPERATOR_CANCELLED; } @@ -2473,17 +2484,20 @@ static bool make_override_library_poll(bContext *C) Object *obact = CTX_data_active_object(C); /* Object must be directly linked to be overridable. */ - return (ED_operator_objectmode(C) && obact != NULL && - (ID_IS_LINKED(obact) || (obact->instance_collection != NULL && - ID_IS_OVERRIDABLE_LIBRARY(obact->instance_collection) && - !ID_IS_OVERRIDE_LIBRARY(obact)))); + return ( + ED_operator_objectmode(C) && obact != NULL && + (ID_IS_LINKED(obact) || ID_IS_OVERRIDE_LIBRARY(obact) || + (obact->instance_collection != NULL && + ID_IS_OVERRIDABLE_LIBRARY(obact->instance_collection) && !ID_IS_OVERRIDE_LIBRARY(obact)))); } void OBJECT_OT_make_override_library(wmOperatorType *ot) { /* identifiers */ ot->name = "Make Library Override"; - ot->description = "Make a local override of this library linked data-block"; + ot->description = + "Create a local override of the selected linked objects, and their hierarchy of " + "dependencies"; ot->idname = "OBJECT_OT_make_override_library"; /* api callbacks */ @@ -2510,6 +2524,93 @@ void OBJECT_OT_make_override_library(wmOperatorType *ot) ot->prop = prop; } +static bool reset_clear_override_library_poll(bContext *C) +{ + Object *obact = CTX_data_active_object(C); + + /* Object must be local and an override. */ + return (ED_operator_objectmode(C) && obact != NULL && !ID_IS_LINKED(obact) && + ID_IS_OVERRIDE_LIBRARY(obact)); +} + +static int reset_override_library_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + + /* Make already existing selected liboverrides editable. */ + FOREACH_SELECTED_OBJECT_BEGIN (CTX_data_view_layer(C), CTX_wm_view3d(C), ob_iter) { + if (ID_IS_OVERRIDE_LIBRARY_REAL(ob_iter) && !ID_IS_LINKED(ob_iter)) { + BKE_lib_override_library_id_reset(bmain, &ob_iter->id, false); + } + } + FOREACH_SELECTED_OBJECT_END; + + WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, NULL); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_reset_override_library(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Reset Library Override"; + ot->description = "Reset the selected local overrides to their linked references values"; + ot->idname = "OBJECT_OT_reset_override_library"; + + /* api callbacks */ + ot->exec = reset_override_library_exec; + ot->poll = reset_clear_override_library_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int clear_override_library_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + + /* Make already existing selected liboverrides editable. */ + FOREACH_SELECTED_OBJECT_BEGIN (CTX_data_view_layer(C), CTX_wm_view3d(C), ob_iter) { + if (ID_IS_LINKED(ob_iter)) { + continue; + } + if (BKE_lib_override_library_is_hierarchy_leaf(bmain, &ob_iter->id)) { + BKE_libblock_remap(bmain, + &ob_iter->id, + ob_iter->id.override_library->reference, + ID_REMAP_SKIP_INDIRECT_USAGE); + 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); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_clear_override_library(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Library Override"; + ot->description = + "Delete the selected local overrides and relink their usages to the linked data-blocks if " + "possible, else reset them and mark them as non editable"; + ot->idname = "OBJECT_OT_clear_override_library"; + + /* api callbacks */ + ot->exec = clear_override_library_exec; + ot->poll = reset_clear_override_library_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /** \} */ /* ------------------------------------------------------------------- */ diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc index 61b2b6c0002..73c9ccca048 100644 --- a/source/blender/editors/space_outliner/outliner_tools.cc +++ b/source/blender/editors/space_outliner/outliner_tools.cc @@ -1641,7 +1641,7 @@ static const EnumPropertyItem prop_liboverride_op_types[] = { "OVERRIDE_LIBRARY_RESET", 0, "Reset", - "Reset the selected local override to their linked references values"}, + "Reset the selected local overrides to their linked references values"}, {OUTLINER_LIBOVERRIDE_OP_CLEAR_SINGLE, "OVERRIDE_LIBRARY_CLEAR_SINGLE", 0, -- cgit v1.2.3