diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2019-04-01 22:10:25 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2019-04-01 22:15:43 +0300 |
commit | 17c15798c35f33e4150beacb0f7b612bcef90c3e (patch) | |
tree | 1130b4a04cc1757eb660f50d395322c831c34172 /source/blender/editors/object | |
parent | b5382c92cf9e265714862a19dbdcce1ec81e202a (diff) |
Fix T63101: Blender crashes on adding any object to collection duplicated with added scene.
Issue was that (deep) duplication code of scene ended up leaving
children collections of new master one without any parent.
Note that even though I think that fix is OK for now, we should really
make 'deep' duplication of IDs part of the generic ID management code.
Am less and less happy with current handling of this, done half from
/editors code, half from some semi-specialized helpers from /blenkernel,
with sometimes nearly the same logic replicated several times for
slightly different needs, etc. Unfortunately this would not be a small
refactor, so it will have to wait...
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r-- | source/blender/editors/object/object_relations.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index dbee2e77cf5..ec6c1059ed3 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1602,7 +1602,7 @@ static void libblock_relink_collection(Collection *collection) } } -static void single_object_users_collection( +static Collection *single_object_users_collection( Main *bmain, Scene *scene, Collection *collection, const int flag, const bool copy_collections, const bool is_master_collection) { @@ -1623,9 +1623,24 @@ static void single_object_users_collection( } } - for (CollectionChild *child = collection->children.first; child; child = child->next) { - single_object_users_collection(bmain, scene, child->collection, flag, copy_collections, false); + /* Since master collection has already be duplicated as part of scene copy, we do not duplictae it here. + * However, this means its children need to be re-added manually here, otherwise their parent lists are empty + * (which will lead to crashes, see T63101). */ + CollectionChild *child_next, *child = collection->children.first; + if (is_master_collection) { + BLI_listbase_clear(&collection->children); + } + for (; child; child = child_next) { + child_next = child->next; + Collection *collection_child_new = single_object_users_collection( + bmain, scene, child->collection, flag, copy_collections, false); + if (is_master_collection) { + BKE_collection_child_add(bmain, collection, collection_child_new); + MEM_freeN(child); + } } + + return collection; } /* Warning, sets ID->newid pointers of objects and collections, but does not clear them. */ @@ -1679,9 +1694,7 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in } /* Making single user may affect other scenes if they share with current one some collections in their ViewLayer. */ - for (Scene *sce = bmain->scenes.first; sce != NULL; sce = sce->id.next) { - BKE_scene_collection_sync(sce); - } + BKE_main_collection_sync(bmain); } /* not an especially efficient function, only added so the single user |