Title: Introduction to the Maya C API
1Introduction to the Maya C API
- Brent Haley
- The Ohio State University
- (bhaley_at_accad.ohio-state.edu)
2Programming for Maya
- The Book (Complete Maya Programming)
- Maya Help (Developer Resources, Commands, Nodes,
API Classes) - MEL Scripts
- Can be really easy to test
- Can see how Maya does its own with echo
- Hard to get complex data structures
- Slower, due to interpretation
- C API Plug-ins
- Very confusing at first, hard to find help /
concise examples - Faster, due to machine language
3Topics
- Day 1
- Plug-in Introduction
- How to Create a MLL
- Command Basics
- Node Basics
- Warnings
- Day 2
- VC Examples
4Simple Scene in Maya
- 3D View, Hypergraph, and Outliner
- Using built in functionality
- Mocap driven animation
5Nodes, Plugs, and Attributes
Note Im zooming in on LilyGeometry to get the
2nd image
6Turning Character into Smoke
- Create a built in fluid container
- Have the vertices on Lilys surface generate
density values - Requires a way to link Lilys output geometry to
the fluid containers density values in the
hypergraph - Note Lilys input geometry is driven by her
original mesh skeletal rig and smooth skin
binding
7Using a Plug-in (1)
- Add new nodes and commands to Maya
- Requires one to load the plug-in
8Using a Plug-in (2)
- Select the required components
- Run the command
9Tweak the SmokeNode1 Attributes
10Topics
- Day 1
- Plug-in Introduction
- How to Create a MLL
- Command Basics
- Node Basics
- Warnings
- Day 2
- VC Examples
11Create a Visual C Project
- The project creation wizard may not be installed
(or doesnt work correctly) - Make a Win32Project
- Under application settings, choose dll and empty
project
12Open the Project Properties
Note make sure you apply the settings on the
next slide to both the debug and release versions
(all configs should work).
13Set the Project Properties
- C/C -gt General -gt Additional Include
Directories C\Program Files\Alias\Maya8.0\includ
e - C/C -gt Preprocessor -gt Preprocessor
Definitions WIN32NDEBUG_WINDOWSNT_PLUGIN - Linker -gt General -gt Output File change the .dll
to .mll - Linker-gt General -gt Additional Libarary
C\Program Files\Alias\Maya8.0\lib - Linker -gt Input -gt Additional Dependencies
opengl32.lib Foundation.lib OpenMaya.lib
OpenMayaUI.lib OpenMayaAnim.lib OpenMayaFX.lib
OpenMayaRender.lib - Linker -gt CommandLine -gt Additional Options
/exportinitializePlugin /exportuninitializePlugi
n
14Required Code (main.cpp)
- include ltmaya/MFnPlugingt
- include ltmaya/MObjectgt
- include ltmaya/MStatusgt
- MStatus initializePlugin(MObject obj)
-
- MStatus stat
- MFnPlugin plugin(obj, "Brent Haley", 1.0",
8.0") - return(stat)
-
- MStatus unintializePlugin(MObject obj)
-
- MStatus stat
- MFnPlugin plugin(obj)
- return(stat)
- Initialize plugin procedure is an entry point
that gets called when you load your plugin in
Maya - Uninitialize plugin procedure is an entry point
that gets called when you unload your plugin from
Maya - Remember these were specified under the project
settings - Through these entry points we tell Maya what
Nodes and Commands our Plugin has
15Topics
- Day 1
- Plug-in Introduction
- How to Create a MLL
- Command Basics
- Node Basics
- Warnings
- Day 2
- VC Examples
16Example Command
- Specification
- class GeomToDensityCmd public MPxCommand
-
- public
- //creator function
- static void creator()
- //command execution functions
- virtual MStatus doIt(const MArgList args)
- virtual MStatus redoIt()
- virtual MStatus undoIt()
- virtual bool isUndoable() const
- private
- //graph modifier, used to support undo and redo
- MDagModifier dagMod
- Implementation (except doIt)
- void GeomToDensityCmdcreator()
-
- return new GeomToDensityCm
-
- MStatus GeomToDensityCmdredoIt()
-
- //commit the work set in doIt
- MStatus stat dagMod.doIt()
- return(stat)
-
- MStatus GeomToDensityCmdundoIt()
-
- //erase any work set in doIt
- MStatus stat dagMod.undoIt()
- return(stat)
-
- bool GeomToDensityCmdisUndoable() const
return(true)
17doIt
- Where the actual work is done
- Changes made to the graph
- Get nodes through selection
- Get data through those nodes plugs
- Be careful not to setup a cyclic graph
- See day 2 VC examples
18(De)Register the Command
- Register commands in the initializePlugin
procedure (from the required bit of code) - stat plugin.registerCommand(
- geom2smoke",
- GeomToDensityCmdcreator)
- if (!stat) MGlobaldisplayError("register
MudBoxCommand failed") - Deregister commands in the unitializePlugin
procedure - stat plugin.deregisterCommand(geom2smoke")
- if (!stat) MGlobaldisplayError("deregister
MudBoxCommand failed")
19Topics
- Day 1
- Plug-in Introduction
- How to Create a MLL
- Command Basics
- Node Basics
- Warnings
- Day 2
- VC Examples
20Example Node
- Specification
- class SmokeNode public MPxNode
-
- public
- //identifier
- static MTypeId id
- //attributes
- static MObject filterSize
-
- //creator function
- static void creator()
- //initializer for the node
- static MStatus initialize()
- //computational function to do the real work
- virtual MStatus compute (const MPlug plug,
MDataBlock data) - private
-
- Implementation (no compute)
- void SmokeNodecreator()
- return new SmokeNode
- MStatus SmokeNodeinitialize()
- //create the attributes
- MFnNumericAttribute fsAttribute
- filterSize fsAttribute.create(filterSize",
fs", MFnNumericDatakInt, 0) - ...
- //add the attributes to the node
- addAttribute(filterSize)
- ...
- //specify attribute relations
- attributeAffects(filterSize,is2D)
- ...
- //return without error
- return(MSkSuccess)
21Compute
- Where the actual work is done
- MStatus SmokeNodecompute (const MPlug plug,
MDataBlock data) - MStatus stat
- //determine which output plug needs to be
computed - if (plug is2D)
- //get input data handles
- MDataHandle filterSizeData
data.inputValue(filterSize) - ...
- //turn input handles into data
- int fs filterSizeData.asInt()
- ...
- //get output data handles
- MDataHandle cfdData data.outputValue(is2
D) - //turn output handles into data
- ltSNIPgt
- //set the output data and mark the plug
- cfdData.set(false)
- data.setClean(plug)
- else
22(De)Register the Node
- Register nodes in the initializePlugin procedure
- stat plugin.registerNode(
- SmokeNode",
- SmokeNodeid,
- SmokeNodecreator,
- SmokeNodeinitialize
- )
- if (!stat) MGlobaldisplayError("register
SmokeNode failed") - Deregister nodes in the uninitializePlugin
procedure - stat plugin.deregisterNode(SmokeNodeid)
- if (!stat) MGlobaldisplayError("deregister
SmokeNode failed")
23Topics
- Day 1
- Plug-in Introduction
- How to Create a MLL
- Command Basics
- Node Basics
- Warnings
- Day 2
- VC Examples
24Warnings (1)
- Node Ids need to be unique
- Bad
- Good
In NodeAs implementation MTypeId
NodeAid(0x43215) In NodeBs implementation
MTypeId NodeBid(0x43215)
In NodeAs implementation MTypeId
NodeAid(0x43215) In NodeBs implementation
MTypeId NodeBid(0x43216)
25Warnings (2)
- Attribute affects shouldnt be multi-level
- Create several nodes instead of trying to
accomplish everything in a single node - Bad
- Good
In NodeAs initialize() procedure attributeAffect
s(X,Y) attributeAffects(Y,Z)
In NodeAs initialize() procedure
attributeAffects(X,Y) In NodeBs initialize()
procedure attributeAffects(S,T) Where Ys
output is plugged into Ss input
26Warnings (3)
- Dont create cyclic structures in the hypergraph
(can result in infinite loops)
27Warnings (4)
- Per-frame node evaluation will occur in chunks if
you use the rendering farm - Dont rely on old values from the previous frame
in your code since they may not exist - Alternatively (if you really need to),
- Explicitly step the time back for each frame
- Particles can be cached
- Dynamics can be forced to run from the start time
to the current time before rendering each frame
28Topics
- Day 1
- Plug-in Introduction
- How to Create a MLL
- Command Basics
- Node Basics
- Warnings
- Day 2
- VC Examples