You are on page 1of 173

Maya Programming for 3D Graphics

Wanho Choi
Last Update: 2011.9.8 http://wanochoi.com

What to do with Maya Programming


Development of our own in-house plug-in Visualization of our demonstration

Maya Programming for 3D Graphics

http://wanochoi.com

Commercial Maya Plug-ins

Qualoth FXHair cMuscle

Syflex Blast Code

Maya Programming for 3D Graphics

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!

However, its not kind for beginners.


Maya Programming for 3D Graphics http://wanochoi.com

Books of Recommendation
Maya MEL programming

Maya Programming for 3D Graphics

http://wanochoi.com

Books of Recommendation
Maya API programming

Maya Programming for 3D Graphics

http://wanochoi.com

Some Codes Provided by Maya Itself


[Maya installed path]\devkit\plug-ins.

Maya Programming for 3D Graphics

http://wanochoi.com

Introduction to Maya

Maya Programming for 3D Graphics

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.

Maya Programming for 3D Graphics

http://wanochoi.com

A Brief Introduction to Maya


One of the greatest and most complex computer program ever made First released in 1998

Commercial total solution for 3D animation & visual effects


Modeling Texturing Animation Rendering Dynamics (rigid body, particles, fluids, etc.)

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.

Maya expert = Artist + Computer Scientist

Maya Programming for 3D Graphics

http://wanochoi.com

Maya Version
Maya 1.0 (1998)
Maya 1.5 (1998)

Maya 2.0 (1999)


Maya 2.5 (1999)

Maya 3.0 (2000)


Maya 3.5 (2001)

Maya 4.0 (2001)


Maya 4.5 (2002)

Maya 5.0 (2003)


Maya 5.5 (2003)

Maya 6.0 (2004)


Maya 6.5 (2005)

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

Maya Programming for 3D Graphics

About Vendor
Alias Research, 1983 Wavefront Technologies, 1984 Alias|Wavefront under SGI, 1995 Alias@, 2003 Integrated into Autodesk, 2006

Maya Programming for 3D Graphics

http://wanochoi.com

Other 3D Tools
Softimage | XSI 3D Studio Max LightWave 3D Cinema 4D Houdini Blender etc.

Maya Programming for 3D Graphics

http://wanochoi.com

Maya as a 3D Animation Package


Maya has many features as default.

Maya Programming for 3D Graphics

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)

Maya Programming for 3D Graphics

http://wanochoi.com

Two Main Interfaces between User and Maya


GUI (Graphical User Interface)
Menus, dialog boxes, buttons, etc. Most artists complete their work in Maya by using GUI.

Easy to use, but hard to extend Maya functionalities

Programming interface (Plug-in)


A small program to be added into Maya Additional functionalities to Maya

Maya Programming for 3D Graphics

http://wanochoi.com

Why Programming Interface?


Maya is very powerful tool, but cannot do everything.
Programming interface is needed. You can bend Maya in your own direction.

Develop your own features using programming interface!


Automate and simplify tasks
Advanced macros and your own GUI

Add new features that are not incorporated


New file formats, object types and behaviors New dynamics and animation components

Two programming interfaces


MEL script C++ API

Maya Programming for 3D Graphics

http://wanochoi.com

MEL or C++?
Two possible options for programming Maya (Recently, you can also use Python.)

They are not mutually exclusive.


They are complementary each other.

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.

Maya Programming for 3D Graphics

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.

Similar to pseudo code


It can be easy to read and written quickly. It can result in subtle bugs which may be hard to find.

Maya Programming for 3D Graphics

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

Most powerful means of extending Maya


It provides low level access to Maya.

Maya Programming for 3D Graphics

http://wanochoi.com

Class Name Prefixes

Prefix M MPx MIt MFn

Logical Grouping Maya class Proxy object Iterator class Function set

Examples MObject, MPoint, M3dView MPxNode MItDag, MItMeshEdge MFnMesh, MFnDagNode

Maya Programming for 3D Graphics

http://wanochoi.com

Dependency Graph Node Plug-ins


Twelve parent classes for dependency graph node plug-ins
MPxNode MPxLocatorNode MPxIkSolverNode MPxDeformerNode MPxFieldNode MPxEmitterNode MPxSpringNode MPxManipContainer MPxSurfaceShape MPxObjectSet MPxTransform MPxHwShaderNode

You can subclass new nodes from these!

Maya Programming for 3D Graphics

http://wanochoi.com

Brief Exploration into Maya

Maya Programming for 3D Graphics

http://wanochoi.com

Script Editor
Window > General Editors > Script Editor

Maya Programming for 3D Graphics

http://wanochoi.com

Make a Cube
polyCube; [crtl+enter]

Maya Programming for 3D Graphics

http://wanochoi.com

Hypergraph
Windows > Hypergraph

Maya Programming for 3D Graphics

http://wanochoi.com

Check Node Type


nodeType pCube1; [crtl+enter] nodeType pCubeShape1; [crtl+enter]

Transform Node

Shape Node

Maya Programming for 3D Graphics

http://wanochoi.com

Check Attributes
listAttr pCube1; [crtl+enter]

Maya Programming for 3D Graphics

http://wanochoi.com

Check Attributes
listAttr time1; [crtl+enter] nodeType time1; [crtl+enter]

Maya Programming for 3D Graphics

http://wanochoi.com

Connect Attributes
connectAttr time1.outTime pCube1.tx; [crtl+enter]

Maya Programming for 3D Graphics

http://wanochoi.com

Hypergraph
Windows > Hypergraph

Maya Programming for 3D Graphics

http://wanochoi.com

Result
Press

Maya Programming for 3D Graphics

http://wanochoi.com

About Maya Node

Maya Programming for 3D Graphics

http://wanochoi.com

Node-base Architecture
DAG node DG node transform

time1

timeToUnitConversion1 DG nodes

transform

shape node input output DAG nodes

Maya Programming for 3D Graphics

http://wanochoi.com

DAG (Directed Acyclic Graph)


DAG path
The complete path to a given node in DAG You can get from the root node to the specific node by traveling down through the intervening nodes in the tree.

DAG path for rightArmShape


: |head|toroso|rightArm|rightArmShape

head headShape torso torsoShape leftArm leftArmShape rightArm rightArmShape

Maya Programming for 3D Graphics

http://wanochoi.com

DAG Node
DAG nodes form parent-child relationship (hierarchy)
Transform node-shape node

DAG nodes are in DG - they are DG nodes


Some DAG nodes connect to non-DAG DG nodes Some DAG nodes may not be connected to any non-DAG nodes.

Maya shows either DAG hierarchy or connected DG nodes, not both simultaneously.

Maya Programming for 3D Graphics

http://wanochoi.com

Shape Node
All shape nodes must have a parent transform node.
Meshes NURBS curves and surfaces Springs Camera Lights Particles Etc.

Maya Programming for 3D Graphics

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

Maya Programming for 3D Graphics

http://wanochoi.com

DG (Dependency Graph)
Data flow model
Data manipulated by series of operations Pipeline Push-pull model

DG(Dependency Graph) - heart of Maya


Data and operations represented as nodes Network of nodes to perform task Add functionality by defining new node

Maya Programming for 3D Graphics

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

The output of other node

Node input compute() output

The input of other node

When an attribute changes, recomputation propagates through the graph until all affected values have been updated.

Maya Programming for 3D Graphics

http://wanochoi.com

Hypergraph
A window that allows you to see the nodes in their DAG hierarchical form or as the DG nodes

It doesnt allow you to see them both at the same time.


Default existing nodes in Maya through Hypergraph

Maya Programming for 3D Graphics

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.

Maya Programming for 3D Graphics

http://wanochoi.com

Introduction to MEL script

Maya Programming for 3D Graphics

http://wanochoi.com

How to execute MEL scripts


Command Shell
Window > General Editors > Command Shell

Script Editor
Window > General Editors > Script Editor

Command Line

Maya Programming for 3D Graphics

http://wanochoi.com

Variable Naming Convention


All variables in MEL begin with $.
int $a = 1; double $b = 1.1; string $c = 1.1;

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

Maya Programming for 3D Graphics

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 >>;

There are not bool & double type in MEL.

Maya Programming for 3D Graphics

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.

Maya Programming for 3D Graphics

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 >>;

Maya Programming for 3D Graphics

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; }

Maya Programming for 3D Graphics

http://wanochoi.com

Others are similar to C / C++


Data-type conversions
float $f = 4.0 / 3.0;

Comparison operators
<, >, >=, <=, ==, !=
&&, ||, !

Logical operators Conditional statement

if( 1 > 2 ) { } else { } switch( ) { case 1: } int $i=0; for( ; $i<100; i++ ) { } while( ) { } // /* */

Loop statement

Comment

Maya Programming for 3D Graphics

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!

Maya Programming for 3D Graphics

http://wanochoi.com

MEL script
Examples

Maya Programming for 3D Graphics

http://wanochoi.com

MEL Command Mode


Creation mode
with no flag A command generates a new object.

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.

Maya Programming for 3D Graphics

http://wanochoi.com

MEL Command Mode (Examples)


Create mode
sphere name Sphere01;

Query mode
sphere query radius Sphere01;

Edit mode
sphere edit -radius 2 Sphere01;

Maya Programming for 3D Graphics

http://wanochoi.com

help

Maya Programming for 3D Graphics

http://wanochoi.com

print / tokenizeList
$i=10; print $i;

$f=3.1415926535; print $f;

$s = Hello Everyone; print $s;

vector $v = << 1.1, 2.2, 3.3 >>; print $v;

matrix $m[2][3] = << 1, 2, 3; 4, 5, 6; 7, 8, 9 >>; print $m;

string $a = 1 , 3 4, 67; string $b[]; tokenizeList( $a, $b ); print $b;

Maya Programming for 3D Graphics

http://wanochoi.com

ls / Back Quote(`) / eval


ls; ls -sl; ls type surfaceShape; ls showType; $objs = `ls -selection`; for( $obj in $objs ) { print($obj + " "); }; ls -selection;

string $s[] = `sphere`; print $s[0]; print $s[1];

string $cmdName = sphere; eval( $cmdName + r 5 ); eval( $cmdName + r 10 );

Maya Programming for 3D Graphics

http://wanochoi.com

pickWalk / listRelatives

string $Shape = `createNode nurbsSurface`; select $Shape; string $Transform[] = `pickWalk -d up`;

string $Shape = `createNode nurbsSurface`; string $Transform[] = `listRelatives -p $Shape`;

string $Shape = `createNode nurbsSurface`; string $Transform[] = `listRelatives -p $Shape`;

string $Shape = `createNode nurbsSurface`; select $Shape; string $Transform[] = `pickWalk -d up`; string $again[] = `listRelatives c $Transform[0]`; print $again[0]; print \n;

Maya Programming for 3D Graphics

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; } }

Maya Programming for 3D Graphics

http://wanochoi.com

listAttr / getAttr / setAttr


polySphere; listAttr pSphere1; getAttr pSphere1.tx; setAttr pSphere1.tx 10;

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" );

Maya Programming for 3D Graphics

http://wanochoi.com

pluginInfo
int $isLoaded = `pluginInfo -q -l testNode.mll"`; if( !$isLoaded ) { loadPlugin testNode.mll"; }

Maya Programming for 3D Graphics

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;

Maya Programming for 3D Graphics

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" ); } }

Maya Programming for 3D Graphics

http://wanochoi.com

createNode / connectAttr (polygon)


global proc test() { // input string $inMeshTransform[] = `polySphere`; string $inMeshShape[] = `listRelatives -c $inMeshTransform[0]`; // output string $outMeshTransform = `createNode transform`; string $outMeshShape = `createNode mesh p $outMeshTransform`; sets -add initialShadingGroup $outMeshShape; // intermediate string $testNode = `createNode testNode`; connectAttr ( $inMeshShape[0] + .worldMesh) ( $testNode + .inputMesh ); connectAttr ( $testNode + .outputMesh ) ( $outMeshShape + .inMesh ); };

Maya Programming for 3D Graphics

http://wanochoi.com

createNode / connectAttr (NURBS Surface)


global proc test() { // input string $inSurfaceTransform[] = `sphere`; string $inSurfaceShape[] = `listRelatives -c $inSurfaceTransform[0]`; // output string $outSurfaceShape = `createNode nurbsSurface`; string $outSurfaceTransform[] = `listRelatives -p $outSurfaceShape`; sets -add initialShadingGroup $outSurfaceShape; // intermediate string $testNode = `createNode testNode`; connectAttr ( $inSurfaceShape[0] + .worldSpace ) ( $testNode + .inSurface ); connectAttr ( $testNode + .outSurface ) ( $outSurfaceShape + .create ); };

Maya Programming for 3D Graphics

http://wanochoi.com

Expression

Maya Programming for 3D Graphics

http://wanochoi.com

Expression
Expressions can be used to create complex animations with little or no manual intervention.

Generally, any attribute can be controlled by an expression.


Ex.) nurbsSphere1.translateX = frame;

Maya Programming for 3D Graphics

http://wanochoi.com

GUI using MEL

Maya Programming for 3D Graphics

http://wanochoi.com

ELF
ELF (Extended Layer Framework)

Maya Programming for 3D Graphics

http://wanochoi.com

Maya Environment Variables

Maya Programming for 3D Graphics

http://wanochoi.com

Two Environment Variables


MAYA_PLUG_IN_PATH MAYA_SCRIPT_PATH

Maya Programming for 3D Graphics

http://wanochoi.com

Two Environment Variables


MAYA_PLUG_IN_PATH
Its order is the order of plug-ins in Maya Plug-in Manager.

MAYA_SCRIPT_PATH
The .mel files in the folder of this path can be executed in the Maya.

Maya Programming for 3D Graphics

http://wanochoi.com

Visual C++ Development Environment Settings

Maya Programming for 3D Graphics

http://wanochoi.com

Maya Plug-in Wizard


Maya 6.0
Wizard will be installed automatically.

Maya 6.5 & 7.0


At this time the Maya install process will not copy the wizard files into the appropriate .NET directories. This process should be done manually.

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.

Maya Programming for 3D Graphics

http://wanochoi.com

How to install Wizard (MS VS.NET)


Please, go to following folder. C:\Program Files\Alias\Maya7.0\devkit\pluginwizard MayaPluginWizard2.0.zip One folder Maya PlugIn Wizard Three files MayaPlugInWizard.ico MayaPlugInWizard.vsdir MayaPlugInWizard.vsz Copy the three files to
Visual Studio.NET 2003 C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\vcprojects Visual Studio.NET 2005 C:\Program Files\Microsoft Visual Studio 8\VC\vcprojects Visual Studio.NET 2003 C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\VCWizards Visual Studio.NET 2005 C:\Program Files\Microsoft Visual Studio 8\VC\VCWizards
http://wanochoi.com

Copy the folder to

Maya Programming for 3D Graphics

How to create a project


File > New > Project
VS.NET 2003

VS.NET 2005

Maya Programming for 3D Graphics

http://wanochoi.com

Directories Setting (VS.NET 2003)


Tools > Options

Maya Programming for 3D Graphics

http://wanochoi.com

Directories Setting (VS.NET 2003)


Or set in project properties.

Maya Programming for 3D Graphics

http://wanochoi.com

Directories Setting (VS.NET 2005)


Tools > Options

Maya Programming for 3D Graphics

http://wanochoi.com

Directories Setting (VS.NET 2005)


Or set in project properties.

Maya Programming for 3D Graphics

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

Maya Programming for 3D Graphics

http://wanochoi.com

Link Libraries (VS.NET 2003)


Set in project properties.

Or set in source code.


#pragma comment( lib, "Foundation.lib" ) #pragma comment( lib, "OpenMaya.lib" )

Maya Programming for 3D Graphics

http://wanochoi.com

Link Libraries (VS.NET 2003)


Set in project properties.

Or set in source code.


#pragma comment( lib, "Foundation.lib" ) #pragma comment( lib, "OpenMaya.lib" )

Maya Programming for 3D Graphics

http://wanochoi.com

My First Maya plug-in

Maya Programming for 3D Graphics

http://wanochoi.com

Common Code of Maya plug-in


Create empty project & type following code.
#pragma comment( lib, "Foundation.lib" ) #pragma comment( lib, "OpenMaya.lib" ) #include <maya/MFnPlugin.h> MStatus initializePlugin( MObject obj ) { MStatus stat; MFnPlugin plugin( obj, My Company, 1.0, Any ); return stat; } MStatus uninitializePlugin( MObject obj ) { MStatus stat; MFnPlugin plugin( obj ); return stat; }

Maya Programming for 3D Graphics

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().

Maya Programming for 3D Graphics

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

Maya Programming for 3D Graphics

http://wanochoi.com

Minimal Code for Command Plug-in


#include <maya/MPxCommand.h> class testCmd : public MPxCommand { public: MStatus doIt( const MArgList& args ); static void* creator() { return new testCmd; }; }; #include "testCmd.h" MStatus testCmd::doIt( const MArgList& args ) { MStatus stat; return MS::kSuccess; }

testCmd.h

testCmd.cpp

Maya Programming for 3D Graphics

http://wanochoi.com

Minimal Code for Command Plug-in


#include <maya/MFnPlugin.h> #include "testCmd.h" MStatus initializePlugin( MObject obj ) { MStatus stat; MFnPlugin plugin( obj, My Company, 1.0, Any ); stat = plugin.registerCommand( testCmd, testCmd::creator ); if( !stat ) { stat.perror( Register Command Failure! ); return stat; } return stat;

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;

Maya Programming for 3D Graphics

http://wanochoi.com

Load plug-in & execute it.


Load through Plug-in Manager.

Execute it.

Nothing happened, but it is successively executed.

Maya Programming for 3D Graphics

http://wanochoi.com

MPxCommand
It provides all the functionalities necessary for maya to use the command as if it were built in.

Maya Programming for 3D Graphics

http://wanochoi.com

doIt()
It does the real work of the command. It is called when the command is executed

Maya Programming for 3D Graphics

http://wanochoi.com

Print out & String in Maya

Maya Programming for 3D Graphics

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;

Maya Programming for 3D Graphics

http://wanochoi.com

Methods for Printing Out


printf( );
#include <stdio.h> Print out in Output Window Caution : It will not be printed immediately.

MGlobal::displayInfo( MString( ) );
#include <maya/MGlobal.h> Print out in Script Editor & Command Feedback Line

Maya Programming for 3D Graphics

http://wanochoi.com

Printing Out for Error Messages


displayError
#include <maya/MGlobal.h> MGlobal::displayError( Error! ); Print out in Command Feedback & Script Editor

perror
#include <maya/MStatus.h> or none MStatus stat = MS::kFailure; stat.perror( Error! ); Print out in Output Window

Maya Programming for 3D Graphics

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 );

unsigned int num = 10; MGlobal::displayInfo( Mstring(num:) + num );

MString str( 3.14159 ); float pi = str.asFloat();

Maya Programming for 3D Graphics

http://wanochoi.com

MObject & Function Sets


MObject
Maya owns the actual data and never gives you direct access to it. It is the generic class for accessing all Maya internal objects.
curve, surface, mesh, node, plug, light, shader, texture, etc.

It is just a handle to an object inside the core.


It can be thought of as a pointer to some internal data.

Function set
It is C++ classes which operate on objects. MFn prefix indicates this.

Maya Programming for 3D Graphics

http://wanochoi.com

Dependency Node plug-in

Maya Programming for 3D Graphics

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.

User-defined nodes must have both input & output attributes.


If there are neither input or output connection to other nodes, this node will do nothing. All input & output attributes must be the type of MObject. All variables for input & output attributes must be type of static. They must be initialized at the outside of the class.

Maya Programming for 3D Graphics

http://wanochoi.com

An Example of Simple DG Node (1/6)


#ifndef _TESTNODE_H_ #define _TESTNODE_H_ #include <maya/MPxNode.h> class testNode : public MPxNode { public: // member variables static MTypeId typeID; static MString typeName; static MObject input; static MObject output;

testNode.h

// node ID // node name // input attribute // output attribute

};

public: // member functions static void* creator() { return new testNode(); }; virtual MStatus compute( const MPlug& plug, MDataBlock& data ); static MStatus initialize();

#endif

Maya Programming for 3D Graphics

http://wanochoi.com

An Example of Simple DG Node (2/6)


#include "testNode.h" #include <maya/MFnNumericAttribute.h> // unique dependency node ID & Name MTypeId testNode::typeID( 0x00001 ); MString testNode::typeName( "testNode" );

testNode.cpp

Dont use the existing ID & name in Maya.

// initialization for 'static' member variables as NULL MObject testNode::input; MObject testNode::output; MStatus testNode::initialize() { } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { }

Maya Programming for 3D Graphics

http://wanochoi.com

An Example of Simple DG Node (3/6)


MStatus testNode::initialize() { MStatus stat; MFnNumericAttribute nAttr; // 1/3) create & set attributes input = nAttr.create( "input", "in", MFnNumericData::kDouble, 1.0, &stat ); nAttr.setConnectable( true ); output = nAttr.create( "output", "out", MFnNumericData::kDouble, 1.0, &stat ); nAttr.setConnectable( true ); // 2/3) add attributes addAttribute( input ); addAttribute( output ); // 3/3) set causality attributeAffects( input, output ); } return stat;

Dont use the existing long name or short name in Maya.

Maya Programming for 3D Graphics

http://wanochoi.com

An Example of Simple DG Node (4/6)


MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { MStatus stat; if( plug == output ) { // which output attribute is requested to be recomputed MDataHandle inputHnd = data.inputValue( input, &stat ); double inputValue = inputHnd.asDouble(); MDataHandle outputHnd = data.outputValue( output ); outputHnd.set( 2*inputValue ); data.setClean( plug ); // inform the DG that the given plug has been updated } else { } } return MS::kUnknownParameter; // other attributes to be treated in parent node

return stat;

Maya Programming for 3D Graphics

http://wanochoi.com

An Example of Simple DG Node (5/6)


#include "testNode.h" #include <maya/MFnPlugin.h> MStatus initializePlugin( MObject obj ) { MStatus stat; MFnPlugin plugin( obj, My Company", "1.0", "Any" ); // Register testNode stat = plugin.registerNode( testNode::typeName, testNode::typeID, testNode::creator, testNode::initialize ); if( !stat ) { stat.perror( "registerNode" ); return stat; } return stat; } MStatus uninitializePlugin( MObject obj) { MStatus stat; MFnPlugin plugin( obj ); // Deregister testNode stat = plugin.deregisterNode( testNode::typeID ); if( !stat ) { stat.perror( "deregisterNode" ); return stat; } return stat; }

pluginMain.cpp

Maya Programming for 3D Graphics

http://wanochoi.com

An Example of Simple DG Node (6/6)

Maya Programming for 3D Graphics

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.

Maya Programming for 3D Graphics

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.

Maya Programming for 3D Graphics

http://wanochoi.com

Plugs
Which output attribute the recompute is being requested for?
if( plug == output1 ) {} else if( plug == output2 ) {}

else if( plug == output3 ) {}


else return MS::kUnknownParameter;

It lets Maya know that the recomputing is done and it holds the now correct value.
data.setClean( plug );

Maya Programming for 3D Graphics

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.

Maya Programming for 3D Graphics

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

Maya Programming for 3D Graphics

http://wanochoi.com

Compound Attribute
A compound attribute is used to group other attributes.
Children : the grouped attributes Parent : itself

Representative of compound attribute : boundingBox

Maya Programming for 3D Graphics

http://wanochoi.com

Deformer Node plug-in

Maya Programming for 3D Graphics

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()

Maya Programming for 3D Graphics

http://wanochoi.com

Deformer Node Example (1/3)


#include <maya/MPxDeformerNode.h> #ifndef __TESTDEFORMER_H_ #define __TESTDEFORMER_H_ class testDeformer : public MPxDeformerNode { public: static void *creator() {return new testDeformer(); }; static MStatus initialize() { return MS::kSuccess; }; virtual MStatus deform( MDataBlock &block, MItGeometry &iter, const MMatrix &mat, unsigned int multiIndex ); }; #endif

testDeformer.h

Maya Programming for 3D Graphics

http://wanochoi.com

Deformer Node Example (2/3)


#include <maya/MFnMatrixAttribute.h> #include <maya/MMatrix.h> #include <maya/MItGeometry.h> #include <maya/MDagModifier.h> #include <maya/MPoint.h> #include "testDeformer.h" MTypeId testDeformer::typeId( 0x00111 ); MString testDeformer::typeName( "testDeformer" ); MStatus testDeformer::deform( MDataBlock& block, MItGeometry &iter, const MMatrix &localToWorld, unsigned int geomIndex ) { MStatus stat; MDataHandle envData = block.inputValue( envelope ); float env = envData.asFloat(); if( env == 0.0 ) // Deformer has no effect return MS::kSuccess; MPoint pt; for( iter.reset(); !iter.isDone(); iter.next() ) { // per each point to be deformed pt = iter.position(); pt = pt * 1.5; iter.setPosition( pt ); } return stat; }

testDeformer.cpp

Maya Programming for 3D Graphics

http://wanochoi.com

Deformer Node Example (3/3)


#include <maya/MFnPlugin.h> #include "testDeformer.h" #pragma comment( lib, "Foundation.lib" ) #pragma comment( lib, "OpenMaya.lib" ) #pragma comment( lib, "OpenMayaAnim.lib" ) MStatus initializePlugin( MObject obj ) { MStatus status; MFnPlugin plugin( obj, My Company", 1.0", "Any"); plugin.registerNode( testDeformer::typeName, testDeformer::typeId, testDeformer::creator, testDeformer::initialize, MPxNode::kDeformerNode ); return status; } MStatus uninitializePlugin( MObject obj ) { MStatus status; MFnPlugin plugin( obj ); stat = plugin.deregisterNode( testDeformer::typeId ); return status; }
Maya Programming for 3D Graphics 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.

4) unsigned int geomIndex


It is possible for a deformer to deform multiple geometry nodes multiple components of a single geometry node.
Maya Programming for 3D Graphics http://wanochoi.com

Changes in Hypergraph
polySphere;

Maya Programming for 3D Graphics

http://wanochoi.com

Changes in Hypergraph
deformer -type testDeformer

Maya Programming for 3D Graphics

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

Maya Programming for 3D Graphics

http://wanochoi.com

Locator Node plug-in

Maya Programming for 3D Graphics

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

Other additional member functions


raw(), isBounded(), boundingBox(), color(), colorRGB()

Maya Programming for 3D Graphics

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

Maya Programming for 3D Graphics

http://wanochoi.com

isBounded(), boundingBox()
isBounded()
It is called when Maya needs to determine if the node knows its own bounding extents.

If it returns false, you dont need to implement boundingBox().

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.

Maya Programming for 3D Graphics

http://wanochoi.com

Locator Node Example (1/3)


#include <maya/MPxLocatorNode.h> #include <maya/M3dView.h> #include <maya/MString.h> #include <maya/MTypeId.h> #ifndef __TESTLOCATOR_H_ #define __TESTLOCATOR_H_ class testLocator : public MPxLocatorNode { public: virtual void draw( M3dView &view, const MDagPath &path, M3dView::DisplayStyle style, M3dView::DisplayStatus status ); virtual bool isBounded() const { return false; }; virtual MBoundingBox boundingBox() const; static void *creator() {return new testDeformer(); }; static MStatus initialize() { return MS::kSuccess; }; public: static MTypeId typeId; static MString typeName;

testLocator.h

}; #endif

Maya Programming for 3D Graphics

http://wanochoi.com

Locator Node Example (2/3)


#include "testLocator.h" MTypeId testLocator::typeId( 0x00111 ); MString testLocator::typeName( "testLocator" ); void BasicLocator::draw( M3dView & view, const MDagPath & path, M3dView::DisplayStyle style, M3dView::DisplayStatus status ) { view.beginGL(); glPushAttrib( GL_CURRENT_BIT ); glBegin(GL_LINES); glVertex3f( -0.5f, 0.0f, 0.0f ); glVertex3f( 0.5f, 0.0f, 0.0f ); glVertex3f( 0.0f, 0.0f, -0.5f ); glVertex3f( 0.0f, 0.0f, 0.5f ); glEnd(); glPopAttrib(); view.endGL(); }

testLocator.cpp

Maya Programming for 3D Graphics

http://wanochoi.com

Locator Node Example (3/3)


#include <maya/MFnPlugin.h> #include "testLocator.h" #pragma comment( lib, "Foundation.lib" ) #pragma comment( lib, "OpenMaya.lib" ) #pragma comment( lib, OpenMayaUI.lib ) #pragma comment( lib, opengl32.lib ) MStatus initializePlugin( MObject obj ) { MStatus status; MFnPlugin plugin( obj, My Company", 1.0", "Any"); plugin.registerNode( testLocator::typeName, testLocator::typeId, testLocator::creator, testLocator::initialize, MPxNode::kLocatorNode ); return status;

pluginMain.cpp

MStatus uninitializePlugin( MObject obj ) { MStatus status; MFnPlugin plugin( obj ); plugin.deregisterNode( testDeformer::typeId ); return status; }

Maya Programming for 3D Graphics

http://wanochoi.com

Maya Stand-alone Application

Maya Programming for 3D Graphics

http://wanochoi.com

Stand-alone Application
It contains the main routine for the application and makes API calls to access Maya in batch mode.

Maya Programming for 3D Graphics

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); }

Maya Programming for 3D Graphics

http://wanochoi.com

User Defined Attributes

Maya Programming for 3D Graphics

http://wanochoi.com

User Defined Attribute (1/4)


All user defined connectable attribute of node that is to be passed between nodes in the dependency graph must be derived from MPxData.
definedType.h #include <maya/MPxData.h> class definedType : public MPxData { public: static const MString typeName; static const MTypeId id; public: static void *creator() {return new definedType; }; };

#include definedType.h const MTypeId definedType::id( 0xF1000 ); const MString definedType::typeName( definedType );

definedType.cpp

Maya Programming for 3D Graphics

http://wanochoi.com

User Defined Attribute (2/4)


#include <maya/MPxNode.h> #include <maya/MTypeId.h> #include <maya/MString.h> class testNode : public MPxNode { public: static MTypeId id; static MString typeName; MObject input; MObject output; public: virtual MStatus compute( const MPlug& plug, MDataBlock& data ); static void* creator() { return new testNode; }; static MStatus initialize(); void Modifier( definedType *in, definedType *out ); };

testNode.h

Maya Programming for 3D Graphics

http://wanochoi.com

User Defined Attribute (3/4)


#include testNode.h #include <maya/MFnTypedAttribute.h> #include <maya/MFnPluginData.h> const MTypeId testNode::id( 0xF1100 ); const MString testNode::typeName( testNode ); MObject testNode::input; MObject testNode::output; MStatus testNode::initialize() { MFnTypedAttribute tAttr; input = tAttr.create( "input", "in", definedType::id, MObject::kNullObj ); output = tAttr.create( "output", "out", definedType::id, MObject::kNullObj ); addAttribute( input ); addAttribute( output ); } attributeAffects( input, output );

testNode.cpp

Maya Programming for 3D Graphics

http://wanochoi.com

User Defined Attribute (4/4)

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

void testNode::Modifier( definedType *in, definedType *out ) { }

Maya Programming for 3D Graphics

http://wanochoi.com

Maya plug-in Tips

Maya Programming for 3D Graphics

http://wanochoi.com

How to execute MEL command


MGlobal::executeCommand( sphere p 0 0 0 r 1 ); MStringArray Locator; MGlobal::executeCommand( MString( "spaceLocator -p " ) + p0.x + " " + p0.y + " " + p0.z, Locator ); MGlobal::displayInfo( MString( Locator Name : + Locator[0] );

Maya Programming for 3D Graphics

http://wanochoi.com

How to get selected meshes


#include <maya/MSelectinList.h> #include <maya/MItSelectinList.h> #include <maya/MDagPath.h> #include <maya/MFnMesh.h> MSelectionList selection; MGlobal::getActiveSelectionList( selection ); MDagPath dagPath; MFnMesh meshFn; MItSelectionList iter( selection, MFn::kMesh ); for( ; !iter.isDone(); iter.next() ) { iter.getDagPath( dagPath ); meshFn.setObject( dagPath ); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to get time attribute


class testNode : public MPxNode { static MObject inTime; }; #include <maya/MTime.h> #include <maya/MFnUnitAttribute.h> MObject testNode::inTime; MStatus testNode::initialize() { MFnUnitAttribute uAttr; inTime = uAttr.create( "inTime", "it", MFnUnitAttribute::kTime ); } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { MDataHandle inTimeHnd = data.inputValue( inTime ); MTime time = inTimeHnd.asTime(); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to get bool attribute


class testNode : public MPxNode { static MObject inValue; }; #include <maya/MFnNumericAttribute.h> MObject testNode::inValue; MStatus testNode::initialize() { MFnNumericAttribute nAttr; inValue = nAttr.create( "inVal", "iv", MFnNumericData::kBoolean, true ); } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { MDataHandle inValueHnd = data.inputValue( inValue ); bool inVal = inValueHnd.asBool(); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to get int attribute


class testNode : public MPxNode { static MObject inValue; }; #include <maya/MFnNumericAttribute.h> MObject testNode::inValue; MStatus testNode::initialize() { MFnNumericAttribute nAttr; inValue = nAttr.create( "inVal", "iv", MFnNumericData::kInt, 1 ); } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { MDataHandle inValueHnd = data.inputValue( inValue ); int inVal = inValueHnd.asInt(); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to get double attribute


class testNode : public MPxNode { static MObject inValue; }; #include <maya/MFnNumericAttribute.h> MObject testNode::inValue; MStatus testNode::initialize() { MFnNumericAttribute nAttr; inValue = nAttr.create( "inVal", "iv", MFnNumericData::kDouble, 1.0 ); } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { MDataHandle inValueHnd = data.inputValue( inValue ); double inVal = inValueHnd.asDouble(); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to get NURBS curve


class testNode : public MPxNode { static MObject inCurve; }; #include <maya/MFnNurbsCurve.h> #include <maya/MFnTypedAttribute.h> MObject testNode::inCurve; MStatus testNode::initialize() { MFnTypedAttribut tAttr; inCurve = tAttr.create( "inCurve", "ic", MFnData::kNurbsCurve ); } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { MDataHandle inCurveHnd = data.inputValue( inCurve ); MObject inCurveObj = inCurveHnd.asNurbsCurve(); MFnNurbsCurve inCurveFn( inCurveObj ); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to get NURBS surface


class testNode : public MPxNode { static MObject inSurface; }; #include <maya/MFnNurbsSurface.h> #include <maya/MFnTypedAttribute.h> MObject testNode::inSurface; MStatus testNode::initialize() { MFnTypedAttribut tAttr; inSurface = tAttr.create( "inSurface", "ic", MFnData::kNurbsSurface ); } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { MDataHandle inSurfaceHnd = data.inputValue( inSurface ); MObject inSurfaceObj = inCurveHnd.asNurbsSurface(); MFnNurbsSurface inSurfaceFn( inSurfaceObj ); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to get Mesh


class testNode : public MPxNode { static MObject inMesh; }; #include <maya/MFnMeshData.h> #include <maya/MFnMesh.h> MObject testNode::inMesh;

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 ); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to output Mesh


class testNode : public MPxNode { static MObject outMesh; }; #include <maya/MFnMeshData.h> #include <maya/MFnMesh.h> #include <maya/MFnTypedAttribute.h> MObject testNode::outMesh; MStatus testNode::initialize() { MFnTypedAttribut tAttr; outMesh = tAttr.create( outputMesh", outM", MFnMeshData::kMesh ); } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { MFnMeshData dataCreator; MObject newData = dataCreator.create(); MFnMesh mesh; mesh.create( nVerts, nPolys, vertsArray, , newData ); MDataHandle outMeshHnd = data.outputValue( outMesh ); outMeshHnd.set( newData ); data.setClean( plug ); }
Maya Programming for 3D Graphics http://wanochoi.com

How to output NURBS surface


class testNode : public MPxNode { static MObject outSurface; }; #include <maya/MFnNurbsSurface.h> #include <maya/MFnNurbsSurfaceData.h> #include <maya/MFnTypedAttribute.h> MObject testNode::outSurface; MStatus testNode::initialize() { MFnTypedAttribut tAttr; outSurface = tAttr.create( outSurface", os", MFnData::kNurbsSurface ); } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ){ MFnNurbsSurfaceData dataCreator; MObject newOutSurface = dataCreator.create(); MFnNurbsSurface nurbsFS; MObject newNurbs = nurbsFS.create( ctrlVerts, , newOutSurface ); MDataHandle outSurfaceHnd = data.outputValue( outSurface ); outMeshHnd.set( newOutSurface ); data.setClean( plug ); }
Maya Programming for 3D Graphics http://wanochoi.com

How to copy NURBS surface


class testNode : public MPxNode { static MObject inSurface; static MObject outSurface; }; #include <maya/MFnNurbsSurfaceData.h> #include <maya/MFnTypedAttribute.h> MObject testNode::inSurface; MObject testNode::outSurface MStatus testNode::initialize() { MFnTypedAttribute tAttr; inSurface = tAttr.create( inSurface", is", MFnData::kNurbsSurface ); outSurface = tAttr.creat( outSurface, os, MFnData::kNurbsSurface ); addAttribute( inSurface); addAttribute( outSurface ); attributeAffects( inSuface, outSurface ); } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { if( plug == outSurface ) { MDataHandle inSurfaceHnd = data.inValue( inSurface ); MObject inSurfaceObj = inSurfaceHnd.asNurbsSurface(); MFnNurbsSurfaceData surfaceData( inSurfaceObj ); MObject outSurfaceObj = surfaceData.object(); MDataHandle outSurfaceHnd = data.inValue( outSurface ); outSurfaceHnd.set( outSurfaceObj ); data.setClean( plug ); } }
Maya Programming for 3D Graphics http://wanochoi.com

How to limit numeric attribute value


MStatus testNode::initialize() { MFnNumericAttribute nAttr; inValue1 = nAttr.create( "inVal1", "iv1", MFnNumericData::kDouble, 1.0 ); inValue2 = nAttr.create( "inVal2", "iv2", MFnNumericData::kDouble, 1.0 ); nAttr.setMin(0.0); nAttr.setMax(10.0); inValue3 = nAttr.create( "inVal3", "iv3", MFnNumericData::kDouble, 1.0 ); nAttr.setMin(0.0); nAttr.setSoftMax(10.0); inValue4 = nAttr.create( "inVal4", "iv4", MFnNumericData::kDouble, 1.0 ); nAttr.setSoftMin(0.0); nAttr.setSoftMax(10.0); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to limit numeric attribute value


createNode testNode;
Attribute Editor : testNode1

Maya Programming for 3D Graphics

http://wanochoi.com

How to get compound attribute


class testNode : public MPxNode { static MObject output; static MObject iboundingBox; static MObject iboundingBoxMin; static MObject iboundingBoxMax; static MObject iboundingBoxSize; }; #include <maya/MFnCompoundAttribute.h> #include <maya/MFnNumericAttribute.h> MObject testNode::input; MObject testNode::iboundingBox; MObject testNode::iboundingBoxMin; MObject testNode::iboundingBoxMax; MObject testNode::iboundingBoxSize; MStatus testNode::initialize() { MFnCompoundAttribute cAttr; MFnNumericAttribute nAttr; output = nAttr.create( output, out ); iboundingBox = cAttr.create( iboundingBox", ibbox" ); iboundingBoxMin = nAttr.create( iboundingBoxMin, ibbmin, MFnNumericData::k3Double ); iboundingBoxMax = nAttr.create( iboundingBoxMax, ibbmax, MFnNumericData::k3Double ); iboundingBoxSize = nAttr.create( iboundingBoxSize, ibbsize, MFnNumericData::k3Double );

testNode.h

testNode.cpp

Maya Programming for 3D Graphics

http://wanochoi.com

How to get compound attribute


cAttr.addChild( iboundingBoxMin ); cAttr.addChild( iboundingBoxMax ); cAttr.addChild( iboundingBoxSize ); addAttribute( iboundingBox ); addAttribute( output ); attributeAffects( iboundingBoxMin, output ); attributeAffects( iboundingBoxMax, output ); attributeAffects( iboundingBoxSize, output ); } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { MDataHandle iboundingBoxMinHnd = data.inputValue( iboundingBoxMin ); MVector minPosition = iboundingBoxMinHnd.asDouble3(); MDataHandle iboundingBoxMaxHnd = data.inputValue( iboundingBoxMax ); MVector maxPosition = iboundingBoxMaxHnd.asDouble3(); MDataHandle iboundingBoxSizeHnd = data.inputValue( iboundingBoxSize ); MVector bBoxSize = iboundingBoxSizeHnd.asDouble3(); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to get node itself


#include <maya/MFnDependencyNode.h> MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { if( plug == output ) { MFnDependencyNode dependNodeFn( thisMObject() ); } }

MPxNode::thisMObject()
It returns the MObject associated with this user defined node.

Maya Programming for 3D Graphics

http://wanochoi.com

How to get MObject by nodes name


#include <maya/MGlobal.h> #include <maya/MDagPath.h> #include <maya/MStringArray.h> #include <maya/MSelectionList.h> #include <maya/MFnDependencyNode.h> MStringArray testNodes; MGlobal::executeCommand( MString( "ls -type testNode" ), testNodes ); for( int i=0; i<testNodes.length(); i++ ) { MSelectionList sel; MGlobal::getSelectionListByName( testNodes[0], sel ); MObject testNodeObj; sel.getDependNode( i, testNodeObj ); MFnDependencyNode depFn( testNodeObj ); MString nodeName = depFn.name(); MGlobal::displayInfo( nodeName ); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to get array attribute


class testNode : public MPxNode { static MObject inValues; }; #include <maya/MPlug.h> #include <maya/MIntArray.h> #include <maya/MFnNumericAttribute.h> MObject testNode::inValues; MStatus testNode::initialize() { MFnNumericAttribute nAttr; inValues = nAttr.create( inValues", "iv", MFnNumericData::kDouble ); nAttr.setArray( true ); } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { MFnDependencyNode depFn( thisMObject() ); MPlug inValuesPlg = depFn.findPlug( inValues ); int nElems = inValuesPlg.numElements(); MIntArray logicalIndex; inValuesPlg.getExistingArrayAttributeIndices( logicalIndex ); for( int i=0; i<logicalIndex.length(); i++) { double temp; MPlug inValue = inValuesPlg.elementByLogicalIndex( logicalIndex[i] ); inValue.getValue( temp ); } }
Maya Programming for 3D Graphics http://wanochoi.com

How to output array attribute


class testNode : public MPxNode { static MObject outputs; }; #include <maya/MPlug.h> #include <maya/MIntArray.h> #include <maya/MFnNumericAttribute.h> MObject testNode::outputs; MStatus testNode::initialize() { MFnNumericAttribute nAttr; outputs = nAttr.create( outputs", outs", MFnNumericData::kDouble ); nAttr.setArray( true ); } MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { MFnDependencyNode depFn( thisMObject() ); MPlug outputsPlg = depFn.findPlug( outputs ); int nElems = outputsPlg.numElements(); MIntArray logicalIndex; outputsPlg.getExistingArrayAttributeIndices( logicalIndex ); for( int i=0; i<logicalIndex.length(); i++) { MPlug output = outputsPlg.elementByLogicalIndex( logicalIndex[i] ); output.getValue( 10.0 ); } }
Maya Programming for 3D Graphics http://wanochoi.com

How to input / output array attribute


MStatus testNode::compute( const MPlug& plug, MDataBlock& data ) { MStatus stat; if( plug == outSurfaces ) { MArrayDataHandle inSurfacesHnd = data.inputArrayValue( inSurfaces ); inSurfacesHnd.jumpToElement( plug.logicalIndex() ); MDataHandle inSurfaceHnd = inSurfacesHnd.inputValue(); MObject inSurfaceObj = inSurfaceHnd.asNurbsSurface(); MFnNurbsSurface inSurfaceFn( inSurfaceObj ); MObject outSurfaceObj; GenerateSurface( inSurfaceObj, outSurfaceObj ); MArrayDataHandle outSurfacesHnd = data.outputArrayValue( outSurfaces ); outSurfacesHnd.jumpToElement( plug.logicalIndex() ); MDataHandle outSurfaceHnd = outSurfacesHnd.inputValue(); outSurfaceHnd.set( outSurfaceObj ); data.setClean( plug ); } else { return MS::kUnknownParameter; } return stat; }

Maya Programming for 3D Graphics

http://wanochoi.com

How to input / output array attribute


MStatus tetsNode::compute( const MPlug& plug, MDataBlock& data ) { MStatus stat; if( plug == outSurfaces ) { MObject thisNodeObj = thisMObject(); MFnDependencyNode thisNodeFn( thisNodeObj ); MPlug inSurfacesPlug = thisNodeFn.findPlug( inSurfaces ); MIntArray inSurfacesIndex; inSurfacesPlug.getExistingArrayAttributeIndices( inSurfacesIndex ); for( unsigned int i=0; i<inSurfacesPlug.numConnecteElements(); i++ ) { MPlug inSurfacePlug = inSurfacesPlug.elementByLogicalIndex( inSurfacesIndex[i] ); MObject inSurfaceObj; inSurfacePlug.getValue( inSurfaceObj ); MFnNurbsSurface inSurfaceFn( inSurfaceObj ); MObject outSurfaceObj; GenerateSurface( inSurfaceObj, outSurfaceObj ); MArrayDataHandle outSurfacesHnd = data.outputArrayValue( outSurfaces ); outSurfacesHnd.jumpToElement( plug.logicalIndex() ); MDataHandle outSurfaceHnd = outSurfacesHnd.inputValue(); outSurfaceHnd.set( outSurfaceObj ); } data.setClean( plug ); } else { return MS::kUnknownParameter; } return stat; }
Maya Programming for 3D Graphics http://wanochoi.com

How to get matrix attribute


class testNode : public MPxNode { static MObject inMatrix; };

#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(); }

Maya Programming for 3D Graphics

http://wanochoi.com

Plug Connection Test


MFnDependencyNode thisDGNode( MPxNode::thisMObject() ); MPlug inputType1 = thisDGNode.findPlug( inValue1 , &stat ); MPlug inputType2 = thisDGNode.findPlug( inValue2, &stat ); if( inputType1.isConnected( &stat ) ) {...}

Maya Programming for 3D Graphics

http://wanochoi.com

Traveling Dependency Graph


MStatus testCmd::doIt( const MArgList& ) { MStatus stat; MSelectionList selectedList; MGlobal::getActiveSelectionList( selectedList ); MItSelectionList iter( selectedList ); for(; !iter.isDone(); iter.next() ) { MObject thisNodeObj; MFnDependencyNode thisNodeFn; MObject prevNodeObj; MFnDependencyNode prevNodeFn; MObject nextNodeObj; MFnDependencyNode nextNodeFn; selectedList.getDepenNode( 0, thisNodeObj ); thisNodeFn.setObject( thisNodeObj ); MPlug inputPlug = thisNodeFn.findPlug( "input" ); MPlugArray plugs; inputPlug.connectedTo( plugs, true, false ); prevNodeObj = plug[0].node(); prevNodeFn.setObject( prevNodeObj ); plugs.clear(); MPlug outputPlug = thisNodeFn.findPlug( "output" ); outputPlug.connectedTo( plugs, false, true ); nextNodeObj = plug[0].node(); nexeNodeFn.setObject( nextNodeObj ); } MGlobal::executeCommand( MString( "select -cl" ) ); return MS::kSuccess; }
Maya Programming for 3D Graphics http://wanochoi.com

How to get dag path by node name


MString nodeName( "aaa" ); MString nodeName( "bbb" ); MSelectionList sList; sList.add( node1Name ); sList.add( node2Name ); MDagPath dagPath1, dagPath2; sList.getDagPath( 0, dagPath1 ); sList.getDagPath( 1, dagPath2 );

Maya Programming for 3D Graphics

http://wanochoi.com

How to get & set MPlug for MDoubleArray


MString nodeName = ; MObject nodeObj = ; MFnDependencyNode nodeFn( nodeObj ); Mplug plg = nodeFn.findPlug( nodeName ); MObject daData; plg.getValue( daData ); MFnDoubleArrayData daFn( daData ); MDoubleArray dArray = daFn.array();

MString nodeName = ; MObject nodeObj = ; MDoubleArray dArray = ; MFnDependencyNode nodeFn( nodeObj ); Mplug plg = nodeFn.findPlug( nodeName ); MFnDoubleArrayData daFn; plg.setMObject( daFn.create( dArray ) );

Maya Programming for 3D Graphics

http://wanochoi.com

How to copy from input Mesh to output Mesh


#include <maya/MPlug.h> #include <maya/MObject.h> #include <maya/MFnMesh.h> #include <maya/MDataBlock.h> #include <maya/MFnMeshData.h> void copyMesh( const MPlug& plug, MDataBlock& data ) { MFnMesh newMeshFn; MFnMeshData dataCreator; MObject newMeshData = dataCreator.create(); newMeshFn.copy( data.inputValue( inMeshObj ).asMeshTransformed(), newMeshData ); data.outputValue( outMeshObj ).set( newMeshData ); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to get the shape node of a mesh


MDagPath dagPath; // transform node name dagPath.extendToShape(); MFnMesh meshFn( dagPath );

Maya Programming for 3D Graphics

http://wanochoi.com

How to get the worldMatrix of a shape node


Mobject thisNodeObj = thisMObject(); MFnDependencyNode fnThisNode( thisNodeObj ); MObject worldMatrixObj = fnThisNode.attribute( "worldMatrix", &stat ); MPlug worldMatrixPlg( thisNodeObj, worldMatrixObj ); worldMatrixPlg = worldMatrixPlg.elementByLogicalIndex( 0 ); MObject matrixObject; stat = worldMatrixPlg.getValue( matrixObject ); if( !stat ) { stat.perror( "Failed to get worldMatrix object." ); } MFnMatrixData worldMatrixData( matrixObject, &stat ); if( !stat ) { stat.perror( "Failed to get worldMatrix data." ); } worldMatrix = worldMatrixData.matrix( &stat ); if( !stat ) { stat.perror( "Failed to get worldMatrix." ); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to get Fields in the current scene


#include <maya/MItDag.h> #include <maya/MFnField.h> for( MItDag it(MItDag::kDepthFirst, MFn::kField); !it.isDone(); it.next() ) { MFnField fieldFn( it.item() ); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to copy from input mesh to output mesh


#include <maya/MPlug.h> #include <maya/MObject.h> #include <maya/MFnMesh.h> #include <maya/MDataBlock.h> #include <maya/MFnMeshData.h> void copyMesh( const MPlug& plug, MDataBlock& data ) { MFnMesh newMeshFn; MFnMeshData dataCreator; MObject newMeshData = dataCreator.create(); newMeshFn.copy( data.inputValue( inMeshObj ).asMeshTransformed(), newMeshData ); data.outputValue( outMeshObj ).set( newMeshData ); }

Maya Programming for 3D Graphics

http://wanochoi.com

How to get current view & camera


#include <maya/M3dView.h> #include <maya/MFnCamera.h> M3dView view = M3dView::active3dView(); MDagPath camDagPath; View.getCamera( camDagPath ); MFnCamera cam( camDagPath );

Maya Programming for 3D Graphics

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/

Maya Programming for 3D Graphics

http://wanochoi.com

You might also like