Fix further (unreported) issues in object collection cache cleanup code.
`BKE_collection_object_cache_free` can be called from some points in code (e.g. during ID remapping) where proper parenting relationships between collections cannot be ensured. Would be good to check if recursive cache cleanup is actually needed from these points, it would almost certainly be better and safer to instead tag parent collections as dirty too, but this will be for another time. For now, just add a NULL-check on the parent collection pointer.
This commit is contained in:
@@ -887,21 +887,33 @@ ListBase BKE_collection_object_cache_instanced_get(Collection *collection)
|
||||
|
||||
static void collection_object_cache_free(Collection *collection)
|
||||
{
|
||||
/* Clear own cache an for all parents, since those are affected by changes as well. */
|
||||
collection->flag &= ~(COLLECTION_HAS_OBJECT_CACHE | COLLECTION_HAS_OBJECT_CACHE_INSTANCED);
|
||||
BLI_freelistN(&collection->runtime.object_cache);
|
||||
BLI_freelistN(&collection->runtime.object_cache_instanced);
|
||||
}
|
||||
|
||||
void BKE_collection_object_cache_free(Collection *collection)
|
||||
static void collection_object_cache_free_parent_recursive(Collection *collection)
|
||||
{
|
||||
collection_object_cache_free(collection);
|
||||
|
||||
/* Clear cache in all parents recursively, since those are affected by changes as well. */
|
||||
LISTBASE_FOREACH (CollectionParent *, parent, &collection->runtime.parents) {
|
||||
BKE_collection_object_cache_free(parent->collection);
|
||||
/* In theory there should be no NULL pointer here. However, this code can be called from
|
||||
* non-valid temporary states (e.g. indirectly from #BKE_collections_object_remove_invalids
|
||||
* as part of ID remapping process). */
|
||||
if (parent->collection == NULL) {
|
||||
continue;
|
||||
}
|
||||
collection_object_cache_free_parent_recursive(parent->collection);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_collection_object_cache_free(Collection *collection)
|
||||
{
|
||||
BLI_assert(collection != NULL);
|
||||
collection_object_cache_free_parent_recursive(collection);
|
||||
}
|
||||
|
||||
void BKE_main_collections_object_cache_free(const Main *bmain)
|
||||
{
|
||||
for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
|
||||
|
||||
Reference in New Issue
Block a user