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!

Thursday, September 16, 2010

MEL Script: Incremental Save

This mel script will automatically increment your saved scene for you. Simple and sweet, just source the script to either increment your already numbered scene or to add a serial number at the end of a filename without one. Also adds your new file to your Recent Files list in the File menu. I recommend saving it and then calling it with a shelf button for easy access.

Download Here: MEL Script - jgIncrementalSave.mel


// **********************************************************
// Automatically Increments A Saved Maya File
global proc jgIncrementalSave () {

// Scene File Name
string $sceneFile = `file -q -sn` ;

// Get File Extension
string $extension = `fileExtension $sceneFile` ;

// Remove Extension
string $fileNameNoExt ;
if($extension == "mb" || $extension == ".ma") {

// Tokenize Filename
string $buffer[] ;
tokenize $sceneFile "." $buffer ;

// Recompile Scenename Without Extension
for($i = 0; $i < (size($buffer)-1); $i++) { $fileNameNoExt = $fileNameNoExt + $buffer[$i] ; } } else { // Error Check error "Open file isn't .mb or .ma, please save before incrementing." ; } // Extract Name And Current Version Using Regex string $nameWithNoVersion = `match ".*[^0-9]" $fileNameNoExt` ; string $currentVersion = `match "[0-9]+$" $fileNameNoExt` ; // Check For Integer, Add One If None if($currentVersion == "") $currentVersion = "00" ; // Increment Version int $int = $currentVersion ; $int++ ; // Pad Digits If Needed int $beforeCount = size($currentVersion) ; string $incVersion = $int ; int $afterCount = size($incVersion) ; if($beforeCount > $afterCount) {
while($beforeCount > $afterCount) {
$incVersion = ("0"+$incVersion) ;
$afterCount = size($incVersion) ;
}
}

// Make New Filename
string $newFileName = ($nameWithNoVersion+$incVersion+"."+$extension) ;

// Save It
file -rename $newFileName ;
file -f -save ;

// Add To Recent File List
if($extension == "mb") catch(`addRecentFile $newFileName "mayaBinary"`) ;
if($extension == "ma") catch(`addRecentFile $newFileName "mayaAscii"`) ;

// Finish
print ("Saved as "+$newFileName+"\n") ;

} jgIncrementalSave ;


As always if you find any bugs, have any questions about the code, or would like to make suggestions please leave a comment below.

Monday, September 13, 2010

MEL Script: Remove All Namespaces

There are already a few posts on ScriptSwell dealing with namespaces in general, but here is a quick and dirty way to just remove all of them from your scene, no questions asked.


// Get All Nodes In Scene
string $allNodes[] = `ls` ;

// Loop Through Them
for($node in $allNodes) {

// Tokenize And Rename
string $buffer[] ;
tokenize $node ":" $buffer ;
string $newName = $buffer[size($buffer)-1] ;
catch(`rename $node $newName`) ;

}
This uses the tokenize command. For more info, check out this mel tutorial on how to use the tokenize command. Essentially it's looping through every node in your scene, checking if there are colons in the name of it, and renaming the object to what it would be with no namespaces.

The reason I call this dirty is because it has potential to cause naming conflicts in your scene file. In a lot of cases namespaces are there for a reason, so you should make sure it's safe to remove them before doing so. Maya does not support having more than one object with the same name, so if you run this script it may end up changing the names of some of your nodes. Usually this is in the form of adding a number to the end of it. (i.e. hand_CTRL becomes hand_CTRL1). Be sure to save your scene before running this (as you should with any MEL script) and do some testing before you continue forward to make sure everything is working like it should.

Also:
  • Every Maya scene file has a list of namespaces that have at one time or another been used in that scene. This script will not remove any from that list.
  • If something is referenced in your scene, this will not be able to remove the namespace properly.
  • You'll see a slew of error messages pass by, this is Maya trying to rename nodes that aren't allowed to be renamed. You can ignore these.

For more reading about namespaces in Maya, check out the following:

Saturday, August 21, 2010

Repost: Some lesser-known truths about programming

I saw this on Reddit this morning and thought some of you may like to read it. Find the link to the full article on http://dotmac.rationalmind.net below.
My experience as a programmer has taught me a few things about writing software. Here are some things that people might find surprising about writing code:
  • A programmer spends about 10-20% of his time writing code, and most programmers write about 10-12 lines of code per day that goes into the final product, regardless of their skill level. Good programmers spend much of the other 90% thinking, researching, and experimenting to find the best design. Bad programmers spend much of that 90% debugging code by randomly making changes and seeing if they work.
    “A great lathe operator commands several times the wage of an average lathe operator, but a great writer of software code is worth 10,000 times the price of an average software writer.” –Bill Gates
  • A good programmer is ten times more productive than an average programmer. A great programmer is 20-100 times more productive than the average. This is not an exaggeration – studies since the 1960′s have consistently shown this. A bad programmer is not just unproductive – he will not only not get any work done, but create a lot of work and headaches for others to fix.
Read the full article here: http://dotmac.rationalmind.net/2010/08/some-lesser-known-truths-about-programming/

Tuesday, July 27, 2010

Maya: Transfer Mesh UVs After Rigging

This is slightly off-topic than the usual scripting posts, but I found this really useful and wanted to share.

It's a technique on how to transfer UVs from one mesh to another while maintaining deformer history on your object. It worked for what I was doing and I imagine I'll be using it again in the future.

http://animbiz.blogspot.com/2010/02/transferring-uvs-after-rigging.html

I'm currently working on a bullet proof transfer script, I'll let the world know when it works. :)

Wednesday, July 21, 2010

Maxscript: Check If Auto Key Is Turned On

Need to query if auto key is turned on or off using maxscript? Use the animButtonState command. It returns true or false, so using this info you can check it's current state and then setup a toggle for it, or use it make sure Max is in the correct mode before running a script.

Simple, yet extremely useful!

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