Tuesday, September 21, 2010

MEL: List All Deformers On A Mesh

Yesterday while working on another script, I found myself in need of a list of all of the deformers on a piece of geometry. It seemed like a simple enough thing to get. After all, it was listed right there in the history tab. Fast forward an hour later and the only method I had come up with to find the data was not going to work for what I needed. So, I reached out to a couple of friends and posted on Tech-Artists.org and got a really great answer. It's still a bit convoluted and I'm bitter that Maya won't just give it to you easily, but it works and it's a relatively small amount of code.

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!

8 comments:

  1. Hi, this is cool! But Maya did provide a convenient way of getting a list of deformers.
    Try:

    findRelatedDeformer $obj;

    Cheers!!!

    ReplyDelete
  2. 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.

    findRelatedDeformer 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. :)

    ReplyDelete
  3. you know what, you are right. autodesk only started shipping it with the 2011 version of Maya.

    http://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.

    ReplyDelete
  4. BTW, I didn't mean to belittle your work. I like 'em. :) Cheers man!

    ReplyDelete
  5. Ah 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.

    Thanks for the tip man. :)

    ReplyDelete
  6. 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:)

    def 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:)

    ReplyDelete
  7. You could also go with this one :D

    def 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')

    ReplyDelete
  8. Hey what about this one liner :D.

    pm.listHistory(node,interestLevel = 2, pruneDagObjects = True)

    ReplyDelete

Scripting Topics

MEL (41) Maya (39) Scripting (32) Scripts (21) programming (14) Free Mel Scripts (8) MaxScript (7) Coding (6) Rigging (5) tutorial (5) 3ds Max (4) Python (4) Tricks (4) faceware (4) image metrics (4) Learn (3) Namespace (3) Namespacing (3) animation (3) facial (3) webinar (3) Code (2) GDC (2) Game Developers Conference (2) Multiple Namespaces (2) Print Selected Objects (2) Recursive (2) Removing Namespace (2) Return (2) Set Driven Keys (2) TOkenize (2) Tips (2) Toggle Background Color with MEL (2) animation tools (2) animators resource (2) deformers (2) learning (2) maya tools (2) mesh (2) modeling (2) nodes (2) procedure (2) script swell (2) transforms (2) Animschool (1) Attribute (1) Background Color (1) Beer (1) Blur (1) Character Setup (1) Check if an object exists (1) Class (1) Command Line (1) Constraints (1) Create SDK (1) Create a directory with mel (1) Data (1) Export (1) FilterString (1) Fix (1) Floating Slider Time (1) Functions (1) Get Maya Version MEL (1) Get Parent (1) Google (1) Holiday (1) How To Write To A Text File (1) Import (1) Incremental Save (1) Index (1) Joint Chain (1) Make Set Driven Keys (1) Maya Version (1) Modules (1) Objects (1) Orient Constraint (1) PYMEL (1) Parent (1) Parent Constraint (1) Point Constraint (1) Position (1) Print (1) Print Current Selection (1) Print Random Quotes (1) Print Selection (1) Print Vertices (1) Progress Bar (1) Progress Window (1) PyQT (1) Removing Spaces From Names (1) Scene File Name (1) Select Connections (1) Select Outgoing Nodes (1) Split Bones (1) Split Joints (1) St. Patrick's Day (1) String Array (1) System (1) Transfer UVs (1) Viewport (1) White Space (1) Windows Username (1) Zero Out Attributes (1) animButtonState (1) arrays (1) articles (1) auto key (1) better (1) blendshapes (1) break (1) confirm dialog (1) continue (1) convention (1) e3 (1) efficiency (1) error (1) eval (1) executable (1) fclose (1) fopen (1) fprint (1) games (1) improving (1) infinite loop (1) joints (1) listHistory (1) listRelatives (1) logic (1) loops (1) milestone (1) nodeType (1) objExists (1) recursion (1) rotates (1) rotations (1) schools (1) sculpting (1) setAttr (1) shout outs (1) source (1) source a script with a variable (1) speed (1) tech-artists.org (1) translates (1) video (1) warning (1) world matrix (1) worldMatrix (1)
 
Script Swell - Blogged