広告
広告

Blender Python のボーンアクセスチートシート

カテゴリ:blender

注意点

グローバル変数に Blender オブジェクトをキャッシュしてはならない

Undo したときにそのオブジェクトは無効化される。

  # 以下の amt オブジェクトは Undo 時に無効化され、アクセスすると EXCEPTION_ACCESS_VIOLOATION を出して Blender がクラッシュする
  amt = bpy.data.objects['Armature']
  
  # Blender オブジェクトが必要な場所で取得するようにする
  armature_name = 'Armature' # 文字列は Undo でも無効化されない
  def some_method():
      amt = bpy.data.objects[armature_name]
      
  # もしくはメソッドでオブジェクトを取得する
  def get_armature():
      return bpy.data.objects['Armature']

ボーンの位置が更新されない

値を更新してすぐその値を読みだしても更新後の値が得られないことがある。このようなときは bpy.context.scene.update() を呼び出した後、値を読みだすようにする。

このような動作になっているのは、あるプロパティの更新は animation function curve、driver、expression、constraint、child object 等の更新を引き起こすかもしれないからだ。値が更新されるたびこれらも更新すると実行速度が遅くなる。

ボーンの種類

data.bones

変形などのプロパティパネルで設定する項目にアクセスできる。

data.edit_bones

ボーンのポーズ位置などの、エディットモードで設定する項目にアクセスできる。編集するのにエディットモードへ移行する必要がある。ボーンの追加等はここからできる。

pose.bones

主にコンストレイントの追加を行う。コンストレイントの編集ならばポーズモードへ移行する必要はない。

アーマチュアへのアクセス

スクリプトにする場合 import bpy が必要になる。

アーマチュアの作成

bpy.ops.object.add(type='ARMATURE', enter_editmode=True, location=(0,0,0))

作成したアーマチュアの取得

enter_editmode=True の場合は以下の方法が使える。

amt = bpy.context.object

名前の変更

amt.name = 'myArmature'

エディットモードでボーンにアクセスする

アーマチュアの edit_bones はエディットモードの時にしかアクセスできないことに注意する。

ボーンの作成

head と tail とを設定するとボーンが作成される。

  bpy.ops.object.mode_set(mode='EDIT')
  b = amt.data.edit_bones.new('Bone')
  b.head = (0,0,0)
  b.tail = (0,0,1)

デフォームの設定

b.use_deform = False # メッシュをデフォームしない

親子関係の設定

  b2 = amt.data.edit_bones.new('Bone2')
  b2.haed = b.tail
  b2.tail = (0,0,2)
  b2.parent = b

座標軸の設定

calculate_roll はボーンの Z 軸の向きを引数で指定した軸と一致させる。この例ではグローバル Z 方向にボーンを伸ばしているので、ボーンのローカル Z を グローバル -Y に向けるとローカル X とグローバル X とが一致する。

  for b in amt.data.edit_bones:
    b.select = True # すべてのボーンを選択
  bpy.ops.armature.calculate_roll(type='GLOBAL_NEG_Y')

bpy.ops.pose.select_all(action="SELECT") でもすべてのボーンを選択できる。

個別に計算するときには roll に回転量を設定する。

  import math
  b.roll = math.radians(90) # 90°回転

ポーズモードでボーンにアクセスする

ポーズボーンのローカル座標の取得

  bpy.ops.object.mode_set(mode='POSE')
  loc = amt.pose.bones['Bone'].location

ポーズボーンの回転モードと回転量の取得

回転モードは AXIS_ANGLE、QUATERNION、XYZ... がある。

  if amt.pose.bones['Bone'].rotation_mode == 'QUATERNION':
      rot = amt.pose.bones['Bone'].rotation_quaternion
  elif amt.pose.bones['Bone'].rotation_mode == 'AXIS_ANGLE':
      rot = amt.pose.bones['Bone'].rotation_axis_angle
  else:
      rot = amt.pose.bones['Bone'].rotation_euler

ポーズボーンのアーマチュア座標の取得

アーマチュア座標はアーマチュアの位置から見たボーンの座標だ。アーマチュアの座標が (0, 0, 0) で回転が0でスケールが1のとき、ボーンのアーマチュア座標とグローバル座標とは一致する。

  amt.pose.bones['Bone'].head

ポーズボーンのグローバル座標の取得

  amt.matrix_world @ amt.pose.bones['Bone'].head

ポーズボーンを隠す

  amt.pose.bones['Bone'].bone.hide = True

ポーズボーンの選択

  amt.pose.bones['Bone'].bone.select = True

最後に選択されたポーズボーンの取得

  amt.pose.bones['Bone'].data.bones.active

選択されているポーズボーンをすべて取得

  bpy.context.selected_pose_bones

位置回転スケールのロック

  pose_bone = amt.pose.bones['Bone']
  pose_bone.lock_location = [True]*3
  pose_bone.lock_scale = [True]*3
  pose_bone.lock_rotation = [True]*3
  pose_bone.lock_rotation_w = True

モディフィア

IK の設定

  c = amt.pose.bones['Bone2'].constraints.new('IK')
  c.name = 'IK'
  c.target = amt
  c.subtarget = 'ik' # ik という名前のボーンを先に作成しておく
  c.chain_count = 2

回転コピーの設定

  c = amt.pose.bones['Bone2'].constraints.new('COPY_ROTATION')
  c.name = 'Copy_Rotation'
  c.target = amt
  c.subtarget = 'Bone'
  c.owner_space = 'LOCAL'
  c.target_space = 'LOCAL'

ボーンにキーを打つ

group があると位置回転スケールなどの複数のキーを折りたたんで表示できる。

  b = amt.pose.bones['Bone']
  b.keyframe_insert(data_path='location',group='Bone')
  b.keyframe_insert(data_path='scale',group='Bone')
  if b.rotation_mode == 'QUATERNION':
      b.keyframe_insert(data_path='rotation_quaternion',group='Bone')
  elif b.rotation_mode == 'AXIS_ANGLE':
      b.keyframe_insert(data_path='rotation_axis_angle',group='Bone')
  else:
      b.keyframe_insert(data_path='rotation_euler',group='Bone')

def_ で始まるボーンの変形にチェックを入れる

import bpy

bones = bpy.context.active_object.data.bones
for b in bones:
    b.use_deform = b.name.startswith('def_')

関連記事

Blender PythonのMeshデータアクセスのチートシート

Dev:Py/Scripts/Cookbook/Code snippets/Armatures

Blender 記事の目次


広告
広告