diff options
-rw-r--r-- | source/blender/blenkernel/BKE_lib_override.h | 22 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.c | 56 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_edit.cc | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_ID.c | 12 |
4 files changed, 77 insertions, 14 deletions
diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h index daa94031489..2447208b49d 100644 --- a/source/blender/blenkernel/BKE_lib_override.h +++ b/source/blender/blenkernel/BKE_lib_override.h @@ -70,6 +70,14 @@ bool BKE_lib_override_library_is_user_edited(struct ID *id); bool BKE_lib_override_library_is_system_defined(struct Main *bmain, struct ID *id); /** + * Check if given ID is a leaf in its liboverride hierarchy (i.e. if it does not use any other + * override ID). + * + * NOTE: Embedded IDs of override IDs are not considered as leaves. + */ +bool BKE_lib_override_library_is_hierarchy_leaf(struct Main *bmain, struct ID *id); + +/** * Create an overridden local copy of linked reference. * * \note This function is very basic, low-level. It does not consider any hierarchical dependency, @@ -374,12 +382,22 @@ bool BKE_lib_override_library_main_operations_create(struct Main *bmain, bool fo /** * Reset all overrides in given \a id_root, while preserving ID relations. + * + * \param do_reset_system_override If \a true, reset the given ID as a system override one (i.e. + * non-editable). */ -void BKE_lib_override_library_id_reset(struct Main *bmain, struct ID *id_root); +void BKE_lib_override_library_id_reset(struct Main *bmain, + struct ID *id_root, + bool do_reset_system_override); /** * Reset all overrides in given \a id_root and its dependencies, while preserving ID relations. + * + * \param do_reset_system_override If \a true, reset the given ID and all of its descendants in the + * override hierarchy as system override ones (i.e. non-editable). */ -void BKE_lib_override_library_id_hierarchy_reset(struct Main *bmain, struct ID *id_root); +void BKE_lib_override_library_id_hierarchy_reset(struct Main *bmain, + struct ID *id_root, + bool do_reset_system_override); /** * Set or clear given tag in all operations in that override property data. diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index 3a44f8ce845..c0c97fc6ff6 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -290,6 +290,32 @@ bool BKE_lib_override_library_is_system_defined(Main *bmain, ID *id) return false; } +static int foreachid_is_hierarchy_leaf_fn(LibraryIDLinkCallbackData *cb_data) +{ + ID *id_owner = cb_data->id_owner; + ID *id = *cb_data->id_pointer; + bool *is_leaf = cb_data->user_data; + + if (id != NULL && ID_IS_OVERRIDE_LIBRARY_REAL(id) && + id->override_library->hierarchy_root == id_owner->override_library->hierarchy_root) { + *is_leaf = false; + return IDWALK_RET_STOP_ITER; + } + return IDWALK_RET_NOP; +} + +bool BKE_lib_override_library_is_hierarchy_leaf(Main *bmain, ID *id) +{ + if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) { + bool is_leaf = true; + BKE_library_foreach_ID_link( + bmain, id, foreachid_is_hierarchy_leaf_fn, &is_leaf, IDWALK_READONLY); + return is_leaf; + } + + return false; +} + ID *BKE_lib_override_library_create_from_id(Main *bmain, ID *reference_id, const bool do_tagged_remap) @@ -3057,10 +3083,16 @@ bool BKE_lib_override_library_main_operations_create(Main *bmain, const bool for return create_pool_data.changed; } -static bool lib_override_library_id_reset_do(Main *bmain, ID *id_root) +static bool lib_override_library_id_reset_do(Main *bmain, + ID *id_root, + const bool do_reset_system_override) { bool was_op_deleted = false; + if (do_reset_system_override) { + id_root->override_library->flag |= IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED; + } + LISTBASE_FOREACH_MUTABLE ( IDOverrideLibraryProperty *, op, &id_root->override_library->properties) { bool do_op_delete = true; @@ -3116,13 +3148,15 @@ static bool lib_override_library_id_reset_do(Main *bmain, ID *id_root) return was_op_deleted; } -void BKE_lib_override_library_id_reset(Main *bmain, ID *id_root) +void BKE_lib_override_library_id_reset(Main *bmain, + ID *id_root, + const bool do_reset_system_override) { if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) { return; } - if (lib_override_library_id_reset_do(bmain, id_root)) { + if (lib_override_library_id_reset_do(bmain, id_root, do_reset_system_override)) { if (id_root->override_library->runtime != NULL && (id_root->override_library->runtime->tag & IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD) != 0) { @@ -3132,7 +3166,9 @@ void BKE_lib_override_library_id_reset(Main *bmain, ID *id_root) } } -static void lib_override_library_id_hierarchy_recursive_reset(Main *bmain, ID *id_root) +static void lib_override_library_id_hierarchy_recursive_reset(Main *bmain, + ID *id_root, + const bool do_reset_system_override) { if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) { return; @@ -3141,7 +3177,7 @@ static void lib_override_library_id_hierarchy_recursive_reset(Main *bmain, ID *i void **entry_vp = BLI_ghash_lookup_p(bmain->relations->relations_from_pointers, id_root); if (entry_vp == NULL) { /* This ID is not used by nor using any other ID. */ - lib_override_library_id_reset_do(bmain, id_root); + lib_override_library_id_reset_do(bmain, id_root, do_reset_system_override); return; } @@ -3151,7 +3187,7 @@ static void lib_override_library_id_hierarchy_recursive_reset(Main *bmain, ID *i return; } - lib_override_library_id_reset_do(bmain, id_root); + lib_override_library_id_reset_do(bmain, id_root, do_reset_system_override); /* This way we won't process again that ID, should we encounter it again through another * relationship hierarchy. */ @@ -3168,17 +3204,19 @@ static void lib_override_library_id_hierarchy_recursive_reset(Main *bmain, ID *i if (*to_id_entry->id_pointer.to != NULL) { ID *to_id = *to_id_entry->id_pointer.to; if (to_id->override_library != NULL) { - lib_override_library_id_hierarchy_recursive_reset(bmain, to_id); + lib_override_library_id_hierarchy_recursive_reset(bmain, to_id, do_reset_system_override); } } } } -void BKE_lib_override_library_id_hierarchy_reset(Main *bmain, ID *id_root) +void BKE_lib_override_library_id_hierarchy_reset(Main *bmain, + ID *id_root, + const bool do_reset_system_override) { BKE_main_relations_create(bmain, 0); - lib_override_library_id_hierarchy_recursive_reset(bmain, id_root); + lib_override_library_id_hierarchy_recursive_reset(bmain, id_root, do_reset_system_override); BKE_main_relations_free(bmain); diff --git a/source/blender/editors/space_outliner/outliner_edit.cc b/source/blender/editors/space_outliner/outliner_edit.cc index ae67e7108bf..d6c5901b546 100644 --- a/source/blender/editors/space_outliner/outliner_edit.cc +++ b/source/blender/editors/space_outliner/outliner_edit.cc @@ -30,6 +30,7 @@ #include "BKE_context.h" #include "BKE_idtype.h" #include "BKE_lib_id.h" +#include "BKE_lib_override.h" #include "BKE_lib_query.h" #include "BKE_lib_remap.h" #include "BKE_main.h" diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 5f264a19d47..d3b7e380afa 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -762,7 +762,8 @@ static void rna_ID_override_library_reset(ID *id, IDOverrideLibrary *UNUSED(override_library), Main *bmain, ReportList *reports, - bool do_hierarchy) + bool do_hierarchy, + bool set_system_override) { if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) { BKE_reportf(reports, RPT_ERROR, "ID '%s' isn't an override", id->name); @@ -770,10 +771,10 @@ static void rna_ID_override_library_reset(ID *id, } if (do_hierarchy) { - BKE_lib_override_library_id_hierarchy_reset(bmain, id); + BKE_lib_override_library_id_hierarchy_reset(bmain, id, set_system_override); } else { - BKE_lib_override_library_id_reset(bmain, id); + BKE_lib_override_library_id_reset(bmain, id, set_system_override); } WM_main_add_notifier(NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL); @@ -1869,6 +1870,11 @@ static void rna_def_ID_override_library(BlenderRNA *brna) true, "", "Also reset all the dependencies of this override to match their reference linked IDs"); + RNA_def_boolean(func, + "set_system_override", + false, + "", + "Reset all user-editable overrides as (non-editable) system overrides"); func = RNA_def_function(srna, "destroy", "rna_ID_override_library_destroy"); RNA_def_function_ui_description( |