fereria
9/8/2019 - 4:29 PM

Study USD 3日目

# -*- coding: utf-8 -*-
"""
USD学習3日目。

アニメーションさせたり、VariantSetをつくってみた

VariantSetを使用した場合、内部的にLayerが複数作られているので
そのままExportしてもSessionLayer(LayerStackに複数Layerがある状態)にVariantSetが入ってないので
データに反映されてなくてハマった。
(VariantSetもコンポジションアークの1つだから、コンポジション処理になる。なので、usdViewではPrimの色がオレンジ=Compになっていた)

usdファイルを分けていなくても、編集過程で複数のLayerStackができてたりするのが
いまいちよくわかっていない。

Layer = 1 usdファイル
Stage = Layerをコンポした結果

MetaDataもよくわからない
"""

# %%
import os.path
import os
from pxr import Usd, UsdGeom, Sdf, Gf, UsdUtils

Root  = "I:/usd_test"

# %%

sampleFile = Root + "/sample_USD.usda"

newScn = Usd.Stage.CreateInMemory()

# アニメーション ---------- #
newScn.SetStartTimeCode(0)
newScn.SetEndTimeCode(100)

# Mem上に作成したUSDファイルを色々コントロール
worldGeom = UsdGeom.Xform.Define(newScn, "/World")
cubeGeom = UsdGeom.Cube.Define(newScn, "/World/Cube")

# PrimのPath(sdfPath)の作成。
worldPath = Sdf.Path("/World")
helloPath = worldPath.AppendChild("hello")

# Cubeをアニメーション
spin = cubeGeom.AddRotateZOp(opSuffix='spin')
spin.Set(time=0, value=0)
spin.Set(time=100, value=360)

# VariantSet作成 https://graphics.pixar.com/usd/docs/Authoring-Variants.html
cubePrim = newScn.GetPrimAtPath(cubeGeom.GetPath())

# %%
vset = cubePrim.GetVariantSets().AddVariantSet('hogehoge')
vset.AddVariant('red')
vset.AddVariant('blue')
vset.AddVariant('green')
# 現在の選択VariantSetを変更
# GetVariantEditContextで、現在選択中のVariantに対して切り替え後(合成後)の値をSetすることで
# Switchできるようにできる。
colorAttr = UsdGeom.Gprim.Get(newScn, '/World/Cube').GetDisplayColorAttr()

vset.SetVariantSelection('red')
with vset.GetVariantEditContext():
    colorAttr.Set([(1, 0, 0)])
    
vset.SetVariantSelection('blue')
with vset.GetVariantEditContext():
    colorAttr.Set([(0, 0, 1)])

vset.SetVariantSelection('green')
with vset.GetVariantEditContext():
    colorAttr.Set([(0, 1, 0)])

# MetaDataについて
# Strongly Typed (強く定型化されている)
# Extensible (増築できる)
# unvarying(不変)
# Core metadata resolution rules vary(コアメタデータルールは様々である)
newScn.SetMetadata('comment', 'Hello World')

# %%
# Stage上でいろいろコンポジションアークの操作をしていると
# 中がどうなってるのかよくわからなくなる。
# (GetRootLayer、SessinLayer?)

# レイヤースタック確認
for i in newScn.GetLayerStack():
    print(i)
# %%
# 色々レイヤー取得テスト
print(newScn.GetUsedLayers())
# %%
# 現在のレイヤー?
print(newScn.GetSessionLayer())
# Rootのレイヤー?
print(newScn.GetRootLayer())
# %%
print(newScn.GetUsedLayers())
# %%
# 出力するときはRootでExport
newScn.GetRootLayer().Export(sampleFile)
# %%
print(newScn.GetRootLayer().ExportToString())
# %%
# Flattenすると、VariantSetではなく現在選択されているContextでFlattenになる
print(newScn.Flatten().ExportToString())