コマンド・プラグインによって新しいノードを作ることができる。
必要なノードをプラグインとして作成すれば原理的にはどんなモデリング・アニメーション・シェーディングでもできるようになる。
nodeName()
virtual ~nodeName()
virtual MStatus compute( const MPlug& plug, MDataBlock& data )
static void* nodeName::creator()
static MStatus nodeName::initialize()
MStatus initializePlugin( MObject obj )
MStatus uninitializePlugin( MObject obj )
MTypeId id
#include <string.h>
#include <iostream.h>
#include <math.h>
#include <maya/MPxNode.h> // ノードを作るために必要
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnPlugin.h>
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MVector.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
class sine : public MPxNode // MPxNodeを継承してノードを作る
{
public:
sine();
virtual ~sine();
virtual MStatus compute( const MPlug& plug, MDataBlock& data );
static void* creator();
static MStatus initialize();
public:
static MObject input; // 入力用アトリビュート
static MObject output; // 出力用アトリビュート
static MTypeId id; // プラグインのId
};
MTypeId sine::id( 0x70000 ); // 適当なid番号(0x00000000以上、0x0007ffff以下)を決める
MObject sine::input;
MObject sine::output;
sine::sine(){} // 空で良い
sine::~sine(){} // 空で良い
MStatus sine::compute( const MPlug& plug, MDataBlock& data )
{
MStatus returnStatus;
if( plug == output ) // プラグがoutputアトリビュートなら以下を実行
{
// inputアトリビュートからMDataHandleを作る
MDataHandle inputData = data.inputValue( input, &returnStatus );
if( returnStatus != MS::kSuccess )
cerr << "ERROR getting data" << endl;
else
{
// inputアトリビュートのMDataHandleからデータをfloatとして取り出して計算
float result = sinf( inputData.asFloat() ) * 10.0f;
// outputアトリビュートからMDataHandleを作る
MDataHandle outputHandle = data.outputValue( sine::output );
// outputアトリビュートのMDataHandleに計算結果を入れる
outputHandle.set( result );
// 計算が終ったらsetCleanを必ず呼ぶ
data.setClean(plug);
}
}
else
{
// output以外のアトリビュートにはエラー(MS::kUnknownParameter)を返す
return MS::kUnknownParameter;
}
// 計算が成功したら(MS::kSuccess)を返す
return MS::kSuccess;
}
void* sine::creator()
{
return new sine();
}
MStatus sine::initialize()
{
MFnNumericAttribute nAttr;
MStatus stat;
// inputアトリビュートの設定
input = nAttr.create( "input", "in", MFnNumericData::kFloat, 0.0 );
// inputアトリビュートをシーンファイル保存時に書き込むように設定
nAttr.setStorable(true);
// outputアトリビュートの設定
output = nAttr.create( "output", "out", MFnNumericData::kFloat, 0.0 );
// outputアトリビュートを出力用に設定
nAttr.setWritable(false);
// outputアトリビュートをシーンファイル保存時に書き込まないように設定
nAttr.setStorable(false);
// inputアトリビュートの登録
stat = addAttribute( input );
if(!stat)
{
stat.perror("addAttribute");
return stat;
}
// outputアトリビュートの登録
stat = addAttribute( output );
if(!stat)
{
stat.perror("addAttribute");
return stat;
}
// inputアトリビュートに新しい値が入って来たら
// outputアトリビュートを計算(compute())するように設定
stat = attributeAffects( input, output );
if(!stat)
{
stat.perror("attributeAffects");
return stat;
}
return MS::kSuccess;
}
MStatus initializePlugin( MObject obj )
{
MStatus status;
MFnPlugin plugin( obj, "Alias|Wavefront - Example", "2.0", "Any");
status = plugin.registerNode( "sine", sine::id, sine::creator,
sine::initialize );
if(!status)
{
status.perror("registerNode");
return status;
}
return status;
}
MStatus uninitializePlugin( MObject obj)
{
MStatus status;
MFnPlugin plugin( obj );
status = plugin.deregisterNode( sine::id );
if(!status)
{
status.perror("deregisterNode");
return status;
}
return status;
}