使用Python脚本在motionbuilder中将动画时间码设置为零

问题描述 投票:0回答:2

大家

我有一些动画文件,其开始时间不为零。我正在尝试创建一个脚本,将动画时间码设置为零。例如,图中显示的时间码不是从零开始的。非常感谢您的帮助。 在此输入图片描述

python max maya motionbuilder
2个回答
0
投票

我有点晚了,但分享这可能仍然很有趣!

您可以使用像这样的 FBTimeSpan() 实例轻松设置当前镜头的时间跨度,方法是将开始帧和结束帧指定为 FBTime() 对象:

lStartFrame = 0
lEndFrame = 100
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))

但我想您正在寻找的是一种偏移动画并使其从 0 开始的方法,不是吗?

这是我自己的库中的两个函数,使用故事模式在给定帧上偏移当前动画。第一个适用于场景的当前或所有角色(角色动画轨道)。第二个关于选定的组件(通用动画轨道)。对于每个帧,您可以将其开始的帧作为参数传递,如果您想在末尾构建新的时间跨度(用新帧替换旧的第一帧/最后一帧)。

from pyfbsdk import *


def offset_character_animation_at_frame(frame = 0, all_chars = True, frame_anim=True):
    ''' Offset current/all(default) characters animation to a given frame, 0 by default '''

    # get list of current/all characters
    if all_chars:
        char_list = FBSystem().Scene.Characters
    else:
        char_list = [FBApplication().CurrentCharacter]

    # get initial timespan
    lStartFrame = FBSystem().CurrentTake.LocalTimeSpan.GetStart().GetFrame()
    lEndFrame = FBSystem().CurrentTake.LocalTimeSpan.GetStop().GetFrame()

    # turn on Story mode
    FBStory().Mute = False

    # process character list
    for char in char_list:
        # set timespan
        FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))
        # set current character
        FBApplication().CurrentCharacter = char
        # insert character animation track
        track = FBStoryTrack(FBStoryTrackType.kFBStoryTrackCharacter, FBStory().RootFolder)
        track.Name = '{}_charAnimTrack'.format(FBApplication().CurrentCharacter.Name)
        track.Details.append(FBApplication().CurrentCharacter)
        # insert take in story mode
        take = FBSystem().CurrentTake
        inserted_clip = track.CopyTakeIntoTrack(take.LocalTimeSpan, take)
        # move inserted clip to given frame
        inserted_clip.Start = FBTime(0,0,0,frame)
        # frame new timespan
        FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, inserted_clip.Start.GetFrame(), 0), FBTime(0, 0, 0, inserted_clip.Stop.GetFrame(), 0))
        # defining plot options and plot to current take
        PlotOptions = FBPlotOptions()
        PlotOptions.ConstantKeyReducerKeepOneKey = True
        PlotOptions.PlotAllTakes = False
        PlotOptions.PlotOnFrame = True
        PlotOptions.PlotPeriod = FBTime( 0, 0, 0, 1 )
        PlotOptions.PlotTranslationOnRootOnly = True
        PlotOptions.PreciseTimeDiscontinuities = True
        PlotOptions.RotationFilterToApply = FBRotationFilter.kFBRotationFilterGimbleKiller
        PlotOptions.UseConstantKeyReducer = True
        char.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnSkeleton, PlotOptions)
        # empty Story mode
        for track in FBStory().RootFolder.Tracks:
            for clip in track.Clips:
                clip.FBDelete()
            track.FBDelete()

    # set back original timespan if specified
    if not frame_anim:
        FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))

    # turn off Story mode
    FBStory().Mute = True


def offset_generic_animation_at_frame(frame = 0, frame_anim = True):
    ''' Offset selected components animation to a given frame, 0 by default '''

    # get selected components
    lModelList = FBModelList()
    FBGetSelectedModels(lModelList)
    if not lModelList:
        raise ValueError("Select at least one component")

    # get initial timespan
    lStartFrame = FBSystem().CurrentTake.LocalTimeSpan.GetStart().GetFrame()
    lEndFrame = FBSystem().CurrentTake.LocalTimeSpan.GetStop().GetFrame()

    # turn on Story mode
    FBStory().Mute = False

    # set timespan        
    FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))
    # insert generic animation track and add selected components to it
    track = FBStoryTrack(FBStoryTrackType.kFBStoryTrackAnimation, FBStory().RootFolder)
    track.Name = 'genericAnimTrack'
    for comp in lModelList:
        track.Details.append(comp)
    # insert take in story mode
    take = FBSystem().CurrentTake
    inserted_clip = track.CopyTakeIntoTrack(take.LocalTimeSpan, take)
    # move inserted clip to given frame
    inserted_clip.Start = FBTime(0,0,0,frame)
    # frame new timespan
    FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, inserted_clip.Start.GetFrame(), 0), FBTime(0, 0, 0, inserted_clip.Stop.GetFrame(), 0))
    # plot selected take
    lOptions = FBPlotOptions()   
    lOptions.ConstantKeyReducerKeepOneKey = False
    lOptions.PlotAllTakes = False
    lOptions.PlotOnFrame = True
    lOptions.PlotPeriod = FBTime( 0, 0, 0, 1 )
    lOptions.PlotTranslationOnRootOnly = False
    lOptions.PreciseTimeDiscontinuities = True
    lOptions.RotationFilterToApply = FBRotationFilter.kFBRotationFilterGimbleKiller
    lOptions.UseConstantKeyReducer = False
    FBSystem().CurrentTake.PlotTakeOnSelected(lOptions)

    # empty Story mode
    for track in FBStory().RootFolder.Tracks:
        for clip in track.Clips:
            clip.FBDelete()
        track.FBDelete()

    # set back original timespan if specified
    if not frame_anim:
        FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))

    # turn off Story mode
    FBStory().Mute = True


# MAIN
offset_generic_animation_at_frame(frame = 0, frame_anim = False)
offset_character_animation_at_frame(frame = 0, all_chars = True, frame_anim=True)

0
投票

我知道已经很晚了。不过对于以后来这里的人来说,如果还担心这个问题的话,可以直接抵消Take。下面是一个例子,重点关注函数OffsetAnimation

from pyfbsdk import *

localTake = FBSystem().CurrentTake   
start_frame = localTake.LocalTimeSpan.GetStart().GetFrame()
end_frame = localTake.LocalTimeSpan.GetStop().GetFrame() 

## setup new time span
compensate_frames = FBTime(0,0,0,-start_frame)
p_start = FBTime(0,0,0,0)
p_end = FBTime(0,0,0,end_frame-start_frame+1)


## offset anim and setup playbar
localTake.OffsetAnimation(compensate_frames)
localTake.LocalTimeSpan = FBTimeSpan(p_start, p_end)
FBPlayerControl().GotoStart()
© www.soinside.com 2019 - 2024. All rights reserved.