diff options
Diffstat (limited to 'source/blender/blenkernel/intern/collection.c')
-rw-r--r-- | source/blender/blenkernel/intern/collection.c | 64 |
1 files changed, 46 insertions, 18 deletions
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index b71bcef229a..2a544871716 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -7,6 +7,8 @@ /* Allow using deprecated functionality for .blend file I/O. */ #define DNA_DEPRECATED_ALLOW +#include "CLG_log.h" + #include <string.h> #include "BLI_blenlib.h" @@ -46,6 +48,8 @@ #include "BLO_read_write.h" +static CLG_LogRef LOG = {"bke.collection"}; + /* -------------------------------------------------------------------- */ /** \name Prototypes * \{ */ @@ -143,6 +147,9 @@ static void collection_foreach_id(ID *id, LibraryForeachIDData *data) { Collection *collection = (Collection *)id; + BKE_LIB_FOREACHID_PROCESS_ID( + data, collection->owner_id, IDWALK_CB_LOOPBACK | IDWALK_CB_NEVER_SELF); + LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) { BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, cob->ob, IDWALK_CB_USER); } @@ -162,7 +169,7 @@ static void collection_foreach_id(ID *id, LibraryForeachIDData *data) } } -static ID *collection_owner_get(Main *bmain, ID *id) +static ID *collection_owner_get(ID *id) { if ((id->flag & LIB_EMBEDDED_DATA) == 0) { return id; @@ -171,15 +178,11 @@ static ID *collection_owner_get(Main *bmain, ID *id) Collection *master_collection = (Collection *)id; BLI_assert((master_collection->flag & COLLECTION_IS_MASTER) != 0); + BLI_assert(master_collection->owner_id != NULL); + BLI_assert(GS(master_collection->owner_id->name) == ID_SCE); + BLI_assert(((Scene *)master_collection->owner_id)->master_collection == master_collection); - LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { - if (scene->master_collection == master_collection) { - return &scene->id; - } - } - - BLI_assert_msg(0, "Embedded collection with no owner. Critical Main inconsistency."); - return NULL; + return master_collection->owner_id; } void BKE_collection_blend_write_nolib(BlendWriter *writer, Collection *collection) @@ -228,8 +231,28 @@ void BKE_collection_compat_blend_read_data(BlendDataReader *reader, SceneCollect } #endif -void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collection) -{ +void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collection, ID *owner_id) +{ + /* Special case for this pointer, do not rely on regular `lib_link` process here. Avoids needs + * for do_versioning, and ensures coherence of data in any case. */ + BLI_assert((collection->id.flag & LIB_EMBEDDED_DATA) != 0 || owner_id == NULL); + BLI_assert(owner_id == NULL || owner_id->lib == collection->id.lib); + if (owner_id != NULL && (collection->id.flag & LIB_EMBEDDED_DATA) == 0) { + /* This is unfortunate, but currently a lot of existing files (including startup ones) have + * missing `LIB_EMBEDDED_DATA` flag. + * + * NOTE: Using do_version is not a solution here, since this code will be called before any + * do_version takes place. Keeping it here also ensures future (or unknown existing) similar + * bugs won't go easily unnoticed. */ + CLOG_WARN(&LOG, + "Fixing root node tree '%s' owned by '%s' missing EMBEDDED tag, please consider " + "re-saving your (startup) file", + collection->id.name, + owner_id->name); + collection->id.flag |= LIB_EMBEDDED_DATA; + } + collection->owner_id = owner_id; + BLO_read_list(reader, &collection->gobject); BLO_read_list(reader, &collection->children); @@ -260,7 +283,7 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect static void collection_blend_read_data(BlendDataReader *reader, ID *id) { Collection *collection = (Collection *)id; - BKE_collection_blend_read_data(reader, collection); + BKE_collection_blend_read_data(reader, collection, NULL); } static void lib_link_collection_data(BlendLibReader *reader, Library *lib, Collection *collection) @@ -461,8 +484,8 @@ void BKE_collection_add_from_collection(Main *bmain, is_instantiated = true; } else if (!is_instantiated && collection_find_child(collection, collection_dst)) { - /* If given collection_dst is already instantiated in scene, even if its 'model' src one is - * not, do not add it to master scene collection. */ + /* If given collection_dst is already instantiated in scene, even if its 'model' + * collection_src one is not, do not add it to master scene collection. */ is_instantiated = true; } } @@ -710,10 +733,11 @@ void BKE_collection_new_name_get(Collection *collection_parent, char *rname) char *name; if (!collection_parent) { - name = BLI_strdup("Collection"); + name = BLI_strdup(DATA_("Collection")); } else if (collection_parent->flag & COLLECTION_IS_MASTER) { - name = BLI_sprintfN("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; @@ -834,7 +858,7 @@ Base *BKE_collection_or_layer_objects(const ViewLayer *view_layer, Collection *c return BKE_collection_object_cache_get(collection).first; } - return FIRSTBASE(view_layer); + return view_layer->object_bases.first; } /** \} */ @@ -843,14 +867,18 @@ Base *BKE_collection_or_layer_objects(const ViewLayer *view_layer, Collection *c /** \name Scene Master Collection * \{ */ -Collection *BKE_collection_master_add() +Collection *BKE_collection_master_add(Scene *scene) { + BLI_assert(scene != NULL && scene->master_collection == NULL); + /* Not an actual datablock, but owned by scene. */ Collection *master_collection = BKE_libblock_alloc( NULL, ID_GR, BKE_SCENE_COLLECTION_NAME, LIB_ID_CREATE_NO_MAIN); master_collection->id.flag |= LIB_EMBEDDED_DATA; + master_collection->owner_id = &scene->id; master_collection->flag |= COLLECTION_IS_MASTER; master_collection->color_tag = COLLECTION_COLOR_NONE; + return master_collection; } |