[Bf-blender-cvs] [bebdb6c8249] master: Fix assert when deleting a RBW constraint object.

Bastien Montagne noreply at git.blender.org
Fri Oct 4 18:57:28 CEST 2019


Commit: bebdb6c8249939623f80cc72433aa7d7418444bf
Author: Bastien Montagne
Date:   Fri Oct 4 18:51:00 2019 +0200
Branches: master
https://developer.blender.org/rBbebdb6c8249939623f80cc72433aa7d7418444bf

Fix assert when deleting a RBW constraint object.

Side-reported in T70505.

Code did not ensure deleted object was removed from the RBW constraints
collection, leading to some invalid status (object in constraints
collection but without relevant contraints data).

Also fixed another issue - code deleting RBW objects would try to remove
any constraint one using it as target, in a very bad and broken way,
since you cannot iterate over objects of a collection while removing
some... Now instead just NULLify relevant pointers... I hope it works,
otherwise we'll have to take a different approach.

Needless to stress again how weak the whole RBW code is in general, and
regarding same object being used by RBW in more than one scene in particular,
that is known broken situation anyway.

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

M	source/blender/blenkernel/BKE_rigidbody.h
M	source/blender/blenkernel/BKE_scene.h
M	source/blender/blenkernel/intern/collection.c
M	source/blender/blenkernel/intern/rigidbody.c
M	source/blender/blenkernel/intern/scene.c
M	source/blender/editors/physics/rigidbody_constraint.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 4c023f54e04..b4c440d54a6 100644
--- a/source/blender/blenkernel/BKE_rigidbody.h
+++ b/source/blender/blenkernel/BKE_rigidbody.h
@@ -103,8 +103,14 @@ bool BKE_rigidbody_add_object(struct Main *bmain,
                               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);
+void BKE_rigidbody_remove_object(struct Main *bmain,
+                                 struct Scene *scene,
+                                 struct Object *ob,
+                                 const bool free_us);
+void BKE_rigidbody_remove_constraint(struct Main *bmain,
+                                     struct Scene *scene,
+                                     struct Object *ob,
+                                     const bool free_us);
 
 /* -------------- */
 /* Utility Macros */
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 846b8d21f28..5b77c36024a 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -75,7 +75,10 @@ void BKE_scene_free(struct Scene *sce);
 void BKE_scene_init(struct Scene *sce);
 struct Scene *BKE_scene_add(struct Main *bmain, const char *name);
 
-void BKE_scene_remove_rigidbody_object(struct Main *bmain, struct Scene *scene, struct Object *ob);
+void BKE_scene_remove_rigidbody_object(struct Main *bmain,
+                                       struct Scene *scene,
+                                       struct Object *ob,
+                                       const bool free_us);
 
 bool BKE_scene_object_find(struct Scene *scene, struct Object *ob);
 struct Object *BKE_scene_object_find_by_name(struct Scene *scene, const char *name);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index f2098cc2430..931d248558d 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -773,7 +773,7 @@ static bool scene_collections_object_remove(
   bool removed = false;
 
   if (collection_skip == NULL) {
-    BKE_scene_remove_rigidbody_object(bmain, scene, ob);
+    BKE_scene_remove_rigidbody_object(bmain, scene, ob, free_us);
   }
 
   FOREACH_SCENE_COLLECTION_BEGIN (scene, collection) {
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 514f000d73d..c7a5104619b 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -1415,7 +1415,7 @@ bool BKE_rigidbody_add_object(Main *bmain, Scene *scene, Object *ob, int type, R
   return true;
 }
 
-void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob)
+void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob, const bool free_us)
 {
   RigidBodyWorld *rbw = scene->rigidbody_world;
   RigidBodyCon *rbc;
@@ -1438,8 +1438,13 @@ void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob)
       FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->constraints, obt) {
         if (obt && obt->rigidbody_constraint) {
           rbc = obt->rigidbody_constraint;
-          if (ELEM(ob, rbc->ob1, rbc->ob2)) {
-            BKE_rigidbody_remove_constraint(scene, obt);
+          if (rbc->ob1 == ob) {
+            rbc->ob1 = NULL;
+            DEG_id_tag_update(&obt->id, ID_RECALC_COPY_ON_WRITE);
+          }
+          if (rbc->ob2 == ob) {
+            rbc->ob2 = NULL;
+            DEG_id_tag_update(&obt->id, ID_RECALC_COPY_ON_WRITE);
           }
         }
       }
@@ -1454,7 +1459,7 @@ void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob)
        * when we remove them from RB simulation. */
       BKE_collection_object_add(bmain, scene->master_collection, ob);
     }
-    BKE_collection_object_remove(bmain, rbw->group, ob, false);
+    BKE_collection_object_remove(bmain, rbw->group, ob, free_us);
   }
 
   /* remove object's settings */
@@ -1468,15 +1473,24 @@ void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob)
   DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
 }
 
-void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
+void BKE_rigidbody_remove_constraint(Main *bmain, Scene *scene, Object *ob, const bool free_us)
 {
   RigidBodyWorld *rbw = scene->rigidbody_world;
   RigidBodyCon *rbc = ob->rigidbody_constraint;
 
-  /* remove from rigidbody world, free object won't do this */
-  if (rbw && rbw->shared->physics_world && rbc->physics_constraint) {
-    RB_dworld_remove_constraint(rbw->shared->physics_world, rbc->physics_constraint);
+  if (rbw != NULL) {
+    /* Remove from RBW constraints collection. */
+    if (rbw->constraints != NULL) {
+      BKE_collection_object_remove(bmain, rbw->constraints, ob, free_us);
+      DEG_id_tag_update(&rbw->constraints->id, ID_RECALC_COPY_ON_WRITE);
+    }
+
+    /* remove from rigidbody world, free object won't do this */
+    if (rbw->shared->physics_world && rbc->physics_constraint) {
+      RB_dworld_remove_constraint(rbw->shared->physics_world, rbc->physics_constraint);
+    }
   }
+
   /* remove object's settings */
   BKE_rigidbody_free_constraint(ob);
 
@@ -2086,10 +2100,10 @@ bool BKE_rigidbody_add_object(Main *bmain, Scene *scene, Object *ob, int type, R
   return false;
 }
 
-void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob)
+void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob, const bool free_us)
 {
 }
-void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
+void BKE_rigidbody_remove_constraint(Main *bmain, Scene *scene, Object *ob, const bool free_us)
 {
 }
 void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 4f855bd7d98..e8e849cdf6d 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1076,15 +1076,18 @@ int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, in
   return (delta_prev < delta_next) ? second_prev : second_next;
 }
 
-void BKE_scene_remove_rigidbody_object(struct Main *bmain, Scene *scene, Object *ob)
+void BKE_scene_remove_rigidbody_object(struct Main *bmain,
+                                       Scene *scene,
+                                       Object *ob,
+                                       const bool free_us)
 {
   /* remove rigid body constraint from world before removing object */
   if (ob->rigidbody_constraint) {
-    BKE_rigidbody_remove_constraint(scene, ob);
+    BKE_rigidbody_remove_constraint(bmain, scene, ob, free_us);
   }
   /* remove rigid body object from world before removing object */
   if (ob->rigidbody_object) {
-    BKE_rigidbody_remove_object(bmain, scene, ob);
+    BKE_rigidbody_remove_object(bmain, scene, ob, free_us);
   }
 }
 
diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c
index 4b1d51ee6c2..303a0714388 100644
--- a/source/blender/editors/physics/rigidbody_constraint.c
+++ b/source/blender/editors/physics/rigidbody_constraint.c
@@ -115,13 +115,7 @@ bool ED_rigidbody_constraint_add(
 
 void ED_rigidbody_constraint_remove(Main *bmain, Scene *scene, Object *ob)
 {
-  RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
-
-  BKE_rigidbody_remove_constraint(scene, ob);
-  if (rbw) {
-    BKE_collection_object_remove(bmain, rbw->constraints, ob, false);
-    DEG_id_tag_update(&rbw->constraints->id, ID_RECALC_COPY_ON_WRITE);
-  }
+  BKE_rigidbody_remove_constraint(bmain, scene, ob, false);
 
   DEG_relations_tag_update(bmain);
   DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c
index bc8a1799fa0..43ca421b9d0 100644
--- a/source/blender/editors/physics/rigidbody_object.c
+++ b/source/blender/editors/physics/rigidbody_object.c
@@ -105,7 +105,7 @@ bool ED_rigidbody_object_add(Main *bmain, Scene *scene, Object *ob, int type, Re
 
 void ED_rigidbody_object_remove(Main *bmain, Scene *scene, Object *ob)
 {
-  BKE_rigidbody_remove_object(bmain, scene, ob);
+  BKE_rigidbody_remove_object(bmain, scene, ob, false);
 
   DEG_relations_tag_update(bmain);
   DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);



More information about the Bf-blender-cvs mailing list