offsetNode/offsetNode.cpp

offsetNode/offsetNode.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.
// ==========================================================================
//+
//
// File: offset.cc
//
// Description:
// Example implementation of a deformer. This node
// offsets vertices according to the CV's weights.
// The weights are set using the set editor or the
// percent command.
//
#include <string.h>
#include <maya/MIOStream.h>
#include <math.h>
#include <maya/MPxDeformerNode.h>
#include <maya/MItGeometry.h>
#include <maya/MPxLocatorNode.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnMatrixAttribute.h>
#include <maya/MFnMatrixData.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MPoint.h>
#include <maya/MVector.h>
#include <maya/MMatrix.h>
#include <maya/MDagModifier.h>
class offset : public MPxDeformerNode
{
public:
offset();
virtual ~offset();
static void* creator();
static MStatus initialize();
// deformation function
//
virtual MStatus deform(MDataBlock& block,
MItGeometry& iter,
const MMatrix& mat,
unsigned int multiIndex);
// when the accessory is deleted, this node will clean itself up
//
virtual MObject& accessoryAttribute() const;
// create accessory nodes when the node is created
//
public:
// local node attributes
static MObject offsetMatrix; // offset center and axis
static MTypeId id;
private:
};
MTypeId offset::id( 0x8000c );
// local attributes
//
MObject offset::offsetMatrix;
offset::offset() {}
offset::~offset() {}
void* offset::creator()
{
return new offset();
}
MStatus offset::initialize()
{
// local attribute initialization
offsetMatrix=mAttr.create( "locateMatrix", "lm");
mAttr.setStorable(false);
mAttr.setConnectable(true);
// deformation attributes
addAttribute( offsetMatrix);
attributeAffects( offset::offsetMatrix, offset::outputGeom );
}
offset::deform( MDataBlock& block,
MItGeometry& iter,
const MMatrix& /*m*/,
unsigned int multiIndex)
//
// Method: deform
//
// Description: Deform the point with a squash algorithm
//
// Arguments:
// block : the datablock of the node
// iter : an iterator for the geometry to be deformed
// m : matrix to transform the point into world space
// multiIndex : the index of the geometry that we are deforming
//
//
{
MStatus returnStatus;
// Envelope data from the base class.
// The envelope is simply a scale factor.
//
MDataHandle envData = block.inputValue(envelope, &returnStatus);
if (MS::kSuccess != returnStatus) return returnStatus;
float env = envData.asFloat();
// Get the matrix which is used to define the direction and scale
// of the offset.
//
MDataHandle matData = block.inputValue(offsetMatrix, &returnStatus );
if (MS::kSuccess != returnStatus) return returnStatus;
MMatrix omat = matData.asMatrix();
MMatrix omatinv = omat.inverse();
// iterate through each point in the geometry
//
for ( ; !iter.isDone(); iter.next()) {
MPoint pt = iter.position();
pt *= omatinv;
float weight = weightValue(block,multiIndex,iter.index());
// offset algorithm
//
pt.y = pt.y + env*weight;
//
// end of offset algorithm
pt *= omat;
iter.setPosition(pt);
}
return returnStatus;
}
/* override */
offset::accessoryAttribute() const
//
// Description:
// This method returns a the attribute to which an accessory
// shape is connected. If the accessory shape is deleted, the deformer
// node will automatically be deleted.
//
// This method is optional.
//
{
return offset::offsetMatrix;
}
/* override */
offset::accessoryNodeSetup(MDagModifier& cmd)
//
// Description:
// This method is called when the deformer is created by the
// "deformer" command. You can add to the cmds in the MDagModifier
// cmd in order to hook up any additional nodes that your node needs
// to operate.
//
// In this example, we create a locator and attach its matrix attribute
// to the matrix input on the offset node. The locator is used to
// set the direction and scale of the random field.
//
// Description:
// This method is optional.
//
{
MStatus result;
// hook up the accessory node
//
MObject objLoc = cmd.createNode(MString("locator"),
&result);
if (MS::kSuccess == result) {
MFnDependencyNode fnLoc(objLoc);
MString attrName;
attrName.set("matrix");
MObject attrMat = fnLoc.attribute(attrName);
result = cmd.connect(objLoc,attrMat,this->thisMObject(),offset::offsetMatrix);
}
return result;
}
// standard initialization procedures
//
MStatus initializePlugin( MObject obj )
{
MStatus result;
MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");
result = plugin.registerNode( "offset", offset::id, offset::creator,
offset::initialize, MPxNode::kDeformerNode );
return result;
}
MStatus uninitializePlugin( MObject obj)
{
MStatus result;
MFnPlugin plugin( obj );
result = plugin.deregisterNode( offset::id );
return result;
}