Who else gets "old" data from MotionBuilder?

Hi,

I have this issue where MotionBuilder quite often gives me “old” data. when I’m talking to it from Python. E.G.:

[ul]
[li]When I go to a frame, evaluate the scene and ask for transform data, it will sometimes give me data that is not current (in this case, not the transforms on that keyframe)
[/li]
[li]The same goes for the output of RelationConstraint networks that sometimes do not output the correct value for the frame you are on
[/li]
[li]The issue is seen when running a block of code, where using FBSystem().Scene.Evaluate() should give you current data. But I also see it in scenarios where I attach a function to UiIdle and dump data on that event (Similar to c++ exporter examples that come with MoBu)
[/li][/ul]

The people working in c++ have the issue too. We suspect that it has something to do with MotionBuilders “realtime” nature and that MoBu would rather return something to you (correct or not) rather than “hang”. Of course in a ton of situations, this would be a very bad thing.

So is anyone else seeing this? Do you have a remedy? This has more than slightly hampered our ability to do tools, let alone on schedule :tear:

Here’s a simple test to check if the issue occurs on a particular machine. I ran this on 7 different machines, including 2 home computers that have nothing in common with our work machines set-up. 4 out of 7 had the problem…

If you would like to reproduce, please run the test below:


"""
Creates a locator in scene and animates it at 0,0,0 - 0,10,0, over the course of frames 0-10
Then goes to frame 9 (could be any frame other than frame 10), then to frame 10 and reads the 
Y translation of the locator. The Y translation should be 10. If it's not prints out a warning.

If you are not getting errors, you may want to run this test multiple times or to increase
the number of iterations through the loop. Could be that you just have a system to does not 
have the issue. Though the people that use your tools may.

Sometimes I can run the test multiple times without errors, though mostly I get a few. Regularily 
I'll get a really high error count. Like 49 or 87. I've gotten 998 & 999 errors (with 1000 loops) on occation!
"""

from pyfbsdk import *

lVector = FBVector3d()
totalErrors = 0

# Set frame range
startFrame = FBTime(0,0,0,0)
endFrame = FBTime(0,0,0,10)
FBPlayerControl().LoopStart = startFrame
FBPlayerControl().LoopStop  = endFrame
FBPlayerControl().ZoomWindowStart = startFrame
FBPlayerControl().ZoomWindowStop  = endFrame

# Create a locator and animate it
loc = FBModelNull('test_loc')
loc.Show = True
loc.Selected = True
FBPlayerControl().Goto(startFrame)
FBPlayerControl().Key()
FBPlayerControl().Goto(endFrame)
FBSystem().Scene.Evaluate()
loc.SetVector(FBVector3d(0, endFrame.GetFrame(False), 0), FBModelTransformationMatrix.kModelTranslation, True)
FBSystem().Scene.Evaluate()
FBPlayerControl().Key()

# Set curve interpolation to linear
for animNode in loc.AnimationNode.Nodes:
    for subnode in animNode.Nodes:
        for key in subnode.FCurve.Keys:
            key.Interpolation = FBInterpolation.kFBInterpolationLinear

for i in range(0, 1999):
    # Go to frame 9 and then to frame 10 where the locator is at 10, 0, 0 
    FBPlayerControl().Goto(FBTime(0,0,0,9))
    FBSystem().Scene.Evaluate()
    FBPlayerControl().Goto(FBTime(0,0,0,10))
    FBSystem().Scene.Evaluate() 
 
    # Read and print the locators location
    loc.GetVector(lVector, FBModelTransformationMatrix.kModelTranslation, False, None)
     
    # If the locator is not at 10 in Y, let me know
    if lVector[1] != 10:
        print 'Y Translation at frame 10 at iteration {0} is:{1}'.format(i, lVector[1], )
        totalErrors += 1

if totalErrors:
    print 'Total errors were: {0}'.format(totalErrors)
else:
    print 'Congratulations there were no errors'

loc.FBDelete()

Thanks :slight_smile:

Which version of mobu are running? We’ve had a bitch of time working with autodesk on a similar bug. After I was able to indentify a consistent repro (and face palm for them), they sent my repro back as a “work around” lol I kept fighting with it and to my surprise they delivered a HF for it this week. Idk if it’s public yet, but if ur in 2012 try viewer_cycle_mode (i don’t remember the pyfbsdk commands), it’s the ctrl+a command to cycle X-ray modes. Try this before running the script, or put it in the script. I may have been doing some funky code, but scripting it would inconsistently crash mobu.

I usually say ‘If you ask motionbuilder to do something for your, you can’t be sure it will! So you’re better of not asking it at all’. Because I’ve seen this error/flaw many times. easiest way to make this occur is to try to change to a new frame and ask for a value.

But I’ve also seen this when you try to import/merge something into a scene. What I did then was this, (its horrible i know ;))


while not fileMerged:
    #try importing a file    
    FBFile.merge("fileBeingMerged")
    #test if file has been imported by testing if a certain object is in the scene
    if TestForObject():
        #if true set fileMerged to true
        fileMerged = true

But what you ended up with was often that the file was merged twice since first time motionbuilder was still loading the file.

When it comes to changing frame and asking for a value, it’s as if the ChangeFrame() function is sent to one thread and the Get()function to another, and they’re asynchronized and the Get function is runned before ChangeFrame().

That’s why the problem still occurs when you run c++ code, because its nothing within the python wrapper, its the internal structure of Motionbuilder.

I tried running your code while fiddeling around with stuff on the motionbuilder.exe settings in the ‘Task Manager’. Changing the priority of the process changed the number of errors i was given, setting it to high gave me up to 100 errors! Having it on normal or lower gave me about 2-3 errors. Also, if I changed the affinity so motionbuilder only was allowed to use one core made the whole software freeze while running the code.

Motionbuilder is interesting in its own way…

Thanks guys for your answers… And sorry for the slightly late reply :wow:

We are on 2011 Advantage Pack SP1. Now I’m not clear on whether I can talk about stuff like fixes, but sufficed to say something happened that fixed the issue :slight_smile: At least the issue as illustrated by running the test script.

I have come across a number of cases where MoBu did not spit out a correct state. Unfortunately I don’t have time ATM to test if this fixes these cases as well. But I’ll let you know if I still run into problems.

Btw. I only have the stock version of 2012 (no sp, adv pack or hotfixes) and changing display mode prior to running the script did not seem to change the behaviour.

Thanks again

My studio was having a similar problem in MotionBuilder 2011 (base install, and Service Pack 1). Our in-house exporter was randomly spitting out the same bone positions multiple frames in a row.

# Pseudo-code of original exporter.
# We'd frequently end up exporting
# the same exact bones positions multiple frames
# in a row. This problem happened more often
# if you were forcing your computer to
# work on other stuff during the export
for frameI in exportFramess:
   frameTime = FBTime(0,0,0,frameI)
   FBPlayerControl.GoTo(frameTime)
   FBSystem().Scene.Evaluate()
   for boneI in exportBones:
       # read bone data
# Pseudo-code of fixed version.
# FBPlayerControl.GoTo() is apparently asynchronous?
for frameI in exportFramess:
   frameTime = FBTime(0,0,0,frameI)
   FBPlayerControl.GoTo(frameTime)
   while FBSystem().LocalTime != frameTime:
      time.sleep(1)
   FBSystem().Scene.Evaluate()
   for boneI in exportBones:
       # read bone data

So this fixed it. We had to wait for the system time to match the GoTo time before calling Evaluate. Forgive me if I’m totally wrong or there’s a more elegant way to do this. I’d never touched MotionBuilder before this bug fell in my lap to fix. Posting here to share it with the internet.