Maya summary

Summary of elementary Maya feature.

Resource

Shortcuts

Camera

alt + left click Rotate
alt + middle click   Strafe / pan
alt + right click Zoom
F Focus on selection

Views

Other

S Insert key frame
   

Architecture

Maya works on nodes. Nodes have attributes which we connect together using MEL or Python scripts.

Maya GUI calls those script to setup the nodes.

MEL script

Manual

You should bookmark the "MEL reference manual" corresponding to the Maya version you are using. Once you get an understanding of MEL scripting this is the go to page to find all MEL built-in commands.

Useful resources

http://ewertb.soundlinker.com/maya.php

MEL syntax (quite good and concise):

http://nccastaff.bournemouth.ac.uk/jmacey/OldWeb/RobTheBloke/www/

https://courses.cs.washington.edu/courses/cse459/06wi/help/mayaguide/Complete/MEL_Expressions.pdf

Syntax

Variables are always prefixed with '$' when declared and used:

int $myInt = 0;
string $helloString = "hello";
print( $helloString + " " + $myInt ); 
// outputs: 'hello 0'

Declaring arrays:

int $myArray[] = {1,3,9}; 

for loops (notice we don't declare the types):

for( $i=0, $j=0.0; $i<10; ++$i, $j+=0.75 ){
    print($j + ", "); 
}
// outputs: '0, 0.75, 1.5, 2.25, 3, 3.75, 4.5, 5.25, 6, 6.75,'

Iterate over array elements:

int $myArray[] = {1,3,9}; 
for($i = 0; $i < size($myArray); ++$i)
    print($myArray[$i] + ", "); 
// outputs: '1, 3, 9,'

// Alternatively:
for( $element in $myArray)  
    print($element + ", "); 

MEL arrays are dynamic

int $myArray[] = {1,3,9}; 
$myArray[9] = -1;
for($i = 0; $i < size($myArray); ++$i)
    print($myArray[$i] + ", ");
// outputs: 1, 3, 9, 0, 0, 0, 0, 0, 0, -1, 

Array /multi attributes

Maya nodes contain attributes (access through 'plugs' in c++/python API). When an attribute holds an array we also call it a multi attribute or array attribute.

Multi attributes can be thought as a map (e.g. map<unsigned (connection idx), Type (value)>):

     attribute[3] (value) : [ elt1,  elt2,  elt3]
     Logical indices (key): {    0,     2,     9} // indices displayed in 'Node Editor'
     Physical indices     : {    0,     1,     2} // Always consecutive

Look up an attribute's connection and list the logical indices of the connection:

string $node_names[] = `listConnections ($source_node+".attribute_name")`;
// example output: {'node1', 'node2'}

int $connection_indices[] = `getAttr -multiIndices ($source_node+".attribute_name")`;
// example output: {0, 4}

// Loop through the nodes connected to the attribute '$source_node+".attribute_name[]"'
for( $i = 0; $i < size($node_names); ++$i) {    
    int $idx = $connection_indices[$i]; 
    string $name = $node_names[$i];   
}

How to describe an attribute / plug:

string $plug_name = "some_node_name.some_attr_name[index_atrr].some_compound_name"

Check connection at index:

Is a source {array} attribute currently connected to a node?
This can be use to determine if an index of an array attribute is free and can be safely connected with connectAttr().

string $con = `connectionInfo -sourceFromDestination ("some_node_name.some_attribute[index]")`;
if( size( $con ) == 0){ 
    /* Yea I'm free */ 
}

Find first available connection (maya doc):

maya2014/scripts/AETemplates/getNextFreeMultiIndex.mel
source "getNextFreeMultiIndex.mel"
// N.B: no need to define index with [idx]
string $attribute_name = "some_node_name.some_attr_name";

// index from which we start looking for the next available connection.
int $start_idx = 0; 
int $free_index = getNextFreeMultiIndex(attribute_name, start_idx);

Remove element at index:

// This will remove the element with index 4 from the input of 
// the choice node as long as there are no incoming or outgoing 
// connections to the attribute. 
removeMultiInstance choice.input[4]; 
// This will remove the element with index 100 from the input of 
// the choice node, breaking any existing connections first.
removeMultiInstance -b true choice.input[100];

c.f maya2014/scripts/AETemplates/AEnewNonNumericMulti.mel and AEremoveMultiElement()

Get the size of the array attribute:

getAttr -size "some_node_name.some_attribute" // N.B: no need to define index with [idx]

List the currently used attribute:

listAttr -multi $plug_name

Source of inspiration to understand how to handle multi-attributes:

maya2014/scripts/AETemplates/AEnewNonNumericMulti.mel

Check out functions like: AEnewNonNumericMultiAddNewItem(), AEremoveMultiElement()

Mesh

Get number of vertices of a mesh:

polyEvaluate -v  "pCylinder1Shape";


C++ API

Introduction

Every data (DAG nodes, lights etc.) are represented as MObject in Maya. Instead of converting the MObject to some specialized type we use function sets MFnXxx(). To access the methods of a specialized type we must use a function set:

MFnAttribute attribute( mObject ); // bind object to functions
attribute.name(); // use object's functions
// We can also bind the function set like so:
attribute.setObject( mObject );

Basics:

Display information in Maya script console: MGlobal::displayInfo("some infos");

Look up the DAG (scene tree), you can start from an arbitrary node with reset, use breadth or depth first order and check the current depth of the iterator (0 for root):

MItDag aItDag(MItDag::kDepthFirst);
aItDag.reset(iNode.mDagPath.node(), MItDag::kDepthFirst);
for(; !aItDag.isDone(); aItDag.next())
{
    MDagPath aDagPath;
    aItDag.getPath(aDagPath);
    MFnDagNode fnNode( aDagPath ); // Get the DAG node
    MString str = fnNode.typeName(); // Get its type for instance "transform" or "joint"
    aItDag.depth();// Depth in the scene tree
    
}

Alternate way to look up the scene tree:

void rec_tree(const MFnDagNode& fnNode)
{
    for(unsigned i = 0; i < fnNode.childCount(); ++i) {
        MObject obj = fnNode.child( i );		
        ret_tree(obj); // Sometimes this conversion fails between MFnNode and MObject wherase the dag iterator works well TODO: search why.
    }
    return;
}

Fetch attribute value of a node:

MFnDependencyNode fn( dagPath );
// get the MPlug for the tx attribute
MPlug plug = fn.findPlug("tx");
// get the value from the plug
float tx;
plug.getValue(tx);

Custom nodes: Construction: Never call Maya API in the custom node. Instead override the method: postConstructor() Destruction: When removing a node with deleteNode the key stroke del etc. you only remove the node from the dependency graph and the node is placed onto the undo list. The destructor will not be called unless the node disappear from the undo list (list flush/overflow, new scene) Removal from the dependency graph can be detected with various callbacks, see: MDGMessage:: MNodeMessage::addNodeAboutToDeleteCallback etc.

Python API

Mostly resemble the C++ API. There are two python APIs:

#Old
from maya.OpenMaya import *
# Python API 2.0
from maya.api.OpenMaya import *

Be sure to not mix them up (especially when looking for documentation they are very similar) and use the latest one for new code.

Tricks

Quick way to check environment variables (PATH, MAYA_PLUGIN_PATH etc)

import sys
for elt in sys.path:
    print(elt)
    
import os, pprint
pprint.pprint(dict(os.environ), width = 1)

No comments

(optional field, I won't disclose or spam but it's necessary to notify you if I respond to your comment)
All html tags except <b> and <i> will be removed from your comment. You can make links by just typing the url or mail-address.
Anti-spam question: