Как получить все ключевые кадры для выбранной полосы в Python?
Предположим, у нас есть полоса изображения в VSE, и у нее есть 2 ключевых кадра для ее непрозрачности. Как я могу редактировать значения каждого из них через python?
Ответы
Импортируйте модуль 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()
Найдите 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)
#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.