#include <stdio.h>
#include <maya/MIOStream.h>
#include <math.h>
#include <maya/MString.h>
#include <maya/MArgList.h>
#include <maya/MEvent.h>
#include <maya/MGlobal.h>
#include <maya/M3dView.h>
#include <maya/MPoint.h>
#include <maya/MPointArray.h>
#include <maya/MDoubleArray.h>
#include <maya/MDagPath.h>
#include <maya/MPxContext.h>
#include <maya/MPxContextCommand.h>
#include <maya/MPxToolCommand.h>
#include <maya/MToolsInfo.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnNurbsCurve.h>
#include <maya/MSyntax.h>
#include <maya/MArgParser.h>
#include <maya/MArgDatabase.h>
#include <maya/MCursor.h>
#include <maya/MGL.h>
#define kPitchFlag "-p"
#define kPitchFlagLong "-pitch"
#define kRadiusFlag "-r"
#define kRadiusFlagLong "-radius"
#define kNumberCVsFlag "-ncv"
#define kNumberCVsFlagLong "-numCVs"
#define kUpsideDownFlag "-ud"
#define kUpsideDownFlagLong "-upsideDown"
#define NUMBER_OF_CVS 20
{
public:
helixTool();
~helixTool() override;
static void* creator();
void setRadius(double newRadius);
void setPitch(double newPitch);
void setNumCVs(unsigned newNumCVs);
void setUpsideDown(bool newUpsideDown);
private:
double radius;
double pitch;
unsigned numCV;
bool upDown;
};
void* helixTool::creator()
{
return new helixTool;
}
helixTool::~helixTool() {}
helixTool::helixTool()
{
numCV = 20;
upDown = false;
setCommandString("helixToolCmd");
}
{
return syntax;
}
{
status = parseArgs(args);
if (MS::kSuccess != status)
return status;
return redoIt();
}
{
if (argData.isFlagSet(kPitchFlag)) {
double tmp;
status = argData.getFlagArgument(kPitchFlag, 0, tmp);
if (!status) {
status.
perror(
"pitch flag parsing failed");
return status;
}
pitch = tmp;
}
if (argData.isFlagSet(kRadiusFlag)) {
double tmp;
status = argData.getFlagArgument(kRadiusFlag, 0, tmp);
if (!status) {
status.
perror(
"radius flag parsing failed");
return status;
}
radius = tmp;
}
if (argData.isFlagSet(kNumberCVsFlag)) {
unsigned tmp;
status = argData.getFlagArgument(kNumberCVsFlag, 0, tmp);
if (!status) {
status.
perror(
"numCVs flag parsing failed");
return status;
}
numCV = tmp;
}
if (argData.isFlagSet(kUpsideDownFlag)) {
bool tmp;
status = argData.getFlagArgument(kUpsideDownFlag, 0, tmp);
if (!status) {
status.
perror(
"upside down flag parsing failed");
return status;
}
upDown = tmp;
}
return MS::kSuccess;
}
{
const unsigned deg = 3;
const unsigned ncvs = numCV;
const unsigned spans = ncvs - deg;
const unsigned nknots = spans+2*deg-1;
unsigned i;
int upFactor;
if (upDown) upFactor = -1;
else upFactor = 1;
for (i = 0; i < ncvs; i++)
upFactor * pitch * (double) i,
radius * sin((double) i)));
for (i = 0; i < nknots; i++)
knotSequences.
append((
double) i);
curveFn.
create(controlVertices, knotSequences, deg,
if (!stat) {
stat.
perror(
"Error creating curve");
return stat;
}
return stat;
}
{
MObject transform = path.transform();
return stat;
}
bool helixTool::isUndoable() const
{
return true;
}
{
command.
addArg(commandString());
}
void helixTool::setRadius(double newRadius)
{
radius = newRadius;
}
void helixTool::setPitch(double newPitch)
{
pitch = newPitch;
}
void helixTool::setNumCVs(unsigned newNumCVs)
{
numCV = newNumCVs;
}
void helixTool::setUpsideDown(bool newUpsideDown)
{
upDown = newUpsideDown;
}
const char helpString[] = "Click and drag to draw helix";
{
public:
helixContext();
void setNumCVs(unsigned newNumCVs);
void setUpsideDown(bool newUpsideDown);
unsigned numCVs();
bool upsideDown();
private:
void drawGuide();
bool firstDraw;
short startPos_x, startPos_y;
short endPos_x, endPos_y;
unsigned numCV;
bool upDown;
GLdouble height,radius;
};
helixContext::helixContext()
{
numCV = 20;
upDown = false;
setTitleString("Helix Tool");
}
void helixContext::toolOnSetup(
MEvent &)
{
setHelpString(helpString);
}
{
event.getPosition(startPos_x, startPos_y);
firstDraw = true;
return MS::kSuccess;
}
void helixContext::drawGuide()
{
int upFactor;
if (upDown) upFactor = 1;
else upFactor = -1;
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glRotatef(upFactor*90.0f, 1.0f, 0.0f, 0.0f);
GLUquadricObj *qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, GLU_LINE);
GLdouble factor = (GLdouble)numCV;
radius = double(abs(endPos_x - startPos_x))/factor + 0.1;
height = double(abs(endPos_y - startPos_y))/factor + 0.1;
gluCylinder( qobj, radius, radius, height, 8, 1 );
glPopMatrix();
}
{
view.beginXorDrawing(false);
if (!firstDraw) {
drawGuide();
} else {
firstDraw = false;
}
event.getPosition(endPos_x, endPos_y);
drawGuide();
view.endXorDrawing();
return MS::kSuccess;
}
{
if (!firstDraw) {
view.beginXorDrawing(false);
drawGuide();
view.endXorDrawing();
}
helixTool * cmd = (helixTool*)newToolCommand();
cmd->setPitch( height/numCV );
cmd->setRadius( radius );
cmd->setNumCVs( numCV );
cmd->setUpsideDown( upDown );
cmd->redoIt();
cmd->finalize();
return MS::kSuccess;
}
{
return setHelpString( helpString );
}
void helixContext::getClassName(
MString & name )
const
{
}
void helixContext::setNumCVs( unsigned newNumCVs )
{
numCV = newNumCVs;
}
void helixContext::setUpsideDown( bool newUpsideDown )
{
upDown = newUpsideDown;
}
unsigned helixContext::numCVs()
{
return numCV;
}
bool helixContext::upsideDown()
{
return upDown;
}
{
public:
helixContextCmd();
static void* creator();
protected:
helixContext* fHelixContext;
};
helixContextCmd::helixContextCmd() {}
{
fHelixContext = new helixContext();
return fHelixContext;
}
void* helixContextCmd::creator()
{
return new helixContextCmd;
}
MStatus helixContextCmd::doEditFlags()
{
unsigned numCVs;
if (!status) {
status.
perror(
"numCVs flag parsing failed.");
return status;
}
fHelixContext->setNumCVs(numCVs);
}
bool upsideDown;
if (!status) {
status.
perror(
"upsideDown flag parsing failed.");
return status;
}
fHelixContext->setUpsideDown(upsideDown);
}
return MS::kSuccess;
}
MStatus helixContextCmd::doQueryFlags()
{
setResult((int) fHelixContext->numCVs());
}
setResult(fHelixContext->upsideDown());
}
return MS::kSuccess;
}
MStatus helixContextCmd::appendSyntax()
{
if (MS::kSuccess != mySyntax.
addFlag(kNumberCVsFlag, kNumberCVsFlagLong,
return MS::kFailure;
}
if (MS::kSuccess !=
mySyntax.
addFlag(kUpsideDownFlag, kUpsideDownFlagLong,
return MS::kFailure;
}
return MS::kSuccess;
}
{
MFnPlugin plugin(obj, PLUGIN_COMPANY,
"3.0",
"Any");
status = plugin.registerContextCommand("helixToolContext",
helixContextCmd::creator,
"helixToolCmd",
helixTool::creator,
helixTool::newSyntax);
if (!status) {
status.
perror(
"registerContextCommand");
return status;
}
return status;
}
{
status = plugin.deregisterContextCommand( "helixToolContext",
"helixToolCmd" );
if (!status) {
status.
perror(
"deregisterContextCommand");
return status;
}
return status;
}