diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index e08604f02ad..810cd5af5a6 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -182,6 +182,9 @@ void BKE_pose_ikparam_init(struct bPose *pose); /* initialize a bItasc structure with default value */ void BKE_pose_itasc_init(struct bItasc *itasc); +/* Sets ik flags based on standard rotation locks (for temporary IK constraints). */ +void BKE_pose_channel_ikflag_set_from_protectflag(struct bPoseChannel *pchan); + /* Checks if a bone is part of an IK chain or not */ bool BKE_pose_channel_in_IK_chain(struct Object *ob, struct bPoseChannel *pchan); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 64a8ae15fd3..41535ac8628 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -924,6 +924,20 @@ static bool pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan, int level) return false; } +void BKE_pose_channel_ikflag_set_from_protectflag(bPoseChannel *pchan) +{ + /* XXX: careful with quats/axis-angle rotations where we're locking 4d components. */ + if (pchan->protectflag & OB_LOCK_ROTX) { + pchan->ikflag |= BONE_IK_NO_XDOF_TEMP; + } + if (pchan->protectflag & OB_LOCK_ROTY) { + pchan->ikflag |= BONE_IK_NO_YDOF_TEMP; + } + if (pchan->protectflag & OB_LOCK_ROTZ) { + pchan->ikflag |= BONE_IK_NO_ZDOF_TEMP; + } +} + bool BKE_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan) { return pose_channel_in_IK_chain(ob, pchan, 0); diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index 6de9ca89425..c1bd7995f18 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -345,17 +345,7 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) /* we only include bones that are part of a continual connected chain */ do { - /* here, we set ik-settings for bone from pchan->protectflag */ - // XXX: careful with quats/axis-angle rotations where we're locking 4d components - if (pchan->protectflag & OB_LOCK_ROTX) { - pchan->ikflag |= BONE_IK_NO_XDOF_TEMP; - } - if (pchan->protectflag & OB_LOCK_ROTY) { - pchan->ikflag |= BONE_IK_NO_YDOF_TEMP; - } - if (pchan->protectflag & OB_LOCK_ROTZ) { - pchan->ikflag |= BONE_IK_NO_ZDOF_TEMP; - } + BKE_pose_channel_ikflag_set_from_protectflag(pchan); /* now we count this pchan as being included */ data->rootbone++; @@ -680,6 +670,15 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr /* Add a temporary auto IK constraint here, as we will only temporarily active this * targetless bone during transform. (Targetless IK constraints are treated as if they are * disabled unless they are transformed). */ + + /* if no chain length has been specified, + * just make things obey standard rotation locks too */ + if (data->rootbone == 0) { + for (bPoseChannel *pchan_iter = pchan; pchan_iter; pchan_iter = pchan_iter->parent) { + BKE_pose_channel_ikflag_set_from_protectflag(pchan_iter); + } + } + add_temporary_ik_constraint(pchan, data); Main *bmain = CTX_data_main(t->context); update_deg_with_temporary_ik(bmain, ob); @@ -1325,6 +1324,15 @@ static void pose_transform_mirror_update(TransInfo *t, TransDataContainer *tc, O /* TODO(germano): Realitve Mirror support */ } data->flag |= CONSTRAINT_IK_AUTO; + + /* if no chain length has been specified, + * just make things obey standard rotation locks too */ + if (data->rootbone == 0) { + for (bPoseChannel *pchan_iter = pchan; pchan_iter; pchan_iter = pchan_iter->parent) { + BKE_pose_channel_ikflag_set_from_protectflag(pchan_iter); + } + } + /* Add a temporary auto IK constraint here, as we will only temporarily active this * target-less bone during transform. (Target-less IK constraints are treated as if they are * disabled unless they are transformed) */