19
Introduction to the Maya C++ API Brent Haley The Ohio State University ([email protected] state.edu)

Intro

  • Upload
    bspremo

  • View
    256

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Intro

Introduction to the Maya C++ API

Brent Haley

The Ohio State University

([email protected])

Page 2: Intro

Topics

• Mud Plugin Introduction

• How to Create a MLL

• Command Basics

• Node Basics

Page 3: Intro

Programming for Maya

• The Book (Complete Maya Programming)• MEL Scripts

– Can be really easy to test– Can see how Maya does its own with echo– Hard to get complex data structures– Slow, due to interpretation

• C++ API Plugins– Very confusing at first (and later), hard to find help /

concise examples– Fast, due to machine language

Page 4: Intro

Particles in Maya

• Maya has a built in particle system• Can exploit this to build a particle based fluid

dynamics system• I took a procedural rather than physically based

approach

Page 5: Intro

Particle Based Fluid

• Idea– Use maya particle

dynamics to create the fluid

– Have a voxelized force field, with a different force in each voxel

– Force depends on particles as well as constants

Page 6: Intro

Plugin Realization

• Needs– Command to create

the mud system– Node(s) to do the

computations– Visual cues to locate

where the field is– Go FAST (so I used

the API + split particle system)

Page 7: Intro

Topics

• Mud Plugin Introduction

• How to Create a MLL

• Command Basics

• Node Basics

Page 8: Intro

Create a Visual C++ Project

• The project creation wizard is not installed

• Make a Win32Project

• Under application settings, choose dll and empty project

Page 9: Intro

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

Page 10: Intro

Set the Project Properties

• C/C++ -> General -> Additional Include Directories: C:\Program Files\AliasWavefront\Maya6.0\include

• C/C++ -> CommandLine -> Additional Options: /I "C:\Program Files\AliasWavefront\Maya6.0\include“

• C/C++ -> Preprocessor -> Preprocessor Definitions: WIN32;NDEBUG;_WINDOWS;NT_PLUGIN

• Linker -> General -> Output File: change the .dll to .mll

• Linker -> Input -> Additional Dependencies: opengl32.lib Foundation.lib OpenMaya.lib OpenMayaUI.lib OpenMayaAnim.lib OpenMayaFX.lib OpenMayaRender.lib

• Linker -> CommandLine -> Additional Options: /LIBPATH:"C:\Program Files\AliasWavefront\Maya6.0\lib" /export:initializePlugin /export:uninitializePlugin

Page 11: Intro

Required Code#include <maya/MFnPlugin>#include <maya/MObject>#include <maya/MStatus>

MStatus initializePlugin(MObject obj){ MStatus stat; MFnPlugin plugin(obj, "Brent Haley",

"2.2.1", "5.0.1"); 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

Page 12: Intro

Topics

• Mud Plugin Introduction

• How to Create a MLL

• Command Basics

• Node Basics

Page 13: Intro

Example Command• Specification

class MudBoxCommand : public MPxCommand

{public:

//creator functionstatic void *creator();

//command execution functionsvirtual MStatus doIt(const MArgList &args);virtual MStatus redoIt();virtual MStatus undoIt();virtual bool isUndoable() const;

private://graph modifier, used to support undo and redoMDagModifier dagMod;

};

• Implementation (except doIt)

void *MudBoxCommand::creator(){

return new MudBoxCommand;}MStatus MudBoxCommand::redoIt(){

//commit the work set in doItMStatus stat = dagMod.doIt();return(stat);

}MStatus MudBoxCommand::undoIt(){

//erase any work set in doItMStatus stat = dagMod.undoIt();return(stat);

}bool MudBoxCommand::isUndoable()

const {return(true);}

Page 14: Intro

doIt

• 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 examples (mud & joint extractor plugins, note the joint extract is a LOT simpler to script)

Page 15: Intro

(De)Register the Command

• Register commands in the initializePlugin procedure (from the required bit of code)

stat = plugin.registerCommand(

"makeMud",

MudBoxCommand::creator);

if (!stat) MGlobal::displayError("register MudBoxCommand failed");

• Deregister commands in the unitializePlugin procedure

stat = plugin.deregisterCommand("makeMud");

if (!stat) MGlobal::displayError("deregister MudBoxCommand failed");

Page 16: Intro

Topics

• Mud Plugin Introduction

• How to Create a MLL

• Command Basics

• Node Basics

Page 17: Intro

Example Node• Specification

class MudBoxNode : public MPxNode{public:

//identifierstatic MTypeId id;//attributesstatic MObject boxCenterX;…//creator functionstatic void *creator();//initializer for the nodestatic MStatus initialize();//computational function to do the real workvirtual MStatus compute (const MPlug &plug, MDataBlock &data);

private:…

};

• Implementation (except for compute)

void *MudBoxNode::creator(){

return new MudBoxNode;}MStatus MudBoxNode::initialize(){

//create the attributes for spacial subdivisionMFnNumericAttribute boxAttributes;boxCenterX = boxAttributes.create("boxCenterX", "bcx", MFnNumericData::kDouble, 0.0);...//add the attributes to the nodeaddAttribute(boxCenterX);...//specify attribute relationsattributeAffects(boxCenterX, boxData);...//return without errorreturn(MS::kSuccess);

}

Page 18: Intro

Compute• Where the actual work is done• See examples (mud plugin)

MStatus MudBoxNode::compute (const MPlug &plug, MDataBlock &data) { MStatus stat; //determine which output plug needs to be computed if (plug == boxData) { //get input data handles MDataHandle boxCenterXData = data.inputValue(boxCenterX); ... //turn input handles into data double bcx = boxCenterXData.asDouble(); ... //get output data handles MDataHandle outputBoxData = data.outputValue(boxData); //turn output handles into data <SNIP> //set the output data and mark the plug outputBoxData.set(ssbDataFn.object()); data.setClean(plug);} else //the plug is for an ancestor, return unknown stat = MS::kUnknownParameter; return(stat);}

Page 19: Intro

(De)Register the Node

• Register nodes in the initializePlugin procedure

stat = plugin.registerNode("MudBoxNode",MudBoxNode::id,&MudBoxNode::creator,&MudBoxNode::initialize,MPxNode::kDependNode

);if (!stat) MGlobal::displayError("register MudBoxNode failed");

• Deregister nodes in the uninitializePlugin procedure

stat = plugin.deregisterNode(MudBoxNode::id);if (!stat) MGlobal::displayError("deregister MudBoxNode failed");