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:
authorBastien Montagne <bastien@blender.org>2021-04-08 12:27:05 +0300
committerBastien Montagne <bastien@blender.org>2021-04-08 12:45:55 +0300
commite92a7800b57620df0a5d7619aead572667f27994 (patch)
tree22023baab0e8a340958391069d09bec3e526eddc /source/blender/blenkernel/intern/lib_override.c
parentc1b1ed4d5b2f90b48296055e817fded0f8ee8f38 (diff)
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).
Diffstat (limited to 'source/blender/blenkernel/intern/lib_override.c')
-rw-r--r--source/blender/blenkernel/intern/lib_override.c121
1 files changed, 46 insertions, 75 deletions
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_override_library_create_post_process(bmain,
+ scene,
+ view_layer,
+ id_root_reference,
+ id_root,
+ override_resync_residual_storage,
+ true);
+ }
/* Cleanup. */
BLI_ghash_free(linkedref_to_old_override, NULL, NULL);
@@ -1252,9 +1218,10 @@ void BKE_lib_override_library_main_resync(Main *bmain, Scene *scene, ViewLayer *
continue;
}
do_continue = true;
+
CLOG_INFO(&LOG, 2, "Resyncing %s...", id->name);
const bool success = BKE_lib_override_library_resync(
- bmain, scene, view_layer, id, override_resync_residual_storage, false);
+ bmain, scene, view_layer, id, override_resync_residual_storage, false, false);
CLOG_INFO(&LOG, 2, "\tSuccess: %d", success);
break;
}
@@ -1266,6 +1233,10 @@ void BKE_lib_override_library_main_resync(Main *bmain, Scene *scene, ViewLayer *
FOREACH_MAIN_LISTBASE_END;
}
+ /* Essentially ensures that potentially new overrides of new objects will be instantiated. */
+ lib_override_library_create_post_process(
+ bmain, scene, view_layer, NULL, NULL, override_resync_residual_storage, true);
+
if (BKE_collection_is_empty(override_resync_residual_storage)) {
BKE_collection_delete(bmain, override_resync_residual_storage, true);
}