Python Scripting in MotionBuilder

02 – RTFM: Documentation and dir

Part Two is an attempt to teach a man to fish, as it were, by pointing out some of the resources that can be used to decipher the occult mysteries of the MotionBuilder API.

Watch on YouTube | Watch in a full window

Key Points


Code

Summarize.py

import inspect

def SummarizeConnections(obj):
    print('\n%s' % obj.Name)
    PrintSourceConnections(obj)
    PrintDestinationConnections(obj)
    PrintConnections('Owned', obj.GetOwnedCount, obj.GetOwned)

def PrintConnections(name, countFunc, getFunc):
    '''
    Prints an indexed list of the connections for a particular component.
    @param name: The type of connection to be printed, typically 'Source'
        or 'Destination'.
    @param countFunc: GetSrcCount or GetDstCount.
    @param getFunc: GetSrc or GetDst.
    '''
    n = countFunc()
    print('\n%s connections (%d):\n----------' % (name, n))

    for i in range(0, n):

        current = getFunc(i)
        try:
            print('[%d]: %s %s' % (i, current.LongName, current))
        except AttributeError:
            print('[%d]: %s' % (i, current))

def PrintSourceConnections(obj):
    '''
    Prints an indexed list of the source connections for this component.
    '''
    PrintConnections('Source', obj.GetSrcCount, obj.GetSrc)

def PrintDestinationConnections(obj):
    '''
    Prints an indexed list of the destination connections for this component.
    '''
    PrintConnections('Destination', obj.GetDstCount, obj.GetDst)

def PrintMethods(obj, methodList):
    '''
    Prints a list of method names for the given object. Expects to be
    given an already-compiled list of method names.
    '''
    print('\nMethods (%d):\n----------' % len(methodList))
    for methodName in methodList:
        print(methodName)

def PrintProperties(obj, propertyList):
    '''
    Prints a list of property names, along with the current value for
    each property, for the given object. Expects to be given an
    already-compiled list of property names.
    '''
    print('\nProperties (%d):\n----------' % len(propertyList))
    for propertyName in propertyList:
        print('%s: %s' % (propertyName, obj.__getattribute__(propertyName)))

def Summarize(obj, searchText = ''):
    '''
    Prints a summary of the given object, which should be an instance
    of an FBComponent subclass. searchText may be optionally specified
    in order to filter the methods and properties grep-style.
    '''
    searchText = searchText.lower()
    methods = []
    properties = []

    for prop in [p for p in dir(obj) if not p.startswith('_')]:

        if searchText and prop.lower().find(searchText) < 0:
            continue

        if inspect.ismethod(obj.__getattribute__(prop)):
            methods.append(prop)
        else:
            properties.append(prop)

    try:
        print('%s\n%s' % (obj.LongName, obj))
    except AttributeError:
        print(obj)

    PrintSourceConnections(obj)
    PrintDestinationConnections(obj)
    PrintMethods(obj, methods)
    PrintProperties(obj, properties)

Notes & Errata

Official Documentation


Property Objects

We'll get into properties in a bit more detail in the next section. I mentioned them briefly here to make you familiar with their syntax, so that when you see a property of type FBPropertySomething, you'll know that you can get its value as an FBSomething and set its value with an FBSomething.

The most important thing to understand about the property system is that it allows a lot of functionality to be exposed using this simple syntax. Because properties are objects rather than just raw attributes, MotionBuilder can impose constraints on their values, allow or disallow editing, and respond to changes in value as they're made. If you're trying to find a way to perform some action on a particular type of component, you may not find a method that does what you're looking for. Don't forget to check the properties too — the reason there's no method may be that assigning to a property does the job just as well.


Additional Resources

Maybe I was being a bit fatalistic when I said you were all alone. Here are a couple of other resources to help you learn more about Python in MotionBuilder:

Also, if you hang around long enough at tech-artists.org, or at Autodesk's own MotionBuilder forums on the AREA, you may hear the occasional whisperings about Python scripting in MotionBuilder, the trouble some poor soul is having with it, and maybe even the solution to his woes. (Just be aware that the AREA forum is stuck in a time warp which only lets through one post about every two weeks.)


Corrections?

If you see any errors that you'd like to point out, or if you know of any resources not listed here, feel free to email me at awforsythe@gmail.com.