Fix (devs-reported) mistake in batch delete code in recent change.

Mistake in own rB358155a8da60, change ended up discarding the case where
we need to also delete IDs using a tagged-to-be-deleted ID in a 'never
NULL' way. Typical example: Whene deleting a Mesh ID, one also needs to
delete all the Objects using that mesh, since obdata pointer is of type
'never NULL'.

Note that luckily, this fix does not affect the performance improvements
from rB358155a8da60.

Noted by Brecht and Clement because of failing unittests, shame on me.
This commit is contained in:
Bastien Montagne 2022-10-19 16:47:57 +02:00
parent d763e294fc
commit ceb0e7fcea
Notes: blender-bot 2023-02-14 19:45:25 +01:00
Referenced by issue #101073, Remove BKE_layer_collection_resync_forbid and BKE_layer_collection_resync_allow
1 changed files with 14 additions and 15 deletions

View File

@ -218,6 +218,7 @@ static size_t id_delete(Main *bmain, const bool do_tagged_deletion)
BKE_main_lock(bmain);
if (do_tagged_deletion) {
struct IDRemapper *id_remapper = BKE_id_remapper_create();
BKE_layer_collection_resync_forbid();
/* Main idea of batch deletion is to remove all IDs to be deleted from Main database.
* This means that we won't have to loop over all deleted IDs to remove usages
@ -253,23 +254,21 @@ static size_t id_delete(Main *bmain, const bool do_tagged_deletion)
}
}
}
/* Will tag 'never NULL' users of this ID too.
*
* NOTE: #BKE_libblock_unlink() cannot be used here, since it would ignore indirect
* links, this can lead to nasty crashing here in second, actual deleting loop.
* Also, this will also flag users of deleted data that cannot be unlinked
* (object using deleted obdata, etc.), so that they also get deleted. */
BKE_libblock_remap_multiple_locked(bmain,
id_remapper,
ID_REMAP_FLAG_NEVER_NULL_USAGE |
ID_REMAP_FORCE_NEVER_NULL_USAGE |
ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS);
BKE_id_remapper_clear(id_remapper);
}
BKE_layer_collection_resync_forbid();
/* Will tag 'never NULL' users of this ID too.
*
* NOTE: #BKE_libblock_unlink() cannot be used here, since it would ignore indirect
* links, this can lead to nasty crashing here in second, actual deleting loop.
* Also, this will also flag users of deleted data that cannot be unlinked
* (object using deleted obdata, etc.), so that they also get deleted. */
BKE_libblock_remap_multiple_locked(bmain,
id_remapper,
ID_REMAP_FLAG_NEVER_NULL_USAGE |
ID_REMAP_FORCE_NEVER_NULL_USAGE |
ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS);
BKE_id_remapper_clear(id_remapper);
/* Since we removed IDs from Main, their own other IDs usages need to be removed 'manually'. */
LinkNode *cleanup_ids = NULL;
for (ID *id = tagged_deleted_ids.first; id; id = id->next) {