meson で pixar usd をビルドする

`usd-23.05`

# meson build

結局 meson でビルドする版 fork 作った。
cmake のかわりに meson でビルドするだけ。
全部対応したわけでは無いが `usdImagingGL` で遊べるところまで準備した。

https://github.com/ousttrue/USD

:::note
cmake 版に比べたメリット。

デバッグ版の見通しが良い。
既存ライブラリの cmake に頼らないので、デバッグ版の dll の配置場所や名前を変えられ(`_d` がつくなど)て困るということが起きない。
install までコントロールしたので `meson install` で即動く状態にできた。
`PXR_PLUGINPATH_NAME` せずとも OK。
:::

## meson の dependency として使う方法

### wrap-git

使う側で `subprojects/usd.wrap` を作成し下のように記述する。

```
[wrap-git]
url = https://github.com/ousttrue/USD
revision = Branch_v23.05
depth = 1

[provide]
usd_usd = usd_usd_dep
usd_imaging = usd_imaging_dep
usd_usdImaging = usd_usdImaging_dep
```

### use dependency

meson.build 側で dependency を下記のようにすると使える。

https://github.com/ousttrue/usd_cpp_samples/blob/master/meson.build

```
# pxr/base と pxr/usd 
usd_usd_dep = dependency('usd_usd')
# pxr/imaging
usd_imaging_dep = dependency('usd_imaging')
# pxr/usdImaging
usd_usdImaging_dep = dependency('usd_usdImaging')
```

:::note warn
c++ が新しすぎるとコンパイルが通らないなど問題が出る。
meson では下記のように依存に対して `c++std` を指定できます。

```
# pxr/base と pxr/usd 
usd_usd_dep = dependency('usd_usd', default_options: ['cpp_std=c++14'])
usd_imaging_dep = dependency('usd_imaging', default_options: ['cpp_std=c++14'])
usd_usdImaging_dep = dependency('usd_usdImaging', default_options: ['cpp_std=c++14'])
```

:::

### .gitignore 

次のようにするのがおすすめ
必要な `wrap` 明示したいため。

```
/subprojects/*
!/subprojects/packagefiles
!/subprojects/usd.wrap
```

::: note warn
meson 実行時に subprojects の subprojects の `wrap` が出現することがある(wrap-redirect)。
これは commit しない。
:::

# USD のビルド

## 最小構成と依存ライブラリ

boost と tbb 依存は必須。
python バインディングを使わないなら、boost は headeronly 使用にできるのでアーカイブを解凍するだけでよい。
tbb は usd が使うバージョンの prebuilt を使った（最新版だとビルドが通らない)。

pxr/base および pxr/usd まではこれでビルドできる。

## imaging と opensubdiv

imaging 部分はオプションを付けなくても opensubdiv は必須となる。
opensubdiv は OpenGL ビルドが必要。
opensubdiv は長大な cmake をさけて適当にビルドしなおした。
- osd_stringify で事前にコード stringify 済み
- glloader は glew
vc では static ビルド専用？よくわからず。

## c++ エラー

### include もれ

```c++
#include <array> // どっか足りないとこがあった
```

### from c++17 ?

```c:stb_image.h:4552
// 無名 struct の禁止
typedef struct {
// 👇
typedef struct _ {
```

### from c++20

```c++
std::shared_ptr<T>::unique() // 消滅

// use_count に置き換え
```

```c++:subprojects\usd\pxr\base\tf\weakPtrFacade.h
// operator== の stack overflow
// C5232 警告が出る。ビルドはできる。
```

# USDの構成

## base

`pxr/base` に格納されているUSDのコアライブラリ。
plugin ではないので `plugInfo.json` を持たない。

## usd

`pxr/usd` に格納されている。
plugin であるものは `plugInfo.json` を持つ。
ここまでが USD のコア。

## imaging

`pxr/imaging`

usd のシーン(とは限らない)を画像にレンダリング(imaging) する機能。
hydra システム。

hydra のデフォルト実装として `hdStorm` がある。
この層は追加の依存ライブラリとして `OpenSubdiv` が必須である。

:::note warn
usd と imaging と usdImaing の名前が間違いやすい。
間違ってリンクエラーがなおらない。

`usd_usdImagingGL.dll` のビルドが難航した・・・
:::

## usdImaging

usd を hydra に送り込むための便利機能集？

### usdImagingGL

OpenGL ビューポートに usd シーンを描画する便利インタフェース。
自前アプリに描画画面を載せられる。

https://fereria.github.io/reincarnation_tech/usd/cpp/viewport_02

https://github.com/cpichard/usdtweak

# USD の初期化挙動

ライブラリが plugin システムでできていて、
最初に plugin をまとめて登録、必要に応じてロード、実行というような挙動をします。

plugin 登録のエントリーポイントが `plugInfo.json` です。
まず、`plugInfo.json` の情報を検索して、目的のものが見つかったら 対応する `dll` のパスを取得して、実行するという手順になります。

:::note
root は以下のようになっていて、サブフォルダを読み込みます。

```json:plugInfo.json
{
    "Includes": [
        "*/resources/"
    ]
}
```
:::

:::note
- plugInfo.json のデフォルトの検索パスがハードコーディングされている
- plugInfo.json に dll のファイル名が書いてある

ことにより debug ビルドで dll に `_d` がついているとか、
違うフォルダに入っているとかがあると辻褄が合わなくなりやすいです。
`release` しか動かない状態になりがちです。
:::

## plugin 置き場のフォルダ構成

```
BUILD
  bin # 本体
    usd_plug.dll
    usd # 👈 PXR_BUILD_LOCATION で決まる
      plugInfo.json # root
      ar/resources/plugInfo.json # pxr/usd/ar に対応する
      usd/resources/plugInfo.json # pxr/usd/usd に対応する
  plugin # external 置き場。
    usd # 👈 PXR_PLUGIN_BUILD_LOCATION で決まる
      plugInfo.json # root
```

最終的に、下記の `result` に root の `plugInfo.json` のあるフォルダが入っている必要があります。

https://github.com/PixarAnimationStudios/OpenUSD/blob/v23.05/pxr/base/plug/initConfig.cpp#L122

デフォルトでは２つ入るようです。

- DLLのフォルダ + `PXR_BUILD_LOCATION`
- DLLのフォルダ + `PXR_PLUGIN_BUILD_LOCATION`

`BUILD\\bin\\usd;BUILD\\plugin\\usd`

- Pluginが要求される
- シングルトンのPlugin登録所要求される
  - Plugin登録所の初期化
    - root plugInfo.json 読み込み。サブフォルダの `plugInfo.json` もすべて読み込まれて登録される
- Plugin 探索
  - 条件に合う Plugin が発見されたら dll のパスを得る(plugInfo.json に書いてある)
- dll を使う

:::note
環境変数 PXR_PLUGINPATH_NAME で root plugInfo.json の場所を追加できる。
:::

:::note

環境変数 `TF_DEBUG=PLUG_*` とするとプラグインのロード状況がわかる

:::

# cmake の読み方
だいたい同じパターンで、`pxr_library` 関数で `dll` が定義されています。
python を使わない場合、
`PUBLIC_CLASSES`, `PRIVATE_CLASSES`, `CPPFILES` でコンパイル対象の `.cpp` になります。
LIBRARIES でリンク対象がわかります。
以上を踏まえて meson.build にわりと機械的に移植できます。

また、RESOURCE_FILES により plugInfo.json や関連アセットのコピーをします。

```cmake:pxr/base/plug/CMakeLists.txt
pxr_library(plug
    LIBRARIES # 依存ライブラリ
        arch
        tf
        js
        trace
        work
        ${Boost_PYTHON_LIBRARY}
        ${TBB_tbb_LIBRARY}

    INCLUDE_DIRS
        ${Boost_INCLUDE_DIRS}
        ${TBB_INCLUDE_DIRS}

    PUBLIC_CLASSES # ".cpp" を追加してソースとして扱う
        interfaceFactory
        notice
        plugin
        registry
        staticInterface

    PRIVATE_CLASSES # ".cpp" を追加してソースとして扱う
        debugCodes
        info
        testPlugBase

    PUBLIC_HEADERS
        api.h
        thisPlugin.h

    CPPFILES # ソース
        initConfig.cpp

    PYTHON_CPPFILES
        moduleDeps.cpp

    PYMODULE_CPPFILES
        module.cpp
        wrapNotice.cpp
        wrapPlugin.cpp
        wrapRegistry.cpp
        wrapTestPlugBase.cpp

    PYMODULE_FILES
        __init__.py

    DOXYGEN_FILES
        overview.dox

    RESOURCE_FILES # 👈 hdSt から抜粋。重要
        plugInfo.json
        shaders/basisCurves.glslfx
        shaders/compute.glslfx

)
```

# python: pip 版

https://pypi.org/project/usd-core/

コアだけですが本家版があります。

> It does not provide any of the optional plugins or imaging feature

`C:\Python310\Lib\site-packages\pxr\pluginfo/plugInfo.json` が root になっています。

# デバッグ

https://qiita.com/takahito-tejima/items/c065c7cd5c3a7abe14f1

plugin の配置ミス、usda の記述エラーの追跡に。

# 参考

https://openusd.org/dev/api/index.html

3年前。
同じところではまって、メモが残っていた。

https://qiita.com/ousttrue/items/b5f34e0f2441ca74467e