[Bf-blender-cvs] [e92a7800b57] master: LibOverride: Fix several issues with resync code.

Bastien Montagne noreply at git.blender.org
Thu Apr 8 11:48:23 CEST 2021


Commit: e92a7800b57620df0a5d7619aead572667f27994
Author: Bastien Montagne
Date:   Thu Apr 8 11:27:05 2021 +0200
Branches: master
https://developer.blender.org/rBe92a7800b57620df0a5d7619aead572667f27994

LibOverride: Fix several issues with resync code.

This commit essentially touches to post-processing of collections and
objects after resync itself has been done, to ensure their proper
instantiation in the scene:

 - Remove a lot of the process in resync case (resynced data are assumed
   to be already instantiated in the scene, unlike override creation
   case).

 - For auto-resync, only do post-processing once after all overrides
   have been resynced (doing it after each individual resynced was
   causing a lot of instantiation glitches, with a lot of unwanted
   extra objects and collections being added to the master collection).

It also deals in a much more reliable way with detection of objects
missing from the scene, by using the new `BKE_scene_objects_as_gset`
utils.

As a bonus this makes auto-resync process slightly faster (only by a few
percents, but that's always good to get).

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

M	source/blender/blenkernel/BKE_lib_override.h
M	source/blender/blenkernel/intern/lib_override.c
M	source/blender/editors/space_outliner/outliner_tools.c

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

diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h
index 0750a3332a8..b9a478f8227 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -84,7 +84,8 @@ bool BKE_lib_override_library_resync(struct Main *bmain,
                                      struct ViewLayer *view_layer,
                                      struct ID *id_root,
                                      struct Collection *override_resync_residual_storage,
-                                     const bool do_hierarchy_enforce);
+                                     const bool do_hierarchy_enforce,
+                                     const bool do_post_process);
 void BKE_lib_override_library_main_resync(struct Main *bmain,
                                           struct Scene *scene,
                                           struct ViewLayer *view_layer);
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index 112c4c21a27..150b9ee8868 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -650,18 +650,6 @@ static bool lib_override_library_create_do(Main *bmain, ID *id_root)
   return BKE_lib_override_library_create_from_tag(bmain);
 }
 
-BLI_INLINE bool lib_override_library_create_post_process_object_is_instantiated(
-    ViewLayer *view_layer, Object *object, const bool is_resync)
-{
-  /* We cannot rely on check for object being actually instantiated in resync case, because often
-   * the overridden collection is 'excluded' from the current view-layer.
-   *
-   * Fallback to a basic user-count check then, this is weak (since it could lead to some object
-   * not being instantiated at all), but it should work fine in most common cases. */
-  return ((is_resync && ID_REAL_USERS(object) >= 1) ||
-          (!is_resync && BKE_view_layer_base_find(view_layer, object) != NULL));
-}
-
 static void lib_override_library_create_post_process(Main *bmain,
                                                      Scene *scene,
                                                      ViewLayer *view_layer,
@@ -672,13 +660,23 @@ static void lib_override_library_create_post_process(Main *bmain,
 {
   BKE_main_collection_sync(bmain);
 
-  if (id_root->newid != NULL) {
+  /* We create a set of all objects referenced into the scene by its hierarchy of collections.
+   * NOTE: This is different that the list of bases, since objects in excluded collections etc.
+   * won't have a base, but are still considered as instanced from our point of view. */
+  GSet *all_objects_in_scene = BKE_scene_objects_as_gset(scene, NULL);
+
+  /* Instantiating the root collection or object should never be needed in resync case, since the
+   * old override would be remapped to the new one. */
+  if (!is_resync && id_root != NULL && id_root->newid != NULL) {
     switch (GS(id_root->name)) {
       case ID_GR: {
         Object *ob_reference = id_reference != NULL && GS(id_reference->name) == ID_OB ?
                                    (Object *)id_reference :
                                    NULL;
         Collection *collection_new = ((Collection *)id_root->newid);
+        if (is_resync && BKE_collection_is_in_scene(collection_new)) {
+          break;
+        }
         if (ob_reference != NULL) {
           BKE_collection_add_from_object(bmain, scene, ob_reference, collection_new);
         }
@@ -692,52 +690,16 @@ static void lib_override_library_create_post_process(Main *bmain,
               bmain, scene, ((Collection *)id_root), collection_new);
         }
 
-        FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection_new, ob_new) {
-          if (ob_new != NULL && ob_new->id.override_library != NULL) {
-            if (ob_reference != NULL) {
-              Base *base = BKE_view_layer_base_find(view_layer, ob_new);
-              if (!lib_override_library_create_post_process_object_is_instantiated(
-                      view_layer, ob_new, is_resync)) {
-                BKE_collection_object_add_from(bmain, scene, ob_reference, ob_new);
-                base = BKE_view_layer_base_find(view_layer, ob_new);
-                DEG_id_tag_update_ex(
-                    bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
-                if (is_resync) {
-                  ob_new->id.flag |= LIB_LIB_OVERRIDE_RESYNC_LEFTOVER;
-                }
-              }
+        BLI_assert(BKE_collection_is_in_scene(collection_new));
 
-              if (ob_new == (Object *)ob_reference->id.newid && base != NULL) {
-                /* TODO: is setting active needed? */
-                BKE_view_layer_base_select_and_set_active(view_layer, base);
-              }
-            }
-            else if (!lib_override_library_create_post_process_object_is_instantiated(
-                         view_layer, ob_new, is_resync)) {
-              BKE_collection_object_add(bmain, collection_new, ob_new);
-              DEG_id_tag_update_ex(bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
-              if (is_resync) {
-                ob_new->id.flag |= LIB_LIB_OVERRIDE_RESYNC_LEFTOVER;
-              }
-            }
-          }
-        }
-        FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+        all_objects_in_scene = BKE_scene_objects_as_gset(scene, all_objects_in_scene);
         break;
       }
       case ID_OB: {
         Object *ob_new = (Object *)id_root->newid;
-        if (!lib_override_library_create_post_process_object_is_instantiated(
-                view_layer, ob_new, is_resync)) {
-          if (is_resync && residual_storage != NULL) {
-            BKE_collection_object_add(bmain, residual_storage, ob_new);
-          }
-          else {
-            BKE_collection_object_add_from(bmain, scene, (Object *)id_root, ob_new);
-          }
-          if (is_resync) {
-            ob_new->id.flag |= LIB_LIB_OVERRIDE_RESYNC_LEFTOVER;
-          }
+        if (BLI_gset_lookup(all_objects_in_scene, ob_new) == NULL) {
+          BKE_collection_object_add_from(bmain, scene, (Object *)id_root, ob_new);
+          all_objects_in_scene = BKE_scene_objects_as_gset(scene, all_objects_in_scene);
         }
         break;
       }
@@ -747,16 +709,15 @@ static void lib_override_library_create_post_process(Main *bmain,
   }
 
   /* We need to ensure all new overrides of objects are properly instantiated. */
+  Collection *default_instantiating_collection = residual_storage;
   LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
     Object *ob_new = (Object *)ob->id.newid;
     if (ob_new != NULL) {
       BLI_assert(ob_new->id.override_library != NULL &&
                  ob_new->id.override_library->reference == &ob->id);
 
-      Collection *default_instantiating_collection = residual_storage;
-      if (!lib_override_library_create_post_process_object_is_instantiated(
-              view_layer, ob_new, is_resync)) {
-        if (default_instantiating_collection == NULL) {
+      if (BLI_gset_lookup(all_objects_in_scene, ob_new) == NULL) {
+        if (id_root != NULL && default_instantiating_collection == NULL) {
           switch (GS(id_root->name)) {
             case ID_GR: {
               default_instantiating_collection = BKE_collection_add(
@@ -777,21 +738,23 @@ static void lib_override_library_create_post_process(Main *bmain,
                   default_instantiating_collection = collection;
                 }
               }
-              if (default_instantiating_collection == NULL) {
-                default_instantiating_collection = scene->master_collection;
-              }
               break;
             }
             default:
               BLI_assert(0);
           }
         }
+        if (default_instantiating_collection == NULL) {
+          default_instantiating_collection = scene->master_collection;
+        }
 
         BKE_collection_object_add(bmain, default_instantiating_collection, ob_new);
         DEG_id_tag_update_ex(bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
       }
     }
   }
+
+  BLI_gset_free(all_objects_in_scene, NULL);
 }
 
 /**
@@ -902,7 +865,8 @@ bool BKE_lib_override_library_resync(Main *bmain,
                                      ViewLayer *view_layer,
                                      ID *id_root,
                                      Collection *override_resync_residual_storage,
-                                     const bool do_hierarchy_enforce)
+                                     const bool do_hierarchy_enforce,
+                                     const bool do_post_process)
 {
   BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root));
   BLI_assert(!ID_IS_LINKED(id_root));
@@ -1109,18 +1073,20 @@ bool BKE_lib_override_library_resync(Main *bmain,
    */
   id_root = id_root_reference->newid;
 
-  /* Essentially ensures that potentially new overrides of new objects will be instantiated. */
-  /* Note: Here 'reference' collection and 'newly added' collection are the same, which is fine
-   * since we already relinked old root override collection to new resync'ed one above. So this
-   * call is not expected to instantiate this new resync'ed collection anywhere, just to ensure
-   * that we do not have any stray objects. */
-  lib_override_library_create_post_process(bmain,
-                                           scene,
-                                           view_layer,
-                                           id_root_reference,
-                                           id_root,
-                                           override_resync_residual_storage,
-                                           true);
+  if (do_post_process) {
+    /* Essentially ensures that potentially new overrides of new objects will be instantiated. */
+    /* Note: Here 'reference' collection and 'newly added' collection are the same, which is fine
+     * since we already relinked old root override collection to new resync'ed one above. So this
+     * call is not expected to instantiate this new resync'ed collection anywhere, just to ensure
+     * that we do not have any stray objects. */
+    lib

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list