diff --git a/source/blender/editors/armature/pose_select.cc b/source/blender/editors/armature/pose_select.cc index 284f9e12272..f6ed35907a8 100644 --- a/source/blender/editors/armature/pose_select.cc +++ b/source/blender/editors/armature/pose_select.cc @@ -1139,7 +1139,10 @@ static wmOperatorStatus pose_select_mirror_exec(bContext *C, wmOperator *op) /* Remember the pre-mirroring selection flags of the bones. */ blender::Map old_selection_flags; LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { - old_selection_flags.add_new(pchan, eBone_Flag(pchan->bone->flag)); + /* Treat invisible bones as deselected. */ + const int flags = PBONE_VISIBLE(arm, pchan->bone) ? pchan->bone->flag : 0; + + old_selection_flags.add_new(pchan, eBone_Flag(flags)); } LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { @@ -1148,8 +1151,10 @@ static wmOperatorStatus pose_select_mirror_exec(bContext *C, wmOperator *op) } bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(ob->pose, pchan->name); - if (!pchan_mirror || !PBONE_VISIBLE(arm, pchan_mirror->bone)) { - set_bone_selection_flags(pchan, eBone_Flag(0)); + if (!pchan_mirror) { + /* If a bone cannot be mirrored, keep its flags as-is. This makes it possible to select + * the spine and an arm, and still flip the selection to the other arm (without losing + * the selection on the spine). */ continue; } @@ -1157,7 +1162,7 @@ static wmOperatorStatus pose_select_mirror_exec(bContext *C, wmOperator *op) pchan_mirror_act = pchan_mirror; } - /* Skip all but the active or its mirror. */ + /* If active-only, don't touch unrelated bones. */ if (active_only && !ELEM(arm->act_bone, pchan->bone, pchan_mirror->bone)) { continue; }