blender

I121 blender ボーン


blenderでボーンを設定して動かしました。
モデルはFreeCADで作成しています。

ボーンの設定

FreeCADモデル

サンプルファイルI121_arm.obj

ボーンの移動や回転は他のオブジェクトと同様です。
tabキーで編集モードに入れます。Eキーで引き出して追加できます。

モデルのハンドリングは、以下にいくつか記載しています。

表示スタイル

ボーンのスタイルを変えることができます。

スティックに変更

ポーズのクリア

移動したボーンをクリアします。

ウェイトペイント

ウェイトがかかっていないと、メッシュが既存の位置に残されるような場合もあります。

靴にウェイトがかかっていない場合。
足のボーンにウェイトをつけた場合。

データ分離

前輪と後輪が紐づけられていて、片方のウェイトを変更するともう片方も変更される構造
オブジェクトモードでシングルユーザー化を選択すると解除される。

人物

3Dモデル :生成AIで用意したものです。

VRM :blenderのエクステンション

IKスクリプト :ボーンにIKを付けるスクリプト

import bpy

# アーマチュアの名前
armature_name = "アーマチュア"

# IKターゲットにする新しいボーンの名前(引き出したボーン)
ik_bone_nameArr = ["IK_Bone1", "IK_Bone2", "IK_Bone3", "IK_Bone4"]

# IKの影響を受けるボーン(根本)の名前
chain_root_bone_nameArr = ["lower_arm.L", "lower_arm.R", "lower_leg.L", "lower_leg.R"]

# IK用の新しいボーンを作成して設定する関数
def addTarget(ik_bone_name, chain_root_bone_name):
    # アーマチュアオブジェクトを取得
    armature = bpy.data.objects.get(armature_name)

    if armature and armature.type == 'ARMATURE':
        # Editモードで新しいボーン(IK用)を追加
        bpy.context.view_layer.objects.active = armature
        bpy.ops.object.mode_set(mode='EDIT')

        # IK用の新しいボーンを作成して、元のボーンから引き出す
        chain_root_bone = armature.data.edit_bones.get(chain_root_bone_name)
        if chain_root_bone:
            ik_bone = armature.data.edit_bones.new(ik_bone_name)
            ik_bone.head = chain_root_bone.tail  # 既存ボーンの終端に一致させる
            ik_bone.tail = (
                chain_root_bone.tail[0],
                chain_root_bone.tail[1],
                chain_root_bone.tail[2] + 0.5,
            )
            ik_bone.use_connect = False  # 親子関係を持たせない

            print(f"'{ik_bone_name}' ボーンを作成しました。")
        else:
            print(f"ボーン '{chain_root_bone_name}' が見つかりません。")

        # オブジェクトモードに戻る
        bpy.ops.object.mode_set(mode='OBJECT')

        # IKコンストレイントの設定を追加するボーンのPose Boneを取得
        pose_bone = armature.pose.bones.get(chain_root_bone_name)
        if pose_bone:
            # IKコンストレイントを追加
            ik_constraint = pose_bone.constraints.new(type="IK")
            ik_constraint.target = armature
            ik_constraint.subtarget = ik_bone_name
            ik_constraint.chain_count = 2  # IKが影響するボーンの数

            # Y軸とZ軸をロック(IK制御下で回転できないようにする)
            pose_bone.lock_ik_y = True
            pose_bone.lock_ik_z = True

            # X軸の回転制限を設定(-180度から0度)
            pose_bone.use_ik_limit_x = True  # IK制限を有効化
            pose_bone.ik_min_x = -3.14159  # -180度(ラジアン)
            pose_bone.ik_max_x = 0  # 0度

            print(f"IKコンストレイントと回転制限を '{chain_root_bone_name}' に設定しました。")
        else:
            print(f"'{chain_root_bone_name}' のポーズボーンが見つかりません。")
    else:
        print(f"アーマチュア '{armature_name}' が見つかりません。")

# IKボーンとルートボーンを結びつける処理
for i in range(len(ik_bone_nameArr)):
    addTarget(ik_bone_nameArr[i], chain_root_bone_nameArr[i])
関節が逆に曲がる場合には制限方向を変えます。

コメント