Commit: a211937892f55ac9510e0f9b625c1bd24cc12550
Author: Bastien Montagne
Date:   Wed Oct 24 14:45:18 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBa211937892f55ac9510e0f9b625c1bd24cc12550

Fix T57361: Creating a new scene with a full copy doesn't work.

BKE_scene_copy() & co. were pretty much doing nothing right...

Was a tough fight, but at least now they should behave a tad better (and
reported issue is fixed).

Proper fix is to fully rewrite that PoS, it was already a mess without
collections, now it's even hairier to handle properly, we need to use
modern new ID handling API for that (and maybe extend it a bit as
needed). But way too late to do that in 2.80.

===================================================================

M       source/blender/editors/object/object_relations.c

===================================================================

diff --git a/source/blender/editors/object/object_relations.c 
b/source/blender/editors/object/object_relations.c
index 306cdc9472a..8464c49f374 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1626,64 +1626,56 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot)
 
 /**************************** Make Single User 
********************************/
 
-static Object *single_object_users_object(Main *bmain, Object *ob)
-{
-       /* base gets copy of object */
-       Object *obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
-
-
-       id_us_plus(&obn->id);
-       id_us_min(&ob->id);
-       return obn;
-}
-
 static void libblock_relink_collection(Collection *collection)
 {
-       for (CollectionObject *cob = collection->gobject.first; cob; cob = 
cob->next) {
-               BKE_libblock_relink_to_newid(&cob->ob->id);
-       }
+       BKE_libblock_relink_to_newid(&collection->id);
 
        for (CollectionChild *child = collection->children.first; child; child 
= child->next) {
                libblock_relink_collection(child->collection);
        }
 }
 
-static void single_object_users_collection(Main *bmain, Scene *scene, 
Collection *collection, const int flag, const bool copy_collections)
+static void single_object_users_collection(
+        Main *bmain, Scene *scene, Collection *collection,
+        const int flag, const bool copy_collections, const bool 
is_master_collection)
 {
+       /* Generate new copies for objects in given collection and all its 
children,
+        * and optionnaly also copy collections themselves. */
+       if (copy_collections && !is_master_collection) {
+               collection = ID_NEW_SET(collection, BKE_collection_copy(bmain, 
NULL, collection));
+       }
+
+       /* We do not remap to new objects here, this is done in separate step. 
*/
        for (CollectionObject *cob = collection->gobject.first; cob; cob = 
cob->next) {
                Object *ob = cob->ob;
                /* an object may be in more than one collection */
                if ((ob->id.newid == NULL) && ((ob->flag & flag) == flag)) {
                        if (!ID_IS_LINKED(ob) && ob->id.us > 1) {
-                               cob->ob = single_object_users_object(bmain, 
cob->ob);
+                               ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
                        }
                }
        }
 
        for (CollectionChild *child = collection->children.first; child; child 
= child->next) {
-               single_object_users_collection(bmain, scene, child->collection, 
flag, copy_collections);
+               single_object_users_collection(bmain, scene, child->collection, 
flag, copy_collections, false);
        }
 }
 
 /* Warning, sets ID->newid pointers of objects and collections, but does not 
clear them. */
 static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const 
int flag, const bool copy_collections)
 {
-       Collection *collection, *collectionn;
-
-       /* duplicate all the objects of the scene */
+       /* duplicate all the objects of the scene (and matching collections, if 
required). */
        Collection *master_collection = BKE_collection_master(scene);
-       single_object_users_collection(bmain, scene, master_collection, flag, 
copy_collections);
-
-       /* loop over ViewLayers and assign the pointers accordingly */
-       for (ViewLayer *view_layer = scene->view_layers.first; view_layer; 
view_layer = view_layer->next) {
-               for (Base *base = view_layer->object_bases.first; base; base = 
base->next) {
-                       ID_NEW_REMAP(base->object);
-               }
-       }
+       single_object_users_collection(bmain, scene, master_collection, flag, 
copy_collections, true);
 
        /* duplicate collections that consist entirely of duplicated objects */
-       for (collection = bmain->collection.first; collection; collection = 
collection->id.next) {
-               if (copy_collections) {
+       /* XXX I guess that was designed for calls from 'make single user' 
operator... But since copy_collection is
+        *     always false then, was not doing anything. And that kind of 
behavior should be added at operator level,
+        *     not in a utility function also used by rather different code... 
*/
+#if 0
+       if (copy_collections) {
+               Collection *collection, *collectionn;
+               for (collection = bmain->collection.first; collection; 
collection = collection->id.next) {
                        bool all_duplicated = true;
                        bool any_duplicated = false;
 
@@ -1705,6 +1697,10 @@ static void single_object_users(Main *bmain, Scene 
*scene, View3D *v3d, const in
                        }
                }
        }
+#endif
+
+       /* Collection and object pointers in collections */
+       libblock_relink_collection(master_collection);
 
        /* collection pointers in scene */
        BKE_scene_groups_relink(scene);
@@ -1713,8 +1709,7 @@ static void single_object_users(Main *bmain, Scene 
*scene, View3D *v3d, const in
        ID_NEW_REMAP(scene->camera);
        if (v3d) ID_NEW_REMAP(v3d->camera);
 
-       /* object and collection pointers */
-       libblock_relink_collection(master_collection);
+       BKE_scene_collection_sync(scene);
 }
 
 /* not an especially efficient function, only added so the single user

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to