Houdiniにおけるデバッグ Vol.2 エラーについて


# はじめに

[Houdiniにおけるデバッグ Vol.1](https://qiita.com/dicepastoso/items/01682bdc88f45e9054f1) ではHoudiniにおいて様々な情報を表示・確認する方法について書きました。
今回はエラーに関わることについて書いていきます。

---

第一回は[こちら](https://qiita.com/dicepastoso/items/01682bdc88f45e9054f1)
第三回は[こちら](https://qiita.com/dicepastoso/items/b1831e480bf717736c5a)

---

# トラブルシューティング
Houdiniのインストール、ライセンス、諸々の不具合については開発元や代理店のトラブルシューティングをご覧の上、不明点があれば各問い合わせ先にお尋ねくださいませ。
## [トラブルシュートFAQ | SideFX](https://www.sidefx.com/ja/faq/)
## [Born Digital サポート Houdini](https://support.borndigital.co.jp/hc/ja/categories/203099087-Houdini)
## [インディゾーンサポート SideFX](https://support.indyzone.jp/hc/ja/categories/115000378591-SideFX)

# エラーに関する[環境変数](https://www.sidefx.com/ja/docs/houdini/ref/env.html)
`houdini.env` に設定できる項目の中にエラーに関するものがいくつかあります。
## HOUDINI_ERRORLOG_FILENAME

エラーのログをこのファイルに書き出します。 

## HOUDINI_ERRORLOG_LEVEL

`HOUDINI_ERRORLOG_FILENAME` で指定したエラーログファイルに書き出す最低エラーレベルをし指定します。 有効な値は、0から6の整数値です。 デフォルト値は3。 
エラーレベルは以下の通りに定義されています。
0,すべてのエラーをログに出力
1, メッセージ
2, プロンプト
3, 警告
4, 中止処理
5, 致命的なエラー
6,何もログに出力しない
例）houdini.envの記入例と実行例です。
 Sweep（旧Sweep）に何も繋がずにエラーバッチが出ている状態の時、設定したLogファイルには下記のように記載されます。
<img width="380" alt="env.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134079/b6096a32-c862-eec3-e30f-3ee6c3b86445.png">
<img width="594" alt="error_sample.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134079/6849dfca-0c29-d258-0360-b3802cf41f47.png">
この他にも様々なエラーに関する環境変数がありますが、例示としてエラーを起こすのが手間なので環境変数の項目のみ記載します。

## HOUDINI_VERBOSE_ERROR
予期しないファイル保存エラーをコンソールとエラーボックスの両方に表示します。

## HOUDINI_DSO_ERROR
プラグインのDSO/DLLエラーをコンソールに出力するかどうか決めます。

## HOUDINI_TIFF_SAMPLEFORMAT
TIFFライブラリの古いバージョンが未知のタグに関して警告/エラーを表示します。

## HOUDINI_OGL_DUMP_SHADER_ERRORS
GLSLコンパイルエラーが発生すると、コンソールに出力します。

## HOUDINI_SCRIPT_DEBUG
ダイアログスクリプトとスクリプト化したオペレータを読み込む時、エラーが出力します。

## HOUDINI_IMAGE_DEBUG
画像を保存/読み込みした時に発生したエラーに関する情報がより詳細になります。

# エラー表示

## [ErrorSOP](https://www.sidefx.com/ja/docs/houdini17.0/nodes/sop/error)

条件によって メッセージ、警告、エラーを発生させることができます。
論理演算で判別され 0（False）の時にそのまま通過し、1(True)の時に上記のエラー等を発生します。

例）グリッドの Row とColomnが10以下の時にエラーを発生して止めます。
![ErrorSOP.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134079/e59de0ec-3874-43b6-9b26-8de1982c2a30.gif)


# エラーハンドリング（例外処理）
## [Swich](https://www.sidefx.com/ja/docs/houdini/nodes/sop/switch.html)の利用

Swichの `Select Input` は整数値が返ってくるエクスプレッションで設定ができるのでエラーを起こす場合を判定して入力を切り替えることができます。

例）他のDCCツールで作成したものを読み込み、そのジオメトリ（ジオメトリでなくても良いですが）に下流で必要なAttributeを予め付与していることがシステム上必要である時、そのジオメトリが不在であっても、必ずそのAttributeを下流に継承させるための補助のネットワークを用意しておき、ジオメトリの有無で判定してネットワークを切り替えます。
![errorHandling_Swich.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134079/a2791d2c-7ad6-7713-e595-7c265ea36cb4.gif)


例）Helpの掲載されているTIPS
エラーがあれば2番めの入力に切り替えます。
Helpに掲載されている例では正常とエラーの入力が逆になっています。前後のネットワークがあることを想定し、それらのメインストリームが左（第一インプトット）であることが多いので下記のようにしました。

ただし、公式Helpでは [直感的には1番目の入力がTrueの方が良いのではと思うかもしれませんが、エクスプレッションやスクリプトの結果を入力番号の0と1に合わせた順番の方が理にかなっています。](https://www.sidefx.com/ja/docs/houdini/nodes/sop/switchif.html) としていますので公式にならったほうが自然ではあると思います。
※ `if(expression, true_value, false_value)`
![Swich2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134079/d30536c8-be18-2cf4-a986-8cbb59f74240.gif)


# エラーを起こさないための工夫
煩雑になればなるほどエラーを起こす危険性は高まります。ではどうすれば良いのでしょうか？これは色々な手段があると思います。私も試行錯誤で少しずつ改善しているところです。ですので極々一例ではありますがご参考までに。

## スペルミス
VEX等でアトリビュートを設定していくときに起きやすいのがスペルミスです。自分で設定するカスタムアトリビュートもそうですが、ビルトインアトリビュートは既にHoudini側で用意しているものなので間違えると動きません。スペルミスを防ぐために [Houdini Expression Editor](http://cgtoolbox.com/houdini-expression-editor/)  というのを使用してVSCodeで書いています。VSCodeでシンタックスハイライトしてくれますし、補完もしてくれるので便利です。くわしくはめんたいこさんの記事に載っているので参考にしてください。
[Houdini: VEXをカスタマイズしたVS Codeで書く02 - kick the base](https://www.kickbase.net/entry/vex-programming-with-vscode02)

## 整理

ネットワークが複雑化すると他の人から分かりにくくなります。一人で作業していても時間が経てば分からなくなることもあります。いかにデータを分かりやすく構築し、整理していくこともエラー回避につながります。

### [ネットワークボックス](https://www.sidefx.com/ja/docs/houdini/network/organize.html#netbox)
まとまった処理をネットワークボックスで囲うことで視認性があがり作業しやすくなります。また左上の `-` を押すことで最小化することもできます。

### [sticky note](https://www.sidefx.com/ja/docs/houdini/network/organize.html#notes)
付箋を配置してそのノード、ネットワークが何を行っているかなどのメモを残して構造を分かりやすくします。

### [サブネットワーク](https://www.sidefx.com/ja/docs/houdini/network/organize.html#%E3%82%B5%E3%83%95-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AE%E5%8F%96%E3%82%8A%E6%89%B1%E3%81%84%E6%96%B9)
まとまった処理のネットワークをサブネットワーク化してルート階層の処理の流れを見やすくします。

### 各ネットワークの集約
ケースバイケースですが、 `/obj` 階層に `matnet` や `ropnet` を配置して各ネットワークの行き来を少なくします。

# おわりに

今回は主にエラーに関することについてまとめました。エラーを回避し、そしてエラーが起こったとしても解析してすばやく想定する動作にもっていく。それが作業効率をあげ、アーティストワークにもより集中できるようになると思います。TOPSやPythonについてなど今回あげられなかったものもたくさんありますが、それらはいずれ詳論として取り上げたいと思います。（そのあたりはまだ詳しくないので学習しつつとなりますが。）
なにかの参考になれば幸いです。時期はあくかもですが次回以降でデバッガーや解析にまつわることを書ければと思います。

# 参考
[Houdiniと環境変数の魔導書 〜補助魔法導入で失敗しないために〜](https://qiita.com/takavfx/items/b58cae65984b15e5ad29) 
[Houdini:Error(SOP)No More Retake | No More Retake](http://nomoreretake.net/2017/12/11/houdini_error_sop/)
[HoudiniのParameter Interfaceで使えるPython②](https://qiita.com/yuya_torii/items/6f07a5708c3f45ad632c)
[Houdiniで長方形のプリミティブを判別するノードを作成した](https://matcha-choco010.net/2018/12/30/houdini-rect-detect-node/) 
[Graph Cleanup](http://ambrosiussen.com/subpages/graphcleanup.html)