API Guide > Manipulators >

# Connect manipulators to the Show Manipulator Tool

The Show Manipulator Tool uses Maya 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 displays 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

makeNurbsSphere1 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 given 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 class MPxSelectionContext has two methods to support the management of manipulators: addManipulator and deleteManipulator.

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

The callback would 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

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.

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

The surfaceBumpManip plug-in example 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

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