API ガイド > デフォーマ ノードを作成する >

# デフォーマ ノードの例

このセクションでは、デフォーマ ノードの一例である 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:
    };

プラグインの初期化

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

    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;
    }

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

    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);
        ddAttribute( 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;
    }

その他のメソッド

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

- 重要な修正イベントを受け取る
- ポイントのセットの編集時における特殊なケースを扱う(セットからすべてのポイントが削除され、そのあと再び追加された場合に、古い入出力インデックスを使用して再接続する)