Showing posts with label python scripts. Show all posts
Showing posts with label python scripts. Show all posts

Friday, May 3, 2013

maya.cmds help snippet

For a long time I'd leave a mel tab up in the Maya script editor simply to use the help command to print maya help. The help command is also in the maya.cmds module but the syntax is a bit annoying to use.

mel      vs.    python
help ls          cmds.help('ls')


I finally got sick enough of doing this to create a little helper function to place in my userSetup.py


#Convenience function for maya.cmds.help
def docs(fn):
    print cmds.help(fn.__name__)

So now I can just go...
docs(cmds.ls)

Woooohoooooo

Monday, April 29, 2013

mayabatch

Easily batch process Maya files with any number of modules. mayabatch.actions subpackage comes with a template module.
Features:
Command line
python batch.py --help

Multiple Worker Processes through multibatch module

Cross-platform support (Haven't tested on Mac or Linux yet but it *should* work.)

Tested on systems with Maya 2012 and 2013

Extensible through actions modules
Command Line Single Process Example:
python batch.py --queue file01.ma file02.ma file03.ma file03.ma --modules mayabatch.actions.actionA mayabatch.actions.actionB
Python Multiprocessing Example:
import os
import mayabatch.multibatch as mb

if __name__ == '__main__':
    path = 'C:/Users/Administrator/Documents/maya/projects/default/'
    filepaths = []
    for root, subdirs, files in os.walk(path):
        for f in files:
            if os.path.splitext(f)[-1] in ['.ma', '.mb']:
                filepaths.append(os.path.join(root, f))
    modules = ['mayabatch.actions.actionA', 'mayabatch.actions.actionB']
    processes = 4
    mb.main(filepaths, processes, modules)
A simple benchmark produced the following results:
50 maya files
4 processes: 10.433 seconds
1 process: 8.145 seconds

350 maya files
4 processes: 15.353 seconds
1 processes: 26.932 seconds
As you can see it's a balancing act between the amount of processes and files. These tests were run on a system where maya's usersetup script is far from ideal for batch processing.

Notes

At the moment filepaths for each individual file are placed in the command line. Depending on the complexity of the paths the maximum length of args in a windows command prompt can be reached quickly. Pickling will be introduced into the mix to work around the command line args limit.


Get it from github: https://github.com/danbradham/mayabatch

Thursday, February 21, 2013

clearFlats or SUPER DELETE STATIC CHANNELS

This script will look at the animation curves of all selected objects in your scene, and delete unnecessary keys. If the value of the previous and next key is the same as the current key, it will mark that key for  deletion. The result of is that it acts like Delete by Type > Static Channels, while also removing unnecessary keys on all your curves. Let me know if you find any bugs!

import maya.cmds as cmds

def clearFlats():
    '''
Clear keys that lie on flat sections of animation curves.
If no channels are selected, clear flats on all keyed channels.
'''
    
    nodes = cmds.ls(sl = True)
    
    cmds.undoInfo(openChunk = True) #Capture all changes in a single undo
    for node in nodes:
        #Make Sure we have channels to work on
        channels = cmds.channelBox('mainChannelBox',
                                   query = True,
                                   selectedMainAttributes = True)
        if not channels:
            keyable_attrs = cmds.listAttr(node, keyable = True)
            user_attrs = cmds.listAttr(node, userDefined = True)
            if user_attrs:
                keyable_attrs.extend(user_attrs)
            channels = [attr for attr in keyable_attrs
                        if cmds.keyframe('{0}.{1}'.format(node, attr),
                                                query = True,
                                                keyframeCount = True)]
        try:
            for channel in channels:
                keyValues = cmds.keyframe('{0}.{1}'.format(node, channel),
                                          q = True,
                                          valueChange = True)
                
                del_index = []
                if len(keyValues) == 1:
                    del_index.append((0,))
                else:
                    for i, keyValue in enumerate(keyValues):
                        if i == 0:
                            if keyValue == keyValues[i + 1]:
                                del_index.append((i,))
                        elif i == len(keyValues) - 1:
                            if keyValue == keyValues[i - 1]:
                                del_index.append((i,))
                        else:
                            if keyValues[i-1] == keyValues[i+1] == keyValue:
                                del_index.append((i,))
                if del_index:
                    cmds.cutKey(node,
                                attribute = channel,
                                index = del_index)
        except TypeError:
            pass
    cmds.undoInfo(closeChunk = True) #Close our undo chunk


if __name__ == '__main__':
    clearFlats()

Wednesday, September 5, 2012

Override Enabled

I quickly wrote this script that mimics the display option overrides section of the attribute editor. Benefit here is that it applies changes to all selected objects.


Place overrideEnabled.py into your scripts directory and run the following in a python prompt in the script editor:

import overrideEnabled as oe
oeUI = oe.overrideEnabled()
oeUI.create()
Download Here

Thursday, July 5, 2012

dbrInsertJoints

import maya.cmds as cmds

def dbrInsertJoints( parent_child, numJoints ):
    if len(parent_child) == 2:
        parentJoint = parent_child[0]
        childJoint = parent_child[1]
    else:
        print 'dbrInsertJoints accepts only 2 joints'
         
    pTrans = cmds.xform( parentJoint, q = True, ws = True, translation = True )
    cTrans = cmds.xform( childJoint, q = True, ws = True, translation = True )
    
    njVect = [ (cTrans[0] - pTrans[0])/(numJoints + 1), (cTrans[1] - pTrans[1])/(numJoints + 1), (cTrans[2] - pTrans[2])/(numJoints + 1) ]
    curParent = parentJoint
    for i in range(numJoints):
        pTrans = cmds.xform( curParent, q = True, ws = True, translation = True )
        cmds.select(curParent, r = True)
        curParent = cmds.joint( p = ( pTrans[0] + njVect[0], pTrans[1] + njVect[1], pTrans[2] + njVect[2] ) )
        if i == numJoints - 1:
            cmds.parent( childJoint, curParent )
            cmds.select( cl = True )
        
sel = cmds.ls( sl = True, type = 'joint' )
dbrInsertJoints( sel, 4 )


Here is a quick insert joints function, select a parent joint then child and run this. Change the 4 in the call to dbrInsertJoints to insert any number of joints.

Monday, July 2, 2012

Add Shape To Parent!

 Rewrote my add shape to parent script in python. Works about the same just includes a checkbox to keep the controls orientation. Woo Woo. This thing works great for adding shapes to joints or locators. Works with multiple selections to boot!


Place dbrShapeToParent.py in your scripts directory. Then enter "import dbrShapeToParent; dbrShapeToParent.win()" in the python command line. Enjoy!

Download dbrShapeToParent

Sunday, July 1, 2012

Renaming Tool

Ahoy! I always wanted a simple renaming script that supported a bunch of features in a single textField. Sooo, I wrote one! dbrNamer supports string replacement, removal, prefixing, suffixing, and integer padding in a convenient and easy to use interface. I threw in namespace removal too, to quickly clean up messy imports.


I'm pretty pleased with how it's functioning. Here is a quick breakdown of how to use the supported features:


Use - to remove a string. ( -joint )
Use + to add a prefix or suffix ( +_GRP or JNT_+ )
Use two strings separated by a space to replace part of a name ( joint bone )
Use the # symbol to add an integer with padding
Use a single string to fully replace a name ( JNT_#### )

Combine multiple methods separated by spaces if you like!
given the selection: shoulder_joint, elbow_joint, wrist_joint
rename string: -_joint R_+ +_JNT
result: R_shoulder_JNT, R_elbow_JNT, R_wrist_JNT

Throw dbrNamer.py into your scripts directory and enter 'import dbrNamer; dbrNamer.win()' in the python command line.

As usual feel free to email me if you have any issues or requests.

Download dbrNamer

Friday, June 1, 2012

unTimeWarp for Maya

Soooo, no option to bake a timewarp?! ARGHHHHHH

Here is a quick python script to bake the timewarp to a selection of items.


import maya.cmds as cmds

objects = cmds.ls(sl = True)
tRange = [ cmds.playbackOptions(q = True, minTime = True), cmds.playbackOptions(q = True, maxTime = True) ]
print tRange

dObjects = []

for obj in objects:
    dup = cmds.duplicate(obj, name = obj + "_unWarped")
    dObjects.append( dup[0] )

for x in range( tRange[0], tRange[1] + 1 ):
    cmds.currentTime(x)
    outTime = cmds.getAttr( 'time1.outTime' )
    unwarpedTime = cmds.getAttr( 'time1.unwarpedTime' )
    
    for y in range(len(objects)):
        rot = cmds.getAttr( objects[y] + ".rotate", t = outTime )
        trans = cmds.getAttr( objects[y] + ".translate", t = outTime )
        scale = cmds.getAttr( objects[y] + ".scale", t = outTime )
        
        cmds.xform( dObjects[y], t = trans[0], ro = rot[0], s = scale[0])
        cmds.setKeyframe( dObjects[y], time = unwarpedTime )

This is not a flawless method, for certain objects that have their animation keyed up chain on groups, you probably need to bake that down before running this script, or select the group and not the object directly.