[Bf-blender-cvs] [105ae3be999] master: Fix T66944: Rigid Body Constraint in duplicated collection is not added to RigidBodyConstraints collection.

Bastien Montagne noreply at git.blender.org
Tue Jul 16 16:08:45 CEST 2019


Commit: 105ae3be9993a646615499bf793cb14549e4104d
Author: Bastien Montagne
Date:   Tue Jul 16 16:04:22 2019 +0200
Branches: master
https://developer.blender.org/rB105ae3be9993a646615499bf793cb14549e4104d

Fix T66944: Rigid Body Constraint in duplicated collection is not added to RigidBodyConstraints collection.

We only had a very limited, specific handling of that in collection
duplication code, but this has to be handled at a much more general
level in Object copy code itself, since it makes no sense to duplicate
rigidbody object data without adding new copy to relevant rigidbody
collections...

WARNING: This is a fairly risky rework of rigidbody handling logic
when copying an Object data-block. It is *NOT* considered safe enough
for 2.80 release.

I tried to take into account copy flags to not mess with other IDs
(collections) when we are copying outside of Main, and also not do deg
tags when this is forbidden, but risk of something going wrong here is
too high...

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

M	source/blender/blenkernel/BKE_collection.h
M	source/blender/blenkernel/BKE_rigidbody.h
M	source/blender/blenkernel/intern/collection.c
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenkernel/intern/rigidbody.c

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

diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index c1e36f5dd83..972ae5e8628 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -85,7 +85,7 @@ struct Scene *BKE_collection_master_scene_search(const struct Main *bmain,
 
 /* Collection Objects */
 
-bool BKE_collection_has_object(struct Collection *collection, struct Object *ob);
+bool BKE_collection_has_object(struct Collection *collection, const struct Object *ob);
 bool BKE_collection_has_object_recursive(struct Collection *collection, struct Object *ob);
 struct Collection *BKE_collection_object_find(struct Main *bmain,
                                               struct Scene *scene,
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h
index cc3f5bbb42e..4c023f54e04 100644
--- a/source/blender/blenkernel/BKE_rigidbody.h
+++ b/source/blender/blenkernel/BKE_rigidbody.h
@@ -44,8 +44,10 @@ void BKE_rigidbody_free_constraint(struct Object *ob);
 
 /* ...... */
 
-struct RigidBodyOb *BKE_rigidbody_copy_object(const struct Object *ob, const int flag);
-struct RigidBodyCon *BKE_rigidbody_copy_constraint(const struct Object *ob, const int flag);
+void BKE_rigidbody_object_copy(struct Main *bmain,
+                               struct Object *ob_dst,
+                               const struct Object *ob_src,
+                               const int flag);
 
 /* Callback format for performing operations on ID-pointers for rigidbody world. */
 typedef void (*RigidbodyWorldIDFunc)(struct RigidBodyWorld *rbw,
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index ac55846714b..965f6e4bc51 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -287,16 +287,6 @@ static Collection *collection_duplicate_recursive(Main *bmain,
 
       collection_object_add(bmain, collection_new, ob_new, 0, true);
       collection_object_remove(bmain, collection_new, ob_old, false);
-
-      if (ob_new->rigidbody_object != NULL) {
-        BLI_assert(ob_old->rigidbody_object != NULL);
-        for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
-          if (scene->rigidbody_world != NULL &&
-              BKE_collection_has_object(scene->rigidbody_world->group, ob_old)) {
-            collection_object_add(bmain, scene->rigidbody_world->group, ob_new, 0, true);
-          }
-        }
-      }
     }
   }
 
@@ -572,7 +562,7 @@ bool BKE_collection_object_cyclic_check(Main *bmain, Object *object, Collection
 
 /******************* Collection Object Membership *******************/
 
-bool BKE_collection_has_object(Collection *collection, Object *ob)
+bool BKE_collection_has_object(Collection *collection, const Object *ob)
 {
   if (ELEM(NULL, collection, ob)) {
     return false;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 2a66edc8d42..d7256cc9604 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1417,8 +1417,7 @@ void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, con
     }
   }
   BKE_object_copy_softbody(ob_dst, ob_src, flag_subdata);
-  ob_dst->rigidbody_object = BKE_rigidbody_copy_object(ob_src, flag_subdata);
-  ob_dst->rigidbody_constraint = BKE_rigidbody_copy_constraint(ob_src, flag_subdata);
+  BKE_rigidbody_object_copy(bmain, ob_dst, ob_src, flag_subdata);
 
   BKE_object_copy_particlesystems(ob_dst, ob_src, flag_subdata);
 
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index a3a0ebd6cb3..c9b18dfc7e6 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -34,6 +34,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "BLI_math.h"
+#include "BLI_listbase.h"
 
 #ifdef WITH_BULLET
 #  include "RBI_api.h"
@@ -228,7 +229,7 @@ void BKE_rigidbody_free_constraint(Object *ob)
  * be added to relevant groups later...
  */
 
-RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int flag)
+static RigidBodyOb *rigidbody_copy_object(const Object *ob, const int flag)
 {
   RigidBodyOb *rboN = NULL;
 
@@ -249,7 +250,7 @@ RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int flag)
   return rboN;
 }
 
-RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob, const int UNUSED(flag))
+static RigidBodyCon *rigidbody_copy_constraint(const Object *ob, const int UNUSED(flag))
 {
   RigidBodyCon *rbcN = NULL;
 
@@ -268,6 +269,54 @@ RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob, const int UNUSED(f
   return rbcN;
 }
 
+void BKE_rigidbody_object_copy(Main *bmain, Object *ob_dst, const Object *ob_src, const int flag)
+{
+  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) {
+    return;
+  }
+
+  /* We have to ensure that duplicated object ends up in relevant rigidbody collections...
+   * Otherwise duplicating the RB data itself is meaningless. */
+  LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+    RigidBodyWorld *rigidbody_world = scene->rigidbody_world;
+
+    if (rigidbody_world != NULL) {
+      bool need_objects_update = false;
+      bool need_constraints_update = false;
+
+      if (ob_dst->rigidbody_object) {
+        if (BKE_collection_has_object(rigidbody_world->group, ob_src)) {
+          BKE_collection_object_add(bmain, rigidbody_world->group, ob_dst);
+          need_objects_update = true;
+        }
+      }
+      if (ob_dst->rigidbody_constraint) {
+        if (BKE_collection_has_object(rigidbody_world->constraints, ob_src)) {
+          BKE_collection_object_add(bmain, rigidbody_world->constraints, ob_dst);
+          need_constraints_update = true;
+        }
+      }
+
+      if ((flag & LIB_ID_CREATE_NO_DEG_TAG) == 0 &&
+          (need_objects_update || need_constraints_update)) {
+        BKE_rigidbody_cache_reset(rigidbody_world);
+
+        DEG_relations_tag_update(bmain);
+        if (need_objects_update) {
+          DEG_id_tag_update(&rigidbody_world->group->id, ID_RECALC_COPY_ON_WRITE);
+        }
+        if (need_constraints_update) {
+          DEG_id_tag_update(&rigidbody_world->constraints->id, ID_RECALC_COPY_ON_WRITE);
+        }
+        DEG_id_tag_update(&ob_dst->id, ID_RECALC_TRANSFORM);
+      }
+    }
+  }
+}
+
 /* ************************************** */
 /* Setup Utilities - Validate Sim Instances */
 
@@ -1983,13 +2032,8 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime
 #    pragma GCC diagnostic ignored "-Wunused-parameter"
 #  endif
 
-struct RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int flag)
-{
-  return NULL;
-}
-struct RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob, const int flag)
+void BKE_rigidbody_object_copy(Main *bmain, Object *ob_dst, const Object *ob_src, const int flag)
 {
-  return NULL;
 }
 void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild)
 {



More information about the Bf-blender-cvs mailing list