From a89f829f12f56214b0e463b33f24edf27228db1f Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 20 May 2022 11:59:39 +0200 Subject: LibOverride: Add option to Hierarchy Creation to get all data user-editable by default. Avoids having to manually enable data-blocks for user-edition when you do not care about what should be edited by whom. Similar to default behavior before introduction of system overrides (aka non-user-editable overrides). --- release/scripts/startup/bl_ui/space_view3d.py | 2 + source/blender/blenkernel/BKE_lib_override.h | 10 +++- source/blender/blenkernel/intern/lib_override.c | 46 ++++++++++++---- .../intern/lib_override_proxy_conversion.c | 2 +- .../editors/interface/interface_templates.c | 20 ++++--- source/blender/editors/object/object_relations.c | 63 +++++++++++++++------- .../editors/space_outliner/outliner_tools.cc | 38 ++++++++++++- source/blender/makesrna/intern/rna_ID.c | 2 +- 8 files changed, 142 insertions(+), 41 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index bcc5976fb59..ffada687868 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2295,6 +2295,8 @@ class VIEW3D_MT_object_relations(Menu): layout = self.layout layout.operator("object.make_override_library", text="Make Library Override...") + layout.operator("object.make_override_library", + text="Make Library Override - Fully Editable...").do_fully_editable=True layout.operator("object.make_dupli_face") diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h index dfb2b900b10..38de4bebdbd 100644 --- a/source/blender/blenkernel/BKE_lib_override.h +++ b/source/blender/blenkernel/BKE_lib_override.h @@ -116,6 +116,8 @@ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain, * \param do_no_main: Create the new override data outside of Main database. * Used for resyncing of linked overrides. * + * \param do_fully_editable: if true, tag all created overrides as user-editable by default. + * * \return \a true on success, \a false otherwise. */ bool BKE_lib_override_library_create_from_tag(struct Main *bmain, @@ -123,7 +125,8 @@ bool BKE_lib_override_library_create_from_tag(struct Main *bmain, const struct ID *id_root_reference, struct ID *id_hierarchy_root, const struct ID *id_hierarchy_root_reference, - bool do_no_main); + bool do_no_main, + const bool do_fully_editable); /** * Advanced 'smart' function to create fully functional overrides. * @@ -154,6 +157,8 @@ bool BKE_lib_override_library_create_from_tag(struct Main *bmain, * * \param r_id_root_override: if not NULL, the override generated for the given \a id_root. * + * \param do_fully_editable: if true, tag all created overrides as user-editable by default. + * * \return true if override was successfully created. */ bool BKE_lib_override_library_create(struct Main *bmain, @@ -163,7 +168,8 @@ bool BKE_lib_override_library_create(struct Main *bmain, struct ID *id_root_reference, struct ID *id_hierarchy_root_reference, struct ID *id_instance_hint, - struct ID **r_id_root_override); + struct ID **r_id_root_override, + const bool do_fully_editable); /** * Create a library override template. */ diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index 6dd13952413..50c9514e810 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -398,7 +398,8 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain, const ID *id_root_reference, ID *id_hierarchy_root, const ID *id_hierarchy_root_reference, - const bool do_no_main) + const bool do_no_main, + const bool do_fully_editable) { BLI_assert(id_root_reference != NULL && ID_IS_LINKED(id_root_reference)); /* If we do not have any hierarchy root given, then the root reference must be tagged for @@ -464,6 +465,9 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain, success = false; break; } + if (do_fully_editable) { + reference_id->newid->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED; + } } /* We also tag the new IDs so that in next step we can remap their pointers too. */ reference_id->newid->tag |= LIB_TAG_DOIT; @@ -993,7 +997,8 @@ static bool lib_override_library_create_do(Main *bmain, Scene *scene, Library *owner_library, ID *id_root_reference, - ID *id_hierarchy_root_reference) + ID *id_hierarchy_root_reference, + const bool do_fully_editable) { BKE_main_relations_create(bmain, 0); LibOverrideGroupTagData data = {.bmain = bmain, @@ -1017,12 +1022,22 @@ static bool lib_override_library_create_do(Main *bmain, BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root_reference)); BLI_assert(id_hierarchy_root_reference->override_library->reference->lib == id_root_reference->lib); - success = BKE_lib_override_library_create_from_tag( - bmain, owner_library, id_root_reference, id_hierarchy_root_reference, NULL, false); + success = BKE_lib_override_library_create_from_tag(bmain, + owner_library, + id_root_reference, + id_hierarchy_root_reference, + NULL, + false, + do_fully_editable); } else { - success = BKE_lib_override_library_create_from_tag( - bmain, owner_library, id_root_reference, NULL, id_hierarchy_root_reference, false); + success = BKE_lib_override_library_create_from_tag(bmain, + owner_library, + id_root_reference, + NULL, + id_hierarchy_root_reference, + false, + do_fully_editable); } return success; @@ -1180,7 +1195,8 @@ bool BKE_lib_override_library_create(Main *bmain, ID *id_root_reference, ID *id_hierarchy_root_reference, ID *id_instance_hint, - ID **r_id_root_override) + ID **r_id_root_override, + const bool do_fully_editable) { if (r_id_root_override != NULL) { *r_id_root_override = NULL; @@ -1190,8 +1206,12 @@ bool BKE_lib_override_library_create(Main *bmain, id_hierarchy_root_reference = id_root_reference; } - const bool success = lib_override_library_create_do( - bmain, scene, owner_library, id_root_reference, id_hierarchy_root_reference); + const bool success = lib_override_library_create_do(bmain, + scene, + owner_library, + id_root_reference, + id_hierarchy_root_reference, + do_fully_editable); if (!success) { return success; @@ -1680,7 +1700,13 @@ static bool lib_override_library_resync(Main *bmain, * override IDs (including within the old overrides themselves, since those are tagged too * above). */ const bool success = BKE_lib_override_library_create_from_tag( - bmain, NULL, id_root_reference, id_root->override_library->hierarchy_root, NULL, true); + bmain, + NULL, + id_root_reference, + id_root->override_library->hierarchy_root, + NULL, + true, + false); if (!success) { BLI_ghash_free(linkedref_to_old_override, NULL, NULL); diff --git a/source/blender/blenkernel/intern/lib_override_proxy_conversion.c b/source/blender/blenkernel/intern/lib_override_proxy_conversion.c index 5e9d8e8c4d0..3d4ccf5f426 100644 --- a/source/blender/blenkernel/intern/lib_override_proxy_conversion.c +++ b/source/blender/blenkernel/intern/lib_override_proxy_conversion.c @@ -82,7 +82,7 @@ bool BKE_lib_override_library_proxy_convert(Main *bmain, FOREACH_MAIN_ID_END; return BKE_lib_override_library_create( - bmain, scene, view_layer, ob_proxy->id.lib, id_root, id_root, id_instance_hint, NULL); + bmain, scene, view_layer, ob_proxy->id.lib, id_root, id_root, id_instance_hint, NULL, false); } static void lib_override_library_proxy_convert_do(Main *bmain, diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 4e6437e043a..cafc87e9c7f 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -742,7 +742,7 @@ static void template_id_liboverride_hierarchy_create(bContext *C, object_active->id.tag |= LIB_TAG_DOIT; } BKE_lib_override_library_create( - bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override); + bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override, false); } else if (object_active != NULL && !ID_IS_LINKED(object_active) && &object_active->instance_collection->id == id) { @@ -754,7 +754,8 @@ static void template_id_liboverride_hierarchy_create(bContext *C, id, &object_active->id, &object_active->id, - &id_override); + &id_override, + false); } break; case ID_OB: @@ -765,7 +766,7 @@ static void template_id_liboverride_hierarchy_create(bContext *C, object_active->id.tag |= LIB_TAG_DOIT; } BKE_lib_override_library_create( - bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override); + bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override, false); } break; case ID_ME: @@ -787,13 +788,20 @@ static void template_id_liboverride_hierarchy_create(bContext *C, if (object_active != NULL) { object_active->id.tag |= LIB_TAG_DOIT; } - BKE_lib_override_library_create( - bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override); + BKE_lib_override_library_create(bmain, + scene, + view_layer, + NULL, + id, + &collection_active->id, + NULL, + &id_override, + false); } else { object_active->id.tag |= LIB_TAG_DOIT; BKE_lib_override_library_create( - bmain, scene, view_layer, NULL, id, &object_active->id, NULL, &id_override); + bmain, scene, view_layer, NULL, id, &object_active->id, NULL, &id_override, false); } } break; diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index a7efb45e803..6e6dbc6837c 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2267,8 +2267,12 @@ static int make_override_library_exec(bContext *C, wmOperator *op) ID *id_root = NULL; bool is_override_instancing_object = false; - GSet *user_overrides_objects_uids = BLI_gset_new( - BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__); + const bool do_fully_editable = RNA_boolean_get(op->ptr, "do_fully_editable"); + + GSet *user_overrides_objects_uids = do_fully_editable ? NULL : + BLI_gset_new(BLI_ghashutil_inthash_p, + BLI_ghashutil_intcmp, + __func__); bool user_overrides_from_selected_objects = false; if (!ID_IS_LINKED(obact) && obact->instance_collection != NULL && @@ -2316,7 +2320,10 @@ static int make_override_library_exec(bContext *C, wmOperator *op) user_overrides_from_selected_objects = true; } - if (user_overrides_from_selected_objects) { + if (do_fully_editable) { + /* Pass. */ + } + else if (user_overrides_from_selected_objects) { /* Only selected objects can be 'user overrides'. */ FOREACH_SELECTED_OBJECT_BEGIN (view_layer, CTX_wm_view3d(C), ob_iter) { BLI_gset_add(user_overrides_objects_uids, POINTER_FROM_UINT(ob_iter->id.session_uuid)); @@ -2336,25 +2343,34 @@ static int make_override_library_exec(bContext *C, wmOperator *op) BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); ID *id_root_override; - const bool success = BKE_lib_override_library_create( - bmain, scene, view_layer, NULL, id_root, id_root, &obact->id, &id_root_override); - - /* Define liboverrides from selected/validated objects as user defined. */ - ID *id_hierarchy_root_override = id_root_override->override_library->hierarchy_root; - ID *id_iter; - FOREACH_MAIN_ID_BEGIN (bmain, id_iter) { - if (ID_IS_LINKED(id_iter) || !ID_IS_OVERRIDE_LIBRARY_REAL(id_iter) || - id_iter->override_library->hierarchy_root != id_hierarchy_root_override) { - continue; - } - if (BLI_gset_haskey(user_overrides_objects_uids, - POINTER_FROM_UINT(id_iter->override_library->reference->session_uuid))) { - id_iter->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED; + const bool success = BKE_lib_override_library_create(bmain, + scene, + view_layer, + NULL, + id_root, + id_root, + &obact->id, + &id_root_override, + do_fully_editable); + + if (!do_fully_editable) { + /* Define liboverrides from selected/validated objects as user defined. */ + ID *id_hierarchy_root_override = id_root_override->override_library->hierarchy_root; + ID *id_iter; + FOREACH_MAIN_ID_BEGIN (bmain, id_iter) { + if (ID_IS_LINKED(id_iter) || !ID_IS_OVERRIDE_LIBRARY_REAL(id_iter) || + id_iter->override_library->hierarchy_root != id_hierarchy_root_override) { + continue; + } + if (BLI_gset_haskey(user_overrides_objects_uids, + POINTER_FROM_UINT(id_iter->override_library->reference->session_uuid))) { + id_iter->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED; + } } - } - FOREACH_MAIN_ID_END; + FOREACH_MAIN_ID_END; - BLI_gset_free(user_overrides_objects_uids, NULL); + BLI_gset_free(user_overrides_objects_uids, NULL); + } /* Remove the instance empty from this scene, the items now have an overridden collection * instead. */ @@ -2468,6 +2484,13 @@ void OBJECT_OT_make_override_library(wmOperatorType *ot) RNA_def_enum_funcs(prop, make_override_collections_of_linked_object_itemf); RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE); ot->prop = prop; + + prop = RNA_def_boolean(ot->srna, + "do_fully_editable", + false, + "Create Fully Editable", + "Make all created override data-blocks fully editable"); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } /** \} */ diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc index cc81d5ed68d..7321fd8fc7a 100644 --- a/source/blender/editors/space_outliner/outliner_tools.cc +++ b/source/blender/editors/space_outliner/outliner_tools.cc @@ -763,6 +763,10 @@ static void id_local_fn(bContext *C, struct OutlinerLibOverrideData { bool do_hierarchy; + + /** When creating new overrides, make them all user-editable. */ + bool do_fully_editable; + /** * For resync operation, force keeping newly created override IDs (or original linked IDs) * instead of re-applying relevant existing ID pointer property override operations. Helps @@ -957,7 +961,8 @@ static void id_override_library_create_fn(bContext *C, id_root_reference, id_hierarchy_root_reference, id_instance_hint, - &id_root_override); + &id_root_override, + data->do_fully_editable); BLI_assert(id_root_override != nullptr); BLI_assert(!ID_IS_LINKED(id_root_override)); @@ -1979,6 +1984,7 @@ enum eOutlinerIdOpTypes { OUTLINER_IDOP_LOCAL, OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE, OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY, + OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY_FULLY_EDITABLE, OUTLINER_IDOP_OVERRIDE_LIBRARY_MAKE_EDITABLE, OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET, OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY, @@ -2024,6 +2030,12 @@ static const EnumPropertyItem prop_id_op_types[] = { "Make Library Override Hierarchy", "Make a local override of this linked data-block, and its hierarchy of dependencies - only " "applies to active Outliner item"}, + {OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY_FULLY_EDITABLE, + "OVERRIDE_LIBRARY_CREATE_HIERARCHY_FULLY_EDITABLE", + 0, + "Make Library Override Hierarchy Fully Editable", + "Make a local override of this linked data-block, and its hierarchy of dependencies, making " + "them all fully user-editable - only applies to active Outliner item"}, {OUTLINER_IDOP_OVERRIDE_LIBRARY_MAKE_EDITABLE, "OVERRIDE_LIBRARY_MAKE_EDITABLE", 0, @@ -2103,6 +2115,7 @@ static bool outliner_id_operation_item_poll(bContext *C, } return false; case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY: + case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY_FULLY_EDITABLE: if (ID_IS_OVERRIDABLE_LIBRARY(tselem->id) || (ID_IS_LINKED(tselem->id))) { return true; } @@ -2300,6 +2313,29 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) ED_undo_push(C, "Overridden Data Hierarchy"); break; } + case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY_FULLY_EDITABLE: { + OutlinerLibOverrideData override_data{}; + override_data.do_hierarchy = true; + override_data.do_fully_editable = true; + outliner_do_libdata_operation(C, + op->reports, + scene, + space_outliner, + &space_outliner->tree, + id_override_library_create_hierarchy_pre_process_fn, + &override_data); + outliner_do_libdata_operation(C, + op->reports, + scene, + space_outliner, + &space_outliner->tree, + id_override_library_create_fn, + &override_data); + id_override_library_create_hierarchy_post_process(C, &override_data); + + ED_undo_push(C, "Overridden Data Hierarchy Fully Editable"); + break; + } case OUTLINER_IDOP_OVERRIDE_LIBRARY_MAKE_EDITABLE: { outliner_do_libdata_operation(C, op->reports, diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index b0488bbfa7a..6a3c0864331 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -722,7 +722,7 @@ static ID *rna_ID_override_hierarchy_create( ID *id_root_override = NULL; BKE_lib_override_library_create( - bmain, scene, view_layer, NULL, id, id, id_instance_hint, &id_root_override); + bmain, scene, view_layer, NULL, id, id, id_instance_hint, &id_root_override, false); WM_main_add_notifier(NC_ID | NA_ADDED, NULL); WM_main_add_notifier(NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL); -- cgit v1.2.3