- Main Page
- Related Pages
- Modules
- Classes
- Examples

# footPrintManip.cpp

    //-
    // ==========================================================================
    // Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved.
    //
    // Use of this software is subject to the terms of the Autodesk
    // license agreement provided at the time of installation or download,
    // or which otherwise accompanies this software in either electronic
    // or hard copy form.
    // ==========================================================================
    //+

    //
    // footPrintManip.cpp
    //
    // This plug-in demonstrates how to use the Show Manip Tool with
    // a user-defined manipulator.
    //
    // This is the script for running this plug-in:
    //
    // loadPlugin "footPrintManip.so";
    // createNode footPrintLocator -n f1;
    //
    // Now click on the showManipTool!
    //

    #include <maya/MIOStream.h>

    #include <maya/MPxNode.h>

    #include <maya/MPxLocatorNode.h>

    #include <maya/MString.h>
    #include <maya/MTypeId.h>
    #include <maya/MPlug.h>
    #include <maya/MVector.h>
    #include <maya/MDataBlock.h>
    #include <maya/MDataHandle.h>
    #include <maya/MColor.h>
    #include <maya/M3dView.h>
    #include <maya/MFnPlugin.h>
    #include <maya/MDistance.h>
    #include <maya/MFnUnitAttribute.h>

    #include <maya/MFn.h>
    #include <maya/MPxNode.h>
    #include <maya/MPxManipContainer.h>
    #include <maya/MFnDistanceManip.h>
    #include <maya/MPxContext.h>
    #include <maya/MPxSelectionContext.h>

    #include <maya/MFnNumericData.h>
    #include <maya/MManipData.h>

    // Foot Data
    //
    static float sole[][3] = { {  0.00f, 0.0f, -0.70f},
                               {  0.04f, 0.0f, -0.69f },
                               {  0.09f, 0.0f, -0.65f },
                               {  0.13f, 0.0f, -0.61f },
                               {  0.16f, 0.0f, -0.54f },
                               {  0.17f, 0.0f, -0.46f },
                               {  0.17f, 0.0f, -0.35f },
                               {  0.16f, 0.0f, -0.25f },
                               {  0.15f, 0.0f, -0.14f },
                               {  0.13f, 0.0f,  0.00f },
                               {  0.00f, 0.0f,  0.00f },
                               { -0.13f, 0.0f,  0.00f },
                               { -0.15f, 0.0f, -0.14f },
                               { -0.16f, 0.0f, -0.25f },
                               { -0.17f, 0.0f, -0.35f },
                               { -0.17f, 0.0f, -0.46f },
                               { -0.16f, 0.0f, -0.54f },
                               { -0.13f, 0.0f, -0.61f },
                               { -0.09f, 0.0f, -0.65f },
                               { -0.04f, 0.0f, -0.69f },
                               { -0.00f, 0.0f, -0.70f } };
    static float heel[][3] = { {  0.00f, 0.0f,  0.06f },
                               {  0.13f, 0.0f,  0.06f },
                               {  0.14f, 0.0f,  0.15f },
                               {  0.14f, 0.0f,  0.21f },
                               {  0.13f, 0.0f,  0.25f },
                               {  0.11f, 0.0f,  0.28f },
                               {  0.09f, 0.0f,  0.29f },
                               {  0.04f, 0.0f,  0.30f },
                               {  0.00f, 0.0f,  0.30f },
                               { -0.04f, 0.0f,  0.30f },
                               { -0.09f, 0.0f,  0.29f },
                               { -0.11f, 0.0f,  0.28f },
                               { -0.13f, 0.0f,  0.25f },
                               { -0.14f, 0.0f,  0.21f },
                               { -0.14f, 0.0f,  0.15f },
                               { -0.13f, 0.0f,  0.06f },
                               { -0.00f, 0.0f,  0.06f } };
    static int heelCount = 17;
    static int soleCount = 21;

    class footPrintLocatorManip : public MPxManipContainer
    {
    public:
        footPrintLocatorManip();
        virtual ~footPrintLocatorManip();

        static void * creator();
        static MStatus initialize();
        virtual MStatus createChildren();
        virtual MStatus connectToDependNode(const MObject & node);

        virtual void draw(M3dView & view,
                          const MDagPath & path,
                          M3dView::DisplayStyle style,
                          M3dView::DisplayStatus status);
        MManipData startPointCallback(unsigned index) const;
        MVector nodeTranslation() const;

        MDagPath fDistanceManip;
        MDagPath fNodePath;

    public:
        static MTypeId id;
    };

    MManipData footPrintLocatorManip::startPointCallback(unsigned index)
    const
    {
        MFnNumericData numData;
        MObject numDataObj = numData.create(MFnNumericData::k3Double);
        MVector vec = nodeTranslation();
        numData.setData(vec.x, vec.y, vec.z);
        return MManipData(numDataObj);
    }

    MVector footPrintLocatorManip::nodeTranslation() const
    {
        MFnDagNode dagFn(fNodePath);
        MDagPath path;
        dagFn.getPath(path);
        path.pop();  // pop from the shape to the transform
        MFnTransform transformFn(path);
        return transformFn.translation(MSpace::kWorld);
    }

    MTypeId footPrintLocatorManip::id( 0x8001b );

    footPrintLocatorManip::footPrintLocatorManip()
    {
        // Do not call createChildren from here
    }

    footPrintLocatorManip::~footPrintLocatorManip()
    {
    }

    void* footPrintLocatorManip::creator()
    {
         return new footPrintLocatorManip();
    }

    MStatus footPrintLocatorManip::initialize()
    {
        MStatus stat;
        stat = MPxManipContainer::initialize();
        return stat;
    }

    MStatus footPrintLocatorManip::createChildren()
    {
        MStatus stat = MStatus::kSuccess;

        MString manipName("distanceManip");
        MString distanceName("distance");

        MPoint startPoint(0.0, 0.0, 0.0);
        MVector direction(0.0, 1.0, 0.0);
        fDistanceManip = addDistanceManip(manipName,
                                          distanceName);
        MFnDistanceManip distanceManipFn(fDistanceManip);
        distanceManipFn.setStartPoint(startPoint);
        distanceManipFn.setDirection(direction);

        return stat;
    }

    MStatus footPrintLocatorManip::connectToDependNode(const MObject &node)
    {
        MStatus stat;

        // Get the DAG path
        //
        MFnDagNode dagNodeFn(node);
        dagNodeFn.getPath(fNodePath);

        // Connect the plugs
        //

        MFnDistanceManip distanceManipFn(fDistanceManip);
        MFnDependencyNode nodeFn(node);

        MPlug sizePlug = nodeFn.findPlug("size", &stat);
        if (MStatus::kFailure != stat) {
            distanceManipFn.connectToDistancePlug(sizePlug);
            unsigned startPointIndex = distanceManipFn.startPointIndex();
            addPlugToManipConversionCallback(startPointIndex,
                                             (plugToManipConversionCallback)
                                             &footPrintLocatorManip::startPointCallback);
            finishAddingManips();
            MPxManipContainer::connectToDependNode(node);
        }

        return stat;
    }

    void footPrintLocatorManip::draw(M3dView & view,
                                     const MDagPath &path,
                                     M3dView::DisplayStyle style,
                                     M3dView::DisplayStatus status)
    {
        MPxManipContainer::draw(view, path, style, status);
        view.beginGL();

        MPoint textPos = nodeTranslation();
        char str[100];
        sprintf(str, "Stretch Me!");
        MString distanceText(str);
        view.drawText(distanceText, textPos, M3dView::kLeft);

        view.endGL();
    }

    class footPrintLocator : public MPxLocatorNode
    {
    public:
        footPrintLocator();
        virtual ~footPrintLocator();

        virtual MStatus         compute(const MPlug& plug, MDataBlock &data);

        virtual void            draw(M3dView &view, const MDagPath &path,
                                     M3dView::DisplayStyle style,
                                     M3dView::DisplayStatus status);

        virtual bool            isBounded() const;
        virtual MBoundingBox    boundingBox() const;

        static  void *          creator();
        static  MStatus         initialize();

        static  MObject         size;         // The size of the foot

    public:
        static  MTypeId     id;
    };

    MTypeId footPrintLocator::id( 0x8001c );
    MObject footPrintLocator::size;

    footPrintLocator::footPrintLocator()
    {}

    footPrintLocator::~footPrintLocator()
    {}

    MStatus footPrintLocator::compute(const MPlug &plug, MDataBlock &data)
    {
        return MS::kUnknownParameter;
    }

    void footPrintLocator::draw(M3dView &view, const MDagPath &path,
                                M3dView::DisplayStyle style,
                                M3dView::DisplayStatus status)
    {
        // Get the size
        //
        MObject thisNode = thisMObject();
        MPlug plug(thisNode, size);
        MDistance sizeVal;
        plug.getValue(sizeVal);

        float multiplier = (float) sizeVal.asCentimeters();

        view.beginGL();

        if ((style == M3dView::kFlatShaded) ||
            (style == M3dView::kGouraudShaded))
        {
            // Push the color settings
            //
            glPushAttrib(GL_CURRENT_BIT);

            if (status == M3dView::kActive) {
                view.setDrawColor(13, M3dView::kActiveColors);
            } else {
                view.setDrawColor(13, M3dView::kDormantColors);
            }

            glBegin(GL_TRIANGLE_FAN);
                int i;
                int last = soleCount - 1;
                for (i = 0; i < last; ++i) {
                    glVertex3f(sole[i][0] * multiplier,
                               sole[i][1] * multiplier,
                               sole[i][2] * multiplier);
                }
            glEnd();
            glBegin(GL_TRIANGLE_FAN);
                last = heelCount - 1;
                for (i = 0; i < last; ++i) {
                    glVertex3f(heel[i][0] * multiplier,
                               heel[i][1] * multiplier,
                               heel[i][2] * multiplier);
                }
            glEnd();

            glPopAttrib();
        }

        // Draw the outline of the foot
        //
        glBegin(GL_LINES);
            int i;
            int last = soleCount - 1;
            for (i = 0; i < last; ++i) {
                glVertex3f(sole[i][0] * multiplier,
                           sole[i][1] * multiplier,
                           sole[i][2] * multiplier);
                glVertex3f(sole[i+1][0] * multiplier,
                           sole[i+1][1] * multiplier,
                           sole[i+1][2] * multiplier);
            }
            last = heelCount - 1;
            for (i = 0; i < last; ++i) {
                glVertex3f(heel[i][0] * multiplier,
                           heel[i][1] * multiplier,
                           heel[i][2] * multiplier);
                glVertex3f(heel[i+1][0] * multiplier,
                           heel[i+1][1] * multiplier,
                           heel[i+1][2] * multiplier);
            }
        glEnd();

        view.endGL();
    }

    bool footPrintLocator::isBounded() const
    {
        return true;
    }

    MBoundingBox footPrintLocator::boundingBox() const
    {
        // Get the size
        //
        MObject thisNode = thisMObject();
        MPlug plug(thisNode, size);
        MDistance sizeVal;
        plug.getValue(sizeVal);

        double multiplier = sizeVal.asCentimeters();

        MPoint corner1(-0.17, 0.0, -0.7);
        MPoint corner2(0.17, 0.0, 0.3);

        corner1 = corner1 * multiplier;
        corner2 = corner2 * multiplier;

        return MBoundingBox(corner1, corner2);
    }

    void* footPrintLocator::creator()
    {
        return new footPrintLocator();
    }

    MStatus footPrintLocator::initialize()
    {
        MFnUnitAttribute unitFn;
        MStatus          stat;

        size = unitFn.create("size", "sz", MFnUnitAttribute::kDistance);
        unitFn.setDefault(10.0);
        unitFn.setStorable(true);
        unitFn.setWritable(true);

        stat = addAttribute(size);
        if (!stat) {
            stat.perror("addAttribute");
            return stat;
        }

        MPxManipContainer::addToManipConnectTable(id);

        return MS::kSuccess;
    }

    MStatus initializePlugin(MObject obj)
    {
        MStatus status;
        MFnPlugin plugin(obj, PLUGIN_COMPANY, "3.0", "Any");

        status = plugin.registerNode("footPrintLocator",
                                     footPrintLocator::id,
                                     &footPrintLocator::creator,
                                     &footPrintLocator::initialize,
                                     MPxNode::kLocatorNode);
        if (!status) {
            status.perror("registerNode");
            return status;
        }

        status = plugin.registerNode("footPrintLocatorManip",
                                     footPrintLocatorManip::id,
                                     &footPrintLocatorManip::creator,
                                     &footPrintLocatorManip::initialize,
                                     MPxNode::kManipContainer);
        if (!status) {
            status.perror("registerNode");
            return status;
        }

        return status;
    }

    MStatus uninitializePlugin(MObject obj)
    {
        MStatus status;
        MFnPlugin plugin(obj);

        status = plugin.deregisterNode(footPrintLocator::id);
        if (!status) {
            status.perror("deregisterNode");
            return status;
        }

        status = plugin.deregisterNode(footPrintLocatorManip::id);
        if (!status) {
            status.perror("deregisterNode");
            return status;
        }

        return status;
    }