diff options
author | Bastien Montagne <bastien@blender.org> | 2022-07-07 13:33:45 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2022-07-07 14:01:02 +0300 |
commit | 97dd10707097536df24dd7ca7d2a45b9a6408711 (patch) | |
tree | 00c4021ed74bb81f71f664c0674a79ee4c3dd6b0 /source | |
parent | 051a341cf00ca1518b50b43bb95f95bc24bf2398 (diff) |
Fix T98029: Support isolated islands of IDs when purging unused ones.
Cases were e.g. an object would use a material, and this material would
use this object (e.g. through a driver), even if both those data-blocks
are technically unused, they would remain forever since they were not
detected as such.
Now this is properly detected and purged as part of the 'recursive
purge' operation.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/lib_query.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c index 5de8704e13b..38252a46b93 100644 --- a/source/blender/blenkernel/intern/lib_query.c +++ b/source/blender/blenkernel/intern/lib_query.c @@ -693,6 +693,13 @@ static void lib_query_unused_ids_tag_recurse(Main *bmain, * First recursively check all its valid users, if all of them can be tagged as * unused, then we can tag this ID as such too. */ bool has_valid_from_users = false; + /* Preemptively consider this ID as unused. That way if there is a loop of dependency leading + * back to it, it won't create a fake 'valid user' detection. + * NOTE: This can only only be done for a subset of IDs, some types are never 'indirectly + * unused', same for IDs with a fake user. */ + if ((id->flag & LIB_FAKEUSER) == 0 && !ELEM(GS(id->name), ID_SCE, ID_WM, ID_SCR, ID_WS, ID_LI)) { + id->tag |= tag; + } for (MainIDRelationsEntryItem *id_from_item = id_relations->from_ids; id_from_item != NULL; id_from_item = id_from_item->next) { if ((id_from_item->usage_flag & ignored_usages) != 0 || @@ -715,7 +722,11 @@ static void lib_query_unused_ids_tag_recurse(Main *bmain, break; } } - if (!has_valid_from_users) { + if (has_valid_from_users) { + /* This ID has 'valid' users, clear the 'tag as unused' preemptively set above. */ + id->tag &= ~tag; + } + else { /* This ID has no 'valid' users, tag it as unused. */ id->tag |= tag; if (r_num_tagged != NULL) { |