忘却まとめ

Blenderの中級者・上級者向けの踏み込んだ情報や、アドオン・3DCGに関する情報を記事にします

IK/FKスナップ機能のソースコード【Blender / Python】

Blender

投稿日:

FK/IK切り替え機能のあるリグにて、FK← →IKそれぞれの回転値にスナップする機能のソースコード。
これによって、ぴったりスナップするので、切り替え後の動きのブレをなくせる。

ソースコード

getting IK constrained rotations - Coding / Python Support - Blender Artists Community

ビジュアルトランスフォームの取得は上記参考。

使い方

  • tgt_bnameに、対象のボーン名を複数設定する。
  • prefix_nameに、FKまたはIKのプレフィックス名を追加する。
  • IKをFKに沿わせる場合は、ik_prefix_nameにIKボーン名のプレフィックスを追加する。
    • FKなら空にする。
  • コンソール画面にコピペして実行する。
import bpy


# スナップしたいデフォームボーン名を入力
tgt_bname = ["upperarm_l","lowerarm_l","hand_l"]

# IK/FKのプレフィックス
# ("REFIK_upperarm_l"のような形を想定。他の形の名前の場合はソースコードを編集すること)
prefix_name = "REFIK_"

# IKの場合、IKボーン名を設定する。
# ik_prefix_nameに値がある場合は、先にIKボーンの位置を手の位置に移動する処理が入る。
# ik_prefix_name = "" # ← FKなら空にする。行頭の「#」をつければ無効化されるので、それで切り替える。
ik_prefix_name = "MYIK_"
def_ik_name = 'hand_l'




# ポーズのビジュアルトランスフォーム(IKを考慮した最終的な位置)を得る
# getting IK constrained rotations - Coding / Python Support - Blender Artists Community
# https://blenderartists.org/t/getting-ik-constrained-rotations/494434/19

def visualmatrix(armature, bone_name):
    '''
        return a local transformation matrix that
        captures the visual transformation including
        IK chain etc
    '''
    pose_bone = armature.pose.bones[bone_name]
    data_bone = armature.data.bones[bone_name]
    #
    M_pose = pose_bone.matrix
    M_data = data_bone.matrix_local
    #
    # grab the parent's world pose and rest matrices
    if data_bone.parent:
        M_parent_data = data_bone.parent.matrix_local.copy()
        M_parent_pose = pose_bone.parent.matrix.copy()
    else:
        M_parent_data = mathutils.Matrix()
        M_parent_pose = mathutils.Matrix()
    #
    M1 = M_data.copy()
    M1.invert()
    #
    M2 = M_parent_pose.copy()
    M2.invert()
    #
    visual_matrix = M1 @ M_parent_data @ M2 @ M_pose
    #
    return visual_matrix



###################################

###################################
# メイン処理

obj = bpy.context.object
tgt_poseb = obj.pose.bones


# IKボーンの位置を手の位置に移動
if ik_prefix_name:
    def_hand = obj.pose.bones[def_ik_name]
    tgt_ik = tgt_poseb[ik_prefix_name + def_ik_name]
    new_matrix = obj.convert_space(pose_bone=tgt_ik, matrix=def_hand.matrix, from_space='POSE', to_space='LOCAL')
    tgt_ik.location = new_matrix.to_translation()


# デフォームボーンのビジュアルトランスフォームを取得し、クォータニオン回転に変換し、対象ボーンの回転値をそれに変更する。
for bn in tgt_bname:
    tgt_poseb[prefix_name+bn].rotation_quaternion = visualmatrix(obj, bn).to_quaternion()

リンク

IK/FK切り替え可能なリグを作る記事はこちら。

3Dモデルなどの制作依頼はこちら

-Blender

Copyright© 忘却まとめ , 2025 All Rights Reserved Powered by STINGER.