[Bf-blender-cvs] [39439a3afe1] master: Fix T69156: Blender crash when baking rigid body world.

Bastien Montagne noreply at git.blender.org
Mon Aug 26 16:06:21 CEST 2019


Commit: 39439a3afe18bb614e7ada1f61682b602a6c0549
Author: Bastien Montagne
Date:   Mon Aug 26 16:01:16 2019 +0200
Branches: master
https://developer.blender.org/rB39439a3afe18bb614e7ada1f61682b602a6c0549

Fix T69156: Blender crash when baking rigid body world.

Issue was exposed by recent own rB03bf84db86b commit, but was actually
present in RNA API for PointCaches since (probably) ages: whole accessor
code here was assuming that owner ID was an Object, when it is actually
a scene for RigidBody simulations...

Had also to make `BKE_ptcache_id_find()` and friends a bit more
flexible, now they also accept a NULL object pointer parameter...

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

M	source/blender/blenkernel/intern/pointcache.c
M	source/blender/makesrna/intern/rna_object_force.c

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

diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 13d0f1adb84..5f073120383 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1831,6 +1831,7 @@ void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, Object *ob, RigidBodyWorld *r
   pid->file_type = PTCACHE_FILE_PTCACHE;
 }
 
+/** Both \param ob and \param scene may be NULL. */
 PTCacheID BKE_ptcache_id_find(Object *ob, Scene *scene, PointCache *cache)
 {
   PTCacheID result = {0};
@@ -1934,40 +1935,45 @@ static bool foreach_object_ptcache(
     Scene *scene, Object *object, int duplis, ForeachPtcacheCb callback, void *callback_user_data)
 {
   PTCacheID pid;
-  /* Soft body. */
-  if (object->soft != NULL) {
-    BKE_ptcache_id_from_softbody(&pid, object, object->soft);
-    if (!callback(&pid, callback_user_data)) {
+
+  if (object != NULL) {
+    /* Soft body. */
+    if (object->soft != NULL) {
+      BKE_ptcache_id_from_softbody(&pid, object, object->soft);
+      if (!callback(&pid, callback_user_data)) {
+        return false;
+      }
+    }
+    /* Particle systems. */
+    if (!foreach_object_particle_ptcache(object, callback, callback_user_data)) {
       return false;
     }
+    /* Modifiers. */
+    if (!foreach_object_modifier_ptcache(object, callback, callback_user_data)) {
+      return false;
+    }
+    /* Consider all object in dupli groups to be part of the same object,
+     * for baking with linking dupligroups. Once we have better overrides
+     * this can be revisited so users select the local objects directly. */
+    if (scene != NULL && (duplis-- > 0) && (object->instance_collection != NULL)) {
+      FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (object->instance_collection, current_object) {
+        if (current_object == object) {
+          continue;
+        }
+        foreach_object_ptcache(scene, current_object, duplis, callback, callback_user_data);
+      }
+      FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+    }
   }
-  /* Particle systems. */
-  if (!foreach_object_particle_ptcache(object, callback, callback_user_data)) {
-    return false;
-  }
-  /* Modifiers. */
-  if (!foreach_object_modifier_ptcache(object, callback, callback_user_data)) {
-    return false;
-  }
+
   /* Rigid body. */
-  if (scene != NULL && object->rigidbody_object != NULL && scene->rigidbody_world != NULL) {
+  if (scene != NULL && (object == NULL || object->rigidbody_object != NULL) &&
+      scene->rigidbody_world != NULL) {
     BKE_ptcache_id_from_rigidbody(&pid, object, scene->rigidbody_world);
     if (!callback(&pid, callback_user_data)) {
       return false;
     }
   }
-  /* Consider all object in dupli groups to be part of the same object,
-   * for baking with linking dupligroups. Once we have better overrides
-   * this can be revisited so users select the local objects directly. */
-  if (scene != NULL && (duplis-- > 0) && (object->instance_collection != NULL)) {
-    FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (object->instance_collection, current_object) {
-      if (current_object == object) {
-        continue;
-      }
-      foreach_object_ptcache(scene, current_object, duplis, callback, callback_user_data);
-    }
-    FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
-  }
   return true;
 }
 
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index d082dfc694c..86da6d59c28 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -120,18 +120,38 @@ static const EnumPropertyItem empty_vortex_shape_items[] = {
 
 #  include "ED_object.h"
 
+static bool rna_Cache_get_valid_owner_ID(PointerRNA *ptr, Object **ob, Scene **scene)
+{
+  switch (GS(ptr->owner_id->name)) {
+    case ID_OB:
+      *ob = (Object *)ptr->owner_id;
+      break;
+    case ID_SCE:
+      *scene = (Scene *)ptr->owner_id;
+      break;
+    default:
+      BLI_assert(!"Trying to get PTCacheID from an invalid ID type "
+                  "(Only scenes and objects are supported).");
+      break;
+  }
+
+  return (*ob != NULL || *scene != NULL);
+}
+
 static void rna_Cache_change(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
 {
-  Object *ob = (Object *)ptr->owner_id;
-  PointCache *cache = (PointCache *)ptr->data;
+  Object *ob = NULL;
+  Scene *scene = NULL;
 
-  if (!ob) {
+  if (!rna_Cache_get_valid_owner_ID(ptr, &ob, &scene)) {
     return;
   }
 
+  PointCache *cache = (PointCache *)ptr->data;
+
   cache->flag |= PTCACHE_OUTDATED;
 
-  PTCacheID pid = BKE_ptcache_id_find(ob, NULL, cache);
+  PTCacheID pid = BKE_ptcache_id_find(ob, scene, cache);
 
   DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
 
@@ -146,14 +166,16 @@ static void rna_Cache_change(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerR
 
 static void rna_Cache_toggle_disk_cache(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
 {
-  Object *ob = (Object *)ptr->owner_id;
-  PointCache *cache = (PointCache *)ptr->data;
+  Object *ob = NULL;
+  Scene *scene = NULL;
 
-  if (!ob) {
+  if (!rna_Cache_get_valid_owner_ID(ptr, &ob, &scene)) {
     return;
   }
 
-  PTCacheID pid = BKE_ptcache_id_find(ob, NULL, cache);
+  PointCache *cache = (PointCache *)ptr->data;
+
+  PTCacheID pid = BKE_ptcache_id_find(ob, scene, cache);
 
   /* smoke can only use disk cache */
   if (pid.cache && pid.type != PTCACHE_TYPE_SMOKE_DOMAIN) {
@@ -166,18 +188,20 @@ static void rna_Cache_toggle_disk_cache(Main *UNUSED(bmain), Scene *UNUSED(scene
 
 static void rna_Cache_idname_change(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
 {
-  Object *ob = (Object *)ptr->owner_id;
-  PointCache *cache = (PointCache *)ptr->data;
-  bool use_new_name = true;
+  Object *ob = NULL;
+  Scene *scene = NULL;
 
-  if (!ob) {
+  if (!rna_Cache_get_valid_owner_ID(ptr, &ob, &scene)) {
     return;
   }
 
+  PointCache *cache = (PointCache *)ptr->data;
+  bool use_new_name = true;
+
   /* TODO: check for proper characters */
 
   if (cache->flag & PTCACHE_EXTERNAL) {
-    PTCacheID pid = BKE_ptcache_id_find(ob, NULL, cache);
+    PTCacheID pid = BKE_ptcache_id_find(ob, scene, cache);
 
     if (pid.cache) {
       BKE_ptcache_load_external(&pid);
@@ -190,7 +214,7 @@ static void rna_Cache_idname_change(Main *UNUSED(bmain), Scene *UNUSED(scene), P
     PTCacheID *pid = NULL, *pid2 = NULL;
     ListBase pidlist;
 
-    BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0);
+    BKE_ptcache_ids_from_object(&pidlist, ob, scene, 0);
 
     for (pid = pidlist.first; pid; pid = pid->next) {
       if (pid->cache == cache) {
@@ -240,13 +264,19 @@ static void rna_Cache_list_begin(CollectionPropertyIterator *iter, PointerRNA *p
 static void rna_Cache_active_point_cache_index_range(
     PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax))
 {
-  Object *ob = (Object *)ptr->owner_id;
-  PointCache *cache = ptr->data;
-  PTCacheID pid = BKE_ptcache_id_find(ob, NULL, cache);
-
   *min = 0;
   *max = 0;
 
+  Object *ob = NULL;
+  Scene *scene = NULL;
+
+  if (!rna_Cache_get_valid_owner_ID(ptr, &ob, &scene)) {
+    return;
+  }
+
+  PointCache *cache = ptr->data;
+  PTCacheID pid = BKE_ptcache_id_find(ob, scene, cache);
+
   if (pid.cache) {
     *max = max_ii(0, BLI_listbase_count(pid.ptcaches) - 1);
   }
@@ -254,11 +284,18 @@ static void rna_Cache_active_point_cache_index_range(
 
 static int rna_Cache_active_point_cache_index_get(PointerRNA *ptr)
 {
-  Object *ob = (Object *)ptr->owner_id;
-  PointCache *cache = ptr->data;
-  PTCacheID pid = BKE_ptcache_id_find(ob, NULL, cache);
   int num = 0;
 
+  Object *ob = NULL;
+  Scene *scene = NULL;
+
+  if (!rna_Cache_get_valid_owner_ID(ptr, &ob, &scene)) {
+    return num;
+  }
+
+  PointCache *cache = ptr->data;
+  PTCacheID pid = BKE_ptcache_id_find(ob, scene, cache);
+
   if (pid.cache) {
     num = BLI_findindex(pid.ptcaches, cache);
   }
@@ -268,9 +305,15 @@ static int rna_Cache_active_point_cache_index_get(PointerRNA *ptr)
 
 static void rna_Cache_active_point_cache_index_set(struct PointerRNA *ptr, int value)
 {
-  Object *ob = (Object *)ptr->owner_id;
+  Object *ob = NULL;
+  Scene *scene = NULL;
+
+  if (!rna_Cache_get_valid_owner_ID(ptr, &ob, &scene)) {
+    return;
+  }
+
   PointCache *cache = ptr->data;
-  PTCacheID pid = BKE_ptcache_id_find(ob, NULL, cache);
+  PTCacheID pid = BKE_ptcache_id_find(ob, scene, cache);
 
   if (pid.cache) {
     *(pid.cache_ptr) = BLI_findlink(pid.ptcaches, value);
@@ -280,13 +323,19 @@ static void rna_Cache_active_point_cache_index_set(struct PointerRNA *ptr, int v
 static void rna_PointCache_frame_step_range(
     PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax))
 {
-  Object *ob = (Object *)ptr->owner_id;
-  PointCache *cache = ptr->data;
-  PTCacheID pid = BKE_ptcache_id_find(ob, NULL, cache);
-
   *min = 1;
   *max = 20;
 
+  Object *ob = NULL;
+  Scene *scene = NULL;
+
+  if (!rna_Cache_get_valid_owner_ID(ptr, &ob, &scene)) {
+    return;
+  }
+
+  PointCache *cache = ptr->data;
+  PTCacheID pid = BKE_ptcache_id_find(ob, scene, cache);
+
   if (pid.cache) {
     *max = pid.max_step;
   }
@@ -294,14 +343,16 @@ static void rna_PointCache_frame_step_range(
 
 int rna_Cache_info_length(PointerRNA *ptr)
 {
-  PointCache *cache = (PointCache *)ptr->data;
-  Object *ob = (Object *)ptr->owner_id;
+  Object *ob = NULL;
+  Scene *scene = NULL;
 
-  if (!ob) {
+  if (!rna_Cache_get_valid_owner_ID(ptr, &ob, &scene)) {
     return 0;
   }
 
-  PTCacheID pid = BKE_ptcache_id_find(ob, NULL, cache);
+  PointCache *cache = (PointCache *)ptr->data;
+
+  PTCacheID pid = BKE_ptcache_id_find(ob, scene, cache);
 
   if (cache->flag & PTCACHE_FLAG_INFO_DIRTY) {
     BKE_ptcache_update_info(&pid);



More information about the Bf-blender-cvs mailing list