[Bf-blender-cvs] [a5ff780065b] master: Fix T63828, T62005: copy/paste or append loses rigid body object

Brecht Van Lommel noreply at git.blender.org
Mon Jun 24 18:51:47 CEST 2019


Commit: a5ff780065bf6768811bf459953a1a1eabe989c1
Author: Brecht Van Lommel
Date:   Mon Jun 24 14:57:52 2019 +0200
Branches: master
https://developer.blender.org/rBa5ff780065bf6768811bf459953a1a1eabe989c1

Fix T63828, T62005: copy/paste or append loses rigid body object

Previously settings were removed, now add to the rigid body world automatically
even if it's a bit ill defined, since this is confusing for users.

Fundamentally the concept of a rigid body world collection could be revised, and
left only as an optional thing.

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

M	source/blender/blenkernel/BKE_rigidbody.h
M	source/blender/blenkernel/intern/library.c
M	source/blender/blenkernel/intern/rigidbody.c
M	source/blender/editors/physics/rigidbody_object.c

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

diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h
index c940e646d95..cc3f5bbb42e 100644
--- a/source/blender/blenkernel/BKE_rigidbody.h
+++ b/source/blender/blenkernel/BKE_rigidbody.h
@@ -32,6 +32,7 @@ struct Collection;
 struct Depsgraph;
 struct Main;
 struct Object;
+struct ReportList;
 struct Scene;
 
 /* -------------- */
@@ -94,6 +95,12 @@ void BKE_rigidbody_calc_center_of_mass(struct Object *ob, float r_center[3]);
 /* Utilities */
 
 struct RigidBodyWorld *BKE_rigidbody_get_world(struct Scene *scene);
+bool BKE_rigidbody_add_object(struct Main *bmain,
+                              struct Scene *scene,
+                              struct Object *ob,
+                              int type,
+                              struct ReportList *reports);
+void BKE_rigidbody_ensure_local_object(struct Main *bmain, struct Object *ob);
 void BKE_rigidbody_remove_object(struct Main *bmain, struct Scene *scene, struct Object *ob);
 void BKE_rigidbody_remove_constraint(struct Scene *scene, struct Object *ob);
 
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 5e54344c80e..974c6d6e0a6 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -57,6 +57,7 @@
 #include "DNA_node_types.h"
 #include "DNA_object_types.h"
 #include "DNA_lightprobe_types.h"
+#include "DNA_rigidbody_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_speaker_types.h"
@@ -2038,6 +2039,10 @@ void BKE_library_make_local(Main *bmain,
       id_clear_lib_data_ex(bmain, id, true);
       BKE_id_expand_local(bmain, id);
       id->tag &= ~LIB_TAG_DOIT;
+
+      if (GS(id->name) == ID_OB) {
+        BKE_rigidbody_ensure_local_object(bmain, (Object *)id);
+      }
     }
     else {
       /* In this specific case, we do want to make ID local even if it has no local usage yet...
@@ -2053,6 +2058,10 @@ void BKE_library_make_local(Main *bmain,
       }
 
       if (id->newid) {
+        if (GS(id->newid->name) == ID_OB) {
+          BKE_rigidbody_ensure_local_object(bmain, (Object *)id->newid);
+        }
+
         /* Reuse already allocated LinkNode (transferring it from todo_ids to copied_ids). */
         BLI_linklist_prepend_nlink(&copied_ids, id, it);
       }
@@ -2178,25 +2187,6 @@ void BKE_library_make_local(Main *bmain,
     }
   }
 
-  /* Reset rigid body objects. */
-  for (LinkNode *it = copied_ids; it; it = it->next) {
-    ID *id = it->link;
-    if (GS(id->name) == ID_OB) {
-      Object *ob = (Object *)id;
-
-      /* If there was ever any rigidbody settings in the object, we reset it. */
-      if (ob->rigidbody_object) {
-        for (Scene *scene_iter = bmain->scenes.first; scene_iter;
-             scene_iter = scene_iter->id.next) {
-          if (scene_iter->rigidbody_world) {
-            BKE_rigidbody_remove_object(bmain, scene_iter, ob);
-          }
-        }
-        BKE_rigidbody_free_object(ob, NULL);
-      }
-    }
-  }
-
 #ifdef DEBUG_TIME
   printf("Hack: Forcefully rebuild armature object poses: Done.\n");
   TIMEIT_VALUE_PRINT(make_local);
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index d4d753eb685..012f5f18910 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -56,6 +56,7 @@
 #include "BKE_mesh_runtime.h"
 #include "BKE_object.h"
 #include "BKE_pointcache.h"
+#include "BKE_report.h"
 #include "BKE_rigidbody.h"
 #include "BKE_scene.h"
 #ifdef WITH_BULLET
@@ -1296,7 +1297,76 @@ RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene)
   return scene->rigidbody_world;
 }
 
-void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob)
+static bool rigidbody_add_object_to_scene(Main *bmain, Scene *scene, Object *ob)
+{
+  /* Add rigid body world and group if they don't exist for convenience */
+  RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
+  if (rbw == NULL) {
+    rbw = BKE_rigidbody_create_world(scene);
+    if (rbw == NULL) {
+      return false;
+    }
+
+    BKE_rigidbody_validate_sim_world(scene, rbw, false);
+    scene->rigidbody_world = rbw;
+  }
+
+  if (rbw->group == NULL) {
+    rbw->group = BKE_collection_add(bmain, NULL, "RigidBodyWorld");
+    id_fake_user_set(&rbw->group->id);
+  }
+
+  /* Add object to rigid body group. */
+  BKE_collection_object_add(bmain, rbw->group, ob);
+  BKE_rigidbody_cache_reset(rbw);
+
+  DEG_relations_tag_update(bmain);
+  DEG_id_tag_update(&rbw->group->id, ID_RECALC_COPY_ON_WRITE);
+
+  return true;
+}
+
+void BKE_rigidbody_ensure_local_object(Main *bmain, Object *ob)
+{
+  if (ob->rigidbody_object == NULL) {
+    return;
+  }
+
+  /* Add newly local object to scene. */
+  for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
+    if (BKE_scene_object_find(scene, ob)) {
+      rigidbody_add_object_to_scene(bmain, scene, ob);
+    }
+  }
+}
+
+bool BKE_rigidbody_add_object(Main *bmain, Scene *scene, Object *ob, int type, ReportList *reports)
+{
+  if (ob->type != OB_MESH) {
+    BKE_report(reports, RPT_ERROR, "Can't add Rigid Body to non mesh object");
+    return false;
+  }
+
+  /* Add object to rigid body world in scene. */
+  if (!rigidbody_add_object_to_scene(bmain, scene, ob)) {
+    BKE_report(reports, RPT_ERROR, "Can't create Rigid Body world");
+    return false;
+  }
+
+  /* make rigidbody object settings */
+  if (ob->rigidbody_object == NULL) {
+    ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, type);
+  }
+  ob->rigidbody_object->type = type;
+  ob->rigidbody_object->flag |= RBO_FLAG_NEEDS_VALIDATE;
+
+  DEG_relations_tag_update(bmain);
+  DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
+
+  return true;
+}
+
+void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob)
 {
   RigidBodyWorld *rbw = scene->rigidbody_world;
   RigidBodyCon *rbc;
@@ -1343,6 +1413,10 @@ void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob)
 
   /* flag cache as outdated */
   BKE_rigidbody_cache_reset(rbw);
+
+  /* Dependency graph update */
+  DEG_relations_tag_update(bmain);
+  DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
 }
 
 void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c
index ed6d31dfd9b..aa323dc53eb 100644
--- a/source/blender/editors/physics/rigidbody_object.c
+++ b/source/blender/editors/physics/rigidbody_object.c
@@ -86,43 +86,7 @@ static bool ED_operator_rigidbody_add_poll(bContext *C)
 
 bool ED_rigidbody_object_add(Main *bmain, Scene *scene, Object *ob, int type, ReportList *reports)
 {
-  RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
-
-  if (ob->type != OB_MESH) {
-    BKE_report(reports, RPT_ERROR, "Can't add Rigid Body to non mesh object");
-    return false;
-  }
-
-  /* Add rigid body world and group if they don't exist for convenience */
-  if (rbw == NULL) {
-    rbw = BKE_rigidbody_create_world(scene);
-    if (rbw == NULL) {
-      BKE_report(reports, RPT_ERROR, "Can't create Rigid Body world");
-      return false;
-    }
-    BKE_rigidbody_validate_sim_world(scene, rbw, false);
-    scene->rigidbody_world = rbw;
-  }
-  if (rbw->group == NULL) {
-    rbw->group = BKE_collection_add(bmain, NULL, "RigidBodyWorld");
-    id_fake_user_set(&rbw->group->id);
-  }
-
-  /* make rigidbody object settings */
-  if (ob->rigidbody_object == NULL) {
-    ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, type);
-  }
-  ob->rigidbody_object->type = type;
-  ob->rigidbody_object->flag |= RBO_FLAG_NEEDS_VALIDATE;
-
-  /* add object to rigid body group */
-  BKE_collection_object_add(bmain, rbw->group, ob);
-
-  DEG_relations_tag_update(bmain);
-  DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
-  DEG_id_tag_update(&rbw->group->id, ID_RECALC_COPY_ON_WRITE);
-
-  return true;
+  return BKE_rigidbody_add_object(bmain, scene, ob, type, reports);
 }
 
 void ED_rigidbody_object_remove(Main *bmain, Scene *scene, Object *ob)



More information about the Bf-blender-cvs mailing list