[Bf-blender-cvs] [1a72744ddc4] master: Fix T90246: Full Copy'ing a scene confuses physics in the original scene.

Bastien Montagne noreply at git.blender.org
Thu Sep 30 16:05:13 CEST 2021


Commit: 1a72744ddc4a34ce32f308a9011423c2099b49d3
Author: Bastien Montagne
Date:   Thu Sep 30 15:22:16 2021 +0200
Branches: master
https://developer.blender.org/rB1a72744ddc4a34ce32f308a9011423c2099b49d3

Fix T90246: Full Copy'ing a scene confuses physics in the original scene.

Handling of RigidBody data in duplicate of scenes/collections was very
wrong. This commit:
 - Add handling of duplication of RB collections when fully duplicating
   a scene.
 - Fix Object duplication trying to add duplicated RB objects to
   matching RBW collections.

While the later behavior is desired when only duplicated objects, when
duplicating their collections and/or scenes it is actually very bad, as
it would add back new object duplicates to old (RBW) collections.

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

M	source/blender/blenkernel/BKE_lib_id.h
M	source/blender/blenkernel/intern/collection.c
M	source/blender/blenkernel/intern/lib_id.c
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenkernel/intern/rigidbody.c
M	source/blender/blenkernel/intern/scene.c

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

diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h
index 36f57209e33..d2a8ec2e332 100644
--- a/source/blender/blenkernel/BKE_lib_id.h
+++ b/source/blender/blenkernel/BKE_lib_id.h
@@ -133,6 +133,9 @@ enum {
   LIB_ID_COPY_SHAPEKEY = 1 << 26,
   /** EXCEPTION! Specific deep-copy of node trees used e.g. for rendering purposes. */
   LIB_ID_COPY_NODETREE_LOCALIZE = 1 << 27,
+  /** EXCEPTION! Specific handling of RB objects regarding collections differs depending whether we
+     duplicate scene/collections, or objects. */
+  LIB_ID_COPY_RIGID_BODY_NO_COLLECTION_HANDLING = 1 << 28,
 
   /* *** Helper 'defines' gathering most common flag sets. *** */
   /** Shapekeys are not real ID's, more like local data to geometry IDs... */
@@ -261,7 +264,8 @@ struct ID *BKE_id_copy_ex(struct Main *bmain,
                           const int flag);
 struct ID *BKE_id_copy_for_duplicate(struct Main *bmain,
                                      struct ID *id,
-                                     const uint duplicate_flags);
+                                     const uint duplicate_flags,
+                                     const int copy_flags);
 
 void BKE_lib_id_swap(struct Main *bmain, struct ID *id_a, struct ID *id_b);
 void BKE_lib_id_swap_full(struct Main *bmain, struct ID *id_a, struct ID *id_b);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 2d172f23428..8e50b9e9534 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -597,7 +597,7 @@ static Collection *collection_duplicate_recursive(Main *bmain,
   }
   else if (collection_old->id.newid == NULL) {
     collection_new = (Collection *)BKE_id_copy_for_duplicate(
-        bmain, (ID *)collection_old, duplicate_flags);
+        bmain, (ID *)collection_old, duplicate_flags, LIB_ID_COPY_DEFAULT);
 
     if (collection_new == collection_old) {
       return collection_new;
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index 18824e73ee5..3b2d2c5d2c3 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -674,7 +674,10 @@ ID *BKE_id_copy(Main *bmain, const ID *id)
  * Invokes the appropriate copy method for the block and returns the result in
  * newid, unless test. Returns true if the block can be copied.
  */
-ID *BKE_id_copy_for_duplicate(Main *bmain, ID *id, const eDupli_ID_Flags duplicate_flags)
+ID *BKE_id_copy_for_duplicate(Main *bmain,
+                              ID *id,
+                              const eDupli_ID_Flags duplicate_flags,
+                              const int copy_flags)
 {
   if (id == NULL) {
     return id;
@@ -685,7 +688,7 @@ ID *BKE_id_copy_for_duplicate(Main *bmain, ID *id, const eDupli_ID_Flags duplica
       return id;
     }
 
-    ID *id_new = BKE_id_copy(bmain, id);
+    ID *id_new = BKE_id_copy_ex(bmain, id, NULL, copy_flags);
     /* Copying add one user by default, need to get rid of that one. */
     id_us_min(id_new);
     ID_NEW_SET(id, id_new);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index fbdf99c91c2..ec39c5b45c4 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -2634,10 +2634,16 @@ Object *BKE_object_duplicate(Main *bmain,
 {
   const bool is_subprocess = (duplicate_options & LIB_ID_DUPLICATE_IS_SUBPROCESS) != 0;
   const bool is_root_id = (duplicate_options & LIB_ID_DUPLICATE_IS_ROOT_ID) != 0;
+  int copy_flags = LIB_ID_COPY_DEFAULT;
 
   if (!is_subprocess) {
     BKE_main_id_newptr_and_tag_clear(bmain);
   }
+  else {
+    /* In case copying object is a sub-process of collection (or scene) copying, do not try to
+     * re-assign RB objects to existing RBW collections. */
+    copy_flags |= LIB_ID_COPY_RIGID_BODY_NO_COLLECTION_HANDLING;
+  }
   if (is_root_id) {
     /* In case root duplicated ID is linked, assume we want to get a local copy of it and duplicate
      * all expected linked data. */
@@ -2649,7 +2655,7 @@ Object *BKE_object_duplicate(Main *bmain,
 
   Material ***matarar;
 
-  Object *obn = (Object *)BKE_id_copy_for_duplicate(bmain, &ob->id, dupflag);
+  Object *obn = (Object *)BKE_id_copy_for_duplicate(bmain, &ob->id, dupflag, copy_flags);
 
   /* 0 == full linked. */
   if (dupflag == 0) {
@@ -2658,13 +2664,13 @@ Object *BKE_object_duplicate(Main *bmain,
 
   if (dupflag & USER_DUP_MAT) {
     for (int i = 0; i < obn->totcol; i++) {
-      BKE_id_copy_for_duplicate(bmain, (ID *)obn->mat[i], dupflag);
+      BKE_id_copy_for_duplicate(bmain, (ID *)obn->mat[i], dupflag, copy_flags);
     }
   }
   if (dupflag & USER_DUP_PSYS) {
     ParticleSystem *psys;
     for (psys = obn->particlesystem.first; psys; psys = psys->next) {
-      BKE_id_copy_for_duplicate(bmain, (ID *)psys->part, dupflag);
+      BKE_id_copy_for_duplicate(bmain, (ID *)psys->part, dupflag, copy_flags);
     }
   }
 
@@ -2675,77 +2681,77 @@ Object *BKE_object_duplicate(Main *bmain,
   switch (obn->type) {
     case OB_MESH:
       if (dupflag & USER_DUP_MESH) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
     case OB_CURVE:
       if (dupflag & USER_DUP_CURVE) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
     case OB_SURF:
       if (dupflag & USER_DUP_SURF) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
     case OB_FONT:
       if (dupflag & USER_DUP_FONT) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
     case OB_MBALL:
       if (dupflag & USER_DUP_MBALL) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
     case OB_LAMP:
       if (dupflag & USER_DUP_LAMP) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
     case OB_ARMATURE:
       if (dupflag & USER_DUP_ARM) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
     case OB_LATTICE:
       if (dupflag != 0) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
     case OB_CAMERA:
       if (dupflag != 0) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
     case OB_LIGHTPROBE:
       if (dupflag & USER_DUP_LIGHTPROBE) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
     case OB_SPEAKER:
       if (dupflag != 0) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
     case OB_GPENCIL:
       if (dupflag & USER_DUP_GPENCIL) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
     case OB_HAIR:
       if (dupflag & USER_DUP_HAIR) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
     case OB_POINTCLOUD:
       if (dupflag & USER_DUP_POINTCLOUD) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
     case OB_VOLUME:
       if (dupflag & USER_DUP_VOLUME) {
-        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag);
+        id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag, copy_flags);
       }
       break;
   }
@@ -2756,7 +2762,7 @@ Object *BKE_object_duplicate(Main *bmain,
       matarar = BKE_object_material_array_p(obn);
       if (matarar) {
         for (int i = 0; i < obn->totcol; i++) {
-          BKE_id_copy_for_duplicate(bmain, (ID *)(*matarar)[i], dupflag);
+          BKE_id_copy_for_duplicate(bmain, (ID *)(*matarar)[i], dupflag, copy_flags);
         }
       }
     }
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 328c54fc21b..947efd88ec1 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -302,7 +302,7 @@ void BKE_rigidbody_object_copy(Main *bmain, Object *ob_dst, const Object *ob_src
   ob_dst->rigidbody_object = rigidbody_copy_object(ob_src, flag);
   ob_dst->rigidbody_constraint = rigidbody_copy_constraint(ob_src, flag);
 
-  if (flag & LIB_ID_CREATE_NO_MAIN) {
+  if ((flag & (LIB_ID_CREATE_NO_MAIN | LIB_ID_COPY_RIGID_BODY_NO_COLLECTION_HANDLING)) != 0) {
     return;
   }
 
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 03f19cef94e..a9a8cd93b1d 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1801,6 +1801,7 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
     /* Scene duplication is always root of duplication currently. */
     const bool is_subprocess = false;
     const bool is_root_id = true;
+    const int copy_flags = LIB_ID_COPY_DEFAULT;
 
     if (!is_subprocess) {
       BKE_main_id_newptr_and_tag_clear(bmain);
@@ -18

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list