Motionbuilder - query relation constraint?

hey everyone,
i’m starting to pick up python in motionbuilder (mobu 2010) for tools development for our animators.

the goal of this tool is to have a UI that controls connection and disconnection of nodes in a relation constraint. i have the ui built (gotta plug ui-builder for mobu written by sergey solohin - http://neill3d.com/tool-programming-in-mobu/ui-builder - made my life easier while trying to figure out ui building).

now my problem is connecting ui controls to the relation constraint, specifically querying the relation constraint to make sure that it connects/disconnects nodes in the proper constraint (thinking about dealing with namespaces and multiple characters in a scene). all of the relation constraint examples that i have come across show ground up creation of the relation constraint so that you have the instance of the constraint right from the beginning, but is there a way to query relation constraints in the scene so that i can manipulate them? i haven’t found anything leading me to that in the docs, but i’m still struggling finding useful information sometimes when looking through them… so that doesn’t mean it doesn’t exist :x

Hey,

I hope I understand what you are looking for…
by using the FBScene class you can get a list of all constraints in the scene


from pyfbsdk import *

lScene = FBSystem().Scene

lConstraints = lScene.Constraints

for each in lConstraints:
    print each.Name


that is exactly what i am looking for. i had found that i had to use the FBSystem().Scene to get the FBScene commands, but in the python docs it says that the command is FBScene.ListConstraints not FBScene.Constraints, that was throwing me off.

Let me know if you figure out how to edit an existing relation constraint, i was running in to that issue also and wasnt able to devote enough time to figure it out, i can make a constraint from the ground up, but I think since none of the nodes in the contraint have unique names i can access them? Though i could be wrong, as i said i was never able to edit or query an existing relation constraint.

i have yet to get into the actual connecting and disconnecting but i plan on tracing through the constraint with AnimationNodeInGet and AnimationNodeOutGet on particular nodes in the graph… then using FBConnect and FBDisconnect to do the actual connect and disconnect

[QUOTE=jeremyc;6276]
… the goal of this tool is to have a UI that controls connection and disconnection of nodes in a relation constraint…[/QUOTE]

this sounds like the UI thats already implemented in newer versions of Motion builder, (well that depends on what version youre using).

I’ve haven’t worked alot with disconnecting/connecting nodes in Motion builder but if you post your python code I’ll be happy to help you as much as I can

could you tell me more about the UI for connecting / disconnecting? is it different from the editor itself? i’m trying to keep animators out of the actual constraint to reduce the chance of things breaking as well as speed up workflow. we’re using mobu 2010.

this tool is actually a port / rewrite of a tool from max, so i am emulating the layout from the max tool as closely as i can. i have that part pretty well locked down. i know the nodes that i need to connect / disconnect, so i plan on using the .Boxes command on the constraint and filtering through that list to find the individual nodes then running the connect and disconnect methods based on a series of checkboxes in a the ui. having to use a for loop on the .Boxes list every time i want to find a node seems inefficient but it’s the only way i’ve seen to get a list of the nodes that exist in the constraint.

edit: nevermind, match by name won’t work because boxes have to have unique names… need to find a way to trace through the graph.

http://jason-parks.com/Pipeline_Tools/MotionBuilder_Scripts.html

this post might get you in the right direction, to get the script sample just rt click and download it.

I’m not sure how you setup your scene but I have worked some with this so I might be able to help if I understand your problem correctly.

Just going to paste a code snippet and maybe you can have some use with it. Its in c++ but i guess you can convert it to Python pretty easy.


// Create the constraint
lNumVecBox = lConstraint->CreateFunctionBox("Converters", "Number to Vector");
lConstraint->SetBoxPosition(lNumVecBox, 1300, 121);

// Get the animation node for each channel
HFBAnimationNode lNumVecXIn = lNumVecBox->AnimationNodeInGet()->Nodes.Find("x");
HFBAnimationNode lNumVecYIn = lNumVecBox->AnimationNodeInGet()->Nodes.Find("y");
HFBAnimationNode lNumVecResultOut = lNumVecBox->AnimationNodeOutGet()->Nodes.Find("Result");

// Connect them
FBConnect(lNumVecResultOut, lEyeCenterRotIn);

I don’t understand what data you are missing or what step you have trouble with. “need to find a way to trace through the graph.” what graph?

the root of my problem stemmed from the fact that i wasn’t creating a relation constraint: i needed to find it in the scene and then find the boxes within it to manipulate them (when i said ‘trace through the graph’ what i meant was finding the boxes in the constraint GUI - sorry, maya hypergraph influence). all of the examples i’ve seen showed creation and manipulation, so all of the object names for the boxes and the constraint itself came for free since they are returned when everything is created.

the way i got around it was to use FBSystem().Scene and scene.Constraints to get the constraint, then constraint.Boxes to get a list of all of the boxes in the constraint… this list seems to be static, so no matter what namespace / name the box has, it’s always in the same index of the list. then, using the indices for 2 boxes, i can FBConnect / FBDisconnect. i’m not a big fan of using the indices, because they are prone to break if the constraint layout changes, but matching by name won’t work because the names change when files are merged (i.e. when you have more than 1 character in the scene). the only other option is to trace through the box connections(ie… find what box “X” is connected to, then find the next box after that), but if the box layout changes then that’s even messier to fix than an index.

so my actual connect looks like this:

    if chk_posX.State:
        print "tx connect"
        src = FindAnimationNode(magicBoxRelationCons.Boxes[2].AnimationNodeOutGet(), 'X')
        dest = FindAnimationNode(magicBoxRelationCons.Boxes[6].AnimationNodeInGet(), 'X')
        FBConnect(src, dest)
    else:
        print "tx disconnect"        
        src = FindAnimationNode(magicBoxRelationCons.Boxes[2].AnimationNodeOutGet(), 'X')
        dest = FindAnimationNode(magicBoxRelationCons.Boxes[6].AnimationNodeInGet(), 'X')
        FBDisconnect(src, dest)    

findAnimationNode is a function i grabbed from a sample that ships with mobu 2010 that takes a box and returns the handle of the desired parameter (2nd parameter)

def FindAnimationNode( pParent, pName ):
    lResult = None
    for lNode in pParent.Nodes:
        if lNode.Name == pName:
            lResult = lNode
            break
    return lResult

you guys from imagination studios: do you distribute python scripts for animators? if so, i’d love to ask a couple of questions about how you efficiently do it (like do you keep them on perforce or some sort of source control? do animators have to add python scripts to every scene / how do you verify that the scripts that are added to scenes are latest versions? does putting python libraries in the startup folder guarentee all of your scripts will be able to call the functions in the libraries?). aside from jason park’s master class and the area, there seems to be a real lack of motionbuilder information out there when it comes to production…

[QUOTE=jeremyc;6317]text

you guys from imagination studios: do you distribute python scripts for animators? if so, i’d love to ask a couple of questions about how you efficiently do it (like do you keep them on perforce or some sort of source control? do animators have to add python scripts to every scene / how do you verify that the scripts that are added to scenes are latest versions? does putting python libraries in the startup folder guarentee all of your scripts will be able to call the functions in the libraries?). aside from jason park’s master class and the area, there seems to be a real lack of motionbuilder information out there when it comes to production…[/QUOTE]

Oh I thought you made the constraints also. Yeah then it’s a bit messy. But I guess that with some error checking it’s okay to use the indices.

Erik knows more about how we distribute our scripts but I can take a swing at your questions for now.

We use a subversion server to handle them and a custom plugin that loads them for the animators basically. I don’t think we have any version checking at the moment but it would be a nice thing to have actually. About the libraries I’m not sure either but i guess most of our python scripts don’t use extra libraries.

Yeah finding info about motionbuilder is really hard, you have to go by the trial and error method for the most parts. I guess we all could try to contribute more to the wiki and make TAO the big place to go to for motionbuilder guidance :nod:

To continue what Eiktyrner describes above. right now our python scripts are mostly tools for editing and not really embedded to affect events in the scene. Our tools are distributed, as mentioned, with revision control. We also have a ORSDK plugin that generate buttons for all the scripts.

your question regarding version testing of scripts is an interesting point.

information about Motionbuilder scripting and programming is something that there could be more of out there on the big internet, i agree

Hi, Bro, I guess u need this( answers from 2020~)

lConstraints = FBFindObjectByFullName("Constraint::NameSpace:Name")