csa3d.com |

Archive for October 2009

Did you know that through MotionBuilder’s Asset Browser, you can map any directory of Python scripts by right clicking in the window and choosing add a “favorite path”?  This allows you to now drag any script into the Viewer Window and have it execute line by line, top to bottom, calling any code it finds in the order it finds it.

To set this up, simply browse to your python scripts directory and choose the OK button.  The directory should populate with any scripts you have currently in that directory.  If you add or remove scripts in the middle of a session, right click on your python folder created above and click “Refresh Directory”.

Now that you’ve got that set up, let’s create a sample script to illustrate the drag to execute functionality.  In that custom directory, create the following script and name it “Greet.py”:

#Greet.py

name = "Chris"
print "Hello, %s." % name

If you left-mouse-drag that script into the Viewer window and choose Execute, you will see the following output print to the python editor window:

>>
Hello, Chris.
>>
 

Python executed that script top to bottom doing exactly as you told it to do.  While this greeting example is rather basic, imagine you’ve created a useful function such as deleting all animation layers, or renaming all takes to all use a common suffix.  You can see how handy dragging a script into the scene and executing it could be.  Triggering this code required no fancy interface to launch it, and grabbing it from the Asset Browser was quick and easy, so that’s a plus.

Now consider that you’ve decided your utility is super handy, and would also be great if other modules could use this code.  I’ve decided all my scripts should greet me, but the code I’ve written isn’t import friendly.  With the module written above, as soon as I import my Greet module python is going to execute the code top to bottom, and thus will immediately import the name object into my current namespace (possibly overwriting something important) and execute the greeting.

Example importing our code from above:

>>> import Greet
Hello, Chris.
>>>

It is obvious that if I plan to import this module into other modules, than I need to wrap this code in a function def.  That way I can call it whenever I want to, and not have it run directly upon initial import.  Let’s re-write our code as follows:

# Greet.py

def hello( name ):
    print "Hello, %s" % name

Now from the python interactive terminal I import the new module and test it out:

>>> import Greet
>>> Greet.hello("Chris")
Hello, Chris
>>> 


Great!  Now any other module can use my greeting code.  One problem, I can no longer be greeted by dragging in my script object from the Asset Browser.  If I wanted to, I could create another module and duplicate my code above, omitting the def() wrapper, just like we had when we first started.  Now I’d have one script to drag, and one script to import.  This is really unnecessary, sloppy, and will eventually become a burden ifwhen… I decide to change code in one of those files, because I’ll have to go and update both scripts with the new changes.  There are better options!


Let’s look at what happens when we drag a script into the Viewer Window. Every module by default, has a __name__ attribute, including the top level module running python.  When you drag a script into the Viewer, the module drug into the scene inherits the value stored in the top level __name__ attribute.  If the module is imported using the import keyword, the __name__ attribute is filled with the name of the .py file imported.


To illustrate this, take this example:

# WhatName.py

def callMe():
    print "My __name__ is %s" % __name__
    print "You called?"

if __name__ == "__builtin__":
    print "You drug me into the viewer.."
    callMe()

Dragging this into the viewer produces:

>>>
You drug me into the viewer..

My __name__ is __builtin__

You called?

>>>


while manually executing the following produces different results:


>>> import WhatName
>>> WhatName.callMe()

My __name__ is WhatName

You called?

>>>


Notice that when we drag WhatName.py into the viewer that  __name__ == ‘__builtin__’ , but when we import it into any other module using import then __name__ == ‘WhatName’.


Taking this info back to our original Greet.py example, we now know how to edit the script so that we can import it into another module and call it by name *or* drag it into the Viewer Window and have it self execute.


Here is the final code for Greet.py:

# Greet.py

def hello( name ):
    print "Hello, %s." % name

if __name__ == "__builtin__":
    myName = "Chris"
    hello( myName )

, Hide

Find it!

Theme Design by devolux.org

Archives

To top