USD 入門編１：ライブラリ概要

これは Pixar USD http://openusd.org に関する情報です。
2016/7/27 時点でのアルファ版に基づいており、モジュール構成などは今後変更される可能性があります。

前回の記事: [USD(ユニバーサルシーンディスクリプション）] (http://qiita.com/takahito-tejima/items/3c2fa4a4a83aa04b9a0e)

# ライブラリ概観
何よりも試してもらうのが一番なわけで、ビルドの仕方を書こうと思ったのですが、2016/7月末現在で USD のビルドは実は結構大変です。かつ OSX や Windows の対応はまだ途中のため、linux 環境が必要になります（VM上でも基本的な動作確認はできますが、GLレンダラーの Hydra が動きません）。

それでも試したい、という方には、https://github.com/PixarAnimationStudios/USD こちらにある依存ライブラリと手順通りに進んで頂ければ一応ビルドは出来るはずです。これらのバージョンは基本的には [VFX リファレンスプラットフォーム](http://www.vfxplatform.com/) に準拠する形で決められており、今後もそれに従って更新されていくと思います。
オープンソースにしたことで今後は環境依存の部分は緩和されていくと期待していますが、現時点では完全に一致するバージョンを使っていただくのが無難かと思います。

今回はビルドはひとまずおいておいて、まずは中身を見て回ろう、という方のためのガイドです。

# 用語
いくつか注意しておきたい、頻出するUSDの用語がありますので、大事なものをここにまとめておきます

|用語|意味|
|:--|:--|
|Prim(プリム)|プリミティブのことですが。一般的にはシーングラフ上のある一つのオブジェクトを指します（キューブ、球、メッシュなど）|
|Variant（バリアント）|あるプリム上で定義される、バリエーションのことです。|
|Stage（ステージ）|シーングラフを保持する一番外側のコンテナです。ステージからは、Pcp のルールにもとづいてコンポジットされた複数のレイヤーを通してシーングラフにアクセスすることができます。|
|Layer（レイヤー）|Stage中の個々の Prim の元になる、コンポジション前の PrimSpec を保持するコンテナです。|
|Asset(アセット）|USDでは、文字列によって識別されるデータの塊で、通常一つまたは複数のファイルが対応します。多くの場合バージョンコントロールが行われる単位でもあります。|
|Gprim（ジープリム）|RenderMan 由来のピクサー用語ですが、Geometric Primitive の略で、描画可能なオブジェクトのことを指します。|

USDのコンポジション用語についてはまた別途詳しく見ていきます。

# ライブラリ構造
[github レポジトリ](https://github.com/PixarAnimationStudios/USD) からクローンすると、以下のようなディレクトリ構成になります（一部省略）


|top dir|内容   |
|:-:|:-:|
|pxr|usd, hydra およびベースライブラリ   |
|extras| サンプル、チュートリアル |
|third_party|maya, katana プラグイン  |

pxr の中は次のようになっています

|   |ライブラリ|用途|
|:--|:-:|:--|
|base|arch|Architecture Dependent: プラットフォーム（処理系）依存レイヤーです。linux, OSX, winなどの差異を扱います|
|   |tf|Tools Foundations: C++の基本的な処理をまとめたライブラリです。参照カウント、型システム、デバッグ出力、シングルトン、メモリ管理などがあります    |
|   |gf|Graphics Foundations: ごく基本的なグラフィックス処理用の数学ライブラリです。ベクトル・行列・クオータニオンなどの定義があります。|
|   |js|Json: JSON のI/Oライブラリです|
|   |plug|Plugin Framework: プラグインシステムの実装です。このAPIを通してアプリケーション固有の拡張をDSO経由で行えます。|
|   |work|Multi-threaded Dispatch: マルチスレッディングの抽象化レイヤーです。現状はデフォルトでTBBを使いますが、必要に応じてスレッディングライブラリを切り替えられるようにしています。|
|   |vt|Value Types: 数値型や配列のデータコンテナとして使われる型です。python から USD データに簡単にアクセスできるように作られています。   |
|imaging|garch|GL architexture Dependent: OpenGL のプラットフォーム依存部分があります|
|   |glf|GL Foundations: GL のコンテキスト処理やテクスチャの管理部分などがあります。ここはかなり暫定的です。|
|   |glfq|GL Foundations Qt: QtOpenGL のコンポーネントがあります。デバッグコンテキストを QtGLWidget で使うためのクラスなどです。これもかなり暫定的です。|
|   |hd|Hydra: レンダリングエンジン Hydra のコードがあります。 |
|   |hdx|Hydra Extensions: Hydra のレンダーグラフやピッキング・ハイライティングなどを扱うハイレベルライブラリです。現状のリリースではあまり洗練されていません。|
|   |pxOsd|OpenSubdiv: OpenSubdiv のデータ型やラッパークラス、サブディビジョンサーフェス（メッシュ）のデータ構造などがあります。これらのクラスはいずれ OpenSubdiv 側に統合される可能性があります。|
|   |cameraUtil|Camera Utilities: カメラのフレーミング情報などを扱うユーティリティクラスがあります。   |
|usd|ar|Asset Resolution: アセットのパスを解決するためのプラグインポイントです。シーンのリファレンス時に重要な役割を果たします。|
|   |pcp|PrimCache Population: レイヤーやリファレンスなど、シーングラフコンポジションの中核になるモジュールです。 |
|   |sdf|Scene Description Foundations: USD のデータモデル（プリム、アトリビュート、リレーションシップ、メタデータなど）を定義するモジュールです。またそれらのファイルフォーマット処理や、シーンディスクリプションを操作するための基本的な抽象構造である、SdfPath, SdfLayer, SdfPrimSpec といったクラスを提供します。|
|   |usd| Universal Scene Description (Core): USD の中核部分になるモジュールです。 |
|   |usdGeom| USD Geometry Schema: DCCツールのパイプラインで利用する３Dグラフィックスデータのプリミティブ（オブジェクト）やプロパティのスキーマが定義されています。 |
|   |usdShade| USD Shading Schema: レンダリング用のシェーディングスキーマが定義されています。|
|   |usdHydra| USD Hydra Schema: Hydra が利用可能なハードウェアシェーディングのスキーマが定義されています。 |
|usdImaging|usdImaging|UsdImaging: Hydra の USD 向けアダプタを実装します。  |
|   |usdviewq|usdview: usdview のGUIを構築する python スクリプトです。python バインディングを経由して UsdImaging が描画処理を行います。|


それぞれモジュールごとに依存関係はありますが、usd 自体は３Dジオメトリとは直接の関係がないという点に注意してください。メッシュ構造やトランスフォームといった機能は UsdGeom 側に、あるいはシェーディング情報は UsdShade に個別にスキーマとして定義されています。これによって、自由にスキーマを定義して usd のシーングラフの持つ機能を別の用途に使うことも可能になっています。XMLとHTMLの関係に似ていると思います。

また、imaging ライブラリは usd に直接依存していません。hydra は単体でレンダリングエンジンとして使うことも可能です（ただし、現状 hydra は SdfPath をインデックスに利用しているため、sdf は必要です）。hydra のインターフェースについてはまた後日詳しく解説したいと思いますが、基本的には SceneDelegate というクラスを通してシーングラフにアクセスします。hydra 自身はフラットで単純なインデックスのみ持っており、シーングラフは管理しません。usdImaging コンポーネントは、hydra の SceneDelegate インタフェースを使って(UsdImagingDelegate クラス）、usd のシーングラフを hydra に渡す役目をします。

hydra が必要ない場合（usd データを自分のレンダラで描画するケース）は、imaging/usdImaging モジュールはビルドする必要がありません。base と usd があれば大丈夫です。

プラットフォーム依存処理はなるべく arch, garch にまとめるようにしていますが、まだ完全に整理しきれていない部分もあります（glfqなど。全体的に imaging モジュール類はまだ完成度が低いです）。

# どこから？
クライアントサイドからみて、真っ先に必要になるであろうモジュールは sdf と usd です。とりわけ UsdStage, SdfPath がシーングラフの操作のほとんどを占めますので、こちらのクラスから見ていくと良いかと思います。hydra の入り口は HdSceneDelegate、HdEngine::Draw （初期リリースでは deprecated とコメントしてありますが、このAPIは残ります。すいません）。おそらく hd/testenv/testHdBasicDrawing.cpp が現状最も簡単な hydra のサンプルになっていると思います。もし usd だけを hydra で描画したい場合は、UsdImagingHdEngine だけを使えば簡単に行うことができます。こちらは usdImaging/testenv/testUsdImagingBasicDrawing.cpp がシンプルな例になるかと思います。

現状まだまだアルファ版ということで、今後の正式リリースまでにもう少しちゃんと整理されてくるはずですが、コアになるコンセプトは変わらないと思いますので、どうぞ見てやってください。

次回は SdfPath について、詳しく説明していきたいと思います。