..read full post
I'm in the midst of working on a Max animation clip saving tool, so I thought I'd share some progress. This is one of the first substantial tools I've worked on since moving to 3Ds Max, from Maya, and it's proving a good learning experience for understanding some of Max's underpinnings. Max is quite different, to Maya, in how it encapsulates an derives an end matrix. At first the 'controller' tracks, used for node transformations, can seem a bit confusing. It can be very powerful, but also can tend make things overly complicated.
..read full post
Just thought I'd share a video of an upcomming title I worked on. Not only was it a blast to work on, it's a blast to play!
I've been playing about with Maya api, with python, a bit more. I took my experiences from this post on a bit further. The previous node i created, in the mentioned post, had a few downfalls as to useability. The main one was I could only define a radial offset from the comparison axis. I wanted to be able to define a more arbitrary shape for the angle comparison, essentially I wanted to elongate the shape, This would help me define more useable shapes to define as my target pose. If that makes any sense! Anyway here’s the node in action.
The node outputs a 0-1 blended value representing if the axis of the node is within the range set. I've just piped that output into a sphere for visual guide.
This node should aid my rigging in terms of deformations. My main reason for wanting to create this, was a solution to some armor rigging that is needed in work. Here's a super rough, quick test where I'm driving an aim constraint and its up vector node via three volume range nodes.
And here’s the obligatory bicep deformation shot. Again a very rough test, but should help give you the idea... like you needed it!
I'm starting to look into Communicating between applications from Maya. So If you’re looking to install the COM python module for Maya, here's how I got it working.
Get the appropriate installer here
For Maya 2012 64 bit get the pywin32-217.win-amd64-py2.6.exe
For Maya 2012 32 bit get the pywin32-217.win32-py2.6.exe
Run the downloaded executable, it should install to your C:\Python26\Lib\site-packages.
Copy the contents of that folder to your C:\Program Files\Autodesk\Maya2012\Python\lib\site-packages.
That should do it!
Of course be aware of what other packages you had installed previously in both site package folders, if you're concerned about overwriting something.
..Maybe because I am.
ls -type "joint" "|*" ;
Sometimes we just need to get something working, and we write functions to get simple pieces of data or whatever. Well I was at my desk recently and the above piece of code just dawned on me. The amount of times I've written code to get all joints at the root of the scene, looping parent queries.... Sometimes I feel stupid.
If you want to display a custom ui and halt all other maya ui interaction whilst it's open, here’s a script.
This uses Maya’s new-ish layoutDialog ui element, and it basically lists things and returns the user's specification. Nothing special, but it is nice that it basically acts like a confirmDialog.. The code is a bit hacked together as I originally thought I could get a textScrollList, in python, to simply accept data with some *args or **kargs callback functions, but no joy there. So I had to wrap this up in a class and use some class attributes to store and access the needed data on events.
Anyway here's the script. This may not be the cleanest way to do this, but I had to get it working. Hope someone finds it useful.
I wrote another custom node, again beholden somewhat to this post, that basically calculates the angle between to vectors.
It takes in two world space matrices and compares specified axis (x,y or z) of the nodes. It returns a ranged, 0-1, value based on user set bounds (actually the node outputs a ranged angle, full angle and dot product). Its really pretty simple but should come in handy.
I have tried to make this setup before, using Maya utility nodes and some elbow grease, but It was always quite cumbersome and I was a bit off with the math, So I thought an api node would be a better bet. So I created a nice self contained node that does it all for you and gave the user a nice display.
Here it is in action. I piped the output into the scale of the cube for visual cue of the output.
I think i can take this a bit further, I'm thinking of trying to make this calculate a u-v space bounds of a sphere, so i can cut a more complex piece of a sphere to calculate if the vector is inside. We'll see how far i get with that!
I wrote a custom locator node for use in my rigs a while back, thought I'd show it off.
As many other have, I'm sure, I read through this post and started playing about with the methods outlined. It's a great tutorial for anyone looking to get into the python api, so check it out now! Yes, stop reading this and go there if you haven't already,
I took it a little further and wrote a node that could be used as an all purpose controller for rig setups. One of the main pluses of this node is that it can be set to 'draw on top', which is very nice for making aesthetically easy to understand rigs. Credit needs to go to Christopher Lewis also for help on the openGL depth methods for that.
I also wrote in the ability to change the draw shape, rescale the drawn shape, edit transparency and other settings.
I've been using it for a while now and its working great!
Post Post Edit! I found a much easier way to do this. :D
scriptJob -uiDeleted "uiName" "someFunction";
Ah well, I learned something anyway!
Add a callback when a window is closed.
Can come in really handy when you have heavy ui usage and require post tool cleanup or whatever.
from maya import OpenMaya
from maya import OpenMayaUI
import maya.cmds as cmds
window = cmds.window( 'TEST_WIN', title="Long Name", iconName='Short Name', widthHeight=(200, 55) )
cmds.columnLayout( adjustableColumn=True )
cmds.button( label='Do Nothing' )
cmds.button( label='Close', command=('cmds.deleteUI(\"' + window + '\", window=True)') )
cmds.setParent( '..' )
cmds.showWindow( window )
def uiDeleteCallback( *args ):
This is the function that will be called whenever the ui, passed to the MUiMessage.addUiDeletedCallback( window, uiDeleteCallback )
cmds.confirmDialog(-message "The Window Was Closed!!!")
# make a test window
win = makeTestWindow()
# create the callback to run when the ui is deleted
uiCallBack = OpenMayaUI.MUiMessage.addUiDeletedCallback( win, uiDeleteCallback )
# removes the callback from memory
#OpenMaya.MMessage.removeCallback( uiCallBack )
I used some nice api code in a script recently, so thought i'd share it. I used it to calculate vertex positions.
import maya.OpenMaya as OpenMaya
import maya.mel as mel
import pymel.core as pm
def getMeshPositions( ):
# get selection
selection = OpenMaya.MSelectionList()
OpenMaya.MGlobal.getActiveSelectionList( selection );
# create an iterator for selection... we use the constant tyer id MFn.kGeometric to filter anything but poly mesh objects
selIter = OpenMaya.MItSelectionList ( selection, OpenMaya.MFn.kGeometric );
# intiialize a list in this scope... to return
distanceArr = 
# iterate/loop over the selection
while not selIter.isDone():
# intialize a MObject class type
mObj = OpenMaya.MObject()
# convert the emtpy MObject into the actual scene node
selIter.getDependNode( mObj )
# create another iterator for the mesh vertecies
meshVertIT = OpenMaya.MItMeshVertex ( mObj )
# iterate/loop over the vertecies
while not meshVertIT.isDone():
# get the current vert index
indx = meshVertIT.index()
# get the position of the current vert
pos = meshVertIT.position (OpenMaya.MSpace.kObject)
# Store the position in the list to return later
distanceArr.append( [pos.x, pos.y, pos.z] )
# move iterator to next vert on mesh
# move iterator to next item in MSelectionList
The code above isn't exactly the code I used, but I wrapped it here for ease of use.
I can't take total credit, I used some exaples on Ryan Trowbridge's and Chad Vernon's site as guidelines.
here's some links if you've never been to them... excellent resources
This isn't hooked up to a plug-in of course so it's not 'un-doable'. It works really well, and was MUCH faster than using basic commands to get the data.