より複雑なサンプル
 
 
 

以下は、これまでより少し複雑なサンプルの一部です。このコードサンプルは 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;
 }