Metadata-Version: 2.4
Name: houdini-asset-library
Version: 0.6.0
Summary: Houdini Asset Library: save Houdini nodes as Hscript (cmd) and whole scenes as hip, and recall them from a standalone browser app
Author: hamu-dev
License-Expression: MIT
Keywords: houdini,sidefx,node,library,hscript
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Environment :: Win32 (MS Windows)
Classifier: Environment :: X11 Applications :: Qt
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: PySide6
Requires-Dist: Pillow
Requires-Dist: markdown-it-py
Requires-Dist: mdit-py-plugins
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-qt; extra == "dev"
Dynamic: license-file

# Houdini Asset Library (HAL)

Houdini のシーンやノードを保存し、独立したブラウザアプリから呼び出すツールです。扱うもの（アセット）は 2 種類だけで、メイン画面の「シーン」「ノード」の 2 つのタブで切り替えます。

| 種類 | 対象 | 保存形式 | 復元の方法 |
|---|---|---|---|
| **シーンアセット** | 現在のシーン全体 | hip（大きなシーンでも数秒で登録・開ける） | シーンを開く（名前なし / 保存先を指定）、現在のシーンにマージ。外部ファイルの収集・検索置き換え、環境変数の保存と復元ができる |
| **ノードアセット** | 選択したノード群（または現在のネットワーク全体） | Hscript（cmd） | 現在のネットワークへ追加、新規シーンにインポート。収集や環境変数は持たない（外部ファイルは「依存」に読み取り専用で並ぶだけ） |

Houdini のシェルフ「HAL」は **Save Scene** / **Save Node Asset** / **Open Library** の 3 つです。ノードの右クリックにも「HAL: Save Node Asset」があります。アプリは Houdini から起動すると、その Houdini の前に表示されます。

## 必要環境

- Windows
- Houdini 20.5 / 21.0 / 22.0（22.0.429 と 21.0.512 で動作を確認しています。確認した範囲は「Houdini の版ごとの確認状況」を見てください。20.5 は Python 3.11 用の起動フックを同梱していますが未確認です）
- Python 3.11 以降（アプリ本体用。Houdini 内蔵の Python とは別です）。**Houdini 21 以降なら、付属の Python でアプリを動かせるので、各 PC への Python のインストールは不要です**（下の「Houdini 付属の Python で使う」）
- TortoiseSVN（任意。SVN でバージョン管理するときだけ。コミット・履歴・差分の画面に使います）

## インストール

1. pip で導入します（仮想環境の利用をおすすめします）。PySide6 などの依存も一緒に入ります。

   ```
   python -m venv hal-env
   hal-env\Scripts\pip install houdini-asset-library
   ```

2. Houdini のユーザー設定に package を導入します。

   ```
   hal-env\Scripts\hal-houdini install
   ```

   `Documents\houdini22.0\packages\hal.json` が作られます。別の版は `--houdini-version 21.0`、設定フォルダが標準の場所に無いときは `--prefs-dir <フォルダ>` で指定します。`hal-houdini status` で導入状態を、`hal-houdini uninstall` で撤去（`hal.json` の削除）ができます。

3. Houdini を再起動します。通常どおり起動した Houdini（GUI）では、起動時にブリッジが自動で立ち上がります。ブリッジは `127.0.0.1` だけで待ち受けます。

4. アプリを起動します。

   ```
   hal-env\Scripts\hal
   ```

   コンソールは出ません。`python -m hal` でも起動できます。起動済みのときは、新しいウィンドウを作らず既存のウィンドウが前面に出ます。Houdini のシェルフ「HAL」の `Open Library` からも起動できます。

`hal.json` には、いま使っている Python の場所が書かれます。Python の環境を作り直したり移動したりしたときは、`hal-houdini install` をやり直してください。

## 旧版（Houdini Node Library / HNL 0.5.x 以前）からの移行（0.6.0）

0.6.0 で名前を **Houdini Asset Library（HAL）** に改めました。PyPI の配布名は `houdini-asset-library`、コマンドは `hal` / `hal-houdini`、import 名は `hal` です。旧版（`houdini-node-library`）は更新されないので、新しい名前を入れ直します。

```
pip uninstall houdini-node-library
pip install houdini-asset-library
hal-houdini install
```

- `hal-houdini install` は、同じ場所に旧版の `hnl.json` が残っていれば削除してよいか聞きます（`--yes` で確認なし）。書き出した一式を使っている場合は、これまでと同じ出力先へ `hal-houdini export` を実行すると、`hal.json` と `hal_package/` を書いたあとで、旧版の `hnl.json` と `hnl_package/` を不要として扱います（SVN 管理下では「不要:」の一覧表示のみ。`--prune` で削除）。
- 設定（`%APPDATA%\HNL`）は、初回起動時に `%APPDATA%\HAL` へ**コピー**されます（旧フォルダは消しません）。環境変数は `HNL_*` を `HAL_*` に改めてください（当面は `HNL_*` も読み、使っているとお知らせが出ます）。
- 既存のライブラリ（`item.json`、`nodes.cmd` の `$HNL_ITEM` など）は変更なしで読めます。`hnl://item/<id>` のリンクも受け付けます。
- 旧版の Houdini 側ブリッジ（`hnl_bridge`）が起動したままの Houdini には、新しいアプリは繋がりません。Houdini を再起動してください。

## 一時的なアイテムとリンクで渡す（0.6.0）

専用の共有機能（共有コードなど）はありません。1 回きりで渡したいものは、登録ダイアログの「一時的（有効期限つき）」にチェックして登録し（既定 7 日）、「リンクをコピー」で出る `hal://item/<id>`（または説明付きの `HAL: <名前> — hal://item/<id>`）をチャットに貼ります。相手は検索欄に貼ると、そのアイテムが選択されます（同じルート＝共有フォルダを見ていることが前提です）。期限が過ぎたものは一覧から消え、登録した本人のアプリが自動で削除します。

## 5 分で試す

1. `hal` で起動します。「ルートフォルダを追加してください」と出るので「設定を開く」を押します。
2. 「追加...」で空のフォルダを選び、OK を押します。これがライブラリのルートです（「用途」は既定の「両方」のままで構いません）。
3. Houdini（package 導入済み）でノードを作って選択し、シェルフ「HAL」の `Save Node Asset` を押します（ノードの右クリック `HAL: Save Node Asset` でも同じです）。シーン全体を残したいときは `Save Scene` です。
4. 登録画面が開くので、名前（必要ならプロジェクト・部署・タグ）を確認して「登録」を押します。
5. ブラウザの「ノード」タブでアイテムを選び、「現在のネットワークへ追加」を押します。Houdini にノードが復元されます。

詳しい使い方は [docs/user-guide.md](docs/user-guide.md)、保存形式は [docs/format.md](docs/format.md)、セキュリティと信頼モデルは [docs/security.md](docs/security.md) を見てください。

## Houdini の版ごとの確認状況（0.6.0）

| 項目 | 22.0.429（Python 3.13 / PySide6 6.8 / Pillow 12） | 21.0.512（Python 3.11 / PySide6 6.5 / Pillow 9.0） |
|---|---|---|
| ブリッジの自動テスト（hython `tests/houdini/run_tests.py`） | 71 件中 70 件が通る（1 件は対象外） | 71 件が通る |
| GUI の Houdini での通し検証（`run_e2e.py`: 登録・ノードアセットの追加・一時的・リンク・期限切れの自動削除・シーン全体・信頼など） | 138 項目すべて確認 | 137 項目すべて確認 |
| 手前表示（`run_front.py`: 所有ウィンドウ・Houdini をクリックしても隠れない・他のアプリの下になる・最小化と復元・ダイアログがアプリの前・Houdini を閉じてもアプリが落ちない・単体起動は常に手前に表示）。アプリは `--runtime houdini` で書き出した一式を付属の Python で起動 | 確認（13 項目） | 確認（13 項目） |
| シェルフ（Save Node Asset）・単一インスタンス・メニュー読み込み（`run_qa.py`） | 確認 | 確認 |

アプリ本体の自動テスト（`.venv` の Python 3.11 / PySide6、`tests/` のうち Houdini を使わないもの）は 576 件が通ります（通しで 2 回）。Houdini 付属の Python でのアプリの自動テストの再実施、標準ノードの往復調査の再実施は 0.6.0 では行っていません（0.5.1 時点の確認を参照してください）。

確認していないもの: 21.0.512 / 22.0.429 以外のビルド、20.5 以前、会社のランチャー・SVN 共有の実環境、Houdini の本物のユーザー設定フォルダでの導入（検証は設定フォルダを隔離して行いました）、`hal-houdini register-url` の実レジストリへの登録（偽のレジストリでの単体テストのみ）、Houdini を強制終了したときのアプリの挙動（`hou.exit` での正常終了では、アプリは落ちず、ウィンドウも残りました）。

## Houdini 付属の Python で使う（各 PC に Python 不要・0.4.0）

Houdini 21 以降には PySide6 と Pillow が付属の Python に入っています。書き出しに `--runtime houdini` を付けると、その Python でアプリが動き、各 PC への Python と `pip install` が要らなくなります。

```
hal-houdini export <出力先フォルダ> --runtime houdini
```

1 台で `pip install` して書き出し → ランチャーの管理領域か SVN に置く → 各 PC は Houdini を起動するだけ、です。`hal_package\hal.bat` をダブルクリックすれば、Houdini を起動していなくてもブラウザを開けます。書き出しには、Houdini に入っていない純 Python ライブラリ（markdown-it-py、mdit-py-plugins、mdurl。約 0.4 MB）が `vendor/` に入り、ライセンスは `THIRD_PARTY_LICENSES.txt` に一覧されます。`hou` は読み込まないので、アプリを開いても Houdini のライセンスは追加で消費しません。対応は Houdini 22.0（PySide6 6.8 / Pillow 12）と 21.0（PySide6 6.5 / Pillow 9.0。0.5.1 で 22.0 と同じ範囲を確認）で、PySide6 の無い版では不足の理由を表示して終了します。手順・更新・制限は [docs/getting-started.md](docs/getting-started.md) の「11.1 Houdini 付属の Python で使う」を見てください。

## ランチャーや共有フォルダ・SVN で使う場合

会社のランチャーが Houdini の環境変数やパッケージを管理していて `Documents\houdini<版>\packages\hal.json` が読まれないときや、共通の SVN で全員に配りたいときは、一式を任意のフォルダへ書き出します。

```
hal-houdini export <出力先フォルダ>
```

```
<出力先>/
  hal.json              Houdini パッケージ定義（相対指定。絶対パスを含まない）
  hal_package/
    hal/                アプリ本体 + Houdini 側ファイル
    requirements.txt  hal.bat  VERSION  README.txt
```

- 場所を移しても、別の PC へコピーしても、SVN で共有しても動きます。出力は決定的（`.pyc` なし、テキストは LF、時刻やマシン名なし）なので、再実行しても無駄な差分は出ません。
- （既定の `--runtime python` では）Python と依存ライブラリ（`requirements.txt`）は各 PC に用意します。`--runtime houdini` なら不要です（上の節）。起動に使う Python は、環境変数 `HAL_APP`（完全なコマンド）、`HAL_PYTHON`（`python.exe` のパス）、出力先と同じ階層の `python\` や `.venv\`、pip 導入環境、`pyw`/`py`、PATH 上の `pythonw`/`python` の順で決まります。全 PC で Python の場所が同じなら `--python <パス>` で `hal.json` に `HAL_PYTHON` を書けます。ライブラリが足りないときは、不足分と `pip install -r requirements.txt` の案内が出ます。
- オプション: `--runtime python|houdini`（前回の値を引き継ぐ）、`--json-name <名前>`、`--no-json`（ランチャーが環境変数を直接設定する場合）、`--dry-run`、`--prune`、`--init-site-settings`。`hal-houdini env [--root <出力先>] [--format bat|ps1|json|plain]` で、ランチャーに登録する `HOUDINI_PATH`（既定の検索パスを表す末尾の `&` を残す）・`PYTHONPATH`・`HAL_PYTHON` の値を表示します。
- 共有の `hal.json` を置く場所が分かっているときは `hal-houdini install --packages-dir <フォルダ>` でも作れます。`hal-houdini status` は、`HOUDINI_PACKAGE_DIR` などの環境変数で既定の場所の `hal.json` が読まれない可能性があるときに知らせます。
- 共通ライブラリを最初から見せたいときは、`hal_package/site_settings.json`（または環境変数 `HAL_SITE_SETTINGS`）に `roots` と `ref_excludes` の既定値を書きます。利用者がルートを 1 つも持たない間だけ初期値として使われ、利用者が編集した後は上書きされません。`export` はこのファイルを上書きも削除もしません。
- 更新: 新しい版を pip で入れる → 同じ出力先へ `hal-houdini export` → SVN にコミット。SVN 管理下で不要になったファイルは一覧表示だけです（`svn delete` は利用者が行う。`--prune` で作業コピーから消せます）。
- Houdini の Python Shell で `import hal_bridge; hal_bridge.diagnose()` と打つと、ブリッジの場所・サーバーの状態・アプリの起動コマンド・シェルフが `HOUDINI_PATH` 上にあるかを確認できます。

詳しくは [docs/getting-started.md](docs/getting-started.md) を見てください。

## 通信と更新の確認（0.5.0）

通信するのは同じ PC 内の Houdini だけです。例外は更新の確認で、pip で導入した場合に限り、1 日 1 回 pypi.org へバージョンの確認を行います（設定でオフにできます。書き出した一式で使う場合は行いません）。 SVN の作業コピーから使う場合は、更新の確認として社内の SVN サーバーへ「新しいリビジョンがあるか」を問い合わせます（これも設定でオフにできます）。

- 更新があると、メイン画面の下部に 1 行（「新しいバージョン 0.6.0 があります（現在 0.5.0）」）と「詳細」ボタンが出ます。モーダルのダイアログでは止めません。詳細には、実行するコマンド（`"<python>" -m pip install --upgrade houdini-asset-library`）と、そのあとの `hal-houdini install` または `hal-houdini export <同じ場所>`、Houdini の再起動が出ます。**アプリが自分で pip を実行することはありません。**
- PyPI へ送るのは GET 1 回だけで、`User-Agent: houdini-asset-library/<版>` 以外に識別できる情報は含みません。1 日 1 回まで、タイムアウト 3 秒、失敗は黙って無視します。最初の問い合わせの前に、画面下部に 1 回だけ「更新を自動で確認します。設定で変更できます」と出ます（OK を押すか次回起動までは問い合わせません）。
- 「設定 > 一般 > 更新の確認」（自動 / PyPI / フォルダ / しない）で変更できます。**管理者は `site_settings.json` に `"update_check": "off"` と書くと、利用者の設定にかかわらず無効にできます。**
- 書き出した一式（`hal-houdini export`）から使う場合は、ネットワークへ問い合わせず、置かれている一式の `VERSION` の変化を検知して「新しいバージョンが配置されました。アプリを再起動すると反映されます」と案内します。
- `hal-houdini check-update` で手動確認できます（終了コード 0=最新、10=更新あり、2=確認できず）。詳しくは [docs/getting-started.md](docs/getting-started.md) の 11.7 と [docs/security.md](docs/security.md) を見てください。

## 開発者向け

ソースから動かすときの手順です。

```
python -m venv .venv
.venv\Scripts\pip install -e .[dev]
.venv\Scripts\hal-houdini install      # ソースの Houdini 側ファイルを読む hal.json を作る
HAL.bat                                  # または .venv\Scripts\python -m hal
```

フォルダ構成:

```
src/hal/              アプリ本体 (core / vcs / houdini / ui)
src/hal/_houdini/     Houdini 側ファイル一式（python/hal_bridge, python3.11libs, python3.13libs, toolbar, OPmenu.xml）。wheel にも同梱される
tests/                pytest（tests/houdini は Houdini を使う検証スクリプト）
tools/                デモライブラリ生成などの補助スクリプト
docs/                 利用者向け文書、設計メモ、検証結果
HAL.bat               開発用の起動バッチ（リポジトリの .venv を使う）
```

テストの実行:

```
.venv\Scripts\python -m pytest -q --ignore=tests/houdini
"%HFS%\bin\hython.exe" tests\houdini\run_tests.py
```

`tests/houdini/` のスクリプトは Houdini が必要です。`run_tests.py` は `hython.exe` で、`run_e2e.py` などは `.venv\Scripts\python` で実行します（実行すると Houdini が起動するものがあります）。

配布物（wheel と sdist）は `python -m build` で作ります（`pip install build` が必要）。

## 既知の制限

- 保存形式は cmd のみです。`.hip` ファイルは扱いません。
- 完全には再現できないノード・構造があります（ハードロックのジオメトリ、ノードグループ、VOP 内蔵ノードなど）。登録・共有時に自動で照合し、お知らせとして出します（止めません）。一覧と対処は [docs/getting-started.md](docs/getting-started.md) の「保存されないもの・制限」を見てください。
- 選択外のノードからの入力接続は、復元後に失われます。選択外へのチャンネル参照は参照切れになります。
- 絶対パスで書いたエクスプレッションは、復元後も元のパスを指します。
- ビューポート撮影の画像に Houdini のロゴ透かしが入ることがあります（Apprentice など、ライセンスの種類によります）。
- バージョン管理は SVN のみです。
- Windows 専用です。
- cmd は実行されるコードです。危険な記述が見つかったときだけインポートを止めます（検査は補助です）。信頼する場所・検査・限界の詳細は [docs/security.md](docs/security.md) を見てください。

## ライセンス

MIT License です。全文は `LICENSE` を参照してください。
