จะรับคีย์เฟรมทั้งหมดสำหรับแถบที่เลือกใน 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 modified_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
    

รับแถบตามชื่อและรับ 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_pointco

    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 เป็นของวัตถุฉาก

สคริปต์ด้านล่าง

  • รับแถบที่ใช้งานอยู่

  • ค้นหาเส้นทางของแถบที่ใช้งานจากวัตถุ 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> คีย์เฟรม