diff options
Diffstat (limited to 'source/blender/editors/armature/pose_transform.c')
-rw-r--r-- | source/blender/editors/armature/pose_transform.c | 192 |
1 files changed, 96 insertions, 96 deletions
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c index e212d426c9a..de0612d840d 100644 --- a/source/blender/editors/armature/pose_transform.c +++ b/source/blender/editors/armature/pose_transform.c @@ -78,16 +78,16 @@ static void applyarmature_fix_boneparents(const bContext *C, Scene *scene, Objec Depsgraph *depsgraph = CTX_data_depsgraph(C); Main *bmain = CTX_data_main(C); Object workob, *ob; - + /* go through all objects in database */ for (ob = bmain->object.first; ob; ob = ob->id.next) { /* if parent is bone in this armature, apply corrections */ if ((ob->parent == armob) && (ob->partype == PARBONE)) { - /* apply current transform from parent (not yet destroyed), + /* apply current transform from parent (not yet destroyed), * then calculate new parent inverse matrix */ BKE_object_apply_mat4(ob, ob->obmat, false, false); - + BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); } @@ -123,18 +123,18 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) /* Get editbones of active armature to alter */ ED_armature_to_edit(arm); - + /* get pose of active object and move it out of posemode */ pose = ob->pose; - + for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { const bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name); curbone = ED_armature_ebone_find_name(arm->edbo, pchan->name); - + /* simply copy the head/tail values from pchan over to curbone */ copy_v3_v3(curbone->head, pchan_eval->pose_head); copy_v3_v3(curbone->tail, pchan_eval->pose_tail); - + /* fix roll: * 1. find auto-calculated roll value for this bone now * 2. remove this from the 'visual' y-rotation @@ -142,23 +142,23 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) { float premat[3][3], imat[3][3], pmat[3][3], tmat[3][3]; float delta[3], eul[3]; - + /* obtain new auto y-rotation */ sub_v3_v3v3(delta, curbone->tail, curbone->head); vec_roll_to_mat3(delta, 0.0f, premat); invert_m3_m3(imat, premat); - + /* get pchan 'visual' matrix */ copy_m3_m4(pmat, pchan_eval->pose_mat); - + /* remove auto from visual and get euler rotation */ mul_m3_m3m3(tmat, imat, pmat); mat3_to_eul(eul, tmat); - + /* just use this euler-y as new roll value */ curbone->roll = eul[1]; } - + /* combine pose and rest values for bendy bone settings, * then clear the pchan values (so we don't get a double-up) */ @@ -174,7 +174,7 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) curbone->ease2 += pchan_eval->ease2; curbone->scaleIn += pchan_eval->scaleIn; curbone->scaleOut += pchan_eval->scaleOut; - + /* reset pose values */ pchan->curveInX = pchan->curveOutX = 0.0f; pchan->curveInY = pchan->curveOutY = 0.0f; @@ -182,32 +182,32 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) pchan->ease1 = pchan->ease2 = 0.0f; pchan->scaleIn = pchan->scaleOut = 1.0f; } - + /* clear transform values for pchan */ zero_v3(pchan->loc); zero_v3(pchan->eul); unit_qt(pchan->quat); unit_axis_angle(pchan->rotAxis, &pchan->rotAngle); pchan->size[0] = pchan->size[1] = pchan->size[2] = 1.0f; - + /* set anim lock */ curbone->flag |= BONE_UNKEYED; } - + /* convert editbones back to bones, and then free the edit-data */ ED_armature_from_edit(arm); ED_armature_edit_free(arm); - + /* flush positions of posebones */ BKE_pose_where_is(depsgraph, scene, ob); - + /* fix parenting of objects which are bone-parented */ applyarmature_fix_boneparents(C, scene, ob); - + /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE); - + return OPERATOR_FINISHED; } @@ -217,11 +217,11 @@ void POSE_OT_armature_apply(wmOperatorType *ot) ot->name = "Apply Pose as Rest Pose"; ot->idname = "POSE_OT_armature_apply"; ot->description = "Apply the current pose as the new rest pose"; - + /* callbacks */ ot->exec = apply_armature_pose2bones_exec; ot->poll = ED_operator_posemode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } @@ -244,21 +244,21 @@ static int pose_visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op)) const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name); float delta_mat[4][4]; - + /* chan_mat already contains the delta transform from rest pose to pose-mode pose * as that is baked into there so that B-Bones will work. Once we've set this as the - * new raw-transform components, don't recalc the poses yet, otherwise IK result will + * new raw-transform components, don't recalc the poses yet, otherwise IK result will * change, thus changing the result we may be trying to record. */ /* XXX For some reason, we can't use pchan->chan_mat here, gives odd rotation/offset (see T38251). * Using pchan->pose_mat and bringing it back in bone space seems to work as expected! */ BKE_armature_mat_pose_to_bone(pchan_eval, pchan_eval->pose_mat, delta_mat); - + BKE_pchan_apply_mat4(pchan, delta_mat, true); } FOREACH_PCHAN_SELECTED_IN_OBJECT_END; - + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); /* note, notifier might evolve */ @@ -275,11 +275,11 @@ void POSE_OT_visual_transform_apply(wmOperatorType *ot) ot->name = "Apply Visual Transform to Pose"; ot->idname = "POSE_OT_visual_transform_apply"; ot->description = "Apply final constrained position of pose bones to their transform"; - + /* callbacks */ ot->exec = pose_visual_transform_apply_exec; ot->poll = ED_operator_posemode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } @@ -287,7 +287,7 @@ void POSE_OT_visual_transform_apply(wmOperatorType *ot) /* ********************************************** */ /* Copy/Paste */ -/* This function is used to indicate that a bone is selected +/* This function is used to indicate that a bone is selected * and needs to be included in copy buffer (used to be for inserting keys) */ static void set_pose_keys(Object *ob) @@ -320,33 +320,33 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bo bPoseChannel *pchan; char name[MAXBONENAME]; short paste_ok; - + /* get the name - if flipping, we must flip this first */ if (flip) BLI_string_flip_side_name(name, chan->name, false, sizeof(name)); else BLI_strncpy(name, chan->name, sizeof(name)); - + /* only copy when: * 1) channel exists - poses are not meant to add random channels to anymore * 2) if selection-masking is on, channel is selected - only selected bones get pasted on, allowing making both sides symmetrical */ pchan = BKE_pose_channel_find_name(ob->pose, name); - + if (selOnly) paste_ok = ((pchan) && (pchan->bone->flag & BONE_SELECTED)); else paste_ok = (pchan != NULL); - + /* continue? */ if (paste_ok) { - /* only loc rot size - * - only copies transform info for the pose + /* only loc rot size + * - only copies transform info for the pose */ copy_v3_v3(pchan->loc, chan->loc); copy_v3_v3(pchan->size, chan->size); pchan->flag = chan->flag; - + /* check if rotation modes are compatible (i.e. do they need any conversions) */ if (pchan->rotmode == chan->rotmode) { /* copy the type of rotation in use */ @@ -382,29 +382,29 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bo else axis_angle_to_quat(pchan->quat, chan->rotAxis, pchan->rotAngle); } - + /* B-Bone posing options should also be included... */ pchan->curveInX = chan->curveInX; pchan->curveInY = chan->curveInY; pchan->curveOutX = chan->curveOutX; pchan->curveOutY = chan->curveOutY; - + pchan->roll1 = chan->roll1; pchan->roll2 = chan->roll2; pchan->ease1 = chan->ease1; pchan->ease2 = chan->ease2; pchan->scaleIn = chan->scaleIn; pchan->scaleOut = chan->scaleOut; - + /* paste flipped pose? */ if (flip) { pchan->loc[0] *= -1; - + pchan->curveInX *= -1; pchan->curveOutX *= -1; pchan->roll1 *= -1; // XXX? pchan->roll2 *= -1; // XXX? - + /* has to be done as eulers... */ if (pchan->rotmode > 0) { pchan->eul[1] *= -1; @@ -412,7 +412,7 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bo } else if (pchan->rotmode == ROT_MODE_AXISANGLE) { float eul[3]; - + axis_angle_to_eulO(eul, EULER_ORDER_DEFAULT, pchan->rotAxis, pchan->rotAngle); eul[1] *= -1; eul[2] *= -1; @@ -420,7 +420,7 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bo } else { float eul[3]; - + normalize_qt(pchan->quat); quat_to_eul(eul, pchan->quat); eul[1] *= -1; @@ -428,12 +428,12 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bo eul_to_quat(pchan->quat, eul); } } - + /* ID properties */ if (chan->prop) { if (pchan->prop) { - /* if we have existing properties on a bone, just copy over the values of - * matching properties (i.e. ones which will have some impact) on to the + /* if we have existing properties on a bone, just copy over the values of + * matching properties (i.e. ones which will have some impact) on to the * target instead of just blinding replacing all [ */ IDP_SyncGroupValues(pchan->prop, chan->prop); @@ -444,7 +444,7 @@ static bPoseChannel *pose_bone_do_paste(Object *ob, bPoseChannel *chan, const bo } } } - + /* return whether paste went ahead */ return pchan; } @@ -502,11 +502,11 @@ void POSE_OT_copy(wmOperatorType *ot) ot->name = "Copy Pose"; ot->idname = "POSE_OT_copy"; ot->description = "Copies the current pose of the selected bones to copy/paste buffer"; - + /* api callbacks */ ot->exec = pose_copy_exec; ot->poll = ED_operator_posemode; - + /* flag */ ot->flag = OPTYPE_REGISTER; } @@ -520,15 +520,15 @@ static int pose_paste_exec(bContext *C, wmOperator *op) bPoseChannel *chan; const bool flip = RNA_boolean_get(op->ptr, "flipped"); bool selOnly = RNA_boolean_get(op->ptr, "selected_mask"); - + /* Get KeyingSet to use. */ KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID); - + /* Sanity checks. */ if (ELEM(NULL, ob, ob->pose)) { return OPERATOR_CANCELLED; } - + /* Read copy buffer .blend file. */ char str[FILE_MAX]; Main *tmp_bmain = BKE_main_new(); @@ -544,7 +544,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op) BKE_main_free(tmp_bmain); return OPERATOR_CANCELLED; } - + Object *object_from = tmp_bmain->object.first; bPose *pose_from = object_from->pose; if (pose_from == NULL) { @@ -552,7 +552,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op) BKE_main_free(tmp_bmain); return OPERATOR_CANCELLED; } - + /* If selOnly option is enabled, if user hasn't selected any bones, * just go back to default behavior to be more in line with other * pose tools. @@ -562,7 +562,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op) selOnly = false; } } - + /* Safely merge all of the channels in the buffer pose into any * existing pose. */ @@ -577,15 +577,15 @@ static int pose_paste_exec(bContext *C, wmOperator *op) } } BKE_main_free(tmp_bmain); - + /* Update event for pose and deformation children. */ DEG_id_tag_update(&ob->id, OB_RECALC_DATA); - + /* Recalculate paths if any of the bones have paths... */ if ((ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) { ED_pose_recalculate_paths(C, scene, ob); } - + /* Notifiers for updates, */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); @@ -600,14 +600,14 @@ void POSE_OT_paste(wmOperatorType *ot) ot->name = "Paste Pose"; ot->idname = "POSE_OT_paste"; ot->description = "Paste the stored pose on to the current pose"; - + /* api callbacks */ ot->exec = pose_paste_exec; ot->poll = ED_operator_posemode; - + /* flag */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + /* properties */ prop = RNA_def_boolean(ot->srna, "flipped", false, "Flipped on X-Axis", "Paste the stored pose flipped on to current pose"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); @@ -627,9 +627,9 @@ static void pchan_clear_scale(bPoseChannel *pchan) pchan->size[1] = 1.0f; if ((pchan->protectflag & OB_LOCK_SCALEZ) == 0) pchan->size[2] = 1.0f; - + pchan->ease1 = 0.0f; - pchan->ease2 = 0.0f; + pchan->ease2 = 0.0f; pchan->scaleIn = 1.0f; pchan->scaleOut = 1.0f; } @@ -661,7 +661,7 @@ static void pchan_clear_rot(bPoseChannel *pchan) pchan->rotAxis[1] = 0.0f; if ((pchan->protectflag & OB_LOCK_ROTZ) == 0) pchan->rotAxis[2] = 0.0f; - + /* check validity of axis - axis should never be 0,0,0 (if so, then we make it rotate about y) */ if (IS_EQF(pchan->rotAxis[0], pchan->rotAxis[1]) && IS_EQF(pchan->rotAxis[1], pchan->rotAxis[2])) pchan->rotAxis[1] = 1.0f; @@ -690,7 +690,7 @@ static void pchan_clear_rot(bPoseChannel *pchan) /* perform clamping using euler form (3-components) */ float eul[3], oldeul[3], quat1[4] = {0}; float qlen = 0.0f; - + if (pchan->rotmode == ROT_MODE_QUAT) { qlen = normalize_qt_qt(quat1, pchan->quat); quat_to_eul(oldeul, quat1); @@ -701,22 +701,22 @@ static void pchan_clear_rot(bPoseChannel *pchan) else { copy_v3_v3(oldeul, pchan->eul); } - + eul[0] = eul[1] = eul[2] = 0.0f; - + if (pchan->protectflag & OB_LOCK_ROTX) eul[0] = oldeul[0]; if (pchan->protectflag & OB_LOCK_ROTY) eul[1] = oldeul[1]; if (pchan->protectflag & OB_LOCK_ROTZ) eul[2] = oldeul[2]; - + if (pchan->rotmode == ROT_MODE_QUAT) { eul_to_quat(pchan->quat, eul); - + /* restore original quat size */ mul_qt_fl(pchan->quat, qlen); - + /* quaternions flip w sign to accumulate rotations correctly */ if ((quat1[0] < 0.0f && pchan->quat[0] > 0.0f) || (quat1[0] > 0.0f && pchan->quat[0] < 0.0f)) { mul_qt_fl(pchan->quat, -1.0f); @@ -742,11 +742,11 @@ static void pchan_clear_rot(bPoseChannel *pchan) zero_v3(pchan->eul); } } - + /* Clear also Bendy Bone stuff - Roll is obvious, but Curve X/Y stuff is also kindof rotational in nature... */ pchan->roll1 = 0.0f; pchan->roll2 = 0.0f; - + pchan->curveInX = 0.0f; pchan->curveInY = 0.0f; pchan->curveOutX = 0.0f; @@ -764,7 +764,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, +static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op, void (*clear_func)(bPoseChannel *), const char default_ksName[]) { Scene *scene = CTX_data_scene(C); @@ -798,7 +798,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op, } /* tag for autokeying later */ 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 */ bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name); clear_func(pchan_eval); @@ -845,7 +845,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op, /* --------------- */ -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); } @@ -856,17 +856,17 @@ void POSE_OT_scale_clear(wmOperatorType *ot) ot->name = "Clear Pose Scale"; ot->idname = "POSE_OT_scale_clear"; ot->description = "Reset scaling of selected bones to their default values"; - + /* api callbacks */ ot->exec = pose_clear_scale_exec; ot->poll = ED_operator_posemode; - + /* flags */ 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); } @@ -877,17 +877,17 @@ void POSE_OT_rot_clear(wmOperatorType *ot) ot->name = "Clear Pose Rotation"; ot->idname = "POSE_OT_rot_clear"; ot->description = "Reset rotations of selected bones to their default values"; - + /* api callbacks */ ot->exec = pose_clear_rot_exec; ot->poll = ED_operator_posemode; - + /* flags */ 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); } @@ -898,17 +898,17 @@ void POSE_OT_loc_clear(wmOperatorType *ot) ot->name = "Clear Pose Location"; ot->idname = "POSE_OT_loc_clear"; ot->description = "Reset locations of selected bones to their default values"; - + /* api callbacks */ ot->exec = pose_clear_loc_exec; ot->poll = ED_operator_posemode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static int pose_clear_transforms_exec(bContext *C, wmOperator *op) +static int pose_clear_transforms_exec(bContext *C, wmOperator *op) { return pose_clear_transform_generic_exec(C, op, pchan_clear_transforms, ANIM_KS_LOC_ROT_SCALE_ID); } @@ -919,11 +919,11 @@ void POSE_OT_transforms_clear(wmOperatorType *ot) ot->name = "Clear Pose Transforms"; ot->idname = "POSE_OT_transforms_clear"; ot->description = "Reset location, rotation, and scaling of selected bones to their default values"; - + /* api callbacks */ ot->exec = pose_clear_transforms_exec; ot->poll = ED_operator_posemode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } @@ -937,7 +937,7 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); float cframe = (float)CFRA; const bool only_select = RNA_boolean_get(op->ptr, "only_selected"); - + FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, OB_MODE_POSE, ob) { if ((ob->adt) && (ob->adt->action)) { @@ -947,10 +947,10 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op) bPose *dummyPose = NULL; Object workob = {{NULL}}; bPoseChannel *pchan; - + /* execute animation step for current frame using a dummy copy of the pose */ BKE_pose_copy_data(&dummyPose, ob->pose, 0); - + BLI_strncpy(workob.id.name, "OB<ClearTfmWorkOb>", sizeof(workob.id.name)); workob.type = OB_ARMATURE; workob.data = ob->data; @@ -958,12 +958,12 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op) workob.pose = dummyPose; BKE_animsys_evaluate_animdata(NULL, scene, &workob.id, workob.adt, cframe, ADT_RECALC_ANIM); - + /* copy back values, but on selected bones only */ for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) { pose_bone_do_paste(ob, pchan, only_select, 0); } - + /* free temp data - free manually as was copied without constraints */ for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) { if (pchan->prop) { @@ -971,7 +971,7 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op) MEM_freeN(pchan->prop); } } - + /* was copied without constraints */ BLI_freelistN(&dummyPose->chanbase); MEM_freeN(dummyPose); @@ -982,13 +982,13 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op) */ BKE_pose_rest(ob->pose); } - + /* notifiers and updates */ DEG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob); } FOREACH_OBJECT_IN_MODE_END; - + return OPERATOR_FINISHED; } @@ -998,11 +998,11 @@ void POSE_OT_user_transforms_clear(wmOperatorType *ot) ot->name = "Clear User Transforms"; ot->idname = "POSE_OT_user_transforms_clear"; ot->description = "Reset pose on selected bones to keyframed state"; - + /* callbacks */ ot->exec = pose_clear_user_transforms_exec; ot->poll = ED_operator_posemode; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; |