[Bf-blender-cvs] [a0957ceab26] master: Fix T97069: Null collection object during layercollection resync when relinking.

Bastien Montagne noreply at git.blender.org
Tue Apr 12 18:48:44 CEST 2022


Commit: a0957ceab2635676b057b69d0a241fe895005466
Author: Bastien Montagne
Date:   Tue Apr 12 18:16:46 2022 +0200
Branches: master
https://developer.blender.org/rBa0957ceab2635676b057b69d0a241fe895005466

Fix T97069: Null collection object during layercollection resync when relinking.

We better handle NULL object pointers before doing layer collections
resync, otherwise said resync process has to deal with those NULL
pointers. By the look of it this mistake has been there since the origin
of the remapping/relinking code.

Also for safety (and optimization), do not perform layer collection
resync from `libblock_remap_data_postprocess_object_update` when
`libblock_remap_data_postprocess_collection_update` is called
immediately afterwards.

Also added same 'skip on NULL collection object pointer' check to
`layer_collection_local_sync` as the one in
`layer_collection_objects_sync`, since it's fairly hard to always
guaranty there is no such NULL pointer when calling that code.

===================================================================

M	source/blender/blenkernel/intern/layer.c
M	source/blender/blenkernel/intern/lib_remap.c

===================================================================

diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 1cc1839d2d0..f0ccd305690 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -1658,7 +1658,10 @@ static void layer_collection_local_sync(ViewLayer *view_layer,
 
   if (visible) {
     LISTBASE_FOREACH (CollectionObject *, cob, &layer_collection->collection->gobject) {
-      BLI_assert(cob->ob);
+      if (cob->ob == NULL) {
+        continue;
+      }
+
       Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
       base->local_collections_bits |= local_collections_uuid;
     }
diff --git a/source/blender/blenkernel/intern/lib_remap.c b/source/blender/blenkernel/intern/lib_remap.c
index 1a6fcf5ff43..2b449ad50bb 100644
--- a/source/blender/blenkernel/intern/lib_remap.c
+++ b/source/blender/blenkernel/intern/lib_remap.c
@@ -317,7 +317,8 @@ static void libblock_remap_data_preprocess(ID *id_owner,
  */
 static void libblock_remap_data_postprocess_object_update(Main *bmain,
                                                           Object *old_ob,
-                                                          Object *new_ob)
+                                                          Object *new_ob,
+                                                          const bool do_sync_collection)
 {
   if (new_ob == NULL) {
     /* In case we unlinked old_ob (new_ob is NULL), the object has already
@@ -331,7 +332,9 @@ static void libblock_remap_data_postprocess_object_update(Main *bmain,
     BKE_collections_object_remove_duplicates(bmain);
   }
 
-  BKE_main_collection_sync_remap(bmain);
+  if (do_sync_collection) {
+    BKE_main_collection_sync_remap(bmain);
+  }
 
   if (old_ob == NULL) {
     for (Object *ob = bmain->objects.first; ob != NULL; ob = ob->id.next) {
@@ -567,7 +570,8 @@ static void libblock_remap_foreach_idpair_cb(ID *old_id, ID *new_id, void *user_
    * Maybe we should do a per-ID callback for this instead? */
   switch (GS(old_id->name)) {
     case ID_OB:
-      libblock_remap_data_postprocess_object_update(bmain, (Object *)old_id, (Object *)new_id);
+      libblock_remap_data_postprocess_object_update(
+          bmain, (Object *)old_id, (Object *)new_id, true);
       break;
     case ID_GR:
       libblock_remap_data_postprocess_collection_update(
@@ -719,7 +723,7 @@ static void libblock_relink_foreach_idpair_cb(ID *old_id, ID *new_id, void *user
           case ID_OB:
             if (!is_object_update_processed) {
               libblock_remap_data_postprocess_object_update(
-                  bmain, (Object *)old_id, (Object *)new_id);
+                  bmain, (Object *)old_id, (Object *)new_id, true);
               is_object_update_processed = true;
             }
             break;
@@ -781,11 +785,14 @@ void BKE_libblock_relink_multiple(Main *bmain,
                                                (Collection *)id_iter :
                                                ((Scene *)id_iter)->master_collection;
             /* No choice but to check whole objects once, and all children collections. */
-            libblock_remap_data_postprocess_collection_update(bmain, owner_collection, NULL, NULL);
             if (!is_object_update_processed) {
-              libblock_remap_data_postprocess_object_update(bmain, NULL, NULL);
+              /* We only want to affect Object pointers here, not Collection ones, LayerCollections
+               * will be resynced as part of the call to
+               * `libblock_remap_data_postprocess_collection_update` below. */
+              libblock_remap_data_postprocess_object_update(bmain, NULL, NULL, false);
               is_object_update_processed = true;
             }
+            libblock_remap_data_postprocess_collection_update(bmain, owner_collection, NULL, NULL);
             break;
           }
           default:



More information about the Bf-blender-cvs mailing list