Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <bastien@blender.org>2020-08-20 12:20:47 +0300
committerBastien Montagne <bastien@blender.org>2020-08-20 18:47:56 +0300
commit05e1ccf108366ee9ef95b41643dcbd656d819f5a (patch)
treef1abe27ffb26913ec433890d7114fa86cdd43f54 /source/blender/blenkernel/intern/collection.c
parentc74b4caa724bf74de41ba3928cdd824aa9ba59d2 (diff)
Fix T79931: Infinite loop in scene "Full Copy" in 2.90.
Code dealing with object copy of master collection was bugy in case one of the new object copy would get a name lesser than the original object, leading to new copy being inserted before original one in lists. Maniphest Tasks: T79931 Differential Revision: https://developer.blender.org/D8656
Diffstat (limited to 'source/blender/blenkernel/intern/collection.c')
-rw-r--r--source/blender/blenkernel/intern/collection.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 5c618c8e9ce..461b40c6856 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -408,18 +408,28 @@ static Collection *collection_duplicate_recursive(Main *bmain,
}
if (do_objects) {
+ /* We need to first duplicate the objects in a separate loop, to support the master collection
+ * case, where both old and new collections are the same.
+ * Otherwise, depending on naming scheme and sorting, we may end up duplicating the new objects
+ * we just added, in some infinite loop. */
+ LISTBASE_FOREACH (CollectionObject *, cob, &collection_old->gobject) {
+ Object *ob_old = cob->ob;
+
+ if (ob_old->id.newid == NULL) {
+ BKE_object_duplicate(
+ bmain, ob_old, duplicate_flags, duplicate_options | LIB_ID_DUPLICATE_IS_SUBPROCESS);
+ }
+ }
+
/* We can loop on collection_old's objects, but have to consider it mutable because with master
* collections collection_old and collection_new are the same data here. */
LISTBASE_FOREACH_MUTABLE (CollectionObject *, cob, &collection_old->gobject) {
Object *ob_old = cob->ob;
Object *ob_new = (Object *)ob_old->id.newid;
- if (ob_new == NULL) {
- ob_new = BKE_object_duplicate(
- bmain, ob_old, duplicate_flags, duplicate_options | LIB_ID_DUPLICATE_IS_SUBPROCESS);
- }
-
- if (ob_new == ob_old) {
+ /* New object can be NULL in master collection case, since new and old objects are in same
+ * collection. */
+ if (ELEM(ob_new, ob_old, NULL)) {
continue;
}