アトリビュートとプラグで説明されている、単純なスタティック アトリビュートに加えて、カスタム ノード クラスに複数のデータ値で構成される複雑なアトリビュートを使用することができます。これらは、同じ種類のデータのインスタンスを複数含む配列、または複数の異なる種類のデータで構成される複合になる場合があります。さらに、ダイナミック アトリビュートを使用すると、ノードからアトリビュートをオンザフライで追加および削除できます。
アトリビュートには、既定でプラグが 1 つ関連付けられています。このアトリビュートを単純アトリビュートと呼びます。アトリビュートは、プラグの任意の長さのリストを含むように定義することもできます。この種のアトリビュートを配列アトリビュート(array attributes)と呼び、配列内のプラグを要素(elements)と呼びます。それぞれの要素プラグには、独自の値と接続を持たせることができ、配列を初期化できます。それぞれの要素のデータ型は、アトリビュートが指定する型として定義されます。配列内のそれぞれの要素は、配列 sparse インデックスで識別します。
Maya のハイパーグラフ(Hypergraph)と接続エディタ(Connection Editor)には、要素プラグのインデックスが、アトリビュート名の後で角括弧([])に囲まれて表示されます。
プラグの配列には、配列プラグ(array plug)という別のプラグでアクセスします。このプラグは、関連するプラグに対するアトリビュートを要求したときに返されます。どのようなアトリビュートでも、配列アトリビュートとして定義できます。仕様は MFnAttribute::setArray() メソッドを使用して作成できますが、これはアトリビュートの create() メソッドのコール後にコールしてください。
配列プラグとして定義されるプラグと配列データを含むように定義される単純なプラグを明確に区別してください。どちらの構造も複数の値を含めることができ、「配列」と呼ばれます。
単純な配列の場合、データ型は、pointArray や intArray のように配列として定義されます(許可されている配列型については、「MFnData」クラスの参照ページを参照)。プラグは配列を 1 つのデータ項目として扱います。プラグの値を要求すると、配列全体が返されます。プラグをシーン内の別のプラグに接続すると、接続に沿って配列全体が渡されます。
配列アトリビュートの場合、アトリビュートのデータ型は、int や double など、1 つの値のデータ型になります。配列は要素プラグのリストで、それぞれに 1 つのデータ値が含まれています。それぞれの要素には別々に接続できます。データ項目を取り出すには、配列内のそれぞれのプラグにアクセスし、プラグに保存されている 1 つの値を取り出します。それぞれの方法には、長所も短所もあります。単一アトリビュートでは、データが単体で扱われるので、ディペンデンシー グラフ ネットワークを通して能率的に移動できますが、それぞれのデータ項目にアクセスする柔軟性がありません。配列アトリビュートでは、それぞれのデータ項目にアクセス可能かつ接続可能なので柔軟性は大きいといえますが、ノードとディペンデンシー グラフ ネットワークのオーバーヘッドが多くなります。
このルールに従うと、データ型が配列であるアトリビュートを定義できます。このようなアトリビュートには、要素プラグそれぞれが配列全体を含む配列プラグが含まれます。それぞれの配列には、別々にアクセスできます。上記のとおり、配列プラグどうしの接続はお勧めできません。
アトリビュートは、別のアトリビュートのコレクションとして定義することもできます。このようなアトリビュートは複合アトリビュートと呼ばれ、そのコレクションのメンバーは子と呼ばれます。複合アトリビュートは、特定データ型を含めるのではなく、コレクションを構成するアトリビュートのセットとして定義されます。
複合アトリビュートは、MFnCompoundAttribute クラスを使用して作成します。このクラスには、複合アトリビュートに含まれる子アトリビュートを指定するメソッドが含まれます。詳細については、「MFnCompoundAttribute」の参照ページを参照してください。
それぞれの子アトリビュートは、他のアトリビュートと同様に扱われます。子アトリビュートは名前とデータ型を持ち、配列アトリビュートや複合アトリビュートとして定義できます。プラグは複合アトリビュート自体に関連付けられ、複合アトリビュートのメンバーの親プラグとして参照されます。それぞれの子アトリビュートも、コネクションについては同じルールに従います。子は独立して接続できます。子アトリビュートが配列アトリビュートとして定義されている場合は、その要素プラグもそれぞれ独立して接続できます。それぞれのプラグの子アトリビュートが同一に定義されていれば、複合アトリビュートの親プラグは、別のノードの複合アトリビュートの親プラグに接続できます。この場合は、すべての子プラグのデータが接続に沿って送信されます。複合アトリビュートを配列アトリビュートとして指定すると、配列のそれぞれの要素プラグには、複合アトリビュートのそれぞれのメンバーの子プラグが含まれます。この要素プラグは親プラグになります。
ダイナミック アトリビュートは、ブラインド データをノードにアタッチするために使用します。すべてのノードには、アトリビュートのセットが最初から定義されています。しかし、1 つのノード、または特定の型のノードすべてに新しいアトリビュートを追加したいこともあります。これらのアトリビュートをダイナミック アトリビュートと呼びます。
ダイナミック アトリビュートは、その他のアトリビュートと同じように扱われます。大きな違いは、静的に作成されないため、誰かが割り当てと割り当て解除を行う必要があることです。
以下は、blindShortDataCmd サンプルから抜粋したコードの断片です。このコードでは、ショート変数を格納する単純なダイナミック アトリビュートが作成され、選択されているディペンデンシー グラフ ノードにアタッチされます。blindComplexDataCmd サンプルでは、ユーザ定義データをダイナミック アトリビュートとして追加する方法を示しています。
MFnNumericAttribute fnAttr; const MString fullName( "blindData" ); const MString briefName( "bd" ); double attrDefault = 99; MObject newAttr = fnAttr.create( fullName, briefName, MFnNumericData::kShort, attrDefault, &stat );
これで、「blindData」 (ショート ネーム「bd」)という新しい数値アトリビュートが作成されます。既定値は 99 です。ダイナミック アトリビュートをブラインド データとして使用するときには、複数のユーザが相互にコンフリクトするアトリビュートを作成することがないように、アトリビュートの名前を固有のものにする必要があります。
stat = fnDN.addAttribute(newAttr,MFnDependencyNode::kLocalDynamicAttr); if ( MS::kSuccess != stat ) { cerr << "Error adding dynamic attribute" << endl; }
この数行では、選択されているディペンデンシー グラフ ノードにアトリビュートが追加されます(fnDN は MFnDependencyNode のインスタンスで、別の場所で初期化されている)。MFnDependencyNode::kLocalDynamicAttr が使用されていることに注意してください。これは、新しいアトリビュートがダイナミック アトリビュートであることを示します。