Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_convert_armature.c
| Show First 20 Lines • Show All 194 Lines • ▼ Show 20 Lines | if (data) { | ||||
| if (data->flag & CONSTRAINT_IK_TIP) { | if (data->flag & CONSTRAINT_IK_TIP) { | ||||
| copy_v3_v3(data->grabtarget, pchan->pose_tail); | copy_v3_v3(data->grabtarget, pchan->pose_tail); | ||||
| } | } | ||||
| else { | else { | ||||
| copy_v3_v3(data->grabtarget, pchan->pose_head); | copy_v3_v3(data->grabtarget, pchan->pose_head); | ||||
| } | } | ||||
| td->loc = data->grabtarget; | td->loc = data->grabtarget; | ||||
| copy_v3_v3(td->iloc, td->loc); | copy_v3_v3(td->iloc, td->loc); | ||||
| data->flag |= CONSTRAINT_IK_AUTO; | data->flag |= CONSTRAINT_IK_AUTO; | ||||
| /* Add a temporary auto IK constraint here, as we will only temporarly active this targetless | |||||
| * bone during transform. (Targetless IK constraints are treated as if they are disabled | |||||
| * unless they are transformed) */ | |||||
| bConstraint *con = BKE_constraint_add_for_pose( | |||||
| NULL, pchan, "TempConstraint", CONSTRAINT_TYPE_KINEMATIC); | |||||
| bKinematicConstraint *temp_con_data = con->data; | |||||
| *temp_con_data = *data; | |||||
| temp_con_data->flag |= CONSTRAINT_IK_TEMP | CONSTRAINT_IK_AUTO | CONSTRAINT_IK_POS; | |||||
| /* for draw, but also for detecting while pose solving */ | |||||
| pchan->constflag |= (PCHAN_HAS_IK | PCHAN_HAS_TARGET); | |||||
| BIK_clear_data(ob->pose); | |||||
| /* TODO(sergey): Consider doing partial update only. */ | |||||
| Main *bmain = CTX_data_main(t->context); | |||||
| DEG_relations_tag_update(bmain); | |||||
brecht: Is this code also needed in `pose_transform_mirror_update` which also sets `CONSTRAINT_IK_AUTO`? | |||||
zeddbAuthorUnsubmitted Done Inline ActionsFor the deg tagging, I guess that I could modify the functions to keep track if they added temporary ik constraints. I don't know how much this will help in practice though as I suspect that only one targetless (or two if in mirror mode) would be active at the same time for most use cases. Do you want me to add extra logic for this? zeddb: For the deg tagging, I guess that I could modify the functions to keep track if they added… | |||||
| /* only object matrix correction */ | /* only object matrix correction */ | ||||
| copy_m3_m3(td->mtx, omat); | copy_m3_m3(td->mtx, omat); | ||||
| pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); | pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); | ||||
| } | } | ||||
| } | } | ||||
| /* store reference to first constraint */ | /* store reference to first constraint */ | ||||
| td->con = pchan->constraints.first; | td->con = pchan->constraints.first; | ||||
| } | } | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Pose Auto-IK | /** \name Pose Auto-IK | ||||
| * \{ */ | * \{ */ | ||||
| bKinematicConstraint *has_targetless_ik(bPoseChannel *pchan) | bKinematicConstraint *has_targetless_ik(bPoseChannel *pchan) | ||||
| { | { | ||||
| bConstraint *con = pchan->constraints.first; | bConstraint *con = pchan->constraints.first; | ||||
| for (; con; con = con->next) { | for (; con; con = con->next) { | ||||
| if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) { | if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->flag & CONSTRAINT_OFF) == 0 && | ||||
| (con->enforce != 0.0f)) { | |||||
| bKinematicConstraint *data = con->data; | bKinematicConstraint *data = con->data; | ||||
| if (data->tar == NULL) { | if (data->tar == NULL) { | ||||
| return data; | return data; | ||||
| } | } | ||||
| if (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0) { | if (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0) { | ||||
| return data; | return data; | ||||
| } | } | ||||
| Show All 40 Lines | if (con->type == CONSTRAINT_TYPE_KINEMATIC) { | ||||
| if (pchan->protectflag & OB_LOCK_ROTY) { | if (pchan->protectflag & OB_LOCK_ROTY) { | ||||
| pchan->ikflag |= BONE_IK_NO_YDOF_TEMP; | pchan->ikflag |= BONE_IK_NO_YDOF_TEMP; | ||||
| } | } | ||||
| if (pchan->protectflag & OB_LOCK_ROTZ) { | if (pchan->protectflag & OB_LOCK_ROTZ) { | ||||
| pchan->ikflag |= BONE_IK_NO_ZDOF_TEMP; | pchan->ikflag |= BONE_IK_NO_ZDOF_TEMP; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return 0; | |||||
| } | } | ||||
| } | } | ||||
| if ((con->flag & CONSTRAINT_DISABLE) == 0 && (con->enforce != 0.0f)) { | if ((con->flag & CONSTRAINT_DISABLE) == 0 && (con->enforce != 0.0f)) { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 774 Lines • Show Last 20 Lines | |||||
Is this code also needed in pose_transform_mirror_update which also sets CONSTRAINT_IK_AUTO?
Can this code be deduplicated with similar code in pose_grab_with_ik_add?
Can we call BIK_clear_data and DEG_relations_tag_update only once, after the constraints have been added for all bones?