もくじ
基本
ドライバー・アクション・NLAトラックなどのアニメーションデータへは、オブジェクトごとにアクセスできる。
アクションは bpy.data.actions から直接アクセスできる。
obj = bpy.context.object obj.animation_data # アクションデータ bpy.data.actions
注意点
そのオブジェクトにアニメーションデータがない場合は、animation_dataの中身が無いので注意。
一括処理する際は事前に作成するか、アニメーションデータを持っていないオブジェクトをcontinueで除外する処理が必要。
obj = bpy.context.object obj.animation_data for obj in bpy.context.selected_objects: if not obj.animation_data: obj.animation_data_create() if not obj.animation_data.action: obj.animation_data.action = bpy.data.actions.new(name="Action") for fc in obj.animation_data.action.fcurves: # 処理...
contextでのアクセス
アニメーションデータへはcontextを使えば簡単にアクセスすることができる。
実行した際のグラフエディターやドープシートの状態に依存するので注意。
# 表示中のFカーブ bpy.context.visible_fcurves # 編集中のFカーブ bpy.context.editable_fcurves # 選択中のFカーブ bpy.context.selected_visible_fcurves # 選択中の編集中のFカーブ bpy.context.selected_editable_fcurves # アクティブFカーブ bpy.context.active_editable_fcurve # 選択中のキーフレーム bpy.context.selected_editable_keyframes # 選択中のNLAストリップ bpy.context.selected_nla_strips
他のエディターからFカーブ関連のcontextを使う方法
これらのcontextはドープシートやグラフエディターでないとアクセスできない。
そのため、それ以外のエディターのメニューボタンからこのcontextを使いたいという場合は、一旦グラフエディターに変えてから処理して、元のエディターに戻すということが必要。
ただし、コンソールエディターで利用しようとすると、エリアタイプを戻す際にクラッシュする模様。
old_area_type = bpy.context.area.type bpy.context.area.type = 'GRAPH_EDITOR' bpy.context.area.ui_type = 'FCURVES' # ドライバーなら'DRIVERS' bpy.context.selected_visible_fcurves bpy.context.area.type = old_area_type
以下はオブジェクトからアニメーションデータにアクセスする方法を紹介する。
アクション
- オブジェクト > アニメーションデータ
> アクション > 位置[0]など > Fカーブ> キーフレーム
位置を変えたい場合は、ポイント・ハンドルの左・ハンドルの右の3つを動かす必要がある。
obj = bpy.context.object # アクション for fc in obj.animation_data.action.fcurves: for p in fc.keyframe_points: # ポイントの位置 p.co.x p.handle_left[0] p.handle_right[0]
特定のFカーブにアクセスする場合
下記は、選択ボーンのZ位置のキーフレームの位置を表示するサンプル。
アニメーションのデータは、実際にはオブジェクトやボーンなどとは直接関連付けられていない。
data_path というFカーブの名前と、同じデータに関連付けられるようになっている。
このため、別のオブジェクトやボーンなどにも名前さえ同じなら関連付けることができる。
data_pathは単なる文字列であるため、確実に同じデータにアクセスするにはボーン名を検索して対応するFカーブを見つける必要がある。
array_indexは、XYZなどの配列の番号がどれなのかが登録されている。
import re obj = bpy.context.object for bone in obj.data.bones: if bone.select: fcurves_l = obj.animation_data.action.fcurves for fcurve in fcurves_l: if re.findall("pose\.bones\[\"(%s)\"]" % bone.name,fcurve.data_path): if fcurve.array_index == 2: if "location" in fcurve.data_path : for p in fcurve.keyframe_points: p.co
下記は、data_pathからボーン名を取得するサンプル。
import re t = 'pose.bones["bone_hoge.L"].rotation_euler' re.findall("pose\.bones\[\"(.+)\"]",t) # > bone_hoge.L
ドライバー
- オブジェクト > アニメーションデータ
> ドライバー> 入力値
設定済みのドライバにアクセス
obj = bpy.context.object for div in obj.animation_data.drivers: div
ドライバを追加
下記はZ位置(つまりlocation[2])にドライバーを追加するサンプル。
追加したい属性の親データに、driver_add()で属性を指定して新しいドライバーを作成する。
ドライバの中には入力値(variables)があり、この入力値にターゲットにしたいボーン位置などを設定する。
obj = bpy.context.object # ドライバー fc = obj.driver_add("location", 2) div = fc.driver div.expression = "var + 1" var = div.variables.new() var.type = 'TRANSFORMS' var.targets[0].id = bpy.data.objects["hoge"] var.targets[0].bone_target = "Bone" var.targets[0].transform_type = "LOC_Y" var.targets[0].transform_space = 'LOCAL_SPACE'
NLAトラック
- オブジェクト > アニメーションデータ > NLAトラック > ストリップ
ストリップの位置を動かしたい場合は、frame_startとframe_endに同じ値を加算して動かす。
obj = bpy.context.object # NLAトラック for track in obj.animation_data.nla_tracks: for strip in track.strips strip.frame_start strip.frame_end
参考
ソースコードの参考となる自作アドオンはこちら。