Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/armature/pose_transform.c
| Show First 20 Lines • Show All 911 Lines • ▼ Show 20 Lines | RNA_def_boolean(ot->srna, | ||||
| "On Selected Only", | "On Selected Only", | ||||
| "Only paste the stored pose on to selected bones in the current pose"); | "Only paste the stored pose on to selected bones in the current pose"); | ||||
| } | } | ||||
| /* ********************************************** */ | /* ********************************************** */ | ||||
| /* Clear Pose Transforms */ | /* Clear Pose Transforms */ | ||||
| /* clear scale of pose-channel */ | /* clear scale of pose-channel */ | ||||
| static void pchan_clear_scale(bPoseChannel *pchan) | static void pchan_clear_scale_helper(bPoseChannel *pchan) | ||||
| { | { | ||||
| if ((pchan->protectflag & OB_LOCK_SCALEX) == 0) { | if ((pchan->protectflag & OB_LOCK_SCALEX) == 0) { | ||||
| pchan->size[0] = 1.0f; | pchan->size[0] = 1.0f; | ||||
| } | } | ||||
| if ((pchan->protectflag & OB_LOCK_SCALEY) == 0) { | if ((pchan->protectflag & OB_LOCK_SCALEY) == 0) { | ||||
| pchan->size[1] = 1.0f; | pchan->size[1] = 1.0f; | ||||
| } | } | ||||
| if ((pchan->protectflag & OB_LOCK_SCALEZ) == 0) { | if ((pchan->protectflag & OB_LOCK_SCALEZ) == 0) { | ||||
| pchan->size[2] = 1.0f; | pchan->size[2] = 1.0f; | ||||
| } | } | ||||
| pchan->ease1 = 0.0f; | pchan->ease1 = 0.0f; | ||||
| pchan->ease2 = 0.0f; | pchan->ease2 = 0.0f; | ||||
| pchan->scale_in_x = pchan->scale_in_y = 1.0f; | pchan->scale_in_x = pchan->scale_in_y = 1.0f; | ||||
| pchan->scale_out_x = pchan->scale_out_y = 1.0f; | pchan->scale_out_x = pchan->scale_out_y = 1.0f; | ||||
| } | } | ||||
| /* The function checks of the X-Mirror settings is toggled and then | |||||
| * if it is, applies the scale reset transforms to both the pose channels */ | |||||
sybren: Comments are certainly welcome, but I think it can be clarified and shortened a bit. How about… | |||||
| static void pchan_clear_scale(const bPose *pose, bPoseChannel *pchan) | |||||
| { | |||||
| bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(pose, pchan->name); | |||||
| if ((pose->flag & POSE_MIRROR_EDIT) && (pchan_mirror != NULL)) { | |||||
sybrenUnsubmitted Done Inline ActionsThis can be optimized a bit. If mirror editing is disabled, there is no need to look up the mirrored pose channel: if (pose->flag & POSE_MIRROR_EDIT) {
bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(pose, pchan->name);
if (pchan_mirror != NULL) {
pchan_clear_scale_helper(pchan_mirror);
}
}sybren: This can be optimized a bit. If mirror editing is disabled, there is no need to look up the… | |||||
| pchan_clear_scale_helper(pchan_mirror); | |||||
| } | |||||
| pchan_clear_scale_helper(pchan); | |||||
| } | |||||
| /* clear location of pose-channel */ | /* clear location of pose-channel */ | ||||
| static void pchan_clear_loc(bPoseChannel *pchan) | static void pchan_clear_loc_helper(bPoseChannel *pchan) | ||||
| { | { | ||||
| if ((pchan->protectflag & OB_LOCK_LOCX) == 0) { | if ((pchan->protectflag & OB_LOCK_LOCX) == 0) { | ||||
| pchan->loc[0] = 0.0f; | pchan->loc[0] = 0.0f; | ||||
| } | } | ||||
| if ((pchan->protectflag & OB_LOCK_LOCY) == 0) { | if ((pchan->protectflag & OB_LOCK_LOCY) == 0) { | ||||
| pchan->loc[1] = 0.0f; | pchan->loc[1] = 0.0f; | ||||
| } | } | ||||
| if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) { | if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) { | ||||
| pchan->loc[2] = 0.0f; | pchan->loc[2] = 0.0f; | ||||
| } | } | ||||
| } | } | ||||
| /* The function checks of the X-Mirror settings is toggled and then | |||||
| * if it is, applies the location reset transforms to both the pose channels */ | |||||
| static void pchan_clear_loc(const bPose *pose, bPoseChannel *pchan) | |||||
| { | |||||
| bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(pose, pchan->name); | |||||
| if ((pose->flag & POSE_MIRROR_EDIT) && (pchan_mirror != NULL)) { | |||||
| pchan_clear_loc_helper(pchan_mirror); | |||||
| } | |||||
| pchan_clear_loc_helper(pchan); | |||||
| } | |||||
| /* clear rotation of pose-channel */ | /* clear rotation of pose-channel */ | ||||
| static void pchan_clear_rot(bPoseChannel *pchan) | static void pchan_clear_rot_helper(bPoseChannel *pchan) | ||||
| { | { | ||||
| if (pchan->protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) { | if (pchan->protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) { | ||||
| /* check if convert to eulers for locking... */ | /* check if convert to eulers for locking... */ | ||||
| if (pchan->protectflag & OB_LOCK_ROT4D) { | if (pchan->protectflag & OB_LOCK_ROT4D) { | ||||
| /* perform clamping on a component by component basis */ | /* perform clamping on a component by component basis */ | ||||
| if (pchan->rotmode == ROT_MODE_AXISANGLE) { | if (pchan->rotmode == ROT_MODE_AXISANGLE) { | ||||
| if ((pchan->protectflag & OB_LOCK_ROTW) == 0) { | if ((pchan->protectflag & OB_LOCK_ROTW) == 0) { | ||||
| pchan->rotAngle = 0.0f; | pchan->rotAngle = 0.0f; | ||||
| ▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | static void pchan_clear_rot_helper(bPoseChannel *pchan) | ||||
| pchan->roll1 = 0.0f; | pchan->roll1 = 0.0f; | ||||
| pchan->roll2 = 0.0f; | pchan->roll2 = 0.0f; | ||||
| pchan->curve_in_x = 0.0f; | pchan->curve_in_x = 0.0f; | ||||
| pchan->curve_in_y = 0.0f; | pchan->curve_in_y = 0.0f; | ||||
| pchan->curve_out_x = 0.0f; | pchan->curve_out_x = 0.0f; | ||||
| pchan->curve_out_y = 0.0f; | pchan->curve_out_y = 0.0f; | ||||
| } | } | ||||
| /* The function checks of the X-Mirror settings is toggled and then | |||||
| * if it is, applies the rotation reset transforms to both the pose channels */ | |||||
| static void pchan_clear_rot(const bPose *pose, bPoseChannel *pchan) | |||||
| { | |||||
| bPoseChannel *pchan_mirror = BKE_pose_channel_get_mirrored(pose, pchan->name); | |||||
| if ((pose->flag & POSE_MIRROR_EDIT) && (pchan_mirror != NULL)) { | |||||
| pchan_clear_rot_helper(pchan_mirror); | |||||
| } | |||||
| pchan_clear_rot_helper(pchan); | |||||
| } | |||||
| /* clear loc/rot/scale of pose-channel */ | /* 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_loc(pose, pchan); | ||||
| pchan_clear_rot(pchan); | pchan_clear_rot(pose, pchan); | ||||
| pchan_clear_scale(pchan); | pchan_clear_scale(pose, pchan); | ||||
| } | } | ||||
| /* --------------- */ | /* --------------- */ | ||||
| /* generic exec for clear-pose operators */ | /* generic exec for clear-pose operators */ | ||||
| static int pose_clear_transform_generic_exec(bContext *C, | static int pose_clear_transform_generic_exec(bContext *C, | ||||
| wmOperator *op, | wmOperator *op, | ||||
| void (*clear_func)(bPoseChannel *), | void (*clear_func)(const bPose *, bPoseChannel *), | ||||
| const char default_ksName[]) | const char default_ksName[]) | ||||
| { | { | ||||
| Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| bool changed_multi = false; | bool changed_multi = false; | ||||
| /* sanity checks */ | /* sanity checks */ | ||||
| if (ELEM(NULL, clear_func, default_ksName)) { | if (ELEM(NULL, clear_func, default_ksName)) { | ||||
| Show All 9 Lines | static int pose_clear_transform_generic_exec(bContext *C, | ||||
| FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) { | FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob_iter) { | ||||
| /* XXX: UGLY HACK (for autokey + clear transforms) */ | /* XXX: UGLY HACK (for autokey + clear transforms) */ | ||||
| Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter); | Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter); | ||||
| ListBase dsources = {NULL, NULL}; | ListBase dsources = {NULL, NULL}; | ||||
| bool changed = false; | bool changed = false; | ||||
| FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) { | FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (ob_iter, pchan) { | ||||
| /* run provided clearing function */ | /* run provided clearing function */ | ||||
| clear_func(pchan); | clear_func(ob_iter->pose, pchan); | ||||
| changed = true; | changed = true; | ||||
| /* do auto-keyframing as appropriate */ | /* do auto-keyframing as appropriate */ | ||||
| if (autokeyframe_cfra_can_key(scene, &ob_iter->id)) { | if (autokeyframe_cfra_can_key(scene, &ob_iter->id)) { | ||||
| /* clear any unkeyed tags */ | /* clear any unkeyed tags */ | ||||
| if (pchan->bone) { | if (pchan->bone) { | ||||
| pchan->bone->flag &= ~BONE_UNKEYED; | pchan->bone->flag &= ~BONE_UNKEYED; | ||||
| } | } | ||||
| /* tag for autokeying later */ | /* tag for autokeying later */ | ||||
| ANIM_relative_keyingset_add_source(&dsources, &ob_iter->id, &RNA_PoseBone, pchan); | ANIM_relative_keyingset_add_source(&dsources, &ob_iter->id, &RNA_PoseBone, pchan); | ||||
| #if 1 /* XXX: Ugly Hack - Run clearing function on evaluated copy of pchan */ | #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); | 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 | #endif | ||||
| } | } | ||||
| else { | else { | ||||
| /* add unkeyed tags */ | /* add unkeyed tags */ | ||||
| if (pchan->bone) { | if (pchan->bone) { | ||||
| pchan->bone->flag |= BONE_UNKEYED; | pchan->bone->flag |= BONE_UNKEYED; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 198 Lines • Show Last 20 Lines | |||||
Comments are certainly welcome, but I think it can be clarified and shortened a bit. How about something like "Clear the scale. When X-mirror is enabled, also clear the scale of the mirrored pose channel." ?