blenderでボーンを設定して動かしました。
モデルは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])






コメント