デフォーマ ノードの例
 
 
 

このセクションでは、デフォーマ ノードの一例である offsetNode プラグインについて説明します。このプラグインは、Maya API 開発キットで提供されています。

プロキシ デフォーマ ノードを実装する

offset クラスは MPxDeformerNode から継承され、deform() などいくつかのバーチャル メソッドを定義します。

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);
	virtual MObject&			accessoryAttribute() const;
	virtual MStatus			accessoryNodeSetup(MDagModifier& cmd);
public:
	static MObject offsetMatrix; 	// offset center and axis
	
	static MTypeId		id;
private:
};

プラグインの初期化

新しいデフォーマ ノードは、プラグインの初期化時に MFnPluguinregisterNode() メソッドで登録する必要があります。

MStatus initializePlugin( MObject obj )
{
	MStatus result;
	MFnPlugin plugin( obj, "Autodesk", "3.0", "Any");
	result = plugin.registerNode( "offset", offset::id, offset::creator, 
					offset::initialize, MPxNode::kDeformerNode );
	return result;
}

デフォーマ ノードを削除するには、MFnPluginderegisterNode() メソッドを呼び出して、これらのプラグインを登録解除する必要があります。

MStatus uninitializePlugin( MObject obj)
{
	MStatus result;
	MFnPlugin plugin( obj );
	result = plugin.deregisterNode( offset::id );
	return result;
}

offsetNodeを実装する

プロキシ ノードに対して新しいアトリビュートを追加し構成する場合、initialize() メソッドを使用します。以下の例では、offsetMatrix アトリビュートがノードに追加され、コネクト可能になっています。入力アトリビュート offsetMatrix への任意の変更は、出力アトリビュート outputGeom に作用します。

MStatus offset::initialize()
{
	MFnMatrixAttribute mAttr;
	offsetMatrix=mAttr.create( "locateMatrix", "lm");
 mAttr.setStorable(false);
		mAttr.setConnectable(true);
	addAttribute( offsetMatrix);
	attributeAffects( offset::offsetMatrix, offset::outputGeom );
	return MStatus::kSuccess;
}

deform メソッド

deform() メソッドは、変形を計算するためのアルゴリズムを実装します。

offset クラス内で、deform() メソッドはスカッシュ アルゴリズムを使用してポイントを変形します。ジオメトリのデータは MDataHandle によってデータ ブロックから抽出され、ジオメトリの各ポイントを変形します。deform() メソッドは、変形の成功を示すため MS::kSuccess を返します。これが返らない場合、変形時に無効なデータ入力やメモリ不足などの問題が発生しています。

このメソッドには、4 つの必須の引数があります。block 引数は、ジオメトリの情報の保存先となる、ノードのデータ ブロックを表します。iter 引数は、変形するジオメトリのイテレータです。m はローカル空間からワールド空間にポイントをトランスフォームするのに使用される行列です。multiIndex は、要求した出力ジオメトリのインデックスです。

MStatus
offset::deform( MDataBlock& block,
		MItGeometry& iter,
		const MMatrix& /*m*/,
		unsigned int multiIndex)
{
	MStatus returnStatus;
	
	MDataHandle envData = block.inputValue(envelope, &returnStatus);
	if (MS::kSuccess != returnStatus) return returnStatus;
	float env = envData.asFloat();	
	MDataHandle matData = block.inputValue(offsetMatrix, &returnStatus );
	if (MS::kSuccess != returnStatus) return returnStatus;
	MMatrix omat = matData.asMatrix();
	MMatrix omatinv = omat.inverse();
	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;
		
		pt *= omat;
		iter.setPosition(pt);
	}
	return returnStatus;
}

上の weightValue() メソッドは、ジオメトリ内のウェイト値を返します。

各頂点、CV、ラティス ポイントのウェイト値は weightValue() メソッドによって取得され、同時にマルチ インデックスがメソッドに渡されます。そして、この値が offset アルゴリズムに統合され、希望の変形を実行することができます。

アクセサリ ノードを実装する

accessoryNodesetup() メソッドは、追加のノードを作成し、デフォーマ ノードにアタッチします。この例では、ロケータが作成され、その行列のアトリビュートがオフセット ノードの行列の入力にコネクトされます。

MStatus
offset::accessoryNodeSetup(MDagModifier& cmd)
{
	MStatus result;
	MObject objLoc = cmd.createNode(MString("locator"),
					MObject::kNullObj,
					&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;
}

accessoryAttribute() メソッドは、アクセサリ シェイプにコネクトされたアトリビュートを返します。この場合は、offset::offsetMatrix です。アクセサリ シェイプが削除されたら、デフォーマ ノードも自動的に削除されます。

MObject&
offset::accessoryAttribute() const
{
	return offset::offsetMatrix;
}

その他のメソッド

このクラスには、その他次のような機能を持つメソッドがあります。