from pyfbsdk import FBApplication, FBSystem, FBFindModelByLabelName, FBBodyNodeId, FBTime, FBTake
import math
import sys
import os
import tempfile
def loadScene(sceneFile):
application = FBApplication()
if (not application.FileOpen(sceneFile, False)):
return False
return True
def getFullPrefix(name):
if len( name.split(":") )>1:
lastPref = name.split(":")[-2]
firstPref = name.split(lastPref)[0]
fullPrefix = firstPref+lastPref
return fullPrefix
else:
return None
def addAllGroupMembers(group, members):
for member in group.Items:
if member.ClassName() == str("FBGroup"):
addAllGroupMembers(member, members)
else:
members.append(member)
def addAllSetMembers(set, members):
for member in set.Items:
if member.ClassName() == str("FBGroup"):
addAllGroupMembers(member, members)
elif member.ClassName() == str("FBSet"):
addAllSetMembers(member, members)
else:
members.append(member)
def getGroupMembers(groupName, members):
for group in FBSystem().Scene.Groups:
if group.Name == groupName.split(":")[-1]:
for item in group.Items:
if not getFullPrefix(item.LongName):
continue
elif getFullPrefix(item.LongName) == groupName.split(":")[-2]:
addAllGroupMembers(group, members)
return
else:
members.append(item)
return
def getSetMembers(setName, members):
for set in FBSystem().Scene.Sets:
if set.Name == setName.split(":")[-1]:
for item in set.Items:
if not getFullPrefix(item.LongName):
continue
elif getFullPrefix(item.LongName) == setName.split(":")[-2]:
addAllSetMembers(set, members)
return
return
def getHierarchy (modelName, rotationModels, translationModels):
model = FBFindModelByLabelName(modelName)
if not model == None:
if not model.ClassName() == str("FBModel"):
rotationModels.append(model)
for child in model.Children:
getHierarchy(child.LongName, rotationModels, None)
if not translationModels == None:
translationModels.append(model)
def getCharacterModels(character, models, transModels):
chars = FBSystem().Scene.Characters
count = 0
countTrans = 0
for char in chars:
if char.Name == character:
for nodeID in FBBodyNodeId.values.values():
mod = char.GetModel(nodeID)
if mod != None:
count = count + 1
models.append(mod)
if nodeID == FBBodyNodeId.kFBHipsNodeId:
transModels.append(mod)
countTrans = countTrans + 1
return
def getModel(modelName, models):
mod = FBFindModelByLabelName(modelName)
if not mod == None:
models.append(mod)
def mineCurve(start, end, fcurve, modifier):
curveData = dict()
counter = start
while counter <= end:
frameTime = FBTime(0,0,0,counter)
value = fcurve.Evaluate(frameTime) * modifier
curveData[frameTime.GetFrame()] = value
counter = counter + 1
return curveData
def exportAnimData(animNodes, prefix, start, end, outData, modifier = 1.0):
if animNodes == None:
return
for animNode in animNodes:
curveName = prefix + animNode.Name
curveData = mineCurve(start, end, animNode.FCurve, modifier)
outData[curveName] = curveData
exportAnimData(animNode.Nodes, prefix, start, end, outData)
def PlotModels(models, start, end):
print "1.Plot the models!"
print "1.1. Select the models:"
for mod in models:
mod.Selected = True
take = FBSystem().CurrentTake
take.SetCurrentLayer(0)
print "1.2. Plot models from frame", start, "to frame", end
period = FBTime(0,0,0,1)
take.PlotTakeOnSelected(period)
print "1.3. Unselect all ploted models!"
for mod in models:
mod.Selected = False
def GetRotationAnimation(models, start, end, allData):
print "2. Rotation models has: ", len( rotationModels), "models."
count = 0
for mod in models:
if mod != None:
nodeAnim = mod.AnimationNode
for nodeAnimNode in nodeAnim.Nodes:
if "Lcl Rotation" in nodeAnimNode.Name:
if len(nodeAnimNode.Nodes) > 0:
exportAnimData(nodeAnimNode.Nodes, mod.FullName + "__Rotation", start, end, allData, math.pi/180.0)
count = count + 1
print "2. Get valid rotation animation from: ", count, " models."
def GetTranslationAnimation(models, start, end, allData):
print "2. Translation models has: ", len( translationModels), "models."
count = 0
for mod in models:
if mod != None:
nodeAnim = mod.AnimationNode
for nodeAnimNode in nodeAnim.Nodes:
if "Lcl Translation" in nodeAnimNode.Name:
if len(nodeAnimNode.Nodes) > 0:
exportAnimData(nodeAnimNode.Nodes, mod.FullName + "__Translation", start, end, allData)
count = count + 1
print "2. Get valid translation animation from: ", count, " models."
def ExportAnimationData(outFile, allData):
print "3. Output animation data into file: ", outFile, "\n"
output = open (outFile, 'w')
output.write('########### Animation Data ###########\n')
for keyModelName,curveDict in allData.items():
output.write('%s\n'%(keyModelName))
keylist = curveDict.keys()
keylist.sort()
for keyFrame in keylist:
output.write('%s: %s\n'%(keyFrame, curveDict[keyFrame]))
output.write('\n')
output.close()
def ExportModelsAnimation(outFile, rotationModels, translationModels, start, end):
PlotModels( rotationModels, start, end )
PlotModels( translationModels, start, end )
allData = dict()
GetRotationAnimation( rotationModels, start, end, allData )
GetTranslationAnimation( translationModels, start, end, allData )
ExportAnimationData( outFile, allData )
start = 120
end = 130
inFile = os.path.realpath(os.path.abspath(os.path.join( FBSystem().ApplicationPath, "../../OpenRealitySDK/Scenes/StoryExample.fbx" )))
outFile = os.path.realpath(os.path.abspath(os.path.join( tempfile.gettempdir(), "StoryExample_output.txt" )))
if not loadScene(inFile):
sys.stderr.write('Could not load file %s' % inFile)
raise Exception('quitting')
rotationModels = list()
translationModels = list()
getCharacterModels("Skeleton_Model", rotationModels, translationModels)
getHierarchy ("Skeleton_Model:Hips", rotationModels, translationModels)
getHierarchy ("Character_Ctrl:HipsEffector", rotationModels, translationModels)
getGroupMembers("KNIGHT:RightThighArmorLowBeltBuckle", rotationModels)
'''
getSetMembers("MyNamespace:MySet", models)
'''
getModel("KNIGHT:Hips", rotationModels)
getModel("KNIGHT:Hips", translationModels)
getModel("Character_Ctrl:HipsEffector", translationModels)
print "0. Totally get", len(rotationModels), "models to export their rotation."
print "0. Totally get", len(translationModels), "models to export their translations."
if len(rotationModels) == 0 & len(translationModels) == 0:
sys.stderr.write('No models were found.')
raise Exception('quitting')
ExportModelsAnimation(outFile, rotationModels, translationModels, start, end)
print "The animation data for from frame ", start, " to frame ", end, " have been exported to file: \n", outFile