Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/collection.c')
-rw-r--r--source/blender/blenkernel/intern/collection.c64
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;
}