Blenderのアニメーション情報は、アクション > Fカーブ > キーフレームのようになっている。
まずキーを入れるFカーブを作る必要があり、Fカーブは各トランスフォームごとの各軸ごとに作る必要がある。
もくじ
Fカーブ
Fカーブの識別は、data_path(属性の文字列)とarray_index(軸指定)で指定できる。
data_pathは、'pose.bones["ぼーん"].location'のように、固有アイテム名(例:ぼーん)を含む文字列となっている。
固有アイテム名と属性名が一緒になっているので扱いづらい。
%sを活用して、文字列を作るとよい。
注意点
そのオブジェクトにアニメーションデータがない場合は、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: # 処理...
例
位置回転スケールで3、XYZ軸で3の、計9こ作る必要があるため、それぞれのリストを用意して、下記のように多重のfor文で回す必要がある。
for bone in ボーン: for trans in トランスフォーム: dp_name = 'pose.bones["%s"].%s' % (bone.name,trans) for axis in 軸: # 新規Fカーブ作成 tgt_fc = ~~.fcurves.new(data_path=dp_name, index=axis, action_group=bone.name) # キーフレーム作成 tgt_fc.keyframe_points.insert(frame=指定のフレーム, value= getattr(bone, trans)[axis])
サンプル
下記は自作アドオンから抜粋したものであり、コピペしただけでは動きはしないので注意。
あくまでこんなかんじになる程度に。
data_path
# data_path def get_target_data_path(bone): sc = bpy.context.scene props = sc.lazy_shapekeys p_sync = props.synckey d_path_l = [] if p_sync.location: d_path_l += [('pose.bones["%s"].location',"location")] if p_sync.rotation: if bone.rotation_mode == 'QUATERNION': d_path_l += [('pose.bones["%s"].rotation_quaternion',"rotation_quaternion")] else: d_path_l += [('pose.bones["%s"].rotation_euler',"rotation_euler")] if p_sync.scale: d_path_l += [('pose.bones["%s"].scale',"scale")] return d_path_l
array_index
クォータニオン回転だけは他と違いWXYZの4つなので、リストを作成する際に分岐を用意する必要がある。
# array_index def get_array_index(trs_name, bone): sc = bpy.context.scene props = sc.lazy_shapekeys p_sync = props.synckey arry_index_l = [] if trs_name == "rotation_quaternion" and bone.rotation_mode == 'QUATERNION': arry_index_l += [0] if p_sync.axis_x: arry_index_l += [1] if p_sync.axis_y: arry_index_l += [2] if p_sync.axis_z: arry_index_l += [3] else: if p_sync.axis_x: arry_index_l += [0] if p_sync.axis_y: arry_index_l += [1] if p_sync.axis_z: arry_index_l += [2] return arry_index_l
キー挿入
# insert def key_insert_bone(self, p_sync, obj, sel_bone_l, cur_f, dp_name): for bone in sel_bone_l: # 対象ボーン d_path_l = get_target_data_path(bone) for dp, trs_name in d_path_l: # data_path dp_name = dp % bone.name # 作っておいたデータパス文字列にボーン名を入れる for id in get_array_index(trs_name, bone): # array_index # 対象Fカーブを探す tgt_fc = None for fc in obj.animation_data.action.fcurves: if fc.data_path == dp_name and fc.array_index == id: tgt_fc = fc break # なければ新規作成 if not tgt_fc: tgt_fc = obj.animation_data.action.fcurves.new(data_path=dp_name, index=id, action_group=bone.name) # 新規キー挿入 key = tgt_fc.keyframe_points.insert(frame=cur_f, value= getattr(bone,trs_name)[id]) if not p_sync.interpolation == "NONE": key.interpolation = p_sync.interpolation