The goal of writing a shape is to take a geometry class you defined and integrate that geometry into Maya in the form of a DAG object.
It is a good idea to keep geometry-specific information in your geometry class. This way it will be easier to represent the geometry as dependency graph data. Keeping geometry specific information in your geometry class will also make it easier to handle drawing as you will have to pass geometry-specific drawing information onto Maya’s draw request queue as draw data.
User-defined shapes are more complex than DG nodes because of the additional drawing, selection, and component functionality. It is a good idea to start by designing the shape node before writing any code. This involves defining your input and output attributes and determining the relationships (or affects) between those attributes.
The simplest shape is one without components or geometry data—for example, a sphere shape that takes an input radius and perhaps x and y divisions and from this computes the geometry for a sphere to draw in OpenGL.
It is also a good idea to write your shape in stages. The first step is to derive from MPxSurfaceShape and MPxSurfaceShapeUI. Writing the MPxSurfaceShape class is the same as writing any MPxNode class. The additional virtual functions can be overridden as the functionality is needed.
For more information about how to create a user-defined shape, see the article at http://around-the-corner.typepad.com/adn/2012/09/custom-shapes-in-the-maya-api-1.html. This article explains the process of creating a user-defined shape along with some example plug-ins.
Registering shapes with Maya is similar to registering DG nodes. The only difference is that shapes have a separate UI class that must be registered with the shape node. The MFnPlugin::resgisterShape function is used for shape registration. Deregistering a shape is exactly the same as deregistering a node. Here is an example of shape registration:
MStatus initializePlugin( MObject obj ) { MFnPlugin plugin( obj,"Autodesk","2.0", "Any"); return plugin.registerShape( "yourShape", yourShape::id, &yourShape::creator, &yourShape::initialize, &yourShapeUI::creator ); } MStatus uninitializePlugin( MObject obj ) { return plugin.deregisterNode( yourShape::id ); }