Important plug-in features

 
 
 

The "Hello World" plug-in introduces a number of important features, outlined below.

MSimple.h

A special header file used for simple command plug-ins. It takes care of all the work necessary to register the new command with Maya through the DeclareSimpleCommand macro. However, you can only create a plug-in that contains a single command.

Note
  • It is quite possible, and even common, to write a plug-in that implements several features, such as dependency graph nodes and commands. For such plug-ins, MSimple.h cannot be used. You must write custom registration code to tell Maya the plug-ins’ capabilities.
  • A major limitation of this macro is that you can only create non-undoable commands. The following sections describe this limitation in detail.

MStatus

Indicates the success or failure of a method. Most methods in API classes return a status code through MStatus and the documentation for each method details the possible status codes returned. To avoid possible name space collisions with other status codes, all MStatus values are scoped with "MS". For example, MS::kSuccess is the success status code. The complete list is in MStatus.h.

Note

API uses few status codes, but if error logging is enabled in the API through MGlobal::startErrorLogging() additional detailed error messages are output to the error log file when a method returns something other than MS::kSuccess. This is described in more detail in Error checking, MStatus class, and Error logging in this chapter.

DeclareSimpleCommand

The DeclareSimpleCommand macro requires three parameters: the name of a class that will be used to implement the command, the name of the vendor (or author) of the command, and the command’s version number.

As in MSimple.h, the DeclareSimpleCommand() macro saves you from writing the registration code necessary for Maya to properly recognize your file as a plug-in. To keep it simple, though, you cannot specify an undo method for the command, so you cannot create truly undoable commands using this macro.

Note

Commands that do not support undo must not change the state of the scene in any way. They can be used to query different aspects of the scene, but not to change anything. If an non-undoable command does in fact change anything, Maya’s undo capability will break.

Writing a plug-in that interacts with Maya

There are only a few changes between this plug-in and the Hello World plug-in (see Writing your first plug-in. Since the "helloWorld" plug-in always prints the same thing, you may want to write a plug-in that interacts with Maya. (One way is through command line arguments in MEL)).

The following is another simple program which prints "Hello" followed by its input.

#include <maya/MSimple.h>
#include <maya/MIOStream.h>
DeclareSimpleCommand( hello, "Autodesk", "2013");
MStatus hello::doIt( const MArgList& args )
{
    cout << "Hello " << args.asString( 0 ).asChar() << endl;
    return MS::kSuccess;
}

This is put in a file called hello.cpp and compiled. Once loaded, typing "hello neighbor" into the command window outputs "Hello neighbor".

MArgList

The MArgList class provides functionality similar to the argc/argv parameters of the entry point of a C or C++ program, which provides a list of arguments to your function. The class provides methods to retrieve the arguments as various types, such as including an integer, a double, a string, or a vector.

In the next example, the helix command is defined to allow several arguments to be passed in via the MArgList object. The two arguments are pitch and radius.

#include <math.h>
#include <maya/MSimple.h>
#include <maya/MIOStream.h>
#include <maya/MFnNurbsCurve.h>
#include <maya/MPointArray.h>
#include <maya/MDoubleArray.h>
#include <maya/MPoint.h>
DeclareSimpleCommand( helix, "Autodesk - Example", "3.0");
MStatus helix::doIt( const MArgList& args )
{
    MStatus stat;
    const unsigned	deg 	= 3;			// Curve Degree
    const unsigned	ncvs 	= 20;			// Number of CVs
    const unsigned	spans 	= ncvs - deg;	// Number of spans
    const unsigned	nknots	= spans+2*deg-1;// Number of knots
    double	radius			= 4.0;			// Helix radius
    double	pitch 			= 0.5;			// Helix pitch
    unsigned	i;
    // Parse the arguments.
    for ( i = 0; i < args.length(); i++ )
        if ( MString( "-p" ) == args.asString( i, &stat )
            && MS::kSuccess == stat)
        {
            double tmp = args.asDouble( ++i, &stat );
            if ( MS::kSuccess == stat )
                pitch = tmp;
        }
        else if ( MString( "-r" ) == args.asString( i, &stat )
            && MS::kSuccess == stat)
        {
            double tmp = args.asDouble( ++i, &stat );
            if ( MS::kSuccess == stat )
                radius = tmp;
        }
    MPointArray	 controlVertices;
    MDoubleArray knotSequences;
    // Set up cvs and knots for the helix
    //
    for (i = 0; i < ncvs; i++)
        controlVertices.append( MPoint( radius * cos( (double)i ),
        pitch * (double)i, radius * sin( (double)i ) ) );
    for (i = 0; i < nknots; i++)
        knotSequences.append( (double)i );
    // Now create the curve
    //
    MFnNurbsCurve curveFn;
    MObject curve = curveFn.create( controlVertices,
        knotSequences, deg, 
        MFnNurbsCurve::kOpen, 
        false, false, 
        MObject::kNullObj, 
        &stat );
    if ( MS::kSuccess != stat )
        cout << "Error creating curve.\n";
    return stat;
}
Tip

One important difference between using argc/argv and an MArgList is that the zeroth element of an MArgList is the first argument to the command and not the command name, as in a C or C++ program.

Building a curve using a plug-in

The following is a plug-in that builds a helical curve. See Appendix A: NURBS Geometry for a brief explanation of NURBS geometry.

#include <math.h>
#include <maya/MIOStream.h>
#include <maya/MSimple.h>
#include <maya/MPoint.h>
#include <maya/MPointArray.h>
#include <maya/MDoubleArray.h>
#include <maya/MFnNurbsCurve.h>
DeclareSimpleCommand( doHelix, "Autodesk - Example", "2013");
MStatus doHelix::doIt( const MArgList& )
{
    MStatus stat;
    const unsigned deg = 3; // Curve Degree
    const unsigned ncvs = 20; // Number of CVs
    const unsigned spans = ncvs - deg; // Number of spans
    const unsigned nknots = spans+2*deg-1; // Number of knots
    double radius = 4.0; // Helix radius
    double pitch = 0.5; // Helix pitch
    unsigned i;
    MPointArray controlVertices;
    MDoubleArray knotSequences;
    // Set up cvs and knots for the helix
    //
    for (i = 0; i < ncvs; i++)
        controlVertices.append( MPoint( radius * cos( (double)i ),
        pitch * (double)i, radius * sin( (double)i ) ) );
    for (i = 0; i < nknots; i++)
        knotSequences.append( (double)i );
    // Now create the curve
    //
    MFnNurbsCurve curveFn;
    MObject curve = curveFn.create( controlVertices,
        knotSequences, deg, MFnNurbsCurve::kOpen, false, false, MObject::kNullObj, &stat );
    if ( MS::kSuccess != stat )
        cout << "Error creating curve.\n";
    return stat;
}

Compile this plug-in, load it, then enter "doHelix" at the prompt. A helical curve displays in the Maya views.