Pythonで選択したストリップのすべてのキーフレームを取得するにはどうすればよいですか?

Aug 19 2020

VSEに画像ストリップがあり、不透明度のために2つのキーフレームがあるとします。Pythonを介してそれらのそれぞれの値を編集するにはどうすればよいですか?

回答

6 Leander Aug 19 2020 at 17:02

bpyモジュールをインポートしてBlenderのデータにアクセスします。

import bpy

コンテキストメソッド

キーフレームを作成したばかりで、テキストエディタでスクリプトを作成しているだけの場合は、コンテキストでオブジェクトを検索できます。ストリップに2つのキーフレームがあり、シーケンサーで選択(アクティブ)されていることを確認する必要があります。

コンテキストごとにアクティブなシーンを取得します。

scene = bpy.context.scene

コンテキストごとにアクティブなシーケンサーストリップを取得します。

strip = scene.sequence_editor.active_strip

data_pathアクティブなストリップのに接続されているfcurveをその名前とプロパティで検索します。(data_pathをよりエレガントに構築する方法に関するbatFINGERの回答を見てくださいstrip.path_from_id("blend_alpha")。)

data_path = 'sequence_editor.sequences_all["' + strip.name + '"].blend_alpha'
fcrv = scene.animation_data.action.fcurves.find(data_path)

keyframe_pointsfcurveに格納されている値にいくつかの値を割り当てます。

for i, y in [[0, 0.0], [1, 1.0]]:
    fcrv.keyframe_points[i].co.y = y
    fcrv.keyframe_points[i].handle_left.y = y
    fcrv.keyframe_points[i].handle_right.y = y

シーケンサーを強制的にリフレッシュします。

bpy.ops.sequencer.refresh_all()

データメソッド

アドオンからこの機能を使用しようとしている場合、またはアクティブなストリップが選択されているかどうかわからない場合、またはキーフレームがまったく存在しない場合でも、データを検証する必要があります。

githubからコードスニペットを表示します。

前提条件が欠落している場合は中止できるメソッドに機能をカプセル化します。必要なパラメーターは次のとおりです。

  • シーンの名前

  • シーケンサーストリップの名前

  • 既存のキーフレーム値を上書きするために使用される値

    def modify_strip_keyframes(scene_name、strip_name、keyframe_values = [1.0、0.0]):

シーンを名前で取得しますが、存在しない場合は戻ります。

    scene = bpy.data.scenes.get(scene_name)
    if scene == None:
        print("Scene not found.")
        return

あることを確認animation_dataしてsequence_editor。キーフレームまたはストリップがない場合、これらのアイテムはになりますNone。(のプロパティを呼び出すNoneと、スクリプトがクラッシュします。)

    if (scene.animation_data == None or scene.sequence_editor == None):
        print("No strips with keyframes.")
        return
    

ストリップを名前で取得し、そのblend_alpha(不透明度)プロパティに関連付けられた曲線を取得します。

    strip = scene.sequence_editor.sequences.get(strip_name)
    if strip == None:
        print("Strip not found.")
        return
    
    data_path = 'sequence_editor.sequences_all["' + strip_name + '"].blend_alpha'
    fcrv = scene.animation_data.action.fcurves.find(data_path)
    
    if fcrv == None:
        print("No opacity keyframes found.")
        return

keyframe_points値が指定されているのと同じ数がfcurveにあることを確認します。次に、ポイントをループして、新しい値をkeyframe_point座標に割り当てますco

    if len(fcrv.keyframe_points) != len(keyframe_values):
        print("The strip has " + str(len(fcrv.keyframe_points)) +
            " keys, but " + str(len(keyframe_values)) + " values were supplied.")
        return
    
    for i in range(len(fcrv.keyframe_points)):
        key = fcrv.keyframe_points[i]
        key.co.y = keyframe_values[i]
        key.handle_left.y = keyframe_values[i]
        key.handle_right.y = keyframe_values[i]
        key.handle_left.x = key.co.x
        key.handle_right.x = key.co.x
    

関数を実行するには、関数を呼び出し、シーケンサーを更新して変更を視覚化します。

modify_strip_keyframes("Scene", "cat", keyframe_values = [1, 0.5])
bpy.ops.sequencer.refresh_all()
6 batFINGER Aug 19 2020 at 17:17

データパスに基づいてfcurveを見つけます

グラフエディタに切り替えて表示されている曲線を確認する提案は、グラフエディタの設定によって異なります。

代わりに、キーフレーム化されたデータパスを作成し、アクションカーブで検索します。

VSEストリップアニメーションはシーンオブジェクトに属します。

以下のスクリプト

  • アクティブなストリップを取得します

  • IDオブジェクト、シーン、「Foo」という名前のアクティブなムービーストリップの例からアクティブなストリップのパスを検索します

     'sequence_editor.sequences_all["Foo"].blend_alpha'
    
  • シーンアクションfcurveコレクション内で検索します

注:上記のプロパティの多くまたはすべてにはNone、シーケンスエディター、アクティブストリップ、アニメーションデータ、アクションなどの値が含まれている可能性があります。それぞれをテストする必要があります。

import bpy
from bpy import context

scene = context.scene
seq = scene.sequence_editor
active_strip = seq.active_strip
datapath = active_strip.path_from_id("blend_alpha")
action = scene.animation_data.action

fc = action.fcurves.find(datapath)
1 Noname Aug 19 2020 at 16:52
#Assuming you are at VSE with your strip selected
context.area.type = 'GRAPH_EDITOR'
for fcurve in context.visible_fcurves:
    for keyframe in fcurve.keyframe_points:
        #Do w/e you want with the keyframe
        pass
#We switch back to VSE
context.area.type = 'SEQUENCE_EDITOR'

私の誤解は、グラフ>キーフレームというものでした。現実はグラフ> FCurves>キーフレームですが。