Connect Manipulators to the Show Manipulator Tool

 
 
 

The Show Manipulator Tool uses manipulators to modify plug values or provide access to the construction history of a node. If you select several objects while in the Show Manipulator Tool, the corresponding manipulator is displayed for each of the objects selected.

The object that the manipulator is attached to does not have to be a DAG node. Some manipulators such as the Revolve manipulator are attached to a dependency node upstream of the final shape. For example, for a sphere called nurbsSphereShape1, the revolve manipulator must be attached to the makeNurbsSphere1 node which is upstream relative to nurbsSphereShape1.

Note The makeNurbsSphere1 node is not a DAG node, and can be selected either in the Hypergraph or the Channel Box.

Other manipulators, such as the camera manipulator and the light manipulator can be attached to either the transform or the shape of the light or camera.

The Show Manipulator Tool is explained in detail in the Basics guide.

Writing a Manipulator to Work with the Show Manipulator Tool

The first step when creating a manipulator that works with the Show Manipulator Tool for a node is to pick a name for the manipulator that corresponds to the node type name. To determine the name of the manipulator, take the name of the node and append Manip to the end of the node name. For example, the Show Manip for footPrintLocator is footPrintLocatorManip.

plugin.registerNode("footPrintLocator", // name of node
                    footPrintLocator::id,
                    &footPrintLocator::creator,
                    &footPrintLocator::initialize,
                    MPxNode::kLocatorNode);
plugin.registerNode("footPrintLocatorManip", // name of manip
                    footPrintLocatorManip::id,
                    &footPrintLocatorManip::creator,
                    &footPrintLocatorManip::initialize,
                    MPxNode::kManipContainer);

The second step is to have the initialize method of the node call MPxManipContainer::addToManipConnectTable(). For example, in the footPrintLocator::initialize() method:

MStatus footPrintLocator::initialize()
{
    ...
    MPxManipContainer::addToManipConnectTable(id);
    ...
}

Where id is defined and declared as:

class footPrintLocator : public MPxLocatorNode
{
    ...
    public:
        static MTypeId id;
};
MTypeId footPrintLocator::id(0x81101);

Adding the Manipulator to a Context

An alternative to invoking a manipulator by the Show Manipulator Tool is to invoke the manipulator from a user-defined context.

The MPxSelectionContext class has two methods to support the management of manipulators: addManipulator() and deleteManipulator().

In addition to using these two methods, MPxSelectionContext::toolOnSetup and MPxContext::toolOffCleanup must be overridden so that toolOnSetup adds a callback for manipulators, and toolOffCleanup removes the callback when the active list is modified.

The callback can be an updateManipulators() function which actually adds and deletes the manipulators.

For example:

MCallbackId id1;
void moveContext::toolOnSetup(MEvent &)
{
    ...
    id1 = ModelMessage::addCallback(
    MModelMessage::kActiveListModified,
    updateManipulators, this, &status);
    .... 
}
void moveContext::toolOffCleanup()
{
    ...
    status = MModelMessage::removeCallback(id1);
    ...
}
void updateManipulators(void * data)
{
    ...
    moveContext * ctxPtr = (moveContext *) data;
    ctxPtr->deleteManipulators();
    ...
    // for each object selected
    MString manipName("moveManip");
    MObject manipObject;
    ctxPtr->moveM = (moveManip *) 
        moveManip::newManipulator(manipName,
        manipObject);
    ...
    ctxPtr->addManipulator(manipObject);
    ...
    ctxPtr->moveM->connectToDependNode(dependNode);
    ...
}

Example Manipulators

Following are the manipulator examples that are available in the Maya installation (devkit\plug-ins) folder:

moveManip

The moveManip.cpp plug-in shows how to create a manipulator from a context. The user-defined manipulator in moveToolManip.cpp is called moveManip and consists of two base manipulators: a FreePointTriadManip and a DistanceManip.

footPrintManip

This plug-in example demonstrates how to use the Show Manipulator Tool with a user-defined node and a user-defined manipulator. The user-defined manipulator consists of a DistanceManip.

Note This manipulator uses a conversion function to place the DistanceManip at the location of the foot. Otherwise, the DistanceManip would appear at the origin.

customAttrManip

This plug-in demonstrates how to create user-defined manipulators on custom attributes of nodes within a user-defined context. This custom manipulator is composed of three DistanceManips.

moveManip

This plug-in shows how to create a manipulator from a context. The user-defined manipulator in moveToolManip.cpp is called moveManip and consists of two base manipulators: a FreePointTriadManip and a DistanceManip.

footPrintManip

This plug-in demonstrates how to use the Show Manipulator Tool with a user-defined node and a user-defined manipulator. The user-defined manipulator consists of a DistanceManip. It also demonstrates how to write plugToManip conversion callback functions so that DistanceManip is always following the location of the foot.

rotateManip

This plug-in demonstrates the different modes of the rotate base manipulator. The user-defined manipulator in rotateManip.cpp consists of a rotate base manipulator and a state base manipulator. The state manipulator is used to control the mode of the rotate manipulator: object mode, world space mode, gimbal mode, and object mode with snapping.

componentScaleManip

This plug-in demonstrates how to use the scale base manipulator and also demonstrates a method for manipulating components. The plug-in componentScaleManip.cpp consists of a scale base manipulator. The manipulator works by attaching manipToPlug conversion callbacks for every selected vertex. The conversion function computes the new vertex positions using stored initial vertex positions and the scale manipValue.

surfaceBumpManip

This plug-in demonstrates how the pointOnSurface base manipulator can be used to modify vertices close to the param manipValue. The plug-in uses a manipToPlug conversion function as a callback to update vertex positions on the NURBS surface.

Note Because this plug-in uses the manipToPlug conversion function as a callback that computes a dummy plug with the vertex positions updated independently, it does not support undo.

swissArmyManip

This plug-in demonstrates a user-defined manipulator that is comprised of a variety of base manipulators such as, CircleSweepManip, DirectionManip, DiscManip, DistanceManip, FreePointTriadManip, StateManip, ToggleManip, RotateManip, and ScaleManip.

lineManip

This example demonstrates how to use the MPxManipulatorNode class along with a command to create a user defined manipulator. The manipulator created is a simple line which is an OpenGL pickable component. As you move the pickable component, the scale attribute of the selected transforms are modified. The line's movements are restricted in a plane. A corresponding command is used to create and delete the manipulator node and to support undo, redo, and others.

squareScaleManip

This example demonstrates how to use the MPxManipulatorNode class along with a command to create a user-defined manipulator. The manipulator is a simple square with four sides as OpenGL pickable components. As you move the pickable component, the scale attribute of the selected transforms are modified. A corresponding command is used to create and delete the manipulator node and to support undo, redo, and others.