From 3731729b96fa2145b7d462dec20277088a75a0c4 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sun, 14 Apr 2019 21:53:03 +0300 Subject: Depsgraph: fix hard CTD on dependency cycles through POSE_INIT. As reported in T63582, it can cause chan_array to be not ready. To reliably avoid crashing, the only easy way seems to be to create the index during COW -- maybe @sergey has a better idea. --- source/blender/blenkernel/BKE_armature.h | 2 ++ source/blender/blenkernel/intern/action.c | 2 ++ source/blender/blenkernel/intern/armature_update.c | 10 ++++++---- source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc | 1 + 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 7182561a038..d9a1064d740 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -245,6 +245,8 @@ void BKE_splineik_execute_tree( struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan_root, float ctime); +void BKE_pose_pchan_index_rebuild(struct bPose *pose); + void BKE_pose_eval_init( struct Depsgraph *depsgraph, struct Scene *scene, diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 9ba3a23df05..da4fea26e64 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -825,6 +825,8 @@ void BKE_pose_channels_free_ex(bPose *pose, bool do_id_user) } BKE_pose_channels_hash_free(pose); + + MEM_SAFE_FREE(pose->chan_array); } void BKE_pose_channels_free(bPose *pose) diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c index 790f5cb2b31..892b2211bf9 100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@ -556,8 +556,9 @@ void BKE_splineik_execute_tree( /* *************** Depsgraph evaluation callbacks ************ */ -static void pose_pchan_index_create(bPose *pose) +void BKE_pose_pchan_index_rebuild(bPose *pose) { + MEM_SAFE_FREE(pose->chan_array); const int num_channels = BLI_listbase_count(&pose->chanbase); pose->chan_array = MEM_malloc_arrayN( num_channels, sizeof(bPoseChannel *), "pose->chan_array"); @@ -605,7 +606,8 @@ void BKE_pose_eval_init(struct Depsgraph *depsgraph, } } - pose_pchan_index_create(pose); + BLI_assert(pose->chan_array != NULL || BLI_listbase_is_empty(&pose->chanbase)); + BKE_armature_cached_bbone_deformation_free_data(object); } @@ -806,7 +808,6 @@ static void pose_eval_cleanup_common(Object *object) bPose *pose = object->pose; BLI_assert(pose != NULL); BLI_assert(pose->chan_array != NULL || BLI_listbase_is_empty(&pose->chanbase)); - MEM_SAFE_FREE(pose->chan_array); } void BKE_pose_eval_done(struct Depsgraph *depsgraph, Object *object) @@ -839,7 +840,8 @@ void BKE_pose_eval_proxy_init(struct Depsgraph *depsgraph, Object *object) BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL); DEG_debug_print_eval(depsgraph, __func__, object->id.name, object); - pose_pchan_index_create(object->pose); + BLI_assert(pose->chan_array != NULL || BLI_listbase_is_empty(&pose->chanbase)); + BKE_armature_cached_bbone_deformation_free_data(object); } diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index 0d60defa9b6..387253ab3fe 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -697,6 +697,7 @@ void update_id_after_copy(const Depsgraph *depsgraph, update_pose_orig_pointers(object_orig->pose, object_cow->pose); } + BKE_pose_pchan_index_rebuild(object_cow->pose); } update_particles_after_copy(object_orig, object_cow); update_modifiers_orig_pointers(object_orig, object_cow); -- cgit v1.2.3