forked from bartvdbraak/blender
Merge branch 'blender-v2.93-release'
This commit is contained in:
commit
8adeac7c27
@ -112,7 +112,9 @@ bool BKE_scene_collections_object_remove(struct Main *bmain,
|
||||
struct Object *object,
|
||||
const bool free_us);
|
||||
void BKE_collections_object_remove_nulls(struct Main *bmain);
|
||||
void BKE_collections_child_remove_nulls(struct Main *bmain, struct Collection *old_collection);
|
||||
void BKE_collections_child_remove_nulls(struct Main *bmain,
|
||||
struct Collection *parent_collection,
|
||||
struct Collection *child_collection);
|
||||
|
||||
/* Dependencies. */
|
||||
|
||||
|
@ -1302,41 +1302,50 @@ static void collection_missing_parents_remove(Collection *collection)
|
||||
*
|
||||
* \note caller must ensure #BKE_main_collection_sync_remap() is called afterwards!
|
||||
*
|
||||
* \param collection: may be \a NULL,
|
||||
* \param parent_collection: The collection owning the pointers that were remapped. May be \a NULL,
|
||||
* in which case whole \a bmain database of collections is checked.
|
||||
* \param child_collection: The collection that was remapped to another pointer. May be \a NULL,
|
||||
* in which case whole \a bmain database of collections is checked.
|
||||
*/
|
||||
void BKE_collections_child_remove_nulls(Main *bmain, Collection *collection)
|
||||
void BKE_collections_child_remove_nulls(Main *bmain,
|
||||
Collection *parent_collection,
|
||||
Collection *child_collection)
|
||||
{
|
||||
if (collection == NULL) {
|
||||
/* We need to do the checks in two steps when more than one collection may be involved,
|
||||
* otherwise we can miss some cases...
|
||||
* Also, master collections are not in bmain, so we also need to loop over scenes.
|
||||
*/
|
||||
for (collection = bmain->collections.first; collection != NULL;
|
||||
collection = collection->id.next) {
|
||||
collection_null_children_remove(collection);
|
||||
if (child_collection == NULL) {
|
||||
if (parent_collection != NULL) {
|
||||
collection_null_children_remove(parent_collection);
|
||||
}
|
||||
for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
|
||||
collection_null_children_remove(scene->master_collection);
|
||||
else {
|
||||
/* We need to do the checks in two steps when more than one collection may be involved,
|
||||
* otherwise we can miss some cases...
|
||||
* Also, master collections are not in bmain, so we also need to loop over scenes.
|
||||
*/
|
||||
for (child_collection = bmain->collections.first; child_collection != NULL;
|
||||
child_collection = child_collection->id.next) {
|
||||
collection_null_children_remove(child_collection);
|
||||
}
|
||||
for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
|
||||
collection_null_children_remove(scene->master_collection);
|
||||
}
|
||||
}
|
||||
|
||||
for (collection = bmain->collections.first; collection != NULL;
|
||||
collection = collection->id.next) {
|
||||
collection_missing_parents_remove(collection);
|
||||
for (child_collection = bmain->collections.first; child_collection != NULL;
|
||||
child_collection = child_collection->id.next) {
|
||||
collection_missing_parents_remove(child_collection);
|
||||
}
|
||||
for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
|
||||
collection_missing_parents_remove(scene->master_collection);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (CollectionParent *parent = collection->parents.first, *parent_next; parent;
|
||||
for (CollectionParent *parent = child_collection->parents.first, *parent_next; parent;
|
||||
parent = parent_next) {
|
||||
parent_next = parent->next;
|
||||
|
||||
collection_null_children_remove(parent->collection);
|
||||
|
||||
if (!collection_find_child(parent->collection, collection)) {
|
||||
BLI_freelinkN(&collection->parents, parent);
|
||||
if (!collection_find_child(parent->collection, child_collection)) {
|
||||
BLI_freelinkN(&child_collection->parents, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -303,6 +303,7 @@ static void libblock_remap_data_postprocess_object_update(Main *bmain,
|
||||
/* Can be called with both old_collection and new_collection being NULL,
|
||||
* this means we have to check whole Main database then. */
|
||||
static void libblock_remap_data_postprocess_collection_update(Main *bmain,
|
||||
Collection *owner_collection,
|
||||
Collection *UNUSED(old_collection),
|
||||
Collection *new_collection)
|
||||
{
|
||||
@ -311,7 +312,7 @@ static void libblock_remap_data_postprocess_collection_update(Main *bmain,
|
||||
* and BKE_main_collection_sync_remap() does not tolerate any of those, so for now always check
|
||||
* whole existing collections for NULL pointers.
|
||||
* I'd consider optimizing that whole collection remapping process a TODO for later. */
|
||||
BKE_collections_child_remove_nulls(bmain, NULL /*old_collection*/);
|
||||
BKE_collections_child_remove_nulls(bmain, owner_collection, NULL /*old_collection*/);
|
||||
}
|
||||
else {
|
||||
/* Temp safe fix, but a "tad" brute force... We should probably be able to use parents from
|
||||
@ -523,7 +524,7 @@ void BKE_libblock_remap_locked(Main *bmain, void *old_idv, void *new_idv, const
|
||||
break;
|
||||
case ID_GR:
|
||||
libblock_remap_data_postprocess_collection_update(
|
||||
bmain, (Collection *)old_id, (Collection *)new_id);
|
||||
bmain, NULL, (Collection *)old_id, (Collection *)new_id);
|
||||
break;
|
||||
case ID_ME:
|
||||
case ID_CU:
|
||||
@ -628,6 +629,12 @@ void BKE_libblock_relink_ex(
|
||||
switch (GS(id->name)) {
|
||||
case ID_SCE:
|
||||
case ID_GR: {
|
||||
/* Note: here we know which collection we have affected, so at lest for NULL children
|
||||
* detection we can only process that one.
|
||||
* This is also a required fix in case `id` would not be in Main anymore, which can happen
|
||||
* e.g. when called from `id_delete`. */
|
||||
Collection *owner_collection = (GS(id->name) == ID_GR) ? (Collection *)id :
|
||||
((Scene *)id)->master_collection;
|
||||
if (old_id) {
|
||||
switch (GS(old_id->name)) {
|
||||
case ID_OB:
|
||||
@ -636,7 +643,7 @@ void BKE_libblock_relink_ex(
|
||||
break;
|
||||
case ID_GR:
|
||||
libblock_remap_data_postprocess_collection_update(
|
||||
bmain, (Collection *)old_id, (Collection *)new_id);
|
||||
bmain, owner_collection, (Collection *)old_id, (Collection *)new_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -644,7 +651,7 @@ void BKE_libblock_relink_ex(
|
||||
}
|
||||
else {
|
||||
/* No choice but to check whole objects/collections. */
|
||||
libblock_remap_data_postprocess_collection_update(bmain, NULL, NULL);
|
||||
libblock_remap_data_postprocess_collection_update(bmain, owner_collection, NULL, NULL);
|
||||
libblock_remap_data_postprocess_object_update(bmain, NULL, NULL);
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user