Professional Documents
Culture Documents
Wanho Choi
Last Update: 2011.9.8 http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
Unfortunately
There are a few references about Maya programming. Among them, the first and most important thing is..
Maya Help file ( Help > Maya Help ) Always keep it at hand and consult with it!
Books of Recommendation
Maya MEL programming
http://wanochoi.com
Books of Recommendation
Maya API programming
http://wanochoi.com
http://wanochoi.com
Introduction to Maya
http://wanochoi.com
Maya in Films
Ice Age, Lord of the Rings, Final Fantasy, Star Wars Episode, The Mummy, Signs, Artificial Intelligence, Perfect Storm, Monster Inc., Stuart Little, Spider-Man, Hollow Man, Blade, Harry Potter, Gladiator, Matrix, etc.
http://wanochoi.com
Maya is everywhere, especially in game, film and animation. Rumor has it that
Implemented by over 200 PhDs. Too big s.t. no one knows it entirely well.
http://wanochoi.com
Maya Version
Maya 1.0 (1998)
Maya 1.5 (1998)
Maya 7.0 (2005) Maya 8.0 (2006) Maya 8.5 (2007) Maya 2008 (2007) Maya 2009 (2008) Maya 2010 (2009) Maya 2011 (2010)
http://wanochoi.com
About Vendor
Alias Research, 1983 Wavefront Technologies, 1984 Alias|Wavefront under SGI, 1995 Alias@, 2003 Integrated into Autodesk, 2006
http://wanochoi.com
Other 3D Tools
Softimage | XSI 3D Studio Max LightWave 3D Cinema 4D Houdini Blender etc.
http://wanochoi.com
http://wanochoi.com
Maya Architecture
Maya := MELs + MLLs
MLL = DLL(Dynamic Link Library) in Maya
(.mll for Windows, .so for Linux)
GUI
command (MEL)
node (MLL)
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
MEL or C++?
Two possible options for programming Maya (Recently, you can also use Python.)
There are some features available in one, but not in the other.
Creation of a new type of node Creation of a new GUI : API : MEL
Some problems can be solved only by a combination of the two. When the C++ programming interface is used, it is typically for specific functionality that cant be found in the MEL interface.
http://wanochoi.com
MEL Script
MEL : Maya Embedded Language Interpreted language
It can be executed immediately without compile & link.
Powerful
It provides all Mayas built-in functionality. You can create new functionality by combining them.
http://wanochoi.com
C++ API
API : Application Programmer Interface Machine language (C++)
It is better performance than MEL. (approximately x10 faster)
C++ libraries
Enormous classes, but designed in a consistent manner
http://wanochoi.com
Logical Grouping Maya class Proxy object Iterator class Function set
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
Script Editor
Window > General Editors > Script Editor
http://wanochoi.com
Make a Cube
polyCube; [crtl+enter]
http://wanochoi.com
Hypergraph
Windows > Hypergraph
http://wanochoi.com
Transform Node
Shape Node
http://wanochoi.com
Check Attributes
listAttr pCube1; [crtl+enter]
http://wanochoi.com
Check Attributes
listAttr time1; [crtl+enter] nodeType time1; [crtl+enter]
http://wanochoi.com
Connect Attributes
connectAttr time1.outTime pCube1.tx; [crtl+enter]
http://wanochoi.com
Hypergraph
Windows > Hypergraph
http://wanochoi.com
Result
Press
http://wanochoi.com
http://wanochoi.com
Node-base Architecture
DAG node DG node transform
time1
timeToUnitConversion1 DG nodes
transform
http://wanochoi.com
http://wanochoi.com
DAG Node
DAG nodes form parent-child relationship (hierarchy)
Transform node-shape node
Maya shows either DAG hierarchy or connected DG nodes, not both simultaneously.
http://wanochoi.com
Shape Node
All shape nodes must have a parent transform node.
Meshes NURBS curves and surfaces Springs Camera Lights Particles Etc.
http://wanochoi.com
Transform Node
Shape node cant exist without a transform node. Shape node holds the data. Transform node holds translation, rotation, scale, etc. Transform node transforms from objects space to world space.
nurbsSphere1 nurbsSphereShape1
http://wanochoi.com
DG (Dependency Graph)
Data flow model
Data manipulated by series of operations Pipeline Push-pull model
http://wanochoi.com
DG Node Mechanism
The fundamental building blocks of Maya Main purpose is to store data and modify it in some way. Attributes - properties of a node
Particular properties of a node Input/output of a node
Compute()
A function to produce one or more output attributes from one or more input attributes
When an attribute changes, recomputation propagates through the graph until all affected values have been updated.
http://wanochoi.com
Hypergraph
A window that allows you to see the nodes in their DAG hierarchical form or as the DG nodes
http://wanochoi.com
Hypergraph
The connection lines are color-coded to indicate the type of attribute that is connecting the nodes. Color blue Type single Examples
transform.translateX makeNurbsSphere.radius file.repeatUV cameraShape.cameraAperature transform.translate lambert.color nurbsSurface.create makeNurbsSphere.outputSurface particleShape.position particleShape.velocity
cyan
green magenta red
double
triple data array
You can change these default colors in the Colors window (Window > Settings/Preferences > Colors). A dotted line in the scene hierarchy indicates a connection to an underworld node or an instanced object.
Maya Programming for 3D Graphics http://wanochoi.com
time1 node
It is the instance of time node. It is globally exists from when Maya started. It is a trigger node for animation & simulation.
http://wanochoi.com
http://wanochoi.com
Script Editor
Window > General Editors > Script Editor
Command Line
http://wanochoi.com
Variables cant contain whitespace (spaces, tabs, ) Variables cant have names that start with a number. Variable names are also case sensitive. Reserved words
break, case, continue, default, do, else, false, float, for, global, if, in, int, matrix, no, off, on, proc, return, string, switch, true, vector, while, yes, global, source, catch, alias, proc, etc. MEL commands
http://wanochoi.com
Variable Types
int
int $i = 1;
float
float $f = 1.1;
string
string $s = myName;
vector
vector $v = << 1.0, 2.0, 3.0 >>;
matrix
matrix $m[3][3] = << 11, 12, 13; 21, 22, 23; 31, 32, 33 >>;
http://wanochoi.com
Cautions
Integer division truncation
float $a = 3 / 2; float $a = 3.0 / 2; float $a = (float)3 / 2; float $a = 3 / (float)2; // result : 1 // result : 1.5 // result : 1.5 // result : 1.5
Precision range
int $a = 2147483647 + 1; int $a = -2147483648 1; int $a = 2147483648; int $a = 2147483647 + 2; // result : -2147483648 // result : 2147483647 // result : -2147483648 // result : -2147483647
It depends on machine.
http://wanochoi.com
Array
int $intArray[2] = { 1, 2 }; intArray[0] = 3; intArray[1] = 4; float $floatArray[3] = { 1.1, 2.1, 3.1 }; floatArray[2] = 0.1; string $stringArray[3] = { abc, def, ghi }; print $stringArray[0]; print \n print $stringArray[1]; print \n print $stringArray[2]; print \n vector $vectorArray[2] = { <<1,2,3>>, <<4,5,6>> };
matrix $m[3][3] = << 11, 12, 13; 21, 22, 23; 31, 32, 33 >>;
http://wanochoi.com
Procedure
It is same as function of C / C++. Procedure = function = command global proc [return value] aaa( [parameters] ) { } Example
global proc string helloValue( int $number, string $name ) { string $result; $result = Your name : + $name + , your number : + $number; return $result; }
http://wanochoi.com
Comparison operators
<, >, >=, <=, ==, !=
&&, ||, !
if( 1 > 2 ) { } else { } switch( ) { case 1: } int $i=0; for( ; $i<100; i++ ) { } while( ) { } // /* */
Loop statement
Comment
http://wanochoi.com
Global vs Local
Local variables
They are accessible only within their block.
Global variables
Once a variable is defined as global, it is accessible anytime and anywhere throughout Maya.
// Block 1 { int $a = 1; // Inner Block 2 { int $b = 2; print $a; } } print $b; // error!
http://wanochoi.com
MEL script
Examples
http://wanochoi.com
Query mode
with -query flag A command retrieves the value of the parameter specified.
Edit mode
with edit flag A Command changes a given property of an object.
http://wanochoi.com
Query mode
sphere query radius Sphere01;
Edit mode
sphere edit -radius 2 Sphere01;
http://wanochoi.com
help
http://wanochoi.com
print / tokenizeList
$i=10; print $i;
http://wanochoi.com
http://wanochoi.com
pickWalk / listRelatives
string $Shape = `createNode nurbsSurface`; select $Shape; string $Transform[] = `pickWalk -d up`;
string $Shape = `createNode nurbsSurface`; select $Shape; string $Transform[] = `pickWalk -d up`; string $again[] = `listRelatives c $Transform[0]`; print $again[0]; print \n;
http://wanochoi.com
More on ls command
global proc testMEL() { string $selected[] = `ls -sl -type transform`; for( $obj in $selected ) { print $obj; } }
global proc testMEL() { string $selected[] = `ls -sl -type transform`; for( $obj in $selected ) { string $meshShape[]; $meshShape = `listRelatives -c $obj`; print $meshShape; } } global proc testMEL() { string $selected[] = `ls -sl -type transform`; for( $obj in $selected ) { string $meshShape[]; $meshShape = `listRelatives -c $obj`; string $type = `nodeType $meshShape[0]`; if( $type == "mesh" ) print $meshShape; } }
http://wanochoi.com
string $inSurfaceTransform[] = `sphere`; string $inSurfaceShape[] = `listRelatives -c $inSurfaceTransform`; eval( "setAttr " + $inSurfaceTransform[0] + ".tx -5" ); eval( "setAttr " + $inSurfaceTransform[0] + ".ty 0" ); eval( "setAttr " + $inSurfaceTransform[0] + ".tz -3" );
http://wanochoi.com
pluginInfo
int $isLoaded = `pluginInfo -q -l testNode.mll"`; if( !$isLoaded ) { loadPlugin testNode.mll"; }
http://wanochoi.com
playbackOptions
This command sets/queries certain values associated with playback.
playbackOptions -q -ast;
0
playbackOptions -q -min;
10
playbackOptions -q -max;
90
playbackOptions -q -aet;
100
playbackOptions -e -ast 1; playbackOptions -e -min 1; playbackOptions -e -max 1000; playbackOptions -e -aet 1000;
http://wanochoi.com
createNode / connectAttr
global proc testMEL() { int $isLoaded = `pluginInfo -q -l testNode.mll"`; if (!$isLoaded) { loadPlugin "testNode.mll"; } string $selected[] = `ls -sl -type transform`; for( $obj in $selected ) { string $inMesh[] = `listRelatives -c $obj`; string $outMesh[] = `polySphere`; string $testNode = `createNode testNode`; connectAttr ($inMesh[0] + ".worldMesh") ($testNode + ".inputMesh"); connectAttr ($testNode + ".output") ($outMesh[0] + ".tx" ); } }
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
Expression
http://wanochoi.com
Expression
Expressions can be used to create complex animations with little or no manual intervention.
http://wanochoi.com
http://wanochoi.com
ELF
ELF (Extended Layer Framework)
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
MAYA_SCRIPT_PATH
The .mel files in the folder of this path can be executed in the Maya.
http://wanochoi.com
http://wanochoi.com
Alternative way
After installing Maya 6.0 & 6.5, create VC 6.0 project using MayaPluginWizard for Maya 6.0. And then, change the path of libraries to be linked into ones of Maya 6.5 or 7.0.
http://wanochoi.com
VS.NET 2005
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
Libraries to be linked
OpenGL32.lib
- Classes for using OpenGL
Foundation.lib
- Fundamental classes for MAYA
OpenMaya.lib
- Classes for defining nodes and commands
OpenMayaUI.lib
- Classes for creating new user interface elements
OpenMayaAnim.lib
- Classes for deformers and inverse kinematics
OpenMayaRender.lib
- Classes for rendering
OpenMayaFX.lib
- Classes for dynamics
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
initializePlugin(), uninitializePlugin()
initializePlugin()
It is called immediately after the plug-in is loaded. It registers command, node, and so on.
uninitializePlugin()
It is called before the plug-in is unloaded. It deregisters what were registered in initializePlugin().
http://wanochoi.com
Load plug-in
Window > Settings/Preferences > Plug-in Manager Browse & select testPlugIn.mll file in Debug or Release folder.
testPlugIn is loaded, but it doesnt do anything because it is empty. You must ensure that your plugin is unloaded before linking.
Maya Programming for 3D Graphics http://wanochoi.com
Command
plug-in
http://wanochoi.com
testCmd.h
testCmd.cpp
http://wanochoi.com
pluginMain.cpp
MStatus uninitializePlugin( MObject obj ) { MStatus stat; MFnPlugin plugin( obj ); stat = plugin.deregisterCommand( testCmd ); if( !stat ) { stat.perror( Deregister Command Failure! ); return stat; } return stat;
http://wanochoi.com
Execute it.
http://wanochoi.com
MPxCommand
It provides all the functionalities necessary for maya to use the command as if it were built in.
http://wanochoi.com
doIt()
It does the real work of the command. It is called when the command is executed
http://wanochoi.com
http://wanochoi.com
MGlobal::displayInfo()
#include "testCmd.h" #include <maya/MGlobal.h> #include <maya/MString.h> MStatus testCmd::doIt( const MArgList& args ) { MStatus stat; char buffer[256]; sprintf( buffer, "%s", "Hi~" ); MGlobal::displayInfo( buffer ); MGlobal::displayInfo( "friends.\n" ); MGlobal::displayInfo( MString("Goodbye") + "\n" ); MGlobal::displayInfo( "..." ); } return MS::kSuccess;
http://wanochoi.com
MGlobal::displayInfo( MString( ) );
#include <maya/MGlobal.h> Print out in Script Editor & Command Feedback Line
http://wanochoi.com
perror
#include <maya/MStatus.h> or none MStatus stat = MS::kFailure; stat.perror( Error! ); Print out in Output Window
http://wanochoi.com
MString
#include <maya/MString.h> String class to be used in Maya Examples
MString txt( Position : ); float pos = 10.f; MGlobal::displayInfo( txt + pos );
http://wanochoi.com
Function set
It is C++ classes which operate on objects. MFn prefix indicates this.
http://wanochoi.com
http://wanochoi.com
DG Node Plug-in
You can define your own type of node in Maya. User-defined nodes are derived from the MPxNode class.
It is the base class for user defined DG node.
When an input changes, the compute() method is called.
http://wanochoi.com
testNode.h
};
public: // member functions static void* creator() { return new testNode(); }; virtual MStatus compute( const MPlug& plug, MDataBlock& data ); static MStatus initialize();
#endif
http://wanochoi.com
testNode.cpp
// initialization for 'static' member variables as NULL MObject testNode::input; MObject testNode::output; MStatus testNode::initialize() { } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { }
http://wanochoi.com
http://wanochoi.com
return stat;
http://wanochoi.com
pluginMain.cpp
http://wanochoi.com
http://wanochoi.com
DG Node ID
Identifier in the binary file format 32bit value (0x00000000 ~ 0x0007ffff) It must be unique in your work of Maya. For any node for permanent purposes, you should get a universally unique ID from Alias|Wavefront Assist.
http://wanochoi.com
Member Functions
creator()
It is called every time a new instance of the node is requested by either the createNode MEL command or MFnDependencyNode::create() method. It allows Maya to instantiate instances of this node.
initialize()
It is called by the registration mechanism for DG nodes. It is used to define the inputs and ouputs of the node.
compute()
It is called whenever outputs should be newly calculated. It does the actual work of the node. It uses the inputs in the node to generate its outputs.
http://wanochoi.com
Plugs
Which output attribute the recompute is being requested for?
if( plug == output1 ) {} else if( plug == output2 ) {}
It lets Maya know that the recomputing is done and it holds the now correct value.
data.setClean( plug );
http://wanochoi.com
Data Blocks
It contains all the data for this instance of the node. For efficiency this data is kept as a single block. You need to specify which of the attributes you want to retrieve. The data is retrieved from the data handle thru. as*().
It must matches the declared type of the attribute.
http://wanochoi.com
Attribute Properties
Property Readable Writable Connectable Storable Keyable Hidden UsedAsColor Cached Array IndexMatter ArrayDataBuilder Indeterminant DisconnectBehavior Internal RenderSource
Description Can be the source of connections Can be the destination of connections Can be connected (superior to readable & writable) Is stored to scene files Can be animated Is hidden Treat values as colors Value is cached Is an array Index shouldnt change Uses array data builder to set value Determines if it can be used in an evaluation Behavior after disconnection Is internal to the node Overrides rendering sampling information
Default true true true true false false false true false true false false kNothing false false
http://wanochoi.com
Compound Attribute
A compound attribute is used to group other attributes.
Children : the grouped attributes Parent : itself
http://wanochoi.com
http://wanochoi.com
Deformer
It takes a series of points and moves them to new location. It cannot create or remove points. It can modify the location of
Lattice points Control vertices Polygonal vertices
It is created by deriving from the MPxDeformerNode class. The major difference from other node
deform() instead of compute()
http://wanochoi.com
testDeformer.h
http://wanochoi.com
testDeformer.cpp
http://wanochoi.com
pluginMain.cpp
deform()
The major function to implement in a deformer node
1) MDataBlock &block It holds the datablock for the deformer node. It is the same datablock as one passed into compute(). 2) MItGeometry &iter An iterator for traversing all the points int the geometric object. Control vertices, lattice points, mesh vertices, etc. 3) MMatrix &mat Local to world transformation When points are given to the deformer, their positions are in the local space. If you want to deform in world space, transform the points using this matrix. However, return them to local space by using the inverse of this matrix.
Changes in Hypergraph
polySphere;
http://wanochoi.com
Changes in Hypergraph
deformer -type testDeformer
http://wanochoi.com
Changes in Hypergraph
pSphereShape1Org node
Exact duplication of the input mesh shape ( pSphereShape1 before the deformer was applied )
testDeformer1 node
An instance of the testDeformer deformer node
pSphereSpahe1 node
The final geometry shape node
http://wanochoi.com
http://wanochoi.com
Locator
It provides users with a 3D visual handle.
Manipulation Control
It wont appear in the final rendered image. It is similar to general DG node. (OpenGL drawable DG node.) It is derived from MPxNode class.
Main difference : draw() compute() is also available
http://wanochoi.com
draw()
You are free to draw the locator in any way you like. Almost all OpenGL functions are available for drawing.
1) M3dView &view Current Maya viewport in which the locator will be drawn. 2) const MDagPath &path Complete DAG path to this locator node 3) M3dView::DisplayStyle style Drawing mode definitions
4) M3dView::DisplayStatus status
The current state of the node in the viewport
http://wanochoi.com
isBounded(), boundingBox()
isBounded()
It is called when Maya needs to determine if the node knows its own bounding extents.
boundingBox()
It is called to retrieve the actual extents of the locator shape. It is highly recommended to implement these function. Without them, Maya has difficulty determining the exact size of the locator, so the Frame All and Frame Selection operations will result in incorrect zooming.
http://wanochoi.com
testLocator.h
}; #endif
http://wanochoi.com
testLocator.cpp
http://wanochoi.com
pluginMain.cpp
MStatus uninitializePlugin( MObject obj ) { MStatus status; MFnPlugin plugin( obj ); plugin.deregisterNode( testDeformer::typeId ); return status; }
http://wanochoi.com
http://wanochoi.com
Stand-alone Application
It contains the main routine for the application and makes API calls to access Maya in batch mode.
http://wanochoi.com
An Example
#include <maya/MLibrary.h> #include <maya/MIOStream.h> #include <maya/MGlobal.h> int main(int argc, char **argv) { MStatus status; status = MLibrary::initialize (true, argv[0], true); if ( !status ) { status.perror("MLibrary::initialize"); return (1); } // Write the text out in 3 different ways. cout << "Hello World! (cout)\n"; MGlobal::displayInfo("Hello world! (script output)" ); MGlobal::executeCommand( "print \"Hello world! (command script output)\\n\"", true ); MLibrary::cleanup(); return (0); }
http://wanochoi.com
http://wanochoi.com
#include definedType.h const MTypeId definedType::id( 0xF1000 ); const MString definedType::typeName( definedType );
definedType.cpp
http://wanochoi.com
testNode.h
http://wanochoi.com
testNode.cpp
http://wanochoi.com
MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { if( plug == output ) { MDataHandle inputDataHnd = data.inputValue( input ); definedType *dType = (defineType*)inputDataHnd.asPluginData(); MDataHandle outputDataHnd = data.outputValue( output ); MFnPluginData dataCreator; MObject newDataObject = dataCreator.create( definedType::id ); definedType *newData = (definedType*)dataCreator.data(); Modifier( dType, newData ); outputDataHnd.set( newData );
testNode.cpp
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
inMesh & im is reserved keyword MStatus testNode::initialize() { tAttr.create( "inputMesh", "inM", MFnMeshData::kMesh ); MFnTypedAttribut tAttr; inMesh = tAttr.create( "inMesh", "im", MFnMeshData::kMesh ); }
MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { MDataHandle inMeshHnd = data.inputValue( inMesh ); MObject inMeshObj = inMeshHnd.asMesh(); MFnMesh inMeshFn( inMeshObj ); }
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
testNode.h
testNode.cpp
http://wanochoi.com
http://wanochoi.com
MPxNode::thisMObject()
It returns the MObject associated with this user defined node.
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
#include <maya/MFnMatrixAttribute.h> MObject testNode::inValue; MStatus testNode::initialize() { MFnMatrixAttribute mAttr; inMatrix1 = mAttr.create( "inMatrix", "im", MFnMatrixAttribute::kDouble ); } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { MDataHandle inMatrixHnd = data.inputValue( inMatrix ); MMatrix inMat = inMatrixHnd.asMatrix(); }
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
MString nodeName = ; MObject nodeObj = ; MDoubleArray dArray = ; MFnDependencyNode nodeFn( nodeObj ); Mplug plg = nodeFn.findPlug( nodeName ); MFnDoubleArrayData daFn; plg.setMObject( daFn.create( dArray ) );
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
http://wanochoi.com
Referneces
David A. D. Gould. 2003. Complete Maya Programming I. Morgan Kaufmann David A. D. Gould. 2005. Complete Maya Programming II. Morgan Kaufmann Alias|Wavefront. 2001. Maya Developers Tool Kit. Version 4. Alias|Wavefront Hiroyuki Haga. 2003. Maya API Quick Start. Alias Entertainment Alias Systems Corp. 2005. Maya API White Paper. Alias|Wavefront . 2002. programming with MAYA MEL & Expression. @rtisan(www.3DArtisan.com) Mark R. Wilkins & Chris Kazmier. MEL Scripting for Maya Animators. Morgan Kaufmann Shuen-Huei Guan, 2003, Introduction to Maya Programming (ppt), http://graphics.csie.ntu.edu.tw/~drake/data/articles/IntroductionToMayaProgramming.ppt Min Gyu Choi, Playing with Maya thru MEL/API. KCGS 2005 Tutorial Rafael Baptista. How to Write a Simple Maya Model Exporter. http://www.gamedev.net/ Bryan Ewert. Maya API How-to. http://www.ewertb.com/maya http://www.robthebloke.org/
http://wanochoi.com