配列プラグのサイズ確保と値設定

カスタムノードに配列アトリビュートを設定すると、
ついやってしまい勝ちなミスが配列外の参照です。
配列アトリビュートが多数あると、コネクトが正確に行われていない状態で
AEパネルを開くとMayaごと強制終了してしまいます。
その回避さくとして、あらかじめ配列プラグのサイズと値の初期設定を行っておきます。

MArrayDataBuilderを使ったコード例

//ArrayPlug
MArrayDataHandle rotHnd = data.inputArrayValue( rotate, &returnStatus );
MArrayDataHandle flagHnd = data.inputArrayValue( flag, &returnStatus );

if( returnStatus != MS::kSuccess )
	MGlobal::displayError( "Node cannot get value\n" );
else
{
	//PlugからNodeObject取得
	MObject myNodeObj = plug.node( &returnStatus );

	//NodeObjectからDepNodeファンクション取得
	MFnDependencyNode depFn( myNodeObj );

	//rotateプラグの要素数取得
	const unsigned int nElems = rotHnd.elementCount();

	for( unsigned int i=0; i<nElems; i++ ){

		returnStatus = rotHnd.jumpToElement( i );
		if( returnStatus != MS::kSuccess )
			MGlobal::displayError( "Node cannot get value\n" );

		returnStatus = flagHnd.jumpToElement( i );
		if( returnStatus != MS::kSuccess ) {
			//flagプラグにコネクトがなくプラグが確保されていない場合
			//ここで要素数を確保する
			MObject flagAttr = depFn.attribute( "flag" );
			MArrayDataBuilder builder( flagAttr, nElems );
			MDataHandle flagHandle = builder.addElement( i );
			flagHandle.set( (int)0 );
			flagHnd.set(builder);

			flagHnd.jumpToElement( i );
		}

		・
		・
		・
	}
}

この他にももっとスマートな方法はあるかと思いますが、とりあえずのメモ替わりに。
配列プラグの要素確保にはMArrayDataBuilderを使うのがミソのようです。
ハンドルに値をセットするには明示的にキャストしないと入りません。
配列プラグを安定して使えるようにするには結構手間がかかりますねぇ。

コメント / トラックバック2件

  1. Hiei より:

    Mayaのプログラムか…難しそうだな。

  2. tad より:

    Hieiさん、コメントありがとうございます!

    アルゴリズムを考えるのは楽しいですが、
    エラー回避のコードを書くのはしんどいですねぇw
    大抵の場合一つひとつ潰していくしかないですから。
    一遍に解決できる方法が見つかるとありがたいですねぇ。

コメントをどうぞ