#include "pointOnSubdNode.h"
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnTypedAttribute.h>
#include <maya/MFnSubdNames.h>
#include <maya/MFnSubdData.h>
#include <maya/MDataHandle.h>
#include <maya/MDataBlock.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnSubd.h>
#include <maya/MGlobal.h>
#include <maya/MVector.h>
#include <maya/MPoint.h>
#include <maya/MPlug.h>
MTypeId pointOnSubd::id( 0x80019 );
#include <maya/MIOStream.h>
#define McheckErr(status,message) \
if( MStatus::kSuccess != stat ) { \
cerr << message << "\n"; \
return stat; \
}
MObject pointOnSubd::aSubd;
MObject pointOnSubd::aFaceFirst;
MObject pointOnSubd::aFaceSecond;
MObject pointOnSubd::aRelativeUV;
MObject pointOnSubd::aU;
MObject pointOnSubd::aV;
MObject pointOnSubd::aPoint;
MObject pointOnSubd::aPointX;
MObject pointOnSubd::aPointY;
MObject pointOnSubd::aPointZ;
MObject pointOnSubd::aNormal;
MObject pointOnSubd::aNormalX;
MObject pointOnSubd::aNormalY;
MObject pointOnSubd::aNormalZ;
pointOnSubd::pointOnSubd() {}
pointOnSubd::~pointOnSubd() {}
MStatus pointOnSubd::compute( const MPlug& plug, MDataBlock& data )
{
MStatus returnStatus;
if( (plug == aPoint) || (plug == aNormal) ||
(plug == aPointX) || (plug == aNormalX) ||
(plug == aPointY) || (plug == aNormalY) ||
(plug == aPointZ) || (plug == aNormalZ) ) {
do {
MDataHandle subdHandle = data.inputValue( aSubd, &returnStatus );
if( returnStatus != MS::kSuccess ) {
MGlobal::displayError( "ERROR: cannot get subd\n" );
break;
}
MDataHandle faceFirstHandle =
data.inputValue( aFaceFirst, &returnStatus );
if( returnStatus != MS::kSuccess ) {
MGlobal::displayError( "ERROR: cannot get face first\n" );
break;
}
MDataHandle faceSecondHandle =
data.inputValue( aFaceSecond, &returnStatus );
if( returnStatus != MS::kSuccess ) {
MGlobal::displayError( "ERROR: cannot get face2\n" );
break;
}
MDataHandle uHandle = data.inputValue( aU, &returnStatus );
if( returnStatus != MS::kSuccess ) {
MGlobal::displayError( "ERROR: cannot get u\n" );
break;
}
MDataHandle vHandle = data.inputValue( aV, &returnStatus );
if( returnStatus != MS::kSuccess ) {
MGlobal::displayError( "ERROR: cannot get v\n" );
break;
}
MDataHandle relHandle = data.inputValue( aRelativeUV, &returnStatus );
if( returnStatus != MS::kSuccess ) {
MGlobal::displayError( "ERROR: cannot get relative UV\n" );
break;
}
MStatus stat;
MObject subdValue = subdHandle.asSubdSurface();
MFnSubd subdFn( subdValue, &stat );
McheckErr(stat,"ERROR creating subd function set");
int faceFirstValue = faceFirstHandle.asLong();
int faceSecondValue = faceSecondHandle.asLong();
double uValue = uHandle.asDouble();
double vValue = vHandle.asDouble();
bool relUV = relHandle.asBool();
MPoint point;
MVector normal;
MUint64 polyId;
stat = MFnSubdNames::fromSelectionIndices( polyId, faceFirstValue,
faceSecondValue );
McheckErr(stat,"ERROR converting indices");
stat = subdFn.evaluatePositionAndNormal( polyId, uValue, vValue,
relUV, point, normal );
normal.normalize();
McheckErr(stat,"ERROR evaluating the position and the normal");
MDataHandle pointHandle = data.outputValue( aPoint );
pointHandle.set( point.x, point.y, point.z );
data.setClean(plug);
MDataHandle normalHandle = data.outputValue( aNormal );
normalHandle.set( normal.x, normal.y, normal.z );
data.setClean(plug);
} while( false );
}
else {
return MS::kUnknownParameter;
}
return MS::kSuccess;
}
void* pointOnSubd::creator()
{
return new pointOnSubd;
}
MStatus pointOnSubd::initialize()
{
MStatus stat;
MFnTypedAttribute subdAttr;
aSubd = subdAttr.create( "subd", "s", MFnSubdData::kSubdSurface, &stat );
McheckErr( stat, "cannot create pointOnSubd::aSubd" );
subdAttr.setStorable(true);
subdAttr.setKeyable(false);
subdAttr.setReadable( true );
subdAttr.setWritable( true );
subdAttr.setCached( false );
stat = addAttribute( pointOnSubd::aSubd );
McheckErr( stat, "cannot add pointOnSubd::aSubd" );
MFnNumericAttribute faceFirstAttr;
aFaceFirst = faceFirstAttr.create( "faceFirst", "ff",
MFnNumericData::kLong, 0, &stat );
McheckErr( stat, "cannot create pointOnSubd::aFaceFirst" );
faceFirstAttr.setStorable(true);
faceFirstAttr.setKeyable(true);
faceFirstAttr.setSoftMin( 0.0 );
faceFirstAttr.setReadable( true );
faceFirstAttr.setWritable( true );
faceFirstAttr.setCached( false );
stat = addAttribute( pointOnSubd::aFaceFirst );
McheckErr( stat, "cannot add pointOnSubd::aFaceFirst" );
MFnNumericAttribute faceSecondAttr;
aFaceSecond = faceSecondAttr.create( "faceSecond", "fs",
MFnNumericData::kLong, 0, &stat );
McheckErr( stat, "cannot create pointOnSubd::aFaceSecond" );
faceSecondAttr.setStorable(true);
faceSecondAttr.setKeyable(true);
faceSecondAttr.setSoftMin( 0.0 );
faceSecondAttr.setReadable( true );
faceSecondAttr.setWritable( true );
faceSecondAttr.setCached( false );
stat = addAttribute( pointOnSubd::aFaceSecond );
McheckErr( stat, "cannot add pointOnSubd::aFaceSecond" );
MFnNumericAttribute uAttr;
aU = uAttr.create( "uValue", "u", MFnNumericData::kDouble,
0, &stat );
McheckErr( stat, "cannot create pointOnSubd::aU" );
uAttr.setStorable(true);
uAttr.setKeyable(true);
uAttr.setSoftMin( 0.0 );
uAttr.setSoftMax( 1.0 );
uAttr.setReadable( true );
uAttr.setWritable( true );
uAttr.setCached( false );
stat = addAttribute( aU );
McheckErr( stat, "cannot add pointOnSubd::aU" );
MFnNumericAttribute vAttr;
aV = vAttr.create( "vValue", "v", MFnNumericData::kDouble,
0, &stat );
McheckErr( stat, "cannot create pointOnSubd::aV" );
vAttr.setStorable(true);
vAttr.setKeyable(true);
vAttr.setSoftMin( 0.0 );
vAttr.setSoftMax( 1.0 );
vAttr.setReadable( true );
vAttr.setWritable( true );
vAttr.setCached( false );
stat = addAttribute( aV );
McheckErr( stat, "cannot add pointOnSubd::aV" );
MFnNumericAttribute relAttr;
aRelativeUV = relAttr.create( "relative", "rel", MFnNumericData::kBoolean,
0, &stat );
McheckErr( stat, "cannot create pointOnSubd::aRelativeUV" );
relAttr.setStorable(true);
relAttr.setKeyable(true);
relAttr.setSoftMin( 0.0 );
relAttr.setSoftMax( 1.0 );
relAttr.setReadable( true );
relAttr.setWritable( true );
relAttr.setCached( false );
stat = addAttribute( pointOnSubd::aRelativeUV );
McheckErr( stat, "cannot add pointOnSubd::aRelativeUV" );
MFnNumericAttribute pointXAttr;
aPointX = pointXAttr.create( "pointX", "px", MFnNumericData::kDouble,
0.0, &stat );
McheckErr( stat, "cannot create pointOnSubd::aPointX" );
pointXAttr.setWritable(false);
pointXAttr.setStorable(false);
pointXAttr.setReadable( true );
pointXAttr.setCached( true );
stat = addAttribute( aPointX );
McheckErr( stat, "cannot add pointOnSubd::aPointX" );
MFnNumericAttribute pointYAttr;
aPointY = pointYAttr.create( "pointY", "py", MFnNumericData::kDouble,
0.0, &stat );
McheckErr( stat, "cannot create pointOnSubd::aPointY" );
pointYAttr.setWritable(false);
pointYAttr.setStorable(false);
pointYAttr.setReadable( true );
pointYAttr.setCached( true );
stat = addAttribute( aPointY );
McheckErr( stat, "cannot add pointOnSubd::aPointY" );
MFnNumericAttribute pointZAttr;
aPointZ = pointZAttr.create( "pointZ", "pz", MFnNumericData::kDouble,
0.0, &stat );
McheckErr( stat, "cannot create pointOnSubd::aPointZ" );
pointZAttr.setWritable(false);
pointZAttr.setStorable(false);
pointZAttr.setReadable( true );
pointZAttr.setCached( true );
stat = addAttribute( aPointZ );
McheckErr( stat, "cannot add pointOnSubd::aPointZ" );
MFnNumericAttribute pointAttr;
aPoint = pointAttr.create( "point", "p", aPointX, aPointY, aPointZ, &stat);
McheckErr( stat, "cannot create pointOnSubd::aPoint" );
pointAttr.setWritable(false);
pointAttr.setStorable(false);
pointAttr.setReadable( true );
pointAttr.setCached( true );
stat = addAttribute( aPoint );
McheckErr( stat, "cannot add pointOnSubd::aPoint" );
MFnNumericAttribute normalXAttr;
aNormalX = normalXAttr.create( "normalX", "nx", MFnNumericData::kDouble,
0.0, &stat );
McheckErr( stat, "cannot create pointOnSubd::aNormal" );
normalXAttr.setWritable(false);
normalXAttr.setStorable(false);
normalXAttr.setReadable( true );
normalXAttr.setCached( true );
stat = addAttribute( aNormalX );
McheckErr( stat, "cannot add pointOnSubd::aNormalX" );
MFnNumericAttribute normalYAttr;
aNormalY = normalYAttr.create( "normalY", "ny", MFnNumericData::kDouble,
0.0, &stat );
McheckErr( stat, "cannot create pointOnSubd::aNormal" );
normalYAttr.setWritable(false);
normalYAttr.setStorable(false);
normalYAttr.setReadable( true );
normalYAttr.setCached( true );
stat = addAttribute( aNormalY );
McheckErr( stat, "cannot add pointOnSubd::aNormalY" );
MFnNumericAttribute normalZAttr;
aNormalZ = normalZAttr.create( "normalZ", "nz", MFnNumericData::kDouble,
0.0, &stat );
McheckErr( stat, "cannot create pointOnSubd::aNormal" );
normalZAttr.setWritable(false);
normalZAttr.setStorable(false);
normalZAttr.setReadable( true );
normalZAttr.setCached( true );
stat = addAttribute( aNormalZ );
McheckErr( stat, "cannot add pointOnSubd::aNormalZ" );
MFnNumericAttribute normalAttr;
aNormal = normalAttr.create("normal","n",aNormalX,aNormalY,aNormalZ,&stat);
McheckErr( stat, "cannot create pointOnSubd::aNormal" );
normalAttr.setWritable(false);
normalAttr.setStorable(false);
normalAttr.setReadable( true );
normalAttr.setCached( true );
stat = addAttribute( aNormal );
McheckErr( stat, "cannot add pointOnSubd::aNormal" );
stat = attributeAffects( aSubd, aPoint );
stat = attributeAffects( aSubd, aPointX );
stat = attributeAffects( aSubd, aPointY );
stat = attributeAffects( aSubd, aPointZ );
stat = attributeAffects( aSubd, aNormal );
stat = attributeAffects( aSubd, aNormalX );
stat = attributeAffects( aSubd, aNormalY );
stat = attributeAffects( aSubd, aNormalZ );
stat = attributeAffects( aFaceFirst, aPoint );
stat = attributeAffects( aFaceFirst, aPointX );
stat = attributeAffects( aFaceFirst, aPointY );
stat = attributeAffects( aFaceFirst, aPointZ );
stat = attributeAffects( aFaceFirst, aNormal );
stat = attributeAffects( aFaceFirst, aNormalX );
stat = attributeAffects( aFaceFirst, aNormalY );
stat = attributeAffects( aFaceFirst, aNormalZ );
stat = attributeAffects( aFaceSecond, aPoint );
stat = attributeAffects( aFaceSecond, aPointX );
stat = attributeAffects( aFaceSecond, aPointY );
stat = attributeAffects( aFaceSecond, aPointZ );
stat = attributeAffects( aFaceSecond, aNormal );
stat = attributeAffects( aFaceSecond, aNormalX );
stat = attributeAffects( aFaceSecond, aNormalY );
stat = attributeAffects( aFaceSecond, aNormalZ );
stat = attributeAffects( aU, aPoint );
stat = attributeAffects( aU, aPointX );
stat = attributeAffects( aU, aPointY );
stat = attributeAffects( aU, aPointZ );
stat = attributeAffects( aU, aNormal );
stat = attributeAffects( aU, aNormalX );
stat = attributeAffects( aU, aNormalY );
stat = attributeAffects( aU, aNormalZ );
stat = attributeAffects( aV, aPoint );
stat = attributeAffects( aV, aPointX );
stat = attributeAffects( aV, aPointY );
stat = attributeAffects( aV, aPointZ );
stat = attributeAffects( aV, aNormal );
stat = attributeAffects( aV, aNormalX );
stat = attributeAffects( aV, aNormalY );
stat = attributeAffects( aV, aNormalZ );
stat = attributeAffects( aRelativeUV, aPoint );
stat = attributeAffects( aRelativeUV, aPointX );
stat = attributeAffects( aRelativeUV, aPointY );
stat = attributeAffects( aRelativeUV, aPointZ );
stat = attributeAffects( aRelativeUV, aNormal );
stat = attributeAffects( aRelativeUV, aNormalX );
stat = attributeAffects( aRelativeUV, aNormalY );
stat = attributeAffects( aRelativeUV, aNormalZ );
return MS::kSuccess;
}
MStatus initializePlugin( MObject obj )
{
MStatus status;
MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");
status = plugin.registerNode( "pointOnSubd",
pointOnSubd::id,
pointOnSubd::creator,
pointOnSubd::initialize );
if (!status) {
status.perror("registerNode");
return status;
}
return status;
}
MStatus uninitializePlugin( MObject obj)
{
MStatus status;
MFnPlugin plugin( obj );
status = plugin.deregisterNode( pointOnSubd::id );
if (!status) {
status.perror("deregisterNode");
return status;
}
return status;
}