forked from bartvdbraak/blender
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...
This commit is contained in:
parent
51d9f56f87
commit
39439a3afe
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user