simpleLoftNode.cpp
#include <string.h>
#include <maya/MIOStream.h>
#include <math.h>
#include <maya/MPxNode.h>
#include <maya/MPxCommand.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnNurbsCurve.h>
#include <maya/MFnNurbsSurface.h>
#include <maya/MFnNurbsCurveData.h>
#include <maya/MFnNurbsSurfaceData.h>
#include <maya/MPointArray.h>
#include <maya/MDoubleArray.h>
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MGlobal.h>
#include <maya/MItCurveCV.h>
#include <maya/MDagPath.h>
class simpleLoft : public MPxNode
{
public:
simpleLoft() {};
virtual ~simpleLoft();
virtual MStatus compute( const MPlug& plug, MDataBlock& data );
MObject loft( MObject &curve, MObject &surfFn, MStatus &stat );
static void* creator();
static MStatus initialize();
public:
static MObject inputCurve;
static MObject outputSurface;
static MTypeId id;
};
MTypeId simpleLoft::id( 0x80011 );
MObject simpleLoft::inputCurve;
MObject simpleLoft::outputSurface;
simpleLoft::~simpleLoft() {}
void* simpleLoft::creator()
{
return new simpleLoft();
}
MStatus simpleLoft::initialize()
{
MFnTypedAttribute typedAttr;
MStatus stat;
inputCurve = typedAttr.create( "inputCurve", "in",
MFnNurbsCurveData::kNurbsCurve, &stat );
if ( !stat ) {
stat.perror("ERROR creating simpleLoft curve attribute");
return stat;
}
outputSurface = typedAttr.create( "outputSurface", "out",
MFnNurbsSurfaceData::kNurbsSurface, &stat );
if ( !stat ) {
stat.perror("ERROR creating simpleLoft surface attribute");
return stat;
}
typedAttr.setStorable( false );
stat = addAttribute( inputCurve );
if (!stat) { stat.perror("addAttribute"); return stat;}
stat = addAttribute( outputSurface );
if (!stat) { stat.perror("addAttribute"); return stat;}
stat = attributeAffects( inputCurve, outputSurface );
if (!stat) { stat.perror("attributeAffects"); return stat;}
return MS::kSuccess;
}
MObject simpleLoft::loft( MObject &curve, MObject &newSurfData, MStatus &stat )
{
MFnNurbsSurface surfFn;
MPointArray cvs;
MDoubleArray ku, kv;
MFnNurbsCurve curveFn (curve);
stat = curveFn.getCVs (cvs, MSpace::kWorld);
if ( stat != MS::kSuccess )
{
cerr << "Error in getting CVs: " << stat << endl;
return MObject::kNullObj;
}
int i, j, k = cvs.length();
ku.append( 0.0 );
ku.append( 0.0 );
ku.append( 0.0 );
ku.append( 1.0 );
ku.append( 1.0 );
ku.append( 1.0 );
kv.append( 0.0 );
kv.append( 0.0 );
kv.append( 0.0 );
for ( i = 1; i < k-3; i ++ )
kv.append( (double) i );
kv.append( k-3 );
kv.append( k-3 );
kv.append( k-3 );
for ( i = 1; i < 4; i++ )
{
for ( j = 0; j < k; j++ )
{
MPoint point = cvs[j];
point.z += (double) i;
cvs.append( point );
}
}
MObject surf = surfFn.create(
cvs, ku, kv, 3, 3,
MFnNurbsSurface::kOpen, MFnNurbsSurface::kOpen,
false, newSurfData, &stat );
if ( stat != MS::kSuccess )
{
cerr << "Error in creating surface: " << stat << endl;
return MObject::kNullObj;
}
return surf;
}
MStatus simpleLoft::compute( const MPlug& plug, MDataBlock& data )
{
MStatus stat;
if ( plug == outputSurface )
{
MDataHandle inputData = data.inputValue( inputCurve, &stat );
if( stat != MS::kSuccess )
{
cerr << "ERROR getting data: " << stat << endl;
return stat;
}
MObject curve = inputData.asNurbsCurve();
MFnNurbsCurve curveFn( curve, &stat );
if( stat != MS::kSuccess )
{
cerr << "ERROR creating curve function set:" << stat << endl;
return stat;
}
MDataHandle surfHandle = data.outputValue( simpleLoft::outputSurface );
if( stat != MS::kSuccess )
{
cerr << "Error in getting data handle: " << stat << endl;
return stat;
}
MFnNurbsSurfaceData dataCreator;
MObject newSurfData = dataCreator.create( &stat );
if ( stat != MS::kSuccess ) {
cerr << "Error creating new nurbs surface data block: "
<< stat << endl;
return stat;
}
loft( curve, newSurfData, stat );
if( stat != MS::kSuccess )
{
cerr << "Error in creating surface: " << stat << endl;
return stat;
}
surfHandle.set( newSurfData );
stat = data.setClean( plug );
if( stat != MS::kSuccess )
{
cerr << "Error in cleaning outputSurface plug: "
<< stat << endl;
return stat;
}
}
else
{
return MS::kUnknownParameter;
}
return MS::kSuccess;
}
MStatus initializePlugin( MObject obj )
{
MStatus status;
MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");
status = plugin.registerNode( "simpleLoft", simpleLoft::id,
simpleLoft::creator, simpleLoft::initialize );
if (!status) {
status.perror("registerNode");
return status;
}
return status;
}
MStatus uninitializePlugin( MObject obj)
{
MStatus status;
MFnPlugin plugin( obj );
status = plugin.deregisterNode( simpleLoft::id );
if (!status) {
status.perror("deregisterNode");
return status;
}
return status;
}