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

# closestPointOnCurveNode.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.
    // ==========================================================================
    //+

    // DISCLAIMER: THIS PLUGIN IS PROVIDED AS IS.  IT IS NOT SUPPORTED BY

    //            AUTODESK, SO PLEASE USE AND MODIFY AT YOUR OWN RISK.

    //

    // PLUGIN NAME: closestPointOnCurve v1.0

    // FILE: closestPointOnCurveNode.cpp

    // DESCRIPTION: -Defines "closestPointOnCurve" node.

    //              -Please see readme.txt for full details.

    // AUTHOR: QT

    // REFERENCES: -This plugin's concept is based off of the "closestPointOnSurface" node.

    //             -The MEL script AEclosestPointOnSurfaceTemplate.mel was referred to for

    //              the AE template MEL script that accompanies the closestPointOnCurve node.

    // LAST UPDATED: Oct. 13th, 2001.

    // COMPILED AND TESTED ON: Maya 4.0 on Windows

    // HEADER FILES:

    #include "closestPointOnCurveNode.h"

    #include "closestTangentUAndDistance.h"

    // DEFINE CLASS'S STATIC DATA MEMBERS:

    MTypeId closestPointOnCurveNode::id(0x00105482);

    MObject closestPointOnCurveNode::aInCurve;

    MObject closestPointOnCurveNode::aInPosition;

    MObject closestPointOnCurveNode::aInPositionX;

    MObject closestPointOnCurveNode::aInPositionY;

    MObject closestPointOnCurveNode::aInPositionZ;

    MObject closestPointOnCurveNode::aPosition;

    MObject closestPointOnCurveNode::aPositionX;

    MObject closestPointOnCurveNode::aPositionY;

    MObject closestPointOnCurveNode::aPositionZ;

    MObject closestPointOnCurveNode::aNormal;

    MObject closestPointOnCurveNode::aNormalX;

    MObject closestPointOnCurveNode::aNormalY;

    MObject closestPointOnCurveNode::aNormalZ;

    MObject closestPointOnCurveNode::aTangent;

    MObject closestPointOnCurveNode::aTangentX;

    MObject closestPointOnCurveNode::aTangentY;

    MObject closestPointOnCurveNode::aTangentZ;

    MObject closestPointOnCurveNode::aParamU;

    MObject closestPointOnCurveNode::aDistance;

    // CONSTRUCTOR DEFINITION:

    closestPointOnCurveNode::closestPointOnCurveNode()

    {

    }

    // DESTRUCTOR DEFINITION:

    closestPointOnCurveNode::~closestPointOnCurveNode()

    {

    }

    // FOR CREATING AN INSTANCE OF THIS NODE:

    void *closestPointOnCurveNode::creator()

    {

       return new closestPointOnCurveNode();

    }

    // INITIALIZES THE NODE BY CREATING ITS ATTRIBUTES:

    MStatus closestPointOnCurveNode::initialize()

    {

       // CREATE AND ADD ".inCurve" ATTRIBUTE:

       MFnTypedAttribute inCurveAttrFn;

       aInCurve = inCurveAttrFn.create("inCurve", "ic", MFnData::kNurbsCurve);

       inCurveAttrFn.setStorable(true);

       inCurveAttrFn.setKeyable(false);

       inCurveAttrFn.setReadable(true);

       inCurveAttrFn.setWritable(true);

       inCurveAttrFn.setCached(false);

       addAttribute(aInCurve);

       // CREATE AND ADD ".inPositionX" ATTRIBUTE:

       MFnNumericAttribute inPositionXAttrFn;

       aInPositionX = inPositionXAttrFn.create("inPositionX", "ipx", MFnNumericData::kDouble, 0.0);

       inPositionXAttrFn.setStorable(true);

       inPositionXAttrFn.setKeyable(true);

       inPositionXAttrFn.setReadable(true);

       inPositionXAttrFn.setWritable(true);

       addAttribute(aInPositionX);

       // CREATE AND ADD ".inPositionY" ATTRIBUTE:

       MFnNumericAttribute inPositionYAttrFn;

       aInPositionY = inPositionYAttrFn.create("inPositionY", "ipy", MFnNumericData::kDouble, 0.0);

       inPositionYAttrFn.setStorable(true);

       inPositionYAttrFn.setKeyable(true);

       inPositionYAttrFn.setReadable(true);

       inPositionYAttrFn.setWritable(true);

       addAttribute(aInPositionY);

       // CREATE AND ADD ".inPositionZ" ATTRIBUTE:

       MFnNumericAttribute inPositionZAttrFn;

       aInPositionZ = inPositionZAttrFn.create("inPositionZ", "ipz", MFnNumericData::kDouble, 0.0);

       inPositionZAttrFn.setStorable(true);

       inPositionZAttrFn.setKeyable(true);

       inPositionZAttrFn.setReadable(true);

       inPositionZAttrFn.setWritable(true);

       addAttribute(aInPositionZ);

       // CREATE AND ADD ".inPosition" ATTRIBUTE:

       MFnNumericAttribute inPositionAttrFn;

       aInPosition = inPositionAttrFn.create("inPosition", "ip", aInPositionX, aInPositionY, aInPositionZ);

       inPositionAttrFn.setStorable(true);

       inPositionAttrFn.setKeyable(true);

       inPositionAttrFn.setReadable(true);

       inPositionAttrFn.setWritable(true);

       addAttribute(aInPosition);

       // CREATE AND ADD ".positionX" ATTRIBUTE:

       MFnNumericAttribute pointXAttrFn;

       aPositionX = pointXAttrFn.create("positionX", "px", MFnNumericData::kDouble, 0.0);

       pointXAttrFn.setStorable(false);

       pointXAttrFn.setKeyable(false);

       pointXAttrFn.setReadable(true);

       pointXAttrFn.setWritable(false);

       addAttribute(aPositionX);

       // CREATE AND ADD ".positionY" ATTRIBUTE:

       MFnNumericAttribute pointYAttrFn;

       aPositionY = pointYAttrFn.create("positionY", "py", MFnNumericData::kDouble, 0.0);

       pointYAttrFn.setStorable(false);

       pointYAttrFn.setKeyable(false);

       pointYAttrFn.setReadable(true);

       pointYAttrFn.setWritable(false);

       addAttribute(aPositionY);

       // CREATE AND ADD ".positionZ" ATTRIBUTE:

       MFnNumericAttribute pointZAttrFn;

       aPositionZ = pointZAttrFn.create("positionZ", "pz", MFnNumericData::kDouble, 0.0);

       pointZAttrFn.setStorable(false);

       pointZAttrFn.setKeyable(false);

       pointZAttrFn.setReadable(true);

       pointZAttrFn.setWritable(false);

       addAttribute(aPositionZ);

       // CREATE AND ADD ".position" ATTRIBUTE:

       MFnNumericAttribute pointAttrFn;

       aPosition = pointAttrFn.create("position", "p", aPositionX, aPositionY, aPositionZ);

       pointAttrFn.setStorable(false);

       pointAttrFn.setKeyable(false);

       pointAttrFn.setReadable(true);

       pointAttrFn.setWritable(false);

       addAttribute(aPosition);

       // CREATE AND ADD ".normalX" ATTRIBUTE:

       MFnNumericAttribute normalXAttrFn;

       aNormalX = normalXAttrFn.create("normalX", "nx", MFnNumericData::kDouble, 0.0);

       normalXAttrFn.setStorable(false);

       normalXAttrFn.setKeyable(false);

       normalXAttrFn.setReadable(true);

       normalXAttrFn.setWritable(false);

       addAttribute(aNormalX);

       // CREATE AND ADD ".normalY" ATTRIBUTE:

       MFnNumericAttribute normalYAttrFn;

       aNormalY = normalYAttrFn.create("normalY", "ny", MFnNumericData::kDouble, 0.0);

       normalYAttrFn.setStorable(false);

       normalYAttrFn.setKeyable(false);

       normalYAttrFn.setReadable(true);

       normalYAttrFn.setWritable(false);

       addAttribute(aNormalY);

       // CREATE AND ADD ".normalZ" ATTRIBUTE:

       MFnNumericAttribute normalZAttrFn;

       aNormalZ = normalZAttrFn.create("normalZ", "nz", MFnNumericData::kDouble, 0.0);

       normalZAttrFn.setStorable(false);

       normalZAttrFn.setKeyable(false);

       normalZAttrFn.setReadable(true);

       normalZAttrFn.setWritable(false);

       addAttribute(aNormalZ);

       // CREATE AND ADD ".normal" ATTRIBUTE:

       MFnNumericAttribute normalAttrFn;

       aNormal = normalAttrFn.create("normal", "n", aNormalX, aNormalY, aNormalZ);

       normalAttrFn.setStorable(false);

       normalAttrFn.setKeyable(false);

       normalAttrFn.setReadable(true);

       normalAttrFn.setWritable(false);

       addAttribute(aNormal);

       // CREATE AND ADD ".tangentX" ATTRIBUTE:

       MFnNumericAttribute tangentXAttrFn;

       aTangentX = tangentXAttrFn.create("tangentX", "tx", MFnNumericData::kDouble, 0.0);

       tangentXAttrFn.setStorable(false);

       tangentXAttrFn.setKeyable(false);

       tangentXAttrFn.setReadable(true);

       tangentXAttrFn.setWritable(false);

       addAttribute(aTangentX);

       // CREATE AND ADD ".tangentY" ATTRIBUTE:

       MFnNumericAttribute tangentYAttrFn;

       aTangentY = tangentYAttrFn.create("tangentY", "ty", MFnNumericData::kDouble, 0.0);

       tangentYAttrFn.setStorable(false);

       tangentYAttrFn.setKeyable(false);

       tangentYAttrFn.setReadable(true);

       tangentYAttrFn.setWritable(false);

       addAttribute(aTangentY);

       // CREATE AND ADD ".tangentZ" ATTRIBUTE:

       MFnNumericAttribute tangentZAttrFn;

       aTangentZ = tangentZAttrFn.create("tangentZ", "tz", MFnNumericData::kDouble, 0.0);

       tangentZAttrFn.setStorable(false);

       tangentZAttrFn.setKeyable(false);

       tangentZAttrFn.setReadable(true);

       tangentZAttrFn.setWritable(false);

       addAttribute(aTangentZ);

       // CREATE AND ADD ".tangent" ATTRIBUTE:

       MFnNumericAttribute tangentAttrFn;

       aTangent = tangentAttrFn.create("tangent", "t", aTangentX, aTangentY, aTangentZ);

       tangentAttrFn.setStorable(false);

       tangentAttrFn.setKeyable(false);

       tangentAttrFn.setReadable(true);

       tangentAttrFn.setWritable(false);

       addAttribute(aTangent);

       // CREATE AND ADD ".parameU" ATTRIBUTE:

       MFnNumericAttribute paramUAttrFn;

       aParamU = paramUAttrFn.create("paramU", "u", MFnNumericData::kDouble, 0.0);

       paramUAttrFn.setStorable(false);

       paramUAttrFn.setKeyable(false);

       paramUAttrFn.setReadable(true);

       paramUAttrFn.setWritable(false);

       addAttribute(aParamU);

       // CREATE AND ADD ".distance" ATTRIBUTE:

       MFnNumericAttribute distanceAttrFn;

       aDistance = distanceAttrFn.create("distance", "d", MFnNumericData::kDouble, 0.0);

       distanceAttrFn.setStorable(false);

       distanceAttrFn.setKeyable(false);

       distanceAttrFn.setReadable(true);

       distanceAttrFn.setWritable(false);

       addAttribute(aDistance);

       // DEPENDENCY RELATIONS FOR ".inCurve":

       attributeAffects(aInCurve, aPosition);

       attributeAffects(aInCurve, aPositionX);

       attributeAffects(aInCurve, aPositionY);

       attributeAffects(aInCurve, aPositionZ);

       attributeAffects(aInCurve, aNormal);

       attributeAffects(aInCurve, aNormalX);

       attributeAffects(aInCurve, aNormalY);

       attributeAffects(aInCurve, aNormalZ);

       attributeAffects(aInCurve, aTangent);

       attributeAffects(aInCurve, aTangentX);

       attributeAffects(aInCurve, aTangentY);

       attributeAffects(aInCurve, aTangentZ);

       attributeAffects(aInCurve, aParamU);

       attributeAffects(aInCurve, aDistance);

       // DEPENDENCY RELATIONS FOR ".inPosition":

       attributeAffects(aInPosition, aPosition);

       attributeAffects(aInPosition, aPositionX);

       attributeAffects(aInPosition, aPositionY);

       attributeAffects(aInPosition, aPositionZ);

       attributeAffects(aInPosition, aNormal);

       attributeAffects(aInPosition, aNormalX);

       attributeAffects(aInPosition, aNormalY);

       attributeAffects(aInPosition, aNormalZ);

       attributeAffects(aInPosition, aTangent);

       attributeAffects(aInPosition, aTangentX);

       attributeAffects(aInPosition, aTangentY);

       attributeAffects(aInPosition, aTangentZ);

       attributeAffects(aInPosition, aParamU);

       attributeAffects(aInPosition, aDistance);

       // DEPENDENCY RELATIONS FOR ".inPositionX":

       attributeAffects(aInPositionX, aPosition);

       attributeAffects(aInPositionX, aPositionX);

       attributeAffects(aInPositionX, aPositionY);

       attributeAffects(aInPositionX, aPositionZ);

       attributeAffects(aInPositionX, aNormal);

       attributeAffects(aInPositionX, aNormalX);

       attributeAffects(aInPositionX, aNormalY);

       attributeAffects(aInPositionX, aNormalZ);

       attributeAffects(aInPositionX, aTangent);

       attributeAffects(aInPositionX, aTangentX);

       attributeAffects(aInPositionX, aTangentY);

       attributeAffects(aInPositionX, aTangentZ);

       attributeAffects(aInPositionX, aParamU);

       attributeAffects(aInPositionX, aDistance);

       // DEPENDENCY RELATIONS FOR ".inPositionY":

       attributeAffects(aInPositionY, aPosition);

       attributeAffects(aInPositionY, aPositionX);

       attributeAffects(aInPositionY, aPositionY);

       attributeAffects(aInPositionY, aPositionZ);

       attributeAffects(aInPositionY, aNormal);

       attributeAffects(aInPositionY, aNormalX);

       attributeAffects(aInPositionY, aNormalY);

       attributeAffects(aInPositionY, aNormalZ);

       attributeAffects(aInPositionY, aTangent);

       attributeAffects(aInPositionY, aTangentX);

       attributeAffects(aInPositionY, aTangentY);

       attributeAffects(aInPositionY, aTangentZ);

       attributeAffects(aInPositionY, aParamU);

       attributeAffects(aInPositionY, aDistance);

       // DEPENDENCY RELATIONS FOR ".inPositionZ":

       attributeAffects(aInPositionZ, aPosition);

       attributeAffects(aInPositionZ, aPositionX);

       attributeAffects(aInPositionZ, aPositionY);

       attributeAffects(aInPositionZ, aPositionZ);

       attributeAffects(aInPositionZ, aNormal);

       attributeAffects(aInPositionZ, aNormalX);

       attributeAffects(aInPositionZ, aNormalY);

       attributeAffects(aInPositionZ, aNormalZ);

       attributeAffects(aInPositionZ, aTangent);

       attributeAffects(aInPositionZ, aTangentX);

       attributeAffects(aInPositionZ, aTangentY);

       attributeAffects(aInPositionZ, aTangentZ);

       attributeAffects(aInPositionZ, aParamU);

       attributeAffects(aInPositionZ, aDistance);

       return MS::kSuccess;

    }

    // COMPUTE METHOD'S DEFINITION:

    MStatus closestPointOnCurveNode::compute(const MPlug &plug, MDataBlock &data)

    {

       // DO THE COMPUTE ONLY FOR THE *OUTPUT* PLUGS THAT ARE DIRTIED:

       if ((plug == aPosition)  || (plug == aPositionX)  || (plug == aPositionY)  || (plug == aPositionZ)

        || (plug == aNormal) || (plug == aNormalX) || (plug == aNormalY) || (plug == aNormalZ)

        || (plug == aTangent) || (plug == aTangentX) || (plug == aTangentY) || (plug == aTangentZ)

        || (plug == aParamU) || (plug == aDistance))

       {

          // READ IN ".inCurve" DATA:

          MDataHandle inCurveDataHandle = data.inputValue(aInCurve);

          MObject inCurve = inCurveDataHandle.asNurbsCurve();

          // READ IN ".inPositionX" DATA:

          MDataHandle inPositionXDataHandle = data.inputValue(aInPositionX);

          double inPositionX = inPositionXDataHandle.asDouble();

          // READ IN ".inPositionY" DATA:

          MDataHandle inPositionYDataHandle = data.inputValue(aInPositionY);

          double inPositionY = inPositionYDataHandle.asDouble();

          // READ IN ".inPositionZ" DATA:

          MDataHandle inPositionZDataHandle = data.inputValue(aInPositionZ);

          double inPositionZ = inPositionZDataHandle.asDouble();

          // GET THE CLOSEST POSITION, NORMAL, TANGENT, PARAMETER-U AND DISTANCE:

          MPoint inPosition(inPositionX, inPositionY, inPositionZ), position;

          MVector normal, tangent;

          double paramU, distance;

          MDagPath dummyDagPath;

          closestTangentUAndDistance(dummyDagPath, inPosition, position, normal, tangent, paramU, distance, inCurve);

          // WRITE OUT ".position" DATA:

          MDataHandle positionDataHandle = data.outputValue(aPosition);

          positionDataHandle.set(position.x, position.y, position.z);

          data.setClean(plug);

          // WRITE OUT ".normal" DATA:

          MDataHandle normalDataHandle = data.outputValue(aNormal);

          normalDataHandle.set(normal.x, normal.y, normal.z);

          data.setClean(plug);

          // WRITE OUT ".tangent" DATA:

          MDataHandle tangentDataHandle = data.outputValue(aTangent);

          tangentDataHandle.set(tangent.x, tangent.y, tangent.z);

          data.setClean(plug);

          // WRITE OUT ".paramU" DATA:

          MDataHandle paramUDataHandle = data.outputValue(aParamU);

          paramUDataHandle.set(paramU);

          data.setClean(plug);

          // WRITE OUT ".distance" DATA:

          MDataHandle distanceDataHandle = data.outputValue(aDistance);

          distanceDataHandle.set(distance);

          data.setClean(plug);

       }

       else

       {

          return MS::kUnknownParameter;

       }

       return MS::kSuccess;

    }