Area :: Header
New tools, templates and workflows
Announcing Extension 2 for 3ds Max 2015 and 3ds Max Design 2015
Discussion Groups


Active Contributor
46 Posts
0 Kudos
Registered: ‎08-25-2006

So, FCurve is just a pointer that's dependable on take??

49 Views, 0 Replies
12-23-2010 07:42 AM

I'm trying to write a script to make additive animations using FCurves. I tried the solution by Neill but it didn't work, and I wanted to learn more about FCurve anyway, instead of iterating by each keyframe. I'm following the same "method" though, take01-take02 = take03.

What I'm trying to do is store each Rotation.AnimationNode from each model of my skeleton on one single array per take. So later I can iterate through this array and do the transformations between each key from each FCurve from each model between both arrays.

Problem is, it seems GetAnimationNode() doesn't stores the FCurves, but a pointer to the FCurve on the current take. Which makes this process impossible. Is this right?

Here's what I'm doing:

from pyfbsdk import *
import pprint

app = FBApplication()
system = FBSystem()
scene = FBSystem().Scene
player = FBPlayerControl()
animationRotationCurves = [] # used to store each model FCurve (on Take 001)
substractionRotationCurves = [] # used to store each model FCurve to be substracted (on Take 002)
pp = pprint.PrettyPrinter()

def getCurve(lmodel):
curveToRet =

for child in lmodel.Children:

return curveToRet

def main():

if (len(scene.Takes)!= 3):
FBMessageBox( "Incorrect amount of takes", "Please create 3 takes in this order: additive anim, substraction anim, result take", "OK", None, None )
return False
takeAnimation = scene.Takes
takeSubstraction = scene.Takes
takeResult = scene.Takes

character = app.CurrentCharacter #FBCharacter()

if character:

rootModel = character.GetModel(FBBodyNodeId.kFBHipsNodeId)
print "rootModel is:", rootModel.Name

system.CurrentTake = takeAnimation
animationRotationCurves = getCurve(rootModel)

system.CurrentTake = takeSubstraction
substractionRotationCurves = getCurve(rootModel)

system.CurrentTake = takeResult

# uncomment this bellow to print stuff for the keys
# system.CurrentTake = takeAnimation
# scene.Evaluate()

resultCurves = []
# iterates through each bone fcurve
for i in range(len(animationRotationCurves)):
print i
# obviusly, this is too much to ask: resultCurves.append(animationRotationCurves - substractionRotationCurves)
# :)
# so we iterate through each axis
for axis in range(0,3):
print animationRotationCurves.Name
print animationRotationCurves.Nodes.Name
print system.CurrentTake.Name
# and through each frame
for lkey in animationRotationCurves.Nodes.FCurve.Keys:
print "model: ", i, " axis number: ", axis, " lkey: ", lkey

else: # if character fails there's no character on the scene/selected
FBMessageBox( "No character selected", "Please select a character", "OK", None, None )


getCurve(lmodel) is where it grabs FCurves. The take is switched and scene.Evaluate() called after each take change. I assumed it was storing each FCurve from each take, but it doesn't seem so.

The script only goes inside the last for if system.CurrentTake is 001 or 002, where there are some animations/keys. And the results are different if the take is different, even though the variable is the same.

I really can't work with FCurves from different takes simultaneously...?