Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/armature/pose_transform.c
| Show First 20 Lines • Show All 928 Lines • ▼ Show 20 Lines | 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; | ||||
| } | } | ||||
| /* Clear the scale. When X-mirror is enabled, | |||||
| * also clear the scale of the mirrored pose channel. */ | |||||
sybren: Comments are certainly welcome, but I think it can be clarified and shortened a bit. How about… | |||||
| 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); | |||||
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… | |||||
| if (pchan_mirror != NULL) { | |||||
| pchan_clear_scale(pchan_mirror); | |||||
| } | |||||
| } | |||||
| pchan_clear_scale(pchan); | |||||
| } | |||||
| /* clear location of pose-channel */ | /* clear location of pose-channel */ | ||||
| static void pchan_clear_loc(bPoseChannel *pchan) | static void pchan_clear_loc(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; | ||||
| } | } | ||||
| } | } | ||||
| /* 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 */ | /* clear rotation of pose-channel */ | ||||
| static void pchan_clear_rot(bPoseChannel *pchan) | static void pchan_clear_rot(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 */ | ||||
| ▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | static void pchan_clear_rot(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; | ||||
| } | } | ||||
| /* 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 */ | /* 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_with_mirrored(pose, pchan); | ||||
| pchan_clear_rot(pchan); | pchan_clear_rot_with_mirrored(pose, pchan); | ||||
| pchan_clear_scale(pchan); | pchan_clear_scale_with_mirrored(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 All 29 Lines | #endif | ||||
| return changed_multi ? OPERATOR_FINISHED : OPERATOR_CANCELLED; | return changed_multi ? OPERATOR_FINISHED : OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* --------------- */ | /* --------------- */ | ||||
| static int pose_clear_scale_exec(bContext *C, wmOperator *op) | 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) | void POSE_OT_scale_clear(wmOperatorType *ot) | ||||
| { | { | ||||
| /* identifiers */ | /* identifiers */ | ||||
| ot->name = "Clear Pose Scale"; | ot->name = "Clear Pose Scale"; | ||||
| ot->idname = "POSE_OT_scale_clear"; | ot->idname = "POSE_OT_scale_clear"; | ||||
| ot->description = "Reset scaling of selected bones to their default values"; | ot->description = "Reset scaling of selected bones to their default values"; | ||||
| /* api callbacks */ | /* api callbacks */ | ||||
| ot->exec = pose_clear_scale_exec; | ot->exec = pose_clear_scale_exec; | ||||
| ot->poll = ED_operator_posemode; | ot->poll = ED_operator_posemode; | ||||
| /* flags */ | /* flags */ | ||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| } | } | ||||
| static int pose_clear_rot_exec(bContext *C, wmOperator *op) | 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) | void POSE_OT_rot_clear(wmOperatorType *ot) | ||||
| { | { | ||||
| /* identifiers */ | /* identifiers */ | ||||
| ot->name = "Clear Pose Rotation"; | ot->name = "Clear Pose Rotation"; | ||||
| ot->idname = "POSE_OT_rot_clear"; | ot->idname = "POSE_OT_rot_clear"; | ||||
| ot->description = "Reset rotations of selected bones to their default values"; | ot->description = "Reset rotations of selected bones to their default values"; | ||||
| /* api callbacks */ | /* api callbacks */ | ||||
| ot->exec = pose_clear_rot_exec; | ot->exec = pose_clear_rot_exec; | ||||
| ot->poll = ED_operator_posemode; | ot->poll = ED_operator_posemode; | ||||
| /* flags */ | /* flags */ | ||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| } | } | ||||
| static int pose_clear_loc_exec(bContext *C, wmOperator *op) | 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) | void POSE_OT_loc_clear(wmOperatorType *ot) | ||||
| { | { | ||||
| /* identifiers */ | /* identifiers */ | ||||
| ot->name = "Clear Pose Location"; | ot->name = "Clear Pose Location"; | ||||
| ot->idname = "POSE_OT_loc_clear"; | ot->idname = "POSE_OT_loc_clear"; | ||||
| ot->description = "Reset locations of selected bones to their default values"; | ot->description = "Reset locations of selected bones to their default values"; | ||||
| ▲ Show 20 Lines • Show All 112 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." ?