diff options
author | Bastien Montagne <bastien@blender.org> | 2020-08-20 13:35:16 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2020-08-20 13:35:16 +0300 |
commit | 4aa04b64904b873256b41b9b972b09bb34e19e44 (patch) | |
tree | 8dbf556b30ff90ed1e9244b3bc467a2edc50e5f9 /source | |
parent | 59180ff15373b4d21b4d1b677170f0fdf864b15d (diff) |
LibOverride: Add 'delete and use linked data' operation.
This will re-link all usages of a library override data-block
(including all of its override dependencies) to its reference linked
IDs, and delete those liboverrides.
As usual, it is available in the ID sub-menu of the outliner context
right-click menu.
Part of T76555.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_lib_override.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.c | 44 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_tools.c | 53 |
3 files changed, 98 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h index 7b10ed4d43c..9a5700d2fbd 100644 --- a/source/blender/blenkernel/BKE_lib_override.h +++ b/source/blender/blenkernel/BKE_lib_override.h @@ -81,6 +81,7 @@ bool BKE_lib_override_library_resync(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, struct ID *id_root); +void BKE_lib_override_library_delete(struct Main *bmain, struct ID *id_root); struct IDOverrideLibraryProperty *BKE_lib_override_library_property_find( struct IDOverrideLibrary *override, const char *rna_path); diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index b4f0905f042..cca312270bc 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -784,6 +784,50 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_ return success; } +/** + * Advanced 'smart' function to delete library overrides (including their existing override + * hierarchy) and remap their usages to their linked reference IDs. + * + * \note All IDs tagged with `LIB_TAG_DOIT` will be deleted. + * + * \param id_root The root liboverride ID to resync from. + */ +void BKE_lib_override_library_delete(Main *bmain, ID *id_root) +{ + BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root)); + + /* Tag all collections and objects, as well as other IDs using them. */ + id_root->tag |= LIB_TAG_DOIT; + + /* Make a mapping 'linked reference IDs' -> 'Local override IDs' of existing overrides, and tag + * linked reference ones to be overridden again. */ + BKE_lib_override_library_override_group_tag(bmain, id_root, LIB_TAG_DOIT, true); + + ID *id; + FOREACH_MAIN_ID_BEGIN (bmain, id) { + if (id->tag & LIB_TAG_DOIT) { + if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) { + ID *id_override_reference = id->override_library->reference; + + /* Remap the whole local IDs to use the linked data. */ + BKE_libblock_remap(bmain, id, id_override_reference, ID_REMAP_SKIP_INDIRECT_USAGE); + } + } + } + FOREACH_MAIN_ID_END; + + /* Delete the override IDs. */ + FOREACH_MAIN_ID_BEGIN (bmain, id) { + if (id->tag & LIB_TAG_DOIT) { + BKE_id_delete(bmain, id); + } + } + FOREACH_MAIN_ID_END; + + /* Should not actually be needed here... */ + BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); +} + BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_runtime_ensure( IDOverrideLibrary *override) { diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 4eed824207e..b2106698054 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -860,6 +860,38 @@ static void id_override_library_resync_fn(bContext *C, } } +static void id_override_library_delete_fn(bContext *C, + ReportList *UNUSED(reports), + Scene *UNUSED(scene), + TreeElement *te, + TreeStoreElem *UNUSED(tsep), + TreeStoreElem *tselem, + void *UNUSED(user_data)) +{ + BLI_assert(TSE_IS_REAL_ID(tselem)); + ID *id_root = tselem->id; + + if (ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) { + Main *bmain = CTX_data_main(C); + + id_root->tag |= LIB_TAG_DOIT; + + /* Tag all linked parents in tree hierarchy to be also overridden. */ + while ((te = te->parent) != NULL) { + if (!TSE_IS_REAL_ID(te->store_elem)) { + continue; + } + if (!ID_IS_OVERRIDE_LIBRARY_REAL(te->store_elem->id)) { + break; + } + te->store_elem->id->tag |= LIB_TAG_DOIT; + } + BKE_lib_override_library_delete(bmain, id_root); + + BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); + } +} + static void id_fake_user_set_fn(bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *UNUSED(scene), @@ -1641,6 +1673,7 @@ typedef enum eOutlinerIdOpTypes { OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET, OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY, OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY, + OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY, OUTLINER_IDOP_SINGLE, OUTLINER_IDOP_DELETE, OUTLINER_IDOP_REMAP, @@ -1693,6 +1726,12 @@ static const EnumPropertyItem prop_id_op_types[] = { "Resync Library Override Hierarchy", "Rebuild this local override from its linked reference, as well as its hierarchy of " "dependencies"}, + {OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY, + "OVERRIDE_LIBRARY_DELETE_HIERARCHY", + 0, + "Delete Library Override Hierarchy", + "Delete this local override (including its hierarchy of override dependencies) and relink " + "its usages to the linked data-blocks"}, {0, "", 0, NULL, NULL}, {OUTLINER_IDOP_COPY, "COPY", ICON_COPYDOWN, "Copy", ""}, {OUTLINER_IDOP_PASTE, "PASTE", ICON_PASTEDOWN, "Paste", ""}, @@ -1725,6 +1764,8 @@ static bool outliner_id_operation_item_poll(bContext *C, return true; case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY: return true; + case OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY: + return true; case OUTLINER_IDOP_SINGLE: if (!space_outliner || ELEM(space_outliner->outlinevis, SO_SCENES, SO_VIEW_LAYER)) { return true; @@ -1919,6 +1960,18 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) ED_undo_push(C, "Resync Overridden Data Hierarchy"); break; } + case OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY: { + /* make local */ + outliner_do_libdata_operation(C, + op->reports, + scene, + space_outliner, + &space_outliner->tree, + id_override_library_delete_fn, + &(OutlinerLibOverrideData){.do_hierarchy = true}); + ED_undo_push(C, "Delete Overridden Data Hierarchy"); + break; + } case OUTLINER_IDOP_SINGLE: { /* make single user */ switch (idlevel) { |