忘却まとめ

Blenderの中級者・上級者向けの踏み込んだ情報や、アドオン・3DCGに関する情報を記事にします

全トランスフォーム・全XYZ軸のキーフレームを挿入する【Blender / Python】

Python

投稿日:

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

アドオンの制作依頼はこちら

-Python

Copyright© 忘却まとめ , 2022 All Rights Reserved Powered by STINGER.