Как получить все ключевые кадры для выбранной полосы в Python?

Aug 19 2020

Предположим, у нас есть полоса изображения в VSE, и у нее есть 2 ключевых кадра для ее непрозрачности. Как я могу редактировать значения каждого из них через python?

Ответы

6 Leander Aug 19 2020 at 17:02

Импортируйте модуль bpy для доступа к данным Blender.

import bpy

Контекстный метод

Если вы только что создали ключевые кадры и просто пишете скрипты в текстовом редакторе, вы можете искать объекты по контексту. Вы должны быть уверены, что полоса имеет два ключевых кадра и выбрана (активна) в секвенсоре.

Получите активную сцену по контексту.

scene = bpy.context.scene

Получите активную полосу секвенсора по контексту.

strip = scene.sequence_editor.active_strip

Найдите fcurve, подключенную к data_pathактивной полосе, по ее имени и свойству. (Посмотрите ответ batFINGER о том, как более элегантно построить data_path 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_pointsхранящимся в fcurve.

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 (имя_сцены, имя_полосы, значения_ключевого кадра = [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
    

Получите полосу по имени и получите fcurve, связанную с ее 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 на основе ее пути к данным

Предложение переключиться в редактор графиков и посмотреть на видимые кривые fcurves будет зависеть от настроек редактора графиков.

Вместо этого создайте канал данных с ключевыми кадрами и найдите его в действии fcurves.

Стрип-анимация VSE принадлежит объекту сцены.

Скрипт ниже

  • получает активную полосу

  • находит путь к активной полосе по ее объекту идентификатора, сцена, пример активной полосы фильма с именем "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'

Мое заблуждение заключалось в том, что Graph> Keyframes. Пока на самом деле это Graph> FCurves> Keyframes.