# -*- coding: utf-8 -*-
from pyfbsdk import *
def offset_character_animation_at_frame(frame=0, all_chars=True,
frame_anim=True):
# 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):
# 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
def get_selected_constraints():
result = []
for constraint in FBSystem().Scene.Constraints:
if constraint.Selected:
result.append(constraint)
return result
def get_connection_constrait(node):
constraints = []
for m in range(node.GetSrcCount()):
src_node = node.GetSrc(m)
if type(src_node) == FBConstraint:
constraints.append(src_node)
return constraints
def get_time_range():
take = FBSystem().CurrentTake
start = take.LocalTimeSpan.GetStart().GetFrame()
end = take.LocalTimeSpan.GetStop().GetFrame()
return (start, end)
def get_animation_node_in_relation(box, attr='', flow='in'):
result = None
if flow == 'in':
parent = box.AnimationNodeInGet()
elif flow == 'out':
parent = box.AnimationNodeOutGet()
else:
return
for node in parent.Nodes:
if node.Name == attr:
result = node
break
return result
def get_animation_curve(obj_node):
all_nodes = []
for property in obj_node.PropertyList:
if property and property.IsAnimatable() and property.IsAnimated():
animation_node = property.GetAnimationNode()
if animation_node.Nodes:
for node in animation_node.Nodes:
all_nodes.append(node.FCurve)
if animation_node.FCurve:
all_nodes.append(animation_node.FCurve)
return [node for node in all_nodes]
def clear_framekey(obj, start, end):
ani_curve_list = get_animation_curve(obj)
for ani_curve in ani_curve_list:
ani_curve.KeyDeleteByTimeRange(FBTime(0, 0, 0, start),
FBTime(0, 0, 0, end))
def ShiftAnimaion(variable):
gFilterManager = FBFilterManager()
gFilter = gFilterManager.CreateFilter("Time Shift And Scale")
gFilter.PropertyList.Find("Shift").Data = variable
for lComponent in FBSystem().Scene.Components:
if lComponent and lComponent.Is(FBModel_TypeInfo()):
for lNode in lComponent.PropertyList:
if lNode and lNode.IsAnimatable() and lNode.IsAnimated():
gFilter.Apply(lNode.GetAnimationNode(), True)
print("Animation Shifted")
def remove_ticket(object):
ani_curve_list = get_animation_curve(object)
for ani_curve in ani_curve_list:
for key in ani_curve.Keys:
key.Time = FBTime(0, 0, 0, key.Time.GetFrame(), 0)
def get_object_by_name(name, no_recursion=False, namespace=''):
component_list = FBComponentList()
FBFindObjectsByName(name, component_list, no_recursion, False)
if namespace:
component_list = [i for i in component_list if
(namespace + ':') in i.FullName]
return list(component_list)
def create_parent_constraint(name='constraint', source_list=[], target=''):
constraint = FBConstraintManager().TypeCreateConstraint('Parent/Child')
constraint.Name = name
if target:
constraint.ReferenceAdd(0, target)
for source in source_list:
constraint.ReferenceAdd(1, source)
constraint.Active = True
constraint.Lock = True
return constraint
def create_int_property(model, name, value):
prop = model.PropertyCreate(name, FBPropertyType.kFBPT_int, 'Integer',
True, True, None)
prop.Data = value
prop.SetAnimated(True)
def create_enum_property(model, name, items):
prop = model.PropertyCreate(name, FBPropertyType.kFBPT_enum,
'Enum', True, True, None)
enum_list = prop.GetEnumStringList(True)
for i in items:
enum_list.Add(i)
prop.NotifyEnumStringListChanged()
prop.SetAnimated(True)
def create_ik_constraint(namespace=''):
"""
创建基本的IK约束,如果有有不完整的则删除
左手:hand_l
右手:hand_r
左脚:foot_l
右脚:foot_r
左手IK:ik_hand_l
右手IK:ik_hand_r
左脚IK:ik_foot_l
右脚IK;ik_foot_r
gun IK:ik_hand_gun
6个约束:
IK_Hd_2_HdSk_L:hand_l → ik_hand_l
IK_Hd_2_HdSk_R:hand_r → ik_hand_r
IK_Ft_2_FtSk_L:foot_l → ik_foot_l
IK_Ft_2_FtSk_R:foot_r → ik_foot_r
IK_Hd_2_gun:hand_r → ik_hand_gun
Returns:
"""
ik_constraint_list = ['IK_Hd_2_HdSk_L', 'IK_Hd_2_HdSk_R',
'IK_Ft_2_FtSk_L', 'IK_Ft_2_FtSk_R',
'IK_Hd_2_gun']
ik_constraint_data_list = [['IK_Hd_2_HdSk_L', 'hand_l', 'ik_hand_l'],
['IK_Hd_2_HdSk_R', 'hand_r', 'ik_hand_r'],
['IK_Ft_2_FtSk_L', 'foot_l', 'ik_foot_l'],
['IK_Ft_2_FtSk_R', 'foot_r', 'ik_foot_r'],
['IK_Hd_2_gun', 'hand_r', 'ik_hand_gun']]
_delete = False
for ik_constraint in ik_constraint_list:
if ik_constraint not in [i.Name for i in
FBSystem().Scene.Constraints]:
_delete = True
break
if _delete:
for ik_constraint in ik_constraint_list:
componentList = get_object_by_name(ik_constraint,
namespace=namespace)
for i in componentList:
if type(i) == FBConstraint:
FBComponent.FBDelete(i)
for constraint_data in ik_constraint_data_list:
constraint_name, bone, ik_bone = constraint_data
create_parent_constraint(constraint_name, [bone], ik_bone, namespace)
def selected_clear():
for comp in FBSystem().Scene.Components:
comp.Selected = False
def export_selected(take, file_path):
file_options = FBFbxOptions(False)
file_options.SaveSelectedModelsOnly = True
file_options.ShowFileDialog = False
file_options.ShowOptionsDialog = False
file_options.UpdateRecentFiles = False
for index in range(file_options.GetTakeCount()):
if file_options.GetTakeName(index) == take.Name:
file_options.SetTakeSelect(index, True)
else:
file_options.SetTakeSelect(index, False)
FBApplication().FileSave(file_path, file_options)
def plot_anim_cr2sk(char):
options = FBPlotOptions()
options.ConstantKeyReducerKeepOneKey = False
options.PlotAllTakes = False
options.PlotOnFrame = True
options.PreciseTimeDiscontinuities = False
options.PlotLockedProperties = False
options.RotationFilterToApply = \
FBRotationFilter.kFBRotationFilterUnroll
options.PlotTranslationOnRootOnly = False
options.UseConstantKeyReducer = False
char.PlotAnimation(FBCharacterPlotWhere.
kFBCharacterPlotOnSkeleton,
options)
def select_skeleton_hierarchy(top_model):
if FBModel.FbxGetObjectSubType(top_model) != 'FBModel':
top_model.Selected = True
for child_model in top_model.Children:
select_skeleton_hierarchy(child_model)
def get_char_skeleton_root(char):
ls_characters = []
ls_char_roots = FBComponentList()
FBFindObjectsByName('root', ls_char_roots, False, True)
char_root = char.GetModel(FBBodyNodeId.kFBHipsNodeId).Parent
if char_root in ls_char_roots:
char_namespace = ''
if ":" in char_root.LongName:
char_namespace = char_root.LongName.rsplit(':', 2)[0]
if char_namespace:
char_namespace = char_namespace + ':'
ls_characters.append([char, char_root, char_namespace])
skel_root = ls_characters[0][1]
else:
skel_root = char_root
return skel_root
def get_selected():
selected_list = FBModelList()
topModel = None # 搜索所有模型,而不仅仅是一个特定的分支
selectionState = True # 返回选择物体
sortBySelectOrder = True # 按照选择顺序排序
FBGetSelectedModels(selected_list,
topModel,
selectionState,
sortBySelectOrder)
return selected_list
发布日期:
2024-05-10
文章字数:
1.2k
阅读时长:
7 分
评论