diff options
-rw-r--r-- | source/blender/blenkernel/BKE_idtype.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_lib_override.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/collection.c | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.cc | 26 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lib_query.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.cc | 9 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_templates.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_collections.cc | 4 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_path.cc | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 2 |
11 files changed, 46 insertions, 21 deletions
diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h index 30f7ed45859..04ea94cbfb4 100644 --- a/source/blender/blenkernel/BKE_idtype.h +++ b/source/blender/blenkernel/BKE_idtype.h @@ -85,7 +85,11 @@ typedef void (*IDTypeForeachCacheFunction)(struct ID *id, typedef void (*IDTypeForeachPathFunction)(struct ID *id, struct BPathForeachPathData *bpath_data); -typedef struct ID *(*IDTypeEmbeddedOwnerGetFunction)(struct Main *bmain, struct ID *id); +/** \param owner_id_hint: If non-NULL, a potential owner of the given embedded ID. Can speed up + * look-up of the owner ID in some cases. */ +typedef struct ID *(*IDTypeEmbeddedOwnerGetFunction)(struct Main *bmain, + struct ID *id, + struct ID *owner_id_hint); typedef void (*IDTypeBlendWriteFunction)(struct BlendWriter *writer, struct ID *id, diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h index 9ad5a32e6f0..38469fd1b8e 100644 --- a/source/blender/blenkernel/BKE_lib_override.h +++ b/source/blender/blenkernel/BKE_lib_override.h @@ -66,10 +66,12 @@ void BKE_lib_override_library_free(struct IDOverrideLibrary **override, bool do_ * \note This is especially useful when `id` is a non-real override (e.g. embedded ID like a master * collection or root node tree, or a shape key). * + * \param owner_id_hint If not NULL, a potential owner for the given override-embedded `id`. * \param r_owner_id If given, will be set with the actual ID owning the return liboverride data. */ IDOverrideLibrary *BKE_lib_override_library_get(struct Main *bmain, struct ID *id, + struct ID *owner_id_hint, struct ID **r_owner_id); /** diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 09085fa8ffb..4967e3482c6 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -162,7 +162,7 @@ static void collection_foreach_id(ID *id, LibraryForeachIDData *data) } } -static ID *collection_owner_get(Main *bmain, ID *id) +static ID *collection_owner_get(Main *bmain, ID *id, ID *owner_id_hint) { if ((id->flag & LIB_EMBEDDED_DATA) == 0) { return id; @@ -172,6 +172,11 @@ static ID *collection_owner_get(Main *bmain, ID *id) Collection *master_collection = (Collection *)id; BLI_assert((master_collection->flag & COLLECTION_IS_MASTER) != 0); + if (owner_id_hint != NULL && GS(owner_id_hint->name) == ID_SCE && + ((Scene *)owner_id_hint)->master_collection == master_collection) { + return owner_id_hint; + } + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { if (scene->master_collection == master_collection) { return &scene->id; @@ -713,7 +718,8 @@ void BKE_collection_new_name_get(Collection *collection_parent, char *rname) name = BLI_strdup(DATA_("Collection")); } else if (collection_parent->flag & COLLECTION_IS_MASTER) { - name = BLI_sprintfN(DATA_("Collection %d"), BLI_listbase_count(&collection_parent->children) + 1); + name = BLI_sprintfN(DATA_("Collection %d"), + BLI_listbase_count(&collection_parent->children) + 1); } else { const int number = BLI_listbase_count(&collection_parent->children) + 1; diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 07ce4e46e9b..461a6f15ca1 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -91,7 +91,7 @@ static void shapekey_foreach_id(ID *id, LibraryForeachIDData *data) BKE_LIB_FOREACHID_PROCESS_ID(data, key->from, IDWALK_CB_LOOPBACK); } -static ID *shapekey_owner_get(Main *UNUSED(bmain), ID *id) +static ID *shapekey_owner_get(Main *UNUSED(bmain), ID *id, ID *UNUSED(owner_id_hint)) { return ((Key *)id)->from; } diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index 758a317e415..05a00fb54fd 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -94,6 +94,7 @@ BLI_INLINE void lib_override_object_posemode_transfer(ID *id_dst, ID *id_src) /** Get override data for a given ID. Needed because of our beloved shape keys snowflake. */ BLI_INLINE const IDOverrideLibrary *BKE_lib_override_library_get(const Main *bmain, const ID *id, + const ID *owner_id_hint, const ID **r_owner_id) { if (r_owner_id != nullptr) { @@ -104,7 +105,8 @@ BLI_INLINE const IDOverrideLibrary *BKE_lib_override_library_get(const Main *bma if (id_type->owner_get != nullptr) { /* The #IDTypeInfo::owner_get callback should not modify the arguments, so casting away const * is okay. */ - const ID *owner_id = id_type->owner_get(const_cast<Main *>(bmain), const_cast<ID *>(id)); + const ID *owner_id = id_type->owner_get( + const_cast<Main *>(bmain), const_cast<ID *>(id), const_cast<ID *>(owner_id_hint)); if (r_owner_id != nullptr) { *r_owner_id = owner_id; } @@ -115,13 +117,17 @@ BLI_INLINE const IDOverrideLibrary *BKE_lib_override_library_get(const Main *bma return id->override_library; } -IDOverrideLibrary *BKE_lib_override_library_get(Main *bmain, ID *id, ID **r_owner_id) +IDOverrideLibrary *BKE_lib_override_library_get(Main *bmain, + ID *id, + ID *owner_id_hint, + ID **r_owner_id) { /* Reuse the implementation of the const access function, which does not change the arguments. * Add const explicitly to make it clear to the compiler to avoid just calling this function. */ return const_cast<IDOverrideLibrary *>( BKE_lib_override_library_get(const_cast<const Main *>(bmain), const_cast<const ID *>(id), + const_cast<const ID *>(owner_id_hint), const_cast<const ID **>(r_owner_id))); } @@ -319,7 +325,7 @@ bool BKE_lib_override_library_is_system_defined(const Main *bmain, const ID *id) { if (ID_IS_OVERRIDE_LIBRARY(id)) { const ID *override_owner_id; - BKE_lib_override_library_get(bmain, id, &override_owner_id); + BKE_lib_override_library_get(bmain, id, nullptr, &override_owner_id); return (override_owner_id->override_library->flag & IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED) != 0; } @@ -1087,8 +1093,9 @@ static void lib_override_overrides_group_tag_recursive(LibOverrideGroupTagData * } const Library *reference_lib = - BKE_lib_override_library_get(bmain, id_owner, nullptr)->reference->lib; - const ID *to_id_reference = BKE_lib_override_library_get(bmain, to_id, nullptr)->reference; + BKE_lib_override_library_get(bmain, id_owner, nullptr, nullptr)->reference->lib; + const ID *to_id_reference = + BKE_lib_override_library_get(bmain, to_id, nullptr, nullptr)->reference; if (to_id_reference->lib != reference_lib) { /* We do not override data-blocks from other libraries, nor do we process them. */ continue; @@ -1439,7 +1446,7 @@ static ID *lib_override_root_find(Main *bmain, ID *id, const int curr_level, int BLI_assert(id->flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE); ID *id_owner; int best_level_placeholder = 0; - BKE_lib_override_library_get(bmain, id, &id_owner); + BKE_lib_override_library_get(bmain, id, nullptr, &id_owner); return lib_override_root_find(bmain, id_owner, curr_level + 1, &best_level_placeholder); } /* This way we won't process again that ID, should we encounter it again through another @@ -1478,7 +1485,7 @@ static ID *lib_override_root_find(Main *bmain, ID *id, const int curr_level, int BLI_assert(id->flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE); ID *id_owner; int best_level_placeholder = 0; - BKE_lib_override_library_get(bmain, best_root_id_candidate, &id_owner); + BKE_lib_override_library_get(bmain, best_root_id_candidate, nullptr, &id_owner); best_root_id_candidate = lib_override_root_find( bmain, id_owner, curr_level + 1, &best_level_placeholder); } @@ -1795,7 +1802,8 @@ static bool lib_override_library_resync(Main *bmain, /* While this should not happen in typical cases (and won't be properly supported here), * user is free to do all kind of very bad things, including having different local * overrides of a same linked ID in a same hierarchy. */ - IDOverrideLibrary *id_override_library = BKE_lib_override_library_get(bmain, id, nullptr); + IDOverrideLibrary *id_override_library = BKE_lib_override_library_get( + bmain, id, nullptr, nullptr); if (id_override_library->hierarchy_root != id_root->override_library->hierarchy_root) { continue; @@ -2177,7 +2185,7 @@ static ID *lib_override_library_main_resync_root_get(Main *bmain, ID *id) if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) { const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id); if (id_type->owner_get != nullptr) { - id = id_type->owner_get(bmain, id); + id = id_type->owner_get(bmain, id, nullptr); } BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id)); } diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c index a869bf4c4b0..6b9d2afe87a 100644 --- a/source/blender/blenkernel/intern/lib_query.c +++ b/source/blender/blenkernel/intern/lib_query.c @@ -713,7 +713,7 @@ static void lib_query_unused_ids_tag_recurse(Main *bmain, /* Directly 'by-pass' to actual real ID owner. */ const IDTypeInfo *type_info_from = BKE_idtype_get_info_from_id(id_from); BLI_assert(type_info_from->owner_get != NULL); - id_from = type_info_from->owner_get(bmain, id_from); + id_from = type_info_from->owner_get(bmain, id_from, NULL); } lib_query_unused_ids_tag_recurse( diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 86c05d6d085..d50b8662f82 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -404,7 +404,7 @@ static void node_foreach_path(ID *id, BPathForeachPathData *bpath_data) } } -static ID *node_owner_get(Main *bmain, ID *id) +static ID *node_owner_get(Main *bmain, ID *id, ID *owner_id_hint) { if ((id->flag & LIB_EMBEDDED_DATA) == 0) { return id; @@ -412,6 +412,12 @@ static ID *node_owner_get(Main *bmain, ID *id) /* TODO: Sort this NO_MAIN or not for embedded node trees. See T86119. */ // BLI_assert((id->tag & LIB_TAG_NO_MAIN) == 0); + bNodeTree *ntree = reinterpret_cast<bNodeTree *>(id); + + if (owner_id_hint != nullptr && ntreeFromID(owner_id_hint) == ntree) { + return owner_id_hint; + } + ListBase *lists[] = {&bmain->materials, &bmain->lights, &bmain->worlds, @@ -421,7 +427,6 @@ static ID *node_owner_get(Main *bmain, ID *id) &bmain->simulations, nullptr}; - bNodeTree *ntree = (bNodeTree *)id; for (int i = 0; lists[i] != nullptr; i++) { LISTBASE_FOREACH (ID *, id_iter, lists[i]) { if (ntreeFromID(id_iter) == ntree) { diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index ac6dcbea052..0f5cd463877 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -663,7 +663,7 @@ static void template_id_liboverride_hierarchy_create(bContext *C, * system override with reset. */ if (!ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY(id)) { if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) { - BKE_lib_override_library_get(bmain, id, &id); + BKE_lib_override_library_get(bmain, id, NULL, &id); } if (id->override_library->flag & IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED) { id->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED; diff --git a/source/blender/editors/space_outliner/outliner_collections.cc b/source/blender/editors/space_outliner/outliner_collections.cc index 8ca2ffe6a9c..b29d20f9f9c 100644 --- a/source/blender/editors/space_outliner/outliner_collections.cc +++ b/source/blender/editors/space_outliner/outliner_collections.cc @@ -364,7 +364,7 @@ void outliner_collection_delete( const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(&parent->id); BLI_assert(id_type->owner_get != nullptr); - ID *scene_owner = id_type->owner_get(bmain, &parent->id); + ID *scene_owner = id_type->owner_get(bmain, &parent->id, NULL); BLI_assert(GS(scene_owner->name) == ID_SCE); if (ID_IS_LINKED(scene_owner) || ID_IS_OVERRIDE_LIBRARY(scene_owner)) { skip = true; @@ -597,7 +597,7 @@ static int collection_duplicate_exec(bContext *C, wmOperator *op) const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(&parent->id); BLI_assert(id_type->owner_get != nullptr); - Scene *scene_owner = (Scene *)id_type->owner_get(bmain, &parent->id); + Scene *scene_owner = (Scene *)id_type->owner_get(bmain, &parent->id, NULL); BLI_assert(scene_owner != nullptr); BLI_assert(GS(scene_owner->id.name) == ID_SCE); diff --git a/source/blender/makesrna/intern/rna_path.cc b/source/blender/makesrna/intern/rna_path.cc index c1613e3927e..0997ad6ee2f 100644 --- a/source/blender/makesrna/intern/rna_path.cc +++ b/source/blender/makesrna/intern/rna_path.cc @@ -942,7 +942,7 @@ ID *RNA_find_real_ID_and_path(Main *bmain, ID *id, const char **r_path) BLI_assert_msg(0, "Missing handling of embedded id type."); return id; } - return id_type->owner_get(bmain, id); + return id_type->owner_get(bmain, id, nullptr); } static char *rna_prepend_real_ID_path(Main *bmain, ID *id, char *path, ID **r_real_id) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index f24aec3447b..8ed07a8dbf7 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1478,7 +1478,7 @@ static void rna_ImageFormatSettings_color_management_set(PointerRNA *ptr, int va if (owner_id && GS(owner_id->name) == ID_NT) { /* For compositing nodes, find the corresponding scene. */ const IDTypeInfo *type_info = BKE_idtype_get_info_from_id(owner_id); - owner_id = type_info->owner_get(G_MAIN, owner_id); + owner_id = type_info->owner_get(G_MAIN, owner_id, NULL); } if (owner_id && GS(owner_id->name) == ID_SCE) { BKE_image_format_color_management_copy_from_scene(imf, (Scene *)owner_id); |