メタ データ

C++ API のメタ データ クラスは、その他すべての Maya API クラスと同様に .NET API に移植されています。さらに、.NET のパワーを活用するため、いくつかの機能強化が行われています。

メタデータは、Maya API の非常に重要な部分であり、クライアントがカスタム データ(ストラクチャ、タイプ、要素ごとのデータにアクセスする方法など)を記述できるようになります。.NET 機能では、C++ の場合よりも処理を大幅に単純化し、強力にすることができます。

.NET の例

このページに記載した .NET 拡張機能を紹介する興味深い複数の例は、Maya に付属している例にも含まれています(「コンパイルの例」を参照)。Microsoft Visual Studio を使用して examples.sln ソリューション(Developer Kit をインストールした devkit\dotnet\examples フォルダ内、「ビルド環境を設定する: Windows 環境(64 ビット)」を参照)を開くと、これらのサンプルを MetaData フォルダ内で見つけることができます。いくつかの興味深い例を次に示します。

概要

メタデータ API の主なクラスのリストとそれぞれの簡単な概要を、.NET に移植された C++ メソッドのリストとともに次に示します。

Associations

これは、MFnDependencyNode.metadata プロパティを取得することなどによって Maya オブジェクトからメタ データにアクセスするためのエントリ ポイントです。

基本的に、チャネルの単純なコンテナです。

C++ から移植された興味深いメソッドをいくつか示します。

Channel

これは、同じトポロジ(同じストリーム インデックス)を共有しているか、ユーザーが論理的に同じグループになるように決定したため(シミュレーション エフェクトのすべてのストリームが同じチャネルになり、エフェクトの名前であるチャネル名が付けられる場合など)にグループ化されたストリームのコレクションです。

チャネルに名前を付けることができますが、いくつかの名前は予約されています(たとえば、vertex はストリームが頂点ごとに 1 つの要素を持つことを示すために予約されています)。

C++ から移植された興味深いメソッドをいくつか示します。

Stream

これは、オブジェクト上のデータのコンテナです(たとえば、メッシュ上のチャネル vertex では、ストリームにある頂点と同じ数のデータ要素があります)。

C++ から移植された興味深いメソッドをいくつか示します。

Structure

このクラスは、ストリームの各要素で検出されたメタ データについて記述します。

このメソッド AddMember は、メタ データの各フィールドを定義するために使用されます。

たとえば、1 つの float と 1 つのブール値をすべての要素に格納する場合は、最初にストラクチャを作成し、AddMember(kFloat,1,”MyFloatField”)AddMember(kBoolean,1,”MyBooleanField”) を呼び出します。

C++ から移植された興味深いメソッドをいくつか示します。

ハンドル

このクラスを使用すると、ストリームの指定された要素のデータにアクセスすることができます。

ハンドルを使用すると、ストリーム要素のデータを取得または設定することができます。

C++ から移植された興味深いメソッドをいくつか示します。

.NET を利用する

.NET では、メタデータ API にいくつかの拡張機能が提供されます。ここでは、.NET の拡張機能がある API の主なクラスを示します。

Associations

このクラスは Channel オブジェクトのディクショナリとして機能するため、.NET インタフェース IDictionary<Channel> をサポートします。

このインタフェースを使用すると、.NET のディクショナリから予測される次の標準のメソッド/プロパティを使用することができます。

Channel

このクラスは Stream オブジェクトのディクショナリとして機能するため、.NET インタフェース IDictionary<Stream> をサポートします。

このインタフェースを使用すると、.NET のディクショナリから予測される次の標準のメソッド/プロパティを使用することができます。

Stream

このクラスは Handle オブジェクトのディクショナリとして機能するため、.NET インタフェース IDictionary<Handle> をサポートします。

これを使用すると、.NET のディクショナリから予測される次の標準のメソッド/プロパティを使用することができます。

Structure

この構文を有効にするために IEnumerable<Member> が追加されました。

foreach( Member member in myStructure )  { ... }

これを使用すると、複雑な C++/STL 構文の代わりに非常に単純な構文を使用してすべてのメンバーを列挙することができます。

for( StructureIterator iter = myStream.begin(); iter.notEqual( myStream.end() ); iter.next() ) { 
    Member member = iter.__deref__();
    ... 
}

ハンドル

C++ API はポインタを使用する単一メソッド(例: int *asInt32())を使用するため、特定のタイプのデータにアクセスすることができます。単一の整数に対するポインタとして使用できます(例: myInteger = *asInt32())。Structure オブジェクトに対応するメンバーを作成するときに 1 より大きいサイズを指定した場合は、整数値の配列に対するポインタとして使用できます(例: asInt32()[6])。

.NET の場合、API でポインタを使用することはできなかったため、タイプごとに 2 つのプロパティが提供されています。

クライアントの .NET タイプと一致: データの記述とアクセスを簡略化するための最終テクニック

Structure クラスを使用して要素のデータを記述すると、データにアクセスする Handle クラスは次のようにかなり低レベルになり、C++ のようになります。

使用しているタイプの各メンバーが予想される Structure オブジェクトのメンバーとなっているデータを、クラスまたはストラクチャ内で記述している場合は、.NET によってプロセス全体が単純化されます。

新しい StructureClass アセンブリ アトリビュート

プラグインで新しい StructureClass アセンブリ アトリビュートを使用し、メタデータのストラクチャを記述するタイプを指定している場合は、.NET によって Structure オブジェクトを自動的に作成することができます。

[assembly: StructureClass(typeof(MyNameSpace.MyStructureClass))]

namespace MyNameSpace
{
   public class MyStructureClass
   {
      public int a;
      public int b { get; set; }
      public float[] c = new float[3];
   }
}

イントロスペクションのおかげで、.NET はクラス(またはストラクチャ)ですべてのパブリック フィールドおよびプロパティを検索し、Structure.registerStructure を使用して登録されている Structure オブジェクトを自動的に作成することができます。

ストラクチャの名前は、タイプのフル ネームです(MyNameSpace.MyStructureClass など)。各ストラクチャ メンバーの名前は、タイプの対応するメンバーの名前です。

Handle から .NET オブジェクト(またはその逆)に変換する

.NET オブジェクト タイプの新しい StructureClass アセンブリ アトリビュート(前のセクションを参照)を使用する場合は、次に示す Handle クラスの新しいメソッドを使用することができます。

ただし、次のセクションで説明する新しい汎用クラス StreamForType<T> を使用する場合、これらのメソッドは不要になります。

StreamForType: .NET タイプに合わせた Stream クラスの特殊なバージョン

Stream は Structure を記述する .NET タイプを提供できない場合に使用するクラスですが、新しい StructureClass アセンブリ アトリビュートを使用してタイプを提供した場合は、クラス StreamForType<T> を使用する必要があります。

この汎用クラスの T パラメータに同じタイプを使用すると、タイプに合わせて完全にカスタマイズされた Stream のようなクラスが提供されます。

この汎用クラスは Stream オブジェクトのラッパーであり、2 つの方法で作成することができます。2 つのコンストラクタを次に示します。

Stream クラスは Handle オブジェクトのディクショナリとみなすことができますが、StreamForType<T> 汎用クラスは T が .NET クラス(またはストラクチャ)である T オブジェクトのディクショナリとみなすことができます。これは、汎用クラスによってサポートされた IDictionary<T> を使用して実行されます。

いくつかの興味深いメソッドを次に示します。

強力な LINQ を使用して SQL のような照会を実行する

IEnumerable はほとんどのクラスでサポートされているため、データで非常に強力な照会を実行することができます。

たとえば、クラスに振幅というフィールドがあり、振幅が 0.5 よりも大きいメッシュの頂点のチャネルでメタデータを検索する場合、次のようにしてこれを簡単に行うことができます。

 Channel chn = myAssociations["vertex"];
 Stream chnStream = chn[“myStream”];
 var strm = new StreamForType<MyStructureClass>(chnStream);
 var list = strm.Where( ( MyStructureClass obj ) =>obj.amplitude >0.5 );
 foreach( MyStructureClass obj in list ) { … }

頂点インデックスを照会するには、次のように実行できます。

var list = strm.Where( ( KeyValuePair<Index,MyStructureClass> keyvalue ) => keyvalue.Value.amplitude > 0.5 );
foreach (var keyvalue in list ) {  
   Index index = keyvalue.Key;
   MyStructureClass obj = keyvalue.Value;
   …   
}

このタイプの照会は、Associations、Channel、Stream、および Structure のいずれかのクラスで実行できます。これらはすべて、LINQ が必要とする唯一のインタフェースである IEnumerable を実装しているためです。