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
path: root/source
diff options
context:
space:
mode:
authorBastien Montagne <bastien@blender.org>2022-01-25 18:42:31 +0300
committerBastien Montagne <bastien@blender.org>2022-01-25 18:44:55 +0300
commit96667e33913e37e257ae444009c5f7bea57b0d72 (patch)
tree848e321c44e3e0ea2f6de1af14d3aa01c9dc0771 /source
parent6c25aabddfb484980e87e2b1cb07e31350c61796 (diff)
Fix T93058: Crash on opening old pre-2.80 .blend files.
Layer resync code would not yet fully properly deal with all possible invalid status of ViewLayer comming from those older files. Now put 2.80-doversion specific fixes into their own dedicated function, so that they do not affect actual regular layer resync code anymore. Also added some sanity-checks in main `BKE_layer_collection_sync` code.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_layer.h7
-rw-r--r--source/blender/blenkernel/intern/layer.c44
-rw-r--r--source/blender/blenloader/intern/versioning_280.c2
3 files changed, 41 insertions, 12 deletions
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index bc2249b93b9..6460dedb736 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -157,6 +157,13 @@ int BKE_layer_collection_findindex(struct ViewLayer *view_layer, const struct La
void BKE_layer_collection_resync_forbid(void);
void BKE_layer_collection_resync_allow(void);
+/** Helper to fix older pre-2.80 blendfiles.
+ *
+ * Ensures the given `view_layer` as a valid first-level layer collection, i.e. a single one
+ * matching the scene's master collection. This is a requirement for `BKE_layer_collection_sync`.
+ */
+void BKE_layer_collection_doversion_2_80(const struct Scene *scene, struct ViewLayer *view_layer);
+
void BKE_main_collection_sync(const struct Main *bmain);
void BKE_scene_collection_sync(const struct Scene *scene);
/**
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 9e3cea40fb8..a59dd6f2e0e 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -1196,6 +1196,23 @@ static bool view_layer_objects_base_cache_validate(ViewLayer *UNUSED(view_layer)
}
#endif
+void BKE_layer_collection_doversion_2_80(const Scene *scene, ViewLayer *view_layer)
+{
+ LayerCollection *first_layer_collection = view_layer->layer_collections.first;
+ if (BLI_listbase_count_at_most(&view_layer->layer_collections, 2) > 1 ||
+ first_layer_collection->collection != scene->master_collection) {
+ /* In some cases (from older files) we do have a master collection, but no matching layer,
+ * instead all the children of the master collection have their layer collections in the
+ * viewlayer's list. This is not a valid situation, add a layer for the master collection and
+ * add all existing first-level layers as children of that new master layer. */
+ ListBase layer_collections = view_layer->layer_collections;
+ BLI_listbase_clear(&view_layer->layer_collections);
+ LayerCollection *master_layer_collection = layer_collection_add(&view_layer->layer_collections,
+ scene->master_collection);
+ master_layer_collection->layer_collections = layer_collections;
+ }
+}
+
void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
{
if (no_resync) {
@@ -1208,21 +1225,24 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
}
if (BLI_listbase_is_empty(&view_layer->layer_collections)) {
- /* In some cases (from older files) we do have a master collection, yet no matching layer.
- * Create the master one here, so that the rest of the code can work as expected. */
+ /* In some cases (from older files, or when creating a new ViewLayer from
+ * #BKE_view_layer_add), we do have a master collection, yet no matching layer. Create the
+ * master one here, so that the rest of the code can work as expected. */
layer_collection_add(&view_layer->layer_collections, scene->master_collection);
}
- else if (BLI_listbase_count_at_most(&view_layer->layer_collections, 2) > 1) {
- /* In some cases (from older files) we do have a master collection, but no matching layer,
- * instead all the children of the master collection have their layer collections in the
- * viewlayer's list. This is not a valid situation, add a layer for the master collection and
- * add all existing first-level layers as children of that new master layer. */
- ListBase layer_collections = view_layer->layer_collections;
- BLI_listbase_clear(&view_layer->layer_collections);
- LayerCollection *master_layer_collection = layer_collection_add(&view_layer->layer_collections,
- scene->master_collection);
- master_layer_collection->layer_collections = layer_collections;
+
+#ifndef NDEBUG
+ {
+ BLI_assert_msg(BLI_listbase_count_at_most(&view_layer->layer_collections, 2) == 1,
+ "ViewLayer's first level of children layer collections should always have "
+ "exactly one item");
+
+ LayerCollection *first_layer_collection = view_layer->layer_collections.first;
+ BLI_assert_msg(first_layer_collection->collection == scene->master_collection,
+ "ViewLayer's first layer collection should always be the one for the scene's "
+ "master collection");
}
+#endif
/* Free cache. */
MEM_SAFE_FREE(view_layer->object_bases_array);
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index d9052c6b1f7..ceddc451a46 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -402,6 +402,8 @@ static void do_version_scene_collection_to_collection(Main *bmain, Scene *scene)
do_version_layer_collection_pre(
view_layer, &view_layer->layer_collections, enabled_set, selectable_set);
+ BKE_layer_collection_doversion_2_80(scene, view_layer);
+
BKE_layer_collection_sync(scene, view_layer);
do_version_layer_collection_post(