API ガイド > Polygon API >

# ポリゴンの内部処理

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

ポリゴン コンポーネント

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

- 頂点(Vertices)
- エッジ(Edges)
- フェース(Faces)

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

- フェース頂点(Face-Vertices)
- UV (UVs)

頂点(Vertices)

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

エッジ(Edges)

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

フェース(Faces)

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

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

フェース頂点(Face-Vertices)

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

フェース頂点は、頂点カラーや 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(UVs)

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

- フェース配列とまったく同じインデックスを使用する UV インデックス配列(フェース頂点配列として表示されます)。
- UVId によってインデックス付けされた UV ポイントのリストを維持する UV 配列。

最初の配列は、それぞれのフェース頂点を特定の 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 の例で示しています。以下で、メッシュのバックアップを復元する場合のデータ フローを説明します。