0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

USDの実践メモ 05 : タイムサンプリング

Posted at

今回は,時系列データに対応した USD ファイルを作成してみます。

タイムサンプリング

時系列データを USD ファイルに含めるのは簡単です。

  • ヘッダに始点タイムコードと終点タイムコードを定義する
  • Primvar データに値をセットするときに,タイムコードで区切って与えるようにする

の 2 点だけです。具体的に見てみます。

ステージファイルの修正

まず,タイムコードの始点と終点の設定ですが,これはステージファイルの作成プログラムを修正して行います。ここでは 16 ステップからなる時系列データを想定しています。

from pxr import Usd, UsdGeom, Sdf

def create_stage():
    stage = Usd.Stage.CreateInMemory()
    UsdGeom.SetStageUpAxis(stage, UsdGeom.Tokens.y)
    UsdGeom.SetStageMetersPerUnit(stage, 0.01)

    # タイムコードの始点と終点の設定
    stage.SetStartTimeCode(0)
    stage.SetEndTimeCode(15)
    
    return stage

メッシュノードの修正

以前の回で,メッシュの頂点を基準にして表示色を設定する例を挙げました。今回はここに時系列データを与えます。前回のシンプルな平板ではつまらないので,少し複雑なトーラスメッシュでテストしてみます。

トーラスメッシュ

トーラスメッシュは次式で定義されます。

\begin{align}
x &= (R + r \cos \theta) \cos(\phi) \\
y &= (R + r \cos \theta) \sin(\phi) \\
z &= r \sin \theta \\
n_x &= \cos(\theta) \cos(\phi) \\
n_y &= \cos(\theta) \sin(\phi) \\
n_z &= \sin(\theta)
\end{align}

$n$ は法線ベクトルです。このメッシュにおいて頂点は何らかの「値」を持っており,それらは等$r$面に沿ったガウス的な分布であると仮定します。つまり,

v = \exp \left(-\frac{s(\theta, \phi, t)^2}{\sigma^2} \right),  \sigma は定数

を考えます。ただし,$s$ には $\theta$ と $\phi$ による「捻り」が加わっており,「経時変化」もあるとします。

s(\theta, \phi) = \frac{1}{2} \left(1 + \cos \left(m \theta - n \phi + \omega t \right) \right)

このようにすると,始点 $t = 0$ では次のような分布になるはずです。ここでは $m, n$はそれぞれ $m = 2, n = 1$ としました。黄色で着色されているところが $v$ の高い領域を表します。

torus_Q0_611x514.png

コードの中身を具体的に見ていきます。

いま,配列 values に全頂点にわたって時系列データが格納されているとします。格納法は「時間」を外側のループとします。つまり,あるタイムコードにおける全頂点データのあとに次のタイムコードの全頂点データが並んでいるとします。

values をもとに全頂点の色データ(RGB)を作成する例を示します。itertools.batched 関数を利用してタイムコードごとにデータをまとめるようにしています(itertools.batched は Python 3.12 の新機能です)。

color3 = []
for v in values:
    color3.append((0.5+0.5*v, 0.5+0.25*v, 0.5-0.5*v))    # Yellow/Grey map
c = [batch for batch in itertools.batched(color3, len(vertices))]

前回と同様にして,PrimvarAPI を使って表示色を設定しますが,色情報とともにタイムコードも入力するところが異なります。ついでに,前回省略した法線ベクトルや表示範囲も設定しておきました。

def create_mesh(stage, path):
    mesh = UsdGeom.Mesh.Define(stage, path)

    # Points, FaceVertexCounts, FaceVertexIndices の設定は前回までと同様.
    ...

    # 表示色の設定
    primvar_api = UsdGeom.PrimvarsAPI(mesh)
    primvar = primvar_api.CreatePrimvar('displayColor', Sdf.ValueTypeNames.Color3f, interpolation=UsdGeom.Tokens.varying)
    frame_range = np.arange(stage.GetStartTimeCode(), stage.GetEndTimeCode() + 1, 1, dtype='int32')
    for frame in frame_range:
        time_code = Usd.TimeCode(float(frame))
        primvar.GetAttr().Set(c[frame], time_code)

    # 法線ベクトルの設定
    mesh.CreateNormalsAttr(normals)

    # 表示範囲
    extent = UsdGeom.Boundable(mesh.GetPrim()).ComputeExtent(Usd.TimeCode(0))
    mesh.CreateExtentAttr(extent)
    
    ...

    return mesh

以上より,USD ファイルは次のようなものになりました。usdchecker によるチェックもパスしています。

#usda 1.0
(
    defaultPrim = "World"
    endTimeCode = 15
    metersPerUnit = 0.01
    startTimeCode = 0
    upAxis = "Y"
)

def Xform "World"
{
    def Mesh "Mesh"
    {
        uniform bool doubleSided = 0
        float3[] extent = [(-2.5, -2.5, -0.5), (2.5, 2.5, 0.5)]
        int[] faceVertexCounts = [3, 3, 3, ... ]
        int[] faceVertexIndices = [0, 1, 2, ... ]
        normal3f[] normals = [(1, 0, 0), (0.980785, 0.19509, 0), ... ]
        point3f[] points = [(2.5, 0, 0), (2.45196, 0.487726, 0), ... ]
        color3f[] primvars:displayColor (
            interpolation = "varying"
        )
        color3f[] primvars:displayColor.timeSamples = {
            0: [(0.5, 0.5, 0.5), (0.5, 0.5, 0.5), ... ]
            1: [(0.5, 0.5, 0.5), (0.5, 0.5, 0.5), ... ]
            ...
            15: [(0.5, 0.5, 0.5), (0.5, 0.5, 0.5), ... ]
        }   
        uniform token subdivisionScheme = "none" 
    }
}            
$ usdchecker Mesh.usda 
Success!

ビューワで表示すると,着色部分が周回するように変化する様子が確かめられます(上段左から $\omega t = 0, \ \pi/2, \ \pi, \ 3\pi/2$ の図)。

Q0_611x514_s.pngQ1_611x514_s.png
Q2_611x514_s.pngQ3_611x514_s.png

まとめ

時系列データを USD ファイルに含める手法についてまとめました。

参考資料

ft-lab (Yutaka Yoshisaka) さん,あんどうめぐみさん による以下のサイトが理解の助けになりました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?