デフォーマ ノードの例

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

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

ytwist クラスは MPxGeometryFilter を継承し、1 つの仮想メソッド deform() を定義します。

class yTwist : public MPxGeometryFilter
{
public:
                         yTwist();
    virtual              ~yTwist();

    static  void*        creator();
    static  MStatus      initialize();

    // deformation function
    virtual MStatus      deform(MDataBlock&  block,
                         MItGeometry&        iter,
                         const MMatrix&      mat,
                         unsigned int        multiIndex);

public:
    // yTwist attributes
    static  MObject     angle;          // angle to twist    
    static  MTypeId        id;

private:

};


プラグインの初期化

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

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


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

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

デフォーマのアトリビュートを追加する

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

MStatus yTwist::initialize()
{
    // local attribute initialization
    //
    MFnNumericAttribute nAttr;
    angle=nAttr.create( "angle", "fa", MFnNumericData::kDouble );
        nAttr.setDefault(0.0);
        nAttr.setKeyable(true);
    addAttribute( angle); 

    // affects
    //
    attributeAffects( yTwist::angle, yTwist::outputGeom );

    return MS::kSuccess;
}


deform メソッド

deform() メソッドは、デフォメーションを計算するためのアルゴリズムを実装します。

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

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

MStatus
yTwist::deform( MDataBlock& block,
                MItGeometry& iter,
                const MMatrix& /*m*/,
                unsigned int /*multiIndex*/)

{
    MStatus status = MS::kSuccess;
    
    // determine the angle of the yTwist
    //
    MDataHandle angleData = block.inputValue(angle,&status);
    McheckErr(status, "Error getting angle data handle\n");
    double magnitude = angleData.asDouble();

    // determine the envelope (this is a global scale factor)
    //
    MDataHandle envData = block.inputValue(envelope,&status);
    McheckErr(status, "Error getting envelope data handle\n");  
    float env = envData.asFloat();  

    // iterate through each point in the geometry
    //
    for ( ; !iter.isDone(); iter.next()) {
        
        MPoint pt = iter.position();

        // do the twist
        //
        double ff = magnitude*pt.y*env;
        if (ff != 0.0) {
            double cct= cos(ff);
            double cst= sin(ff);
            double tt= pt.x*cct-pt.z*cst;
            pt.z= pt.x*cst + pt.z*cct;
            pt.x=tt;;
        }

        iter.setPosition(pt);
    }
    return status;
}

この例では、頂点単位のウェイトはデフォーマに使用されません。頂点単位のウェイトの一例として Developer Kit サンプル offsetNode を参照してください。これは、MPxDeformerNode を継承し、weightValue() を使用して各頂点、CV、ラティス ポイントのウェイト値を取得します。この例でも、アクセサリ ノードを実装する方法を示します。

その他のメソッド

その他にも、MPxGeometryFilter には、プラグインで次のことを可能にするメソッドがいくつかあります。