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:
-rw-r--r--source/blender/blenkernel/BKE_collection.h4
-rw-r--r--source/blender/blenkernel/intern/collection.c49
-rw-r--r--source/blender/blenkernel/intern/lib_remap.c15
3 files changed, 43 insertions, 25 deletions
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index 3412be92a3a..7963d54126e 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -112,7 +112,9 @@ bool BKE_scene_collections_object_remove(struct Main *bmain,
struct Object *object,
const bool free_us);
void BKE_collections_object_remove_nulls(struct Main *bmain);
-void BKE_collections_child_remove_nulls(struct Main *bmain, struct Collection *old_collection);
+void BKE_collections_child_remove_nulls(struct Main *bmain,
+ struct Collection *parent_collection,
+ struct Collection *child_collection);
/* Dependencies. */
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 89bb7b36406..b29dd007c51 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -1302,41 +1302,50 @@ static void collection_missing_parents_remove(Collection *collection)
*
* \note caller must ensure #BKE_main_collection_sync_remap() is called afterwards!
*
- * \param collection: may be \a NULL,
+ * \param parent_collection: The collection owning the pointers that were remapped. May be \a NULL,
+ * in which case whole \a bmain database of collections is checked.
+ * \param child_collection: The collection that was remapped to another pointer. May be \a NULL,
* in which case whole \a bmain database of collections is checked.
*/
-void BKE_collections_child_remove_nulls(Main *bmain, Collection *collection)
-{
- 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->collections.first; collection != NULL;
- collection = collection->id.next) {
- collection_null_children_remove(collection);
- }
- for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
- collection_null_children_remove(scene->master_collection);
+void BKE_collections_child_remove_nulls(Main *bmain,
+ Collection *parent_collection,
+ Collection *child_collection)
+{
+ if (child_collection == NULL) {
+ if (parent_collection != NULL) {
+ collection_null_children_remove(parent_collection);
+ }
+ else {
+ /* 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 (child_collection = bmain->collections.first; child_collection != NULL;
+ child_collection = child_collection->id.next) {
+ collection_null_children_remove(child_collection);
+ }
+ for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
+ collection_null_children_remove(scene->master_collection);
+ }
}
- for (collection = bmain->collections.first; collection != NULL;
- collection = collection->id.next) {
- collection_missing_parents_remove(collection);
+ for (child_collection = bmain->collections.first; child_collection != NULL;
+ child_collection = child_collection->id.next) {
+ collection_missing_parents_remove(child_collection);
}
for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
collection_missing_parents_remove(scene->master_collection);
}
}
else {
- for (CollectionParent *parent = collection->parents.first, *parent_next; parent;
+ for (CollectionParent *parent = child_collection->parents.first, *parent_next; parent;
parent = parent_next) {
parent_next = parent->next;
collection_null_children_remove(parent->collection);
- if (!collection_find_child(parent->collection, collection)) {
- BLI_freelinkN(&collection->parents, parent);
+ if (!collection_find_child(parent->collection, child_collection)) {
+ BLI_freelinkN(&child_collection->parents, parent);
}
}
}
diff --git a/source/blender/blenkernel/intern/lib_remap.c b/source/blender/blenkernel/intern/lib_remap.c
index 1f597bbb9a6..b32b97dc250 100644
--- a/source/blender/blenkernel/intern/lib_remap.c
+++ b/source/blender/blenkernel/intern/lib_remap.c
@@ -303,6 +303,7 @@ static void libblock_remap_data_postprocess_object_update(Main *bmain,
/* Can be called with both old_collection and new_collection being NULL,
* this means we have to check whole Main database then. */
static void libblock_remap_data_postprocess_collection_update(Main *bmain,
+ Collection *owner_collection,
Collection *UNUSED(old_collection),
Collection *new_collection)
{
@@ -311,7 +312,7 @@ static void libblock_remap_data_postprocess_collection_update(Main *bmain,
* and BKE_main_collection_sync_remap() does not tolerate any of those, so for now always check
* whole existing collections for NULL pointers.
* I'd consider optimizing that whole collection remapping process a TODO for later. */
- BKE_collections_child_remove_nulls(bmain, NULL /*old_collection*/);
+ BKE_collections_child_remove_nulls(bmain, owner_collection, NULL /*old_collection*/);
}
else {
/* Temp safe fix, but a "tad" brute force... We should probably be able to use parents from
@@ -523,7 +524,7 @@ void BKE_libblock_remap_locked(Main *bmain, void *old_idv, void *new_idv, const
break;
case ID_GR:
libblock_remap_data_postprocess_collection_update(
- bmain, (Collection *)old_id, (Collection *)new_id);
+ bmain, NULL, (Collection *)old_id, (Collection *)new_id);
break;
case ID_ME:
case ID_CU:
@@ -628,6 +629,12 @@ void BKE_libblock_relink_ex(
switch (GS(id->name)) {
case ID_SCE:
case ID_GR: {
+ /* Note: here we know which collection we have affected, so at lest for NULL children
+ * detection we can only process that one.
+ * This is also a required fix in case `id` would not be in Main anymore, which can happen
+ * e.g. when called from `id_delete`. */
+ Collection *owner_collection = (GS(id->name) == ID_GR) ? (Collection *)id :
+ ((Scene *)id)->master_collection;
if (old_id) {
switch (GS(old_id->name)) {
case ID_OB:
@@ -636,7 +643,7 @@ void BKE_libblock_relink_ex(
break;
case ID_GR:
libblock_remap_data_postprocess_collection_update(
- bmain, (Collection *)old_id, (Collection *)new_id);
+ bmain, owner_collection, (Collection *)old_id, (Collection *)new_id);
break;
default:
break;
@@ -644,7 +651,7 @@ void BKE_libblock_relink_ex(
}
else {
/* No choice but to check whole objects/collections. */
- libblock_remap_data_postprocess_collection_update(bmain, NULL, NULL);
+ libblock_remap_data_postprocess_collection_update(bmain, owner_collection, NULL, NULL);
libblock_remap_data_postprocess_object_update(bmain, NULL, NULL);
}
break;