コンポーネント

視覚的なフィードバックとアトリビュートの操作を必要とするシェイプ、たとえばコントロール ポイントをベースとしたシェイプなどには、これらのアトリビュートにコネクトされたコンポーネントがあることが必要です。ポリゴン メッシュやスプライン サーフェスなどのシェイプには、選択して操作できるコントロール頂点(CV)が含まれています。このコントロール頂点(CV)はシェイプ上でアトリビュートとして存在し、コンポーネントとして表現して Maya 内でインタラクティブに表示できます。

コンポーネントは 2 つの情報を含むオブジェクト(MObject)です。2 つの情報とは、コンポーネントのタイプと、インデックスの値か範囲です。例としてメッシュ シェイプの頂点コンポーネントが挙げられます。このコンポーネントでは、vtx[0] がメッシュの頂点 0、vtx[0:7] がメッシュの最初の 8 個の頂点を表します。

コンポーネントの作成、編集、照会に使用するクラスは以下のとおりです。

コンポーネントは、インデックスの次元に従って 3 つのカテゴリに分類されます。3 つの種類とは、シングル インデックス、ダブル インデックス、トリプル インデックスです。種類の例として、メッシュ頂点(シングル インデックス)、NURBS サーフェス CV (ダブル インデックス)、ラティス ポイント(トリプル インデックス)が挙げられます。

コンポーネントにはすべてマークを付けることができます。これは、コンポーネントが 0 から numElements-1 までのインデックスによって完全なセットを表していることを意味します。

コンポーネント シェイプを作成する

コンポーネントをサポートするサーフェス シェイプを作成する場合、MPxSurfaceShape クラスより MPxComponentShape クラスから始める方が適切です。MPxComponentShapeMPxSurfaceShape から派生して、コンポーネントをサポートするシェイプで作業するための基本機能を提供します。

シェイプのユーザ インタフェース アスペクトを編集する必要がある場合、MPxSurfaceShapeUI クラスから派生させます。このクラスでは、シェイプ内の任意のコンポーネントの描画とインタラクティブな選択が可能です。

アトリビュートをコンポーネントにマッピングする

Maya では、コンポーネントを文字列で指定します。それぞれの種類のコンポーネントには別々の文字列の名前があります。API でのコンポーネントは、API のタイプによって区別される MObject です(「MFn.h」を参照)。たとえば、メッシュ頂点コンポーネントは Maya では vtx[0] として指定でき、プラグインでは apiType MFn::kMeshVertComponent を伴う MObject として表されます。インデックス情報は、MFnComponent 派生クラスを使用して抽出されます。

コンポーネントを Shape アトリビュートのうちの 1 つに関連付ける(マッピングする)には、Maya の既存コンポーネント タイプのうち 1 つを選択し、MPxSurfaceShape::componentToPlugs をオーバーライドしてコンポーネント タイプをプラグに変換する必要があります。

以下は、メッシュ頂点コンポーネントをシェイプの mControlPoints アトリビュートに関連付ける例です。

void yourShape::componentToPlugs( MObject& component,
 				 MSelectionList& list )const
{
     if ( component.hasFn(MFn::kMeshVertComponent) ) {
         MFnSingleIndexedComponent fnVtxComp( component );
         MObject thisNode = thisMObject();
         MPlug plug( thisNode, mControlPoints );
         int len = fnVtxComp.elementCount();
         for ( int i = 0; i < len; i++ ) {
             MPlug vtxPlug = plug.elementByLogicalIndex(
             fnVtxComp.element(i) );
         list.add( vtxPlug );
         }
     }
}

コンポーネントの一致

MEL では、アトリビュートを文字列として指定できます。シェイプではこの文字列を確認し、適切な名前やインデックスなどが指定されたことを確かめられるようにする必要があります。メソッド MPxSurfaceShape::matchComponent はこの目的のために使用します。

virtual MatchResult matchComponent( const MSelectionList& item,
 				 const MAttributeSpecArray& spec,
 				 MSelectionList& list );

このメソッドでは、文字列として指定されたコンポーネント名とインデックスが確認され、渡されたセレクション リストに対応するコンポーネントが追加されます。select shape1.vtx[0:7] などの選択コマンドはこのメソッドで確認され、対応するコンポーネントがセレクション リストに追加されます。

アトリビュート仕様(MAttributeSpec)は、アトリビュートの指定方法に関するすべての情報に簡単にアクセスできるクラスです。この情報には、アトリビュートの名前、インデックス、範囲が含まれます。

コンポーネントの反復

Maya でコンポーネントの位置の取得と設定を行うには、クラス MPxGeometryIterator から派生させてジオメトリのイテレータを定義する必要があります。

ジオメトリ イテレータは、コンポーネントが選択された場合にマニピュレータを配置する場所を決めるために、移動/回転/スケール マニピュレータで使用されます。

デフォーマでも、シェイプのポイントを変形するために、setPoint とポイント メソッドをオーバーライドしたジオメトリ イテレータが必要です。

一般的には、以下のメソッドを MPxGeometryIterator からオーバーライドする必要があります。

 MPxGeometryIterator( void * userGeometry,
 MObjectArray & components );
 MPxGeometryIterator( void * userGeometry,
 MObject & components );
 virtual void reset();
 virtual MPoint point() const;
 virtual void setPoint( const MPoint & ) const;

イテレータをシェイプに関連付けるには、MPxSurfaceShape の以下の関数をオーバーライドする必要があります。

 virtual MPxGeometryIterator* 
 geometryIteratorSetup( MObjectArray&, MObject&, bool );
 virtual bool acceptsGeometryIterator( bool writeable );
 virtual bool acceptsGeometryIterator( MObject&,
 bool, bool );

コンポーネントの移動、スケール、回転ツール

移動ツール(Move Tool)、回転ツール(Rotate Tool)、スケール ツール(Scale Tool)をサポートするには、メソッド MPxSurfaceShape::transformUsing をオーバーライドする必要があります。この関数は、行列とコンポーネントの配列を引数として取ります。行列は適用される変換を指定し、コンポーネントは変換されるアトリビュート インデックスを指定します。

多くのコントロール頂点(CV)を含むシェイプでは、Maya の計算メカニズムに依存すると、アトリビュート値の設定処理が非常に遅くなることがあります。このような状況ではメソッド MPxNode::forceCache を使用し、ノードのデータ ブロックに直接アクセスして、計算せずにアトリビュート値を直接取得または設定できます。この場合は特に注意して、変更するアトリビュートに依存するすべてのアトリビュートも確実に更新する必要があります。たとえばメッシュの頂点を変更する場合は、法線とバウンディング ボックスも更新する必要があります。移動ツールを法線移動モードで動作させる場合は、メソッド vertexOffsetDirection をオーバーライドする必要があります。