MRが楽しい

MRやVRについて学習したことを書き残す

Blender2.8で利用可能なpythonスクリプトを作る その16(ボーンの操作、ポーズの適用)

本日は Blender の技術調査枠です。
Blender2.8で利用可能なpythonスクリプトを作ります。

特定の名前のボーンを操作する

アーマチュア名とボーン名を指定してポーズ角度を変更します。
・change_pose_bone.py

# bpyインポート
import bpy
# mathインポート(角度計算のため)
import math

# 対象ボーンのポーズ角度を変更する
def change_pose_bone(arg_targetarmature='Default',arg_targetbone='Default',arg_rotation=(0,0,0)) -> bool:
    """対象ボーンのポーズ角度を変更する
    
    Keyword Arguments:
        arg_targetarmature {str} -- 対象アーマチュア名 (default: {'Default'})
        arg_targetbone {str} -- 対象ボーン名 (default: {'Default'})
        arg_rotation {tuple} -- 回転角 (default: {(0,0,0)})

    Returns:
        bool -- 実行の正否
    """
    # 他のオブジェクトに操作を適用しないよう全てのオブジェクトを走査する
    for ob in bpy.context.scene.objects:
        # 非選択状態に設定する
        ob.select_set(False)
    
    # 指定オブジェクトを取得する
    # (get関数は対象が存在しない場合 None が返る)
    selectob = bpy.data.objects.get(arg_targetarmature)

    # 指定オブジェクトが存在するか確認する
    if selectob == None:
        # 指定オブジェクトが存在しない場合は処理しない
        return False

    # 指定オブジェクトをアクティブに変更する
    bpy.context.view_layer.objects.active = selectob

    # オブジェクトがアーマチュアなら編集対象とする
    if selectob.type == 'ARMATURE':
        # ポーズモードに移行する
        bpy.ops.object.mode_set(mode='POSE')
        # 他のボーンに操作を適用しないよう全てのボーンを走査する
        for bone in selectob.data.bones:
            # 非選択状態に設定する
            bone.select = False
        # 指定ボーンを取得する
        selectbone=selectob.data.bones[arg_targetbone]
        # 対象ボーンを選択状態に変更する
        selectbone.select = True
        # 今回はポーズ変更なのでポーズ情報を取得する
        pose_bone=selectob.pose.bones[arg_targetbone]
        # 角度の変更方法を「XYZ オイラー角」に変更する
        pose_bone.rotation_mode = 'XYZ'
        # X軸の変更角度を設定する
        pose_bone.rotation_euler.rotate_axis('X', math.radians(arg_rotation[0]))
        # Y軸の変更角度を設定する
        pose_bone.rotation_euler.rotate_axis('Y', math.radians(arg_rotation[1]))
        # Z軸の変更角度を設定する
        pose_bone.rotation_euler.rotate_axis('Z', math.radians(arg_rotation[2]))
        # 角度の変更方法を「クォータニオン」に変更する
        pose_bone.rotation_mode = 'QUATERNION'
        # オブジェクトモードに移行する
        bpy.ops.object.mode_set(mode='OBJECT')

    return True

# 関数の実行例
change_pose_bone(arg_targetarmature="metarig",arg_targetbone="chin",arg_rotation=(15.0,0.0,0.0))

f:id:bluebirdofoz:20200412211210j:plain
f:id:bluebirdofoz:20200412211223j:plain

[デフォルトのポーズに適用]を実行する

指定した名前のアーマチュアオブジェクトに[デフォルトのポーズに適用]を実行します。
・apply_armature_object.py

# bpyインポート
import bpy

# 対象のアーマチュアのポーズをデフォルトのポーズに適用する
def apply_armature_object(arg_targetarmature='Default') -> bool:
    """対象のアーマチュアのポーズをデフォルトのポーズに適用する
    
    Keyword Arguments:
        arg_targetarmature {str} -- 対象アーマチュア名 (default: {'Default'})

    Returns:
        bool -- 実行の正否
    """
    # 他のオブジェクトに操作を適用しないよう全てのオブジェクトを走査する
    for ob in bpy.context.scene.objects:
        # 非選択状態に設定する
        ob.select_set(False)
    
    # 指定オブジェクトを取得する
    # (get関数は対象が存在しない場合 None が返る)
    selectob = bpy.data.objects.get(arg_targetarmature)

    # 指定オブジェクトが存在するか確認する
    if selectob == None:
        # 指定オブジェクトが存在しない場合は処理しない
        return False

    # 指定オブジェクトをアクティブに変更する
    bpy.context.view_layer.objects.active = selectob

    # オブジェクトがアーマチュアならデフォルトポーズの適用の対象とする
    if selectob.type == 'ARMATURE':
        # ポーズモードに移行する
        bpy.ops.object.mode_set(mode='POSE')
        # [デフォルトのポーズに適用]を実行
        bpy.ops.pose.armature_apply()
        # オブジェクトモードに移行する
        bpy.ops.object.mode_set(mode='OBJECT')

    return True

# 関数の実行例
apply_armature_object(arg_targetarmature="metarig")

f:id:bluebirdofoz:20200412211236j:plain
f:id:bluebirdofoz:20200412211246j:plain