ポリゴンの内部処理
 
 
 

基本データ構造は、ポリゴンを表すコンポーネント(フェース、エッジ、頂点)を含みます。これらの構造体はさらにポリゴン シェイプ ノードにカプセル化されて、Maya アーキテクチャの核であるディペンデンシー グラフ内に構造体を提供します。以上のコンセプトは、Maya でのポリゴンの操作およびポリゴンへのインタフェースに不可欠です。

ポリゴン コンポーネント

ポリゴン メッシュは、以下の 3 つの基本コンポーネントから構成されます。

この 3 つの基本的なポリゴン コンポーネント以外に、さらに以下の 2 つの追加コンポーネントがあり、Maya でのポリゴンの操作方法を理解するために重要です。

頂点

ポリゴンメッシュの頂点は 3 次元の float 型の単純配列に格納され、それぞれの頂点には、配列の指定されたインデックスに基づいて頂点 ID が付きます。エッジとフェースは両方とも、この配列に基づいています。

エッジ

ポリゴン メッシュのエッジは、エッジ配列に格納されます。エッジ配列のそれぞれのエッジは、それぞれの頂点 ID を構成する 2 つの整数で構成されます。最初の整数はエッジの開始頂点を表し、次の整数はエッジの終了頂点を表します。これにより、エッジが頂点の構成、方向、エッジ ID(エッジ配列のインデックスで表現)情報を持つようになります。

フェース

ポリゴン メッシュのフェースは整数配列に格納されます。それぞれのフェースは、一連の整数によって記述され、それぞれの整数はエッジ ID によって記述されます。エッジの最初のシーケンスは、フェースの境界を表します。その後のシーケンスは、フェースの穴を表します。それぞれのシーケンスの先頭と末尾は内部フラグによってマークされ、同様にフェースの末尾を表している場所も内部フラグによってマークされます。

フェース オフセットまたはインデックス配列により、フェース配列は補完されます。この配列には、フェース配列での各フェースの記述の開始場所が保存されます。各フェースは、多くのエッジと複数のシーケンスから構成されるので、各フェースの先頭を探しながら配列を調べると冗長になることがあります。このフェースインデックス配列を使用すると、各フェースに関する情報にすばやくアクセスできます。各フェース位置のインデックスは、指定されたフェースのフェース ID と呼ばれます。各フェースの先頭をマークするエレメントに加えて、フェース インデックス配列の末尾には、フェース リストの最終インデックスをマークするエレメントが付きます。この最終インデックスの値により、各フェースの順序(フェースのエッジと頂点の数)にすばやくアクセスできるようになります。

フェース頂点

フェースが相互に隣接している場合、フェースは頂点を共有します。特定の頂点を共有するフェースからその頂点を区別しながら、特定のフェースの特定の頂点にデータを関連付けなければならないことがしばしばあります。これはフェース頂点と呼ばれます。

フェース頂点は、頂点カラーや UV など、ポリゴン フィーチャによって使用される概念コンポーネントです。フェース頂点は、既存データ構造、つまりフェース配列とフェース インデックス配列で表現されます。それぞれのフェース頂点は、指定されたフェース ID と頂点 ID に関連付けられています。フェース ID を使用してフェース配列内でオフセットを検索してから、それぞれのエッジの開始頂点を使用して、エッジ ループ内で特定の頂点 ID を検索できます。各フェースの各頂点 ID は、フェースのある頂点の固有のインデックス、つまりフェース頂点インデックスになります。共有の頂点 ID はフェース配列で複数回出現し、頂点を共有するそれぞれのフェース記述に 1 回ずつ出現します。

以下の図では、(a)が 4 つのフェース(面)を持つポリゴン プレーン(4面ポリゴン)のトポロジを表し、(b)が 4 つのフェース(面)を持つポリゴン プレーン(4 面ポリゴン)のフェース頂点ビューを表します。フェース頂点ビューでは、それぞれのフェースが分離され、それぞれ独自の頂点を維持しています。それぞれの頂点には、それぞれのフェースに対してローカルな頂点インデックスによってラベル付け(0 から 3)されています。また、各フェース頂点には UV が関連付けられています。ただし、フェース頂点ごとに固有の UV が保証されているわけではありません。デフォルトでは、(a)の頂点 4 のように、共有の頂点を表すフェース頂点の場合、それぞれのフェース頂点には同じ UV が関連付けられて UV が共有されています。UV を「分割」すると、共有の頂点の各フェース頂点に固有の UV が提供されます。

以下は、フェース頂点の表現を解釈すると、フェース配列の見た目がどのように変更されるかを説明した図です。

UV

UV は、フェース頂点の概念に大きく依存しています。UV は 2D プレーンに対応し、ポリゴン サーフェスへのテクスチャ マッピングに使用します。テクスチャ マッピングはフェースごとに実行されます。その結果、UV はフェース頂点をベースにマッピングされ、必要に応じて、それぞれのフェースでマッピング座標の独自のセットを持つことができます。Maya で UV を含む構造は、以下の 2 つの配列から構成されます。

最初の配列は、それぞれのフェース頂点を特定の UVId に関連付けますが、フェース頂点が属するフェースがマッピングされていない場合は関連付けしません。それぞれの UVId は、UV が UV 空間に位置している 2D ポイント(U と V の浮動小数値)を維持する UV リストのインデックスに対応しています。

polyShape ノード

コンポーネントは、単独でメッシュのジオメトリを表現できます。しかし、柔軟性に富んだ Maya アーキテクチャに合わせるために、この構造は polyShape ノードという形式でディペンデンシー グラフ アーキテクチャに統合されます。polyShape ノードには、以下の図のように、inMesh、outMesh、cachedInMesh、pnts(ツイーク)という、4 つの基本アトリビュートがあります。

基本アトリビュート

以下では、polyShape ノードの 4 つの基本アトリビュートについて説明します。最初の 3 つのアトリビュートは、それぞれ polyShape ノードのメッシュのコピーを独自にキャッシュします。それぞれの差違は、DG 評価中の評価のステージの差異を表します。

inMesh

polyShape ノードの標準入力アトリビュートです。このアトリビュートは、別の DG ノードから入力メッシュ データを受け取り、ノードを通して outMesh にデータを転送します。outMesh には、ノードに渡されたジオメトリの独自の内部コピーが格納されます。inMesh が有効となるのは、入力コネクションがある場合だけです。入力コネクションが存在しない場合は無視されます。

outMesh

polyShape ノードの標準出力アトリビュートです。このアトリビュートは、ノードの状態によって、inMesh か cachedInMesh から入力メッシュ データを受け取り、メッシュの内部コピーを独自に格納します。outMesh ジオメトリは、シェイプの最終ジオメトリを表しており、常に有効です。

cachedInMesh

polyShape ノードのシミュレート入力アトリビュートです。このアトリビュートは、inMesh アトリビュートが無効で(つまり入力コネクションがなく)、メッシュにツィークが存在する場合に限り、初期化して使用されます。また、ジオメトリの内部コピーを独自に格納します。

pnts

ツィーク アトリビュートです。ジオメトリの各頂点の位置オフセットを格納する配列アトリビュートで、基本コンポーネントの手動によるツィーク(Tweak)が修正を表します。ツィーク が存在するかどうかは、配列アトリビュートでゼロ以外の値を探して判断します。

polyShape データフロー

polyShape ノードのデータ フローは、以下の 2 つの要因によって決まります。

ノードにコンストラクション ヒストリとツィークが存在するということは、ノードに入力コネクションがあり、pnts アトリビュートにゼロ以外の値が存在することになります。この場合は inMesh が有効で、上流ヒストリからメッシュ データを受け取ると、pnts アトリビュートが inMesh データに適用され、生成されるメッシュが outMesh に格納されます。

ノードにコンストラクション ヒストリが存在し、ツィークが存在しない場合、inMesh は outMesh に転送されます。以下は、コンストラクション ヒストリとツィークが存在する場合のデータ フローを表す図です。

ノードにコンストラクション ヒストリもツィークも存在しないということは、入力コネクションがノードに存在せず、pnts アトリビュート配列がすべてゼロであることになります。この場合、InMesh は無効です。しかし、データを転送する必要もツィークを適用する必要もないので、polyShape ノードのジオメトリは outMesh そのものになります。

ノードにコンストラクション ヒストリが存在せず、ツィークが存在するということは、ノードに入力コネクションが存在せず、pnts アトリビュートにゼロ以外の値が存在することになります。この場合は、ツィークを適用する必要があるので、outMesh を使用できません。ツィークを outMesh に直接適用した場合は、元に戻す(undo)機能がないと前の値が失われることになります。このため、シミュレート入力、つまり cashedInMesh が必要になります。これにより、outMesh の現在の状態が格納されてからツィークが適用され、ノードが再評価されます。outMesh ジオメトリが cachedInMesh にコピーされ、ツィークがノードに適用されます。cachedInMesh は、コンストラクション ヒストリとツィークがある inMesh と同じ働きをします。pnts アトリビュートは、cachedInMesh に適用されてから outMesh に転送されます。

ノードのインタフェース

polyShape ノードのインタフェースには、以下の 2 つの基本処理が関連します。

ほとんどの Poly API には、polyShape ノードの構造を認識している accessor メソッドと mutator メソッドがあります。このため、これらのメソッドを使用して、polyShape ノードのジオメトリと適切にインタフェース接続することができます。しかし、ノードのメッシュ データをバックアップする場合など、ノードと直接やり取りしなければならないことがあります。この操作には、プラグの取得、プラグの設定、プラグ データの取得などの DG 操作がほとんど関連します。

データにアクセスする

outMesh は、polyShape ノードのメッシュの最終結果を表すので、常に最新情報を所有します。このため、アクセスする場合はすべて、outMesh から情報を取得します。メッシュをバックアップする場合は、outMesh がノードの最新状態を表すので、outMesh をバックアップします。

データ修正/作成

ノードのデータフローに影響する 2 つの要因、つまりコンストラクション ヒストリとツィークが、ノードの修正方法にも影響します。

コンストラクション ヒストリが存在する場合は(入力コネクションが存在する場合は)、polyShape ノードに上流ノードが存在します。DG 評価中は、polyShape ノードに渡されたデータにより polyShape ノードの inMesh が上書きされ、outMesh が更新されます。このため、ヒストリが存在する場合は、polyShape ノード上でのアトリビュートの設定、またはノードのダイレクト モディファイアは次の DG 評価で上書きされますので避けてください。メッシュを修正するには、修正内容を含むモディファイア ノードを polyShape ノードの上に挿入する必要があります。この修正内容は、ヒストリが存在する限り、ツィークの存在に関係なく適用されます。詳細については、 コンストラクション ヒストリを参照してください。DG では、モディファイア ノードを上に挿入して変更内容の上書きを避ける必要があるので、このケースでは、ノード自体と直接やり取りすることが少なくする必要があります。

コンストラクション ヒストリが存在しない場合は、ヒストリを作成するか、ノードをダイレクト モディファイアします。これは、Maya の「レコード ヒストリ」プリファレンスによって異なります。ヒストリの作成を選択した場合、このケースは、小さなツィークを含む上のケースに類似し、コネクションのセットアップを除いて、ノード自体とやり取りすることは少なくなります。

ヒストリを作成しないでノードに直接書き込む場合は、やり取りが多くなるため、シェイプのアトリビュート構成の目的を理解しておく必要があります。ヒストリとツィークがないノードでは、outMesh はシェイプ ノードのジオメトリのみを表し、その他すべてのメッシュ アトリビュートは無視されます。このような場合は、outMesh を直接操作できます。バックアップ メッシュがある場合は、バックアップ メッシュを outMesh に適用し直すことで、ノードを元の状態に戻すことができます。

ノードにヒストリは存在しないがツィークが存在する場合は、ツィークを適用するために cachedInMesh が outMesh のコピーとして生成されるので、それを使用して最終メッシュを得ます。outMesh を cachedInMesh にコピーする間に、ノードはアトリビュート間で同期化を実行しますが、これはノードに対して内部的なので API からはアクセスできません。このため、cachedInMesh を初期化する前には、outMesh を更新する必要があります。メッシュのバックアップを例に取ると、バックアップ メッシュを cachedInMesh にコピーする場合は、ノードが不安定になるリスクを負うことになります。このため、以下のようなアプローチで実行することをお勧めします。

  1. シェイプ ノードを複製します。
  2. 複製シェイプの outMesh アトリビュートにバックアップ メッシュをコピーします。
  3. バックアップ メッシュの outMesh をシェイプ ノードの inMesh に接続します。
  4. DG 評価を強制実行します。
  5. 複製ノードを切断して削除します。

最初の 3 つの手順は、MEL コマンド polyDuplicateAndConnect を使用して実行できます。

これにより、inMesh を通して outMesh が更新されるので、ノードが切断されて inMesh が無効になると、cachedInMesh がツィークを適用する前の元のメッシュ バックアップを維持します。これについては、 polyModifierCmd の例で説明します。以下で、メッシュのバックアップを復元する場合のデータ フローを説明します。