diff options
author | Bastien Montagne <bastien@blender.org> | 2020-09-24 21:55:24 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2020-09-24 22:08:27 +0300 |
commit | 934b515bc18831366dbc53a26558625db5c43716 (patch) | |
tree | 353ed5e4ece8ece60355bda0d96b1d31886bb6b3 | |
parent | 771d041c4cb3922617484d69f3b3c83c635bcace (diff) |
Fix LibOverride Resync generating orphaned data-blocks.
Part of the code handling deletion of old, not needed anymore local
override IDs, was not working properly, effectively only deleting one
ID ever.
New code should also be a bit faster, though this should not be really
visible from user perspective.
Related to T81059, found while investigating it.
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index ab7e3a64c54..4e25f52cf23 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -800,17 +800,31 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_ } FOREACH_MAIN_LISTBASE_END; - /* Delete old override IDs. */ + /* Delete old override IDs. + * Note that we have to use tagged group deletion here, since ID deletion also uses LIB_TAG_DOIT. + * This improves performances anyway, so everything is fine. */ FOREACH_MAIN_ID_BEGIN (bmain, id) { - if (id->tag & LIB_TAG_DOIT && id->newid != NULL && ID_IS_LINKED(id)) { - ID *id_override_old = BLI_ghash_lookup(linkedref_to_old_override, id); + if (id->tag & LIB_TAG_DOIT) { + /* Note that this work because linked IDs are always after local ones (including overrides), + * so we will only ever tag an old override ID after we have already checked it in this loop, + * hence we cannot untag it later. */ + if (id->newid != NULL && ID_IS_LINKED(id)) { + ID *id_override_old = BLI_ghash_lookup(linkedref_to_old_override, id); - if (id_override_old != NULL) { - BKE_id_delete(bmain, id_override_old); + if (id_override_old != NULL) { + id->newid->tag &= ~LIB_TAG_DOIT; + id_override_old->tag |= LIB_TAG_DOIT; + } } + id->tag &= ~LIB_TAG_DOIT; } } FOREACH_MAIN_ID_END; + BKE_id_multi_tagged_delete(bmain); + + /* At this point, id_root has very likely been deleted, we need to update it to its new version. + */ + id_root = id_root_reference->newid; /* Essentially ensures that potentially new overrides of new objects will be instantiated. */ lib_override_library_create_post_process(bmain, scene, view_layer, id_root_reference, id_root); @@ -819,7 +833,7 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_ BLI_ghash_free(linkedref_to_old_override, NULL, NULL); BKE_main_id_clear_newpoins(bmain); - BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); + BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); /* That one should not be needed in fact. */ return success; } |