Fix T83657: Pose Mode: Clearing transform doesn't respect Mirror X

Extend the pose bone "clear loc/rot/scale" functions so that they
respect the "Mirror X" option.

Reviewed By: sybren

Maniphest Tasks: T83657

Differential Revision: https://developer.blender.org/D9938
This commit is contained in:
Karthik Rangasai Sivaraman 2021-01-18 11:56:57 +01:00 committed by Sybren A. Stüvel
parent 4ef0654449
commit f7a5695676
Notes: blender-bot 2023-02-14 06:23:08 +01:00
Referenced by issue #83657, Pose Mode: Clearing transform doesn't respect Mirror X
Referenced by issue #76915, Pose bone: clearing transformations in pose mode does not affect the mirrored bones even when the X-axis mirror is activated.
1 changed files with 49 additions and 10 deletions

View File

@ -934,6 +934,18 @@ static void pchan_clear_scale(bPoseChannel *pchan)
pchan->scale_in_x = pchan->scale_in_y = 1.0f;
pchan->scale_out_x = pchan->scale_out_y = 1.0f;
}
/* Clear the scale. When X-mirror is enabled,
* also clear the scale of the mirrored pose channel. */
static void pchan_clear_scale_with_mirrored(const bPose *pose, bPoseChannel *pchan)
{
if (pose->flag & POSE_MIRROR_EDIT) {
bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(pose, pchan->name);
if (pchan_mirror != NULL) {
pchan_clear_scale(pchan_mirror);
}
}
pchan_clear_scale(pchan);
}
/* clear location of pose-channel */
static void pchan_clear_loc(bPoseChannel *pchan)
@ -948,6 +960,18 @@ static void pchan_clear_loc(bPoseChannel *pchan)
pchan->loc[2] = 0.0f;
}
}
/* Clear the Location. When X-mirror is enabled,
* also clear the location of the mirrored pose channel. */
static void pchan_clear_loc_with_mirrored(const bPose *pose, bPoseChannel *pchan)
{
if (pose->flag & POSE_MIRROR_EDIT) {
bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(pose, pchan->name);
if (pchan_mirror != NULL) {
pchan_clear_loc(pchan_mirror);
}
}
pchan_clear_loc(pchan);
}
/* clear rotation of pose-channel */
static void pchan_clear_rot(bPoseChannel *pchan)
@ -1075,13 +1099,25 @@ static void pchan_clear_rot(bPoseChannel *pchan)
pchan->curve_out_x = 0.0f;
pchan->curve_out_y = 0.0f;
}
/* Clear the rotation. When X-mirror is enabled,
* also clear the rotation of the mirrored pose channel. */
static void pchan_clear_rot_with_mirrored(const bPose *pose, bPoseChannel *pchan)
{
if (pose->flag & POSE_MIRROR_EDIT) {
bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(pose, pchan->name);
if (pchan_mirror != NULL) {
pchan_clear_rot(pchan_mirror);
}
}
pchan_clear_rot(pchan);
}
/* clear loc/rot/scale of pose-channel */
static void pchan_clear_transforms(bPoseChannel *pchan)
static void pchan_clear_transforms(const bPose *pose, bPoseChannel *pchan)
{
pchan_clear_loc(pchan);
pchan_clear_rot(pchan);
pchan_clear_scale(pchan);
pchan_clear_loc_with_mirrored(pose, pchan);
pchan_clear_rot_with_mirrored(pose, pchan);
pchan_clear_scale_with_mirrored(pose, pchan);
}
/* --------------- */
@ -1089,7 +1125,7 @@ static void pchan_clear_transforms(bPoseChannel *pchan)
/* generic exec for clear-pose operators */
static int pose_clear_transform_generic_exec(bContext *C,
wmOperator *op,
void (*clear_func)(bPoseChannel *),
void (*clear_func)(const bPose *, bPoseChannel *),
const char default_ksName[])
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@ -1115,7 +1151,7 @@ static int pose_clear_transform_generic_exec(bContext *C,
FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) {
/* run provided clearing function */
clear_func(pchan);
clear_func(ob_iter->pose, pchan);
changed = true;
/* do auto-keyframing as appropriate */
@ -1129,7 +1165,7 @@ static int pose_clear_transform_generic_exec(bContext *C,
#if 1 /* XXX: Ugly Hack - Run clearing function on evaluated copy of pchan */
bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
clear_func(pchan_eval);
clear_func(ob_iter->pose, pchan_eval);
#endif
}
else {
@ -1175,7 +1211,8 @@ static int pose_clear_transform_generic_exec(bContext *C,
static int pose_clear_scale_exec(bContext *C, wmOperator *op)
{
return pose_clear_transform_generic_exec(C, op, pchan_clear_scale, ANIM_KS_SCALING_ID);
return pose_clear_transform_generic_exec(
C, op, pchan_clear_scale_with_mirrored, ANIM_KS_SCALING_ID);
}
void POSE_OT_scale_clear(wmOperatorType *ot)
@ -1195,7 +1232,8 @@ void POSE_OT_scale_clear(wmOperatorType *ot)
static int pose_clear_rot_exec(bContext *C, wmOperator *op)
{
return pose_clear_transform_generic_exec(C, op, pchan_clear_rot, ANIM_KS_ROTATION_ID);
return pose_clear_transform_generic_exec(
C, op, pchan_clear_rot_with_mirrored, ANIM_KS_ROTATION_ID);
}
void POSE_OT_rot_clear(wmOperatorType *ot)
@ -1215,7 +1253,8 @@ void POSE_OT_rot_clear(wmOperatorType *ot)
static int pose_clear_loc_exec(bContext *C, wmOperator *op)
{
return pose_clear_transform_generic_exec(C, op, pchan_clear_loc, ANIM_KS_LOCATION_ID);
return pose_clear_transform_generic_exec(
C, op, pchan_clear_loc_with_mirrored, ANIM_KS_LOCATION_ID);
}
void POSE_OT_loc_clear(wmOperatorType *ot)