[Bf-blender-cvs] [f887dc1f5c8] blender2.8: Fix T57372: Second full scene copy crashes on deletion.
Bastien Montagne
noreply at git.blender.org
Mon Oct 29 11:43:38 CET 2018
Commit: f887dc1f5c8414f3a5ad6927730a3a74684ddf26
Author: Bastien Montagne
Date: Mon Oct 29 11:42:38 2018 +0100
Branches: blender2.8
https://developer.blender.org/rBf887dc1f5c8414f3a5ad6927730a3a74684ddf26
Fix T57372: Second full scene copy crashes on deletion.
Hope this time we are done for good (root of the issue was that master
collections are not in bmain...).
===================================================================
M source/blender/blenkernel/intern/collection.c
M source/blender/blenkernel/intern/library_remap.c
===================================================================
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index e6546d4454d..c85632b423b 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -650,28 +650,67 @@ void BKE_collections_object_remove_nulls(Main *bmain)
}
}
-/*
- * Remove all NULL children from parent objects of changed old_collection.
+static void collection_null_children_remove(Collection *collection)
+{
+ for (CollectionChild *child = collection->children.first, *child_next = NULL; child; child = child_next) {
+ child_next = child->next;
+
+ if (child->collection == NULL) {
+ BLI_freelinkN(&collection->children, child);
+ }
+ }
+}
+
+static void collection_missing_parents_remove(Collection *collection)
+{
+ for (CollectionParent *parent = collection->parents.first, *parent_next; parent != NULL; parent = parent_next) {
+ parent_next = parent->next;
+
+ if (!collection_find_child(parent->collection, collection)) {
+ BLI_freelinkN(&collection->parents, parent);
+ }
+ }
+}
+
+/**
+ * Remove all NULL children from parent collections of changed \a collection.
* This is used for library remapping, where these pointers have been set to NULL.
* Otherwise this should never happen.
- * Note: caller must ensure BKE_main_collection_sync_remap() is called afterwards!
+ *
+ * \note caller must ensure BKE_main_collection_sync_remap() is called afterwards!
+ *
+ * \param collection may be \a NULL, in which case whole \a bmain database of collections is checked.
*/
-void BKE_collections_child_remove_nulls(Main *bmain, Collection *old_collection)
+void BKE_collections_child_remove_nulls(Main *bmain, Collection *collection)
{
- for (CollectionParent *cparent = old_collection->parents.first, *cnext; cparent; cparent = cnext) {
- Collection *parent = cparent->collection;
- cnext = cparent->next;
-
- for (CollectionChild *child = parent->children.first, *child_next = NULL; child; child = child_next) {
- child_next = child->next;
+ if (collection == NULL) {
+ /* We need to do the checks in two steps when more than one collection may be involved,
+ * otherwise we can miss some cases...
+ * Also, master collections are not in bmain, so we also need to loop over scenes.
+ */
+ for (collection = bmain->collection.first; collection != NULL; collection = collection->id.next) {
+ collection_null_children_remove(collection);
+ }
+ for (Scene *scene = bmain->scene.first; scene != NULL; scene = scene->id.next) {
+ collection_null_children_remove(BKE_collection_master(scene));
+ }
- if (child->collection == NULL) {
- BLI_freelinkN(&parent->children, child);
- }
+ for (collection = bmain->collection.first; collection != NULL; collection = collection->id.next) {
+ collection_missing_parents_remove(collection);
+ }
+ for (Scene *scene = bmain->scene.first; scene != NULL; scene = scene->id.next) {
+ collection_missing_parents_remove(BKE_collection_master(scene));
}
+ }
+ else {
+ for (CollectionParent *parent = collection->parents.first, *parent_next; parent; parent = parent_next) {
+ parent_next = parent->next;
+
+ collection_null_children_remove(parent->collection);
- if (!collection_find_child(parent, old_collection)) {
- BLI_freelinkN(&old_collection->parents, cparent);
+ if (!collection_find_child(parent->collection, collection)) {
+ BLI_freelinkN(&collection->parents, parent);
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c
index 114159debe3..8a011b55cf3 100644
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@ -326,17 +326,7 @@ static void libblock_remap_data_postprocess_collection_update(
Main *bmain, Collection *old_collection, Collection *new_collection)
{
if (new_collection == NULL) {
- /* In case we unlinked old_collection (new_collection is NULL), we need
- * to remove any collection children that have been set to NULL in the
- * because of pointer replacement. */
- if (old_collection != NULL) {
- BKE_collections_child_remove_nulls(bmain, old_collection);
- }
- else {
- for (Collection *collection = bmain->collection.first; collection; collection = collection->id.next) {
- BKE_collections_child_remove_nulls(bmain, collection);
- }
- }
+ BKE_collections_child_remove_nulls(bmain, old_collection);
}
BKE_main_collection_sync_remap(bmain);
More information about the Bf-blender-cvs
mailing list