Python Reference Guide
 
Loading...
Searching...
No Matches
Tasks\ExportAnimationLibrary.py
1# Copyright 2009 Autodesk, Inc. All rights reserved.
2# Use of this software is subject to the terms of the Autodesk license agreement
3# provided at the time of installation or download, or which otherwise accompanies
4# this software in either electronic or hard copy form.
5#
6# This script is to demonstrate Export the animation for list of models for the given take.
7#
8# Topic: FBApplication, FBSystem, FBFindModelByLabelName, FBBodyNodeId, FBTime, FBTake
9#
10
11from pyfbsdk import FBApplication, FBSystem, FBFindModelByLabelName, FBBodyNodeId, FBTime, FBTake
12import math
13import sys
14import os
15import tempfile
16
17# ************************************************************* #
18# #
19# Export Library #
20# #
21# ************************************************************* #
22
23def loadScene(sceneFile):
24 application = FBApplication()
25 if (not application.FileOpen(sceneFile, False)):
26 return False
27 return True
28
29def getFullPrefix(name):
30 if len( name.split(":") )>1:
31 lastPref = name.split(":")[-2]
32 firstPref = name.split(lastPref)[0]
33 fullPrefix = firstPref+lastPref
34 return fullPrefix
35 else:
36 return None
37
38def addAllGroupMembers(group, members):
39 for member in group.Items:
40 if member.ClassName() == str("FBGroup"):
41 addAllGroupMembers(member, members)
42 else:
43 members.append(member)
44
45def addAllSetMembers(set, members):
46 for member in set.Items:
47 if member.ClassName() == str("FBGroup"):
48 addAllGroupMembers(member, members)
49 elif member.ClassName() == str("FBSet"):
50 addAllSetMembers(member, members)
51 else:
52 members.append(member)
53
54def getGroupMembers(groupName, members):
55 for group in FBSystem().Scene.Groups:
56 if group.Name == groupName.split(":")[-1]:
57 for item in group.Items:
58 if not getFullPrefix(item.LongName):
59 continue
60 elif getFullPrefix(item.LongName) == groupName.split(":")[-2]:
61 addAllGroupMembers(group, members)
62 return
63 else:
64 members.append(item)
65 return
66
67def getSetMembers(setName, members):
68 for set in FBSystem().Scene.Sets:
69 if set.Name == setName.split(":")[-1]:
70 for item in set.Items:
71 if not getFullPrefix(item.LongName):
72 continue
73 elif getFullPrefix(item.LongName) == setName.split(":")[-2]:
74 addAllSetMembers(set, members)
75 return
76 return
77
78def getHierarchy (modelName, rotationModels, translationModels):
79 model = FBFindModelByLabelName(modelName)
80
81 if not model == None:
82 if not model.ClassName() == str("FBModel"):
83 #print "0. Add to rotation model list: ", model.FullName
84 rotationModels.append(model)
85 for child in model.Children:
86 getHierarchy(child.LongName, rotationModels, None)
87
88 if not translationModels == None:
89 translationModels.append(model)
90 #print "0. Add to translation model list: ", model.FullName
91
92
93def getCharacterModels(character, models, transModels):
94 chars = FBSystem().Scene.Characters
95 count = 0
96 countTrans = 0
97 for char in chars:
98 if char.Name == character:
99 for nodeID in FBBodyNodeId.values.values():
100 mod = char.GetModel(nodeID)
101 if mod != None:
102 count = count + 1
103 models.append(mod)
104 if nodeID == FBBodyNodeId.kFBHipsNodeId:
105 transModels.append(mod)
106 countTrans = countTrans + 1
107 #print "0. Get ", count, " models from character for rotation", character
108 #print "0. Get ", countTrans, " hip models from character for translation", character, " \n"
109 return
110
111def getModel(modelName, models):
112 mod = FBFindModelByLabelName(modelName)
113 if not mod == None:
114 models.append(mod)
115
116def mineCurve(start, end, fcurve, modifier):
117 curveData = dict()
118 counter = start
119 while counter <= end:
120 frameTime = FBTime(0,0,0,counter)
121 value = fcurve.Evaluate(frameTime) * modifier
122 curveData[frameTime.GetFrame()] = value
123 counter = counter + 1
124 return curveData
125
126def exportAnimData(animNodes, prefix, start, end, outData, modifier = 1.0):
127 if animNodes == None:
128 return
129
130 for animNode in animNodes:
131 curveName = prefix + animNode.Name
132 curveData = mineCurve(start, end, animNode.FCurve, modifier)
133 outData[curveName] = curveData
134 # Export any animation below this animNode
135 exportAnimData(animNode.Nodes, prefix, start, end, outData)
136
137
138def PlotModels(models, start, end):
139 # Mark the members as selected and plot them.
140 # For now, don't worry about backing up and restoring the current selection.
141 print("1.Plot the models!")
142 print("1.1. Select the models:")
143 for mod in models:
144 mod.Selected = True
145
146 take = FBSystem().CurrentTake
147 # Set the current layer to the Base Layer.
148 # NOTE: This will crash MotionBuilder for versions prior to 2009.g. In version 2010,
149 # the Base Layer index has been changed to 0 instead of -1.
150 take.SetCurrentLayer(0)
151
152 # Perform the plot of all the selected models with plot rate 30, or say "plot for every frame"!
153 print("1.2. Plot models from frame", start, "to frame", end)
154 period = FBTime(0,0,0,1)
155 #period.SetSecondDouble( 1.0 / 30.0 ); # also works
156 take.PlotTakeOnSelected(period)
157
158 # Unselect the model
159 print("1.3. Unselect all ploted models!")
160 for mod in models:
161 mod.Selected = False
162
163
164def GetRotationAnimation(models, start, end, allData):
165 print("2. Rotation models has: ", len( rotationModels), "models.")
166 count = 0
167 for mod in models:
168 if mod != None:
169 nodeAnim = mod.AnimationNode
170 for nodeAnimNode in nodeAnim.Nodes:
171 if "Lcl Rotation" in nodeAnimNode.Name:
172 if len(nodeAnimNode.Nodes) > 0:
173 exportAnimData(nodeAnimNode.Nodes, mod.FullName + "__Rotation", start, end, allData, math.pi/180.0)
174 count = count + 1
175 #print mod.FullName
176 print("2. Get valid rotation animation from: ", count, " models.")
177
178def GetTranslationAnimation(models, start, end, allData):
179 print("2. Translation models has: ", len( translationModels), "models.")
180 count = 0
181 for mod in models:
182 if mod != None:
183 #print mod.FullName
184 nodeAnim = mod.AnimationNode
185 for nodeAnimNode in nodeAnim.Nodes:
186 if "Lcl Translation" in nodeAnimNode.Name:
187 if len(nodeAnimNode.Nodes) > 0:
188 exportAnimData(nodeAnimNode.Nodes, mod.FullName + "__Translation", start, end, allData)
189 count = count + 1
190 #print mod.FullName
191 print("2. Get valid translation animation from: ", count, " models.")
192
193def ExportAnimationData(outFile, allData):
194 print("3. Output animation data into file: ", outFile, "\n")
195
196 # Output the data.
197 output = open (outFile, 'w')
198 output.write('########### Animation Data ###########\n')
199 for keyModelName,curveDict in allData.items():
200 output.write('%s\n'%(keyModelName))
201 #Sort curve dict
202 keylist = curveDict.keys()
203 keylist.sort()
204 for keyFrame in keylist:
205 output.write('%s: %s\n'%(keyFrame, curveDict[keyFrame]))
206 output.write('\n')
207 output.close()
208
209def ExportModelsAnimation(outFile, rotationModels, translationModels, start, end):
210 PlotModels( rotationModels, start, end )
211 PlotModels( translationModels, start, end )
212
213 allData = dict()
214 GetRotationAnimation( rotationModels, start, end, allData )
215 GetTranslationAnimation( translationModels, start, end, allData )
216
217 ExportAnimationData( outFile, allData )
218
219
220# ************************************************************* #
221# #
222# File Specific Code #
223# #
224# ************************************************************* #
225
226# Attention: This script use the StoryExample.fbx as an example, but you may want to replace the file with your own.
227# Meanwhile, you should also change the parameters below according to your own file before using them.
228
229# Specify the export parameters.
230start = 120
231end = 130
232inFile = os.path.realpath(os.path.abspath(os.path.join( FBSystem().ApplicationPath, "../../OpenRealitySDK/Scenes/StoryExample.fbx" )))
233outFile = os.path.realpath(os.path.abspath(os.path.join( tempfile.gettempdir(), "StoryExample_output.txt" )))
234
235# Load the scene to be exported.
236if not loadScene(inFile):
237 sys.stderr.write('Could not load file %s' % inFile)
238 raise Exception('quitting')
239
240
241# Initialize a list to contain the accumulated models.
242# Rotation information will be generated for each of these models in rotationModels list.
243# Additional model list, translationModels, is to contain models which should have translations exported for them.
244rotationModels = list()
245translationModels = list()
246
247# If exporting characters, get the models in the named characters.
248# Characters may contain their own hips unknown at export time.
249# Add any hips found in the character to the list of transModels
250# so they will have translations exported for them.
251getCharacterModels("Skeleton_Model", rotationModels, translationModels)
252
253# If exporting hierarchies, get the models in the named hierarchies.
254# The root model of the hierarchy will be added to the transModels list.
255getHierarchy ("Skeleton_Model:Hips", rotationModels, translationModels)
256getHierarchy ("Character_Ctrl:HipsEffector", rotationModels, translationModels)
257
258# If exporting groups, get the models in the named groups. For groups
259# containing root models, add those models to the list of transModels.
260getGroupMembers("KNIGHT:RightThighArmorLowBeltBuckle", rotationModels)
261
262# If exporting sets, get the models in the named sets. For sets
263# containing root models, add those models to the list of transModels.
264# Attention: Here we just show how to get SetMembers, and MyNamespace:MySet doesn't really exist.
265'''
266getSetMembers("MyNamespace:MySet", models)
267'''
268
269# Finally, add any additional models which should have translations
270# and rotations exported for them.
271getModel("KNIGHT:Hips", rotationModels)
272getModel("KNIGHT:Hips", translationModels)
273getModel("Character_Ctrl:HipsEffector", translationModels)
274
275
276print("0. Totally get", len(rotationModels), "models to export their rotation.")
277#for model in rotationModels:
278# print model.FullName
279print("0. Totally get", len(translationModels), "models to export their translations.")
280#for model in translationModels:
281# print model.FullName
282
283# If no models have been found, raise an exception
284if len(rotationModels) == 0 & len(translationModels) == 0:
285 sys.stderr.write('No models were found.')
286 raise Exception('quitting')
287
288# Export the animation for the given list of models for the given takes.
289ExportModelsAnimation(outFile, rotationModels, translationModels, start, end)
290
291print("The animation data for from frame ", start, " to frame ", end, " have been exported to file: \n", outFile)
FBApplication is used mainly to manage files.
Definition: pyfbsdk_generated.h:801
Provides access to the underlying system, and the MotionBuilder scene.
Definition: pyfbsdk_generated.h:18771
Time data structure.
Definition: pyfbsdk_generated.h:19596
Python built-in list container class.
Definition: pyfbsdk.h:65
Python built-in string class.
Definition: pyfbsdk.h:77
FBModel FBFindModelByLabelName(str pModelLabelName)
Find a model in the scene by its label name.