closestPointOnCurveCmd.cpp
#include "closestPointOnCurveCmd.h"
#include "closestTangentUAndDistance.h"
#include "closestPointOnCurveStrings.h"
closestPointOnCurveCommand::closestPointOnCurveCommand()
{
}
closestPointOnCurveCommand::~closestPointOnCurveCommand()
{
}
void *closestPointOnCurveCommand::creator()
{
return new closestPointOnCurveCommand;
}
MSyntax closestPointOnCurveCommand::newSyntax()
{
MSyntax syntax;
syntax.addFlag("-na", "-name", MSyntax::kString);
syntax.addFlag("-ip", "-inPosition", MSyntax::kDouble, MSyntax::kDouble, MSyntax::kDouble);
syntax.addFlag("-p", "-position");
syntax.addFlag("-nr", "-normal");
syntax.addFlag("-t", "-tangent");
syntax.addFlag("-u", "-paramU");
syntax.addFlag("-d", "-distance");
syntax.useSelectionAsDefault(true);
syntax.setObjectType(MSyntax::kSelectionList, 1, 1);
syntax.enableQuery(true);
syntax.enableEdit(false);
return syntax;
}
bool closestPointOnCurveCommand::isUndoable() const
{
return true;
}
MStatus closestPointOnCurveCommand::doIt(const MArgList& args)
{
MArgDatabase argData(syntax(), args);
queryFlagSet = argData.isQuery();
inPositionFlagSet = argData.isFlagSet("inPosition");
positionFlagSet = argData.isFlagSet("-position");
normalFlagSet = argData.isFlagSet("-normal");
tangentFlagSet = argData.isFlagSet("-tangent");
paramUFlagSet = argData.isFlagSet("-paramU");
distanceFlagSet = argData.isFlagSet("-distance");
if (argData.isFlagSet("-name"))
argData.getFlagArgument("-name", 0, closestPointOnCurveNodeName);
else
closestPointOnCurveNodeName = "";
if (inPositionFlagSet)
{
argData.getFlagArgument("-inPosition", 0, inPosition.x);
argData.getFlagArgument("-inPosition", 1, inPosition.y);
argData.getFlagArgument("-inPosition", 2, inPosition.z);
}
else
{
inPosition.x = 0.0;
inPosition.y = 0.0;
inPosition.z = 0.0;
}
argData.getObjects(sList);
return redoIt();
}
MStatus closestPointOnCurveCommand::redoIt()
{
if (sList.length() == 0)
{
MStatus stat;
MString msg = MStringResource::getString(kNoValidObject, stat);
displayError(msg);
return MStatus::kFailure;
}
MDagPath curveDagPath;
sList.getDagPath(0, curveDagPath);
if (!curveDagPath.node().hasFn(MFn::kNurbsCurve) && !(curveDagPath.node().hasFn(MFn::kTransform) && curveDagPath.hasFn(MFn::kNurbsCurve)))
{
MStatus stat;
MString msg;
MString msgFmt = MStringResource::getString(kInvalidType, stat);
MStringArray selectionStrings;
sList.getSelectionStrings(0, selectionStrings);
msg.format(msgFmt, selectionStrings[0]);
displayError(msg);
return MStatus::kFailure;
}
if (!queryFlagSet)
{
MFnDependencyNode depNodeFn;
if (closestPointOnCurveNodeName == "")
depNodeFn.create("closestPointOnCurve");
else
depNodeFn.create("closestPointOnCurve", closestPointOnCurveNodeName);
closestPointOnCurveNodeName = depNodeFn.name();
if (inPositionFlagSet)
{
MPlug inPositionXPlug = depNodeFn.findPlug("inPositionX");
inPositionXPlug.setValue(inPosition.x);
MPlug inPositionYPlug = depNodeFn.findPlug("inPositionY");
inPositionYPlug.setValue(inPosition.y);
MPlug inPositionZPlug = depNodeFn.findPlug("inPositionZ");
inPositionZPlug.setValue(inPosition.z);
}
unsigned instanceNumber=0;
if (curveDagPath.node().hasFn(MFn::kTransform))
{
curveDagPath.extendToShape();
instanceNumber = curveDagPath.instanceNumber();
}
MPlug worldCurvePlug, inCurvePlug;
inCurvePlug = depNodeFn.findPlug("inCurve");
depNodeFn.setObject(curveDagPath.node());
worldCurvePlug = depNodeFn.findPlug("worldSpace");
worldCurvePlug = worldCurvePlug.elementByLogicalIndex(instanceNumber);
MDGModifier dgModifier;
dgModifier.connect(worldCurvePlug, inCurvePlug);
dgModifier.doIt();
setResult(closestPointOnCurveNodeName);
return MStatus::kSuccess;
}
else
{
MPoint position;
MVector normal, tangent;
double paramU, distance;
closestTangentUAndDistance(curveDagPath, inPosition, position, normal, tangent, paramU, distance);
if (!positionFlagSet && !normalFlagSet && !tangentFlagSet && !paramUFlagSet && !distanceFlagSet)
{
MStatus stat;
MString msg = MStringResource::getString(kNoQueryFlag, stat);
displayError(msg);
return MStatus::kFailure;
}
else if (distanceFlagSet && !(positionFlagSet || normalFlagSet || tangentFlagSet || paramUFlagSet))
setResult(distance);
else if (paramUFlagSet && !(positionFlagSet || normalFlagSet || tangentFlagSet || distanceFlagSet))
setResult(paramU);
else
{
MDoubleArray floatArrayResult;
if (positionFlagSet)
{
floatArrayResult.append(position.x);
floatArrayResult.append(position.y);
floatArrayResult.append(position.z);
}
if (normalFlagSet)
{
floatArrayResult.append(normal.x);
floatArrayResult.append(normal.y);
floatArrayResult.append(normal.z);
}
if (tangentFlagSet)
{
floatArrayResult.append(tangent.x);
floatArrayResult.append(tangent.y);
floatArrayResult.append(tangent.z);
}
if (paramUFlagSet)
floatArrayResult.append(paramU);
if (distanceFlagSet)
floatArrayResult.append(distance);
setResult(floatArrayResult);
}
return MStatus::kSuccess;
}
}
MStatus closestPointOnCurveCommand::undoIt()
{
if (!queryFlagSet)
{
MString deleteCmd = "delete ";
deleteCmd += closestPointOnCurveNodeName;
MGlobal::executeCommand(deleteCmd);
}
return MStatus::kSuccess;
}