0から始めるUSDPython(3) Primを作る
0 から始める USDPython(1) と 0 から始める USDPython(2) ステージを検索しよう ではすでに作成されている USD ファイルの読み方と変更方法をやっていきましたが 第 3 回目の今回は、新しい USD ファイルを作り Prim を作っていきます。
新しいステージを作る
まず、空のステージを作るのですが、 新規シーンを作る方法はいくつかあります。 1 つ目が、ファイル名を指定して新規で作る場合。
stage = Usd.Stage.CreateNew('./newScene.usda')
CreateNew では、引数に保存先のファイルを指定し 新規ファイルを作成してから、その USD ファイルをロードします。
こうすると、CreateNew した段階で USD ファイルが作成されるメリットがありますが すでにファイルがある場合は CreateNew の場合はエラーになります。
stage = Usd.Stage.CreateInMemory()
layer = stage.GetRootLayer()
layer.Export("./newScene.usda")
もう 1 つが、CreateInMemory です。 この CreateInMemory は、ファイルを作成することなくメモリ上にだけファイルを作成します。 この場合はファイルが既にあったとしてもエラーになりませんが、 保存するまえはファイルが作成されないのに注意が必要です。
Prim を作る
ステージができたので、次はこのステージに Prim を作ります。
stage = Usd.Stage.CreateInMemory()
prim = stage.DefinePrim("/newPrim")
stage.GetRootLayer().Export("./newScene.usda)
Prim とは、データを入れるためのコンテナ(入れ物)です。 DefinePrim をすると、引数で指定したパスに指定の名前で Prim を作成します。
作成した Prim を usdview で開くと Prim が作成できているのがわかります。 しかし、Type を見ても何も入っていませんし、
Property を見ても、BoundingBox や LocalToWorldXform 等はあるものの 情報がありません。
これは Prim とは「あくまでも入れ物」でしかなく、それがどういったものなのかとか どういう Property が入っているかが入っているわけではありません。 あくまでも階層構造をもった入れ物です。
なので、実際は「こういうデータ構造が入っているよ」という型指定をする必要があります。 USD では、このデータの型を定義するための構造を「 」と呼びます。
from pxr import UsdGeom
cube = UsdGeom.Cube.Define(stage,'/sampleCube')
スキーマを定義した Prim を作成する場合は、 UsdGeom(UsdGeometrySchema)や UsdLux(UsdLightSchema)のようなスキーマクラスの Define 関数を使用します。
スキーマで定義すると、先ほどとは違い Type が指定されているのがわかります。
Property も、Cube を定義するのに必要な size のようなアトリビュートが 指定されています。
# >> UsdGeom.Cube(Usd.Prim(</sampleCube>))
スキーマクラスを使用して Prim を定義した場合は、 Usd.Prim ではなく UsdGeom.Cube のような、スキーマのオブジェクトが帰ってきます。
print(cube.GetSizeAttr().Get())
# >> 2.0
スキーマオブジェクトは、そのスキーマに関連する機能が用意されています。 たとえば、UsdGeomCube であれば、CubeSize を取得したりセットするような関数が 用意されています。
prim = cube.GetPrim()
スキーマオブジェクトではなく、Prim を取得したい場合は、 GetPrim で取得します。
cube = UsdGeom.Cube(cubePrim)
Prim からスキーマオブジェクトを取得する場合は、このようにクラスに Prim を渡します。
Light を作る
これまでは Cube を作っていましたが、次は Light を作ってみます。 とはいえ、ライトもスキーマによって定義されているので 同様の方法で作成できます。
from pxr import UsdLux
light = UsdLux.DistantLight.Define(stage,'/dLight')
# Intensityを取得したい場合 セットなら Get~
print(light.GetIntensityAttr().Get())
DistantLight を作る場合はこのようになります。 このように、3DCG に関連するデータを作成するには指定の定義(スキーマ)を 作成し、そこに指定の Property を設定することで作成できます。