I had been tinkering with using the listHistory mel command but the problem with this is that it returns ALL of the history on the mesh object and not just the deformers. My issue was then, how do I distinguish the deformers from the rest of the data? Without a list of every possible deformer Maya offers to compare it to, there's no way I could find them all.
Solution? `nodeType -inherited`
This command along with the -inherited flag will "Return a string array containing the names of each of the base node types inherited by the given object."
Someone pointed out on the forum that all deformers inherit from the "geometryFilter" base node. With this information we can check through each node in the meshes' history and see if it inherits from geometryFilter. With this, we can return a nice, clean list of all the deformers on a mesh object.
// **********************************************************
// Returns All Deformers On A Mesh
global proc string[] jgReturnMeshDeformers (string $mesh) {
// List History
string $history[] = `listHistory $mesh` ;
// Loop And Check If It's A Deformer
string $deformers[] ;
for($node in $history) {
string $types[] = `nodeType -inherited $node`;
if(stringArrayContains("geometryFilter",$types)) {
stringArrayInsertAtIndex(size($deformers),$deformers,$node) ;
}
}
return $deformers ;
}
Download Here: jgReturnMeshDeformers.mel
Another little gem that comes with this method is that it returns them in the current stack order. Bonus!
So far this method is working out very well for my needs. If you find any issues with it or would like to discuss, please leave a comment below.
Tomorrow's post will be about the script I was originally needing this for, which is a procedure to rebuild a blendShape node with only your specified targets. Maya doesn't allow you delete targets from a blendShape node without a hassle, and when it does delete them it leaves empty target indexes and a big mess under the hood. Swing by tomorrow for more about this. Cheers!
Hi, this is cool! But Maya did provide a convenient way of getting a list of deformers.
ReplyDeleteTry:
findRelatedDeformer $obj;
Cheers!!!
I don't believe that command is built into Maya. Did it ship with 2011? It's not in the MEL docs for 2009, not sure about 2010.
ReplyDeletefindRelatedDeformer is a custom proc found here: http://xyz2.net/mel/mel.081.htm
Also, that procedure is limited to the deformer types you give it, that one I wrote will find all of them regardless of type. :)
you know what, you are right. autodesk only started shipping it with the 2011 version of Maya.
ReplyDeletehttp://download.autodesk.com/us/maya/2011help/Commands/findRelatedDeformer.html
and I checked the actual script (cuz it's in the example scripts in your maya folder) and it looks like it works for all sorts of deformers that fall under 'geometryFilter' (ls -type geometryFilter;) but of course, limiting it to the ones that actually deform your mesh.
I wrote a script that'll list down the deformers in the order that they deform the geometry too.
Check http://redesigndavid.me/9741/2010/10/28/list-ordered-deformers/ if you are interested.
BTW, I didn't mean to belittle your work. I like 'em. :) Cheers man!
ReplyDeleteAh cool! Glad to see it was added. It looks like they used that proc from Bryan Ewert as a starting point. Or at least used the same name.
ReplyDeleteThanks for the tip man. :)
Know this is a belated post but came across this looking for just this kind of thing. Thanks for posting it. Saw in another post that you know Scott Englert - he's a very good friend of mine from college. Anyway, this was super helpful and as I'm mainly python, I pythonized it and in thanks, here's the python version if you want it:)
ReplyDeletedef returnAllDeformers(obj):
objHistory = mc.listHistory(obj,pruneDagObjects=True)
deformers = []
if objHistory != None:
for node in objHistory:
typeBuffer = mc.nodeType(node, inherited=True)
if 'geometryFilter' in typeBuffer:
deformers.append(node)
if len(deformers)>0:
return deformers
else:
return False
Apologies for the formatting getting jacked in the window:)
You could also go with this one :D
ReplyDeletedef getMeshDeformers(meshobj):
history = cmds.listHistory(meshobj)
Arrdeformers = []
for node in history:
types = cmds.nodeType(node, inherited = True)
if "geometryFilter" in types:
Arrdeformers.append(types[1])
return Arrdeformers
print getMeshDeformers('side')
Hey what about this one liner :D.
ReplyDeletepm.listHistory(node,interestLevel = 2, pruneDagObjects = True)