より複雑なサンプル
 
 
 

以下は、これまでより少し複雑なサンプルの一部です。このコードサンプルは simpleLoftNode の例から取ったもので、カーブを入力として取ってサーフェスを作成します。

MObject simpleLoft::inputCurve;
MObject simpleLoft::outputSurface;

このサンプルのアトリビュートは、入力カーブと出力サーフェスの 2 つだけです。

MStatus simpleLoft::initialize()
{
     MStatus stat;
     MFnTypedAttribute typedAttr;

前のサンプルでは、アトリビュートが単純な浮動小数点数だったので、MFnNumericAttribute を使用しました。このサンプルでは複雑なデータを使用するので、MFnTypedAttribute を使用します。

    inputCurve = typedAttr.create( "inputCurve", "in", 
    MFnData::kNurbsCurve, &stat );
    if( !stat )
        return stat;

カーブ オブジェクトが持つアトリビュートが作成されます。MFnData の Type 列挙では、型付きアトリビュートを使用して作成できるデータ型がリストされます。このリストには、カーブ、サーフェス、メッシュ、文字列、ユーザ定義データなどが含まれます。

    outputSurface = typedAttr.create( "outputSurface", "out",
    MFnData::kNurbsSurface, &stat );
    if( !stat )
        return stat;

作成したサーフェス オブジェクトが持つアトリビュートが作成されます。

    typedAttr.setStorable( false );

サーフェスは生成されるオブジェクトなので、ノードをファイルに保存するときに保存する必要はありません。

    addAttribute( inputCurve );
    addAttribute( outputSurface );
    attributeAffects( inputCurve, outputSurface );

最後に 2 つのアトリビュートをノードに追加し、attributeAffects() を使用して、入力カーブが修正されたらサーフェスを再作成する必要があることを示します。

    return MS::kSuccess;
}
MStatus simpleLoft::compute( const MPlug& plug, MDataBlock& data )
{
    MStatus stat;
    if ( plug == outputSurface )
    {

ノードの計算が適切なアトリビュートのみで実行されることが保証されます。

        MDataHandle inputData = data.inputValue( inputCurve, &stat );
        if( !stat )
            return stat;

前に説明したように、データ ブロックには、ノードのすべてのデータが能率的な方法で含まれます。このデータにアクセスするには、データ ハンドルが必要です。

        else
        {
            MObject curve = inputData.asNurbsCurve();
            MFnNurbsCurve curveFn( curve, &stat );
            if( !stat )
                return stat;

ここでデータ ハンドルを使用して入力カーブを取得し、MFnNurbsCurve 関数セットに渡して操作することができます。

            else
            {
                MDataHandle surfHandle = data.outputValue( outputSurface );
                if( !stat )
                    return stat;

2 つ目のデータ ハンドルは、データ ブロックのサーフェス部分にアクセスするために使用します。

                MFnNurbsSurfaceData dataCreator;
                MObject newSurfData = dataCreator.create( &stat );
                if ( !stat )
                    return stat;

このサンプルでは、MFnNurbsSurface を使用せずに MFnNurbsSurfaceData を使用することに注意してください。DAG オブジェクトではなく、ディペンデンシー グラフで渡すデータ オブジェクトを作成するので、必要になります。ディペンデンシー グラフ ノード内でオブジェクトを作成する場合は、常にこのようになります。サーフェス データを DAG にコネクトする特殊なノードがあるので、ジオメトリを作成するノードで DAG ノードを作成する必要はなく、データのみを作成します。

                MObject newSurf = loft( curve, newSurfData, stat );
                if( !stat )
                    return stat;

カーブからロフトされたサーフェスを作成するユーザ定義コードをコールします。このメソッドは、MFnNurbsSurface を使用してサーフェス データ オブジェクト上で動作します。MFnNurbsSurface は、DAG 内のサーフェス上で動作しているかどうかを判断します。DAG 内のサーフェス上で動作していない場合、一部のメソッドはエラーになります。たとえばサーフェス データ オブジェクトは DAG 内にないため、ワールド空間の位置を判断することには意味をなさず、そのメソッドはエラーになります。

                surfHandle.set( newSurfData );

新しいサーフェスをデータ ブロックに追加し、出力を変更します。

                stat = data.setClean( plug );
                if( !stat )
                    return stat;

プラグが問題なく再計算されクリーンになったことがシステムに通知されます。

            }
        }
    }
    else
    {
         cerr << "unknown plug\n";
         return MS::kUnknownParameter;
    } 

プラグが認識されない場合や、特定のキー設定可のプラグで計算が行われない場合は、MS::kUnknownParameter を返す必要があります。これによりベース クラスの compute() メソッドがコールされ、デフォルトのデータ処理を行い次の結果を返します。

     return MS::kSuccess;
}