From 77495e3870ae34bc99895835bd7e91e42c400d21 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Fri, 23 Feb 2024 17:11:45 +0100 Subject: [PATCH 1/2] Fix #118637: crash after editbone duplication in certain case Crash happens in `action_group_colors_set_from_posebone` / `ANIM_bonecolor_posebone_get` on a `bPoseChannel` without a `bone`. If I am not mistaken a new `bPoseChannel` (e.g. after duplication) will only get its `bone` after leaving editmode. So in a way the situation is similar to 2a8ce1f12162 Behavior of `animchan_sync_group` is not reliable in a way that getting a `bPoseChannel` from an `bActionGroup` will guarantee these are really corresponding. So usually, if you dulplicate/symmetrize a bone, there would be no corresponding `bActionGroup` and nothing would happen really. But you could for example group fcurves from `Bone` under a group called `Bone.001` and vice versa. This is totally allowed to do. In this case, `animchan_sync_group` is doing nothing totally helpful, so it could find the "wrong" `bPoseChannel`. And it could try `action_group_colors_set_from_posebone` with that `bPoseChannel` which still does not have a `bone` and then crash. So now only do this if we have a valid `bone`. --- source/blender/blenkernel/intern/action.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/blenkernel/intern/action.cc b/source/blender/blenkernel/intern/action.cc index 232be615bb4..92cc82c3b60 100644 --- a/source/blender/blenkernel/intern/action.cc +++ b/source/blender/blenkernel/intern/action.cc @@ -374,6 +374,11 @@ void action_group_colors_sync(bActionGroup *grp, const bActionGroup *ref_grp) void action_group_colors_set_from_posebone(bActionGroup *grp, const bPoseChannel *pchan) { + /* pchan->bone is only set after leaving editmode. */ + if (pchan == nullptr || pchan->bone == nullptr) { + return; + } + const BoneColor &color = blender::animrig::ANIM_bonecolor_posebone_get(pchan); action_group_colors_set(grp, &color); } -- 2.30.2 From 73b8ea0967fd4405964d5e83be18641cb527d1d7 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Mon, 26 Feb 2024 13:22:03 +0100 Subject: [PATCH 2/2] additional polish by @dr.sybren thx! --- source/blender/animrig/intern/action.cc | 2 +- source/blender/blenkernel/BKE_action.h | 2 ++ source/blender/blenkernel/intern/action.cc | 5 +++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/animrig/intern/action.cc b/source/blender/animrig/intern/action.cc index 75e2cb331ac..9e4de3c55aa 100644 --- a/source/blender/animrig/intern/action.cc +++ b/source/blender/animrig/intern/action.cc @@ -87,7 +87,7 @@ FCurve *action_fcurve_ensure(Main *bmain, agrp = action_groups_add_new(act, group); /* Sync bone group colors if applicable. */ - if (ptr && (ptr->type == &RNA_PoseBone)) { + if (ptr && (ptr->type == &RNA_PoseBone) && ptr->data) { const bPoseChannel *pchan = static_cast(ptr->data); action_group_colors_set_from_posebone(agrp, pchan); } diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index fb8dfea95c0..53fccbe3316 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -136,6 +136,8 @@ void action_group_colors_set(struct bActionGroup *grp, const struct BoneColor *c * * If `pchan->color` is set to a non-default color, that is used. Otherwise the * armature bone color is used. + * + * Note that if `pchan->bone` is `nullptr`, this function silently does nothing. */ void action_group_colors_set_from_posebone(bActionGroup *grp, const bPoseChannel *pchan); diff --git a/source/blender/blenkernel/intern/action.cc b/source/blender/blenkernel/intern/action.cc index 92cc82c3b60..ba1133108f5 100644 --- a/source/blender/blenkernel/intern/action.cc +++ b/source/blender/blenkernel/intern/action.cc @@ -374,8 +374,9 @@ void action_group_colors_sync(bActionGroup *grp, const bActionGroup *ref_grp) void action_group_colors_set_from_posebone(bActionGroup *grp, const bPoseChannel *pchan) { - /* pchan->bone is only set after leaving editmode. */ - if (pchan == nullptr || pchan->bone == nullptr) { + BLI_assert_msg(pchan, "cannot 'set action group colors from posebone' without a posebone"); + if (!pchan->bone) { + /* pchan->bone is only set after leaving editmode. */ return; } -- 2.30.2