HDA作成ガイドライン

# 概要

この記事では私がHDA作成時に決めてるルール、気を付けてる事をまとめます。
HDAは個人で使う分には適当で問題ありませんが、他のユーザーに使ってもらう場合は使いやすさや修正のしやすさは重要です。
またHDAを作る人が複数いる場合はこういったガイドラインを設け、共有する必要があると考えています。

ここに記述してるものはあくまで個人ルールなので、これを守る必要はありませんが、HDA作成時の参考になれば幸いです。

:::note warn
**注意事項**
Houdini19.5からHDA作成メニューがlabsのVersioned Digital Assetに置き換わりましたが、この記事に出てくる設定方法やUIは以前のものになってます。
ルールや気を付けてることに関しては変わらないので、そのまま載せることをご了承下さい。
:::

# 基本的な方針

HDAの設定に関しては基本的に公式のノードに倣って作成します。
そうする事で、ユーザーにも分かりやすく、作成者が迷った時に判断する事が出来るようになります。

# 命名規則

オペレータ名、オペレータラベル、HDAファイル名についてのルールです。
**<font color="red">特にオペレータ名は後から変更する事が出来ない為、慎重に行いましょう。</font>**
![](https://paper-attachments.dropboxusercontent.com/s_DBF2762C36208CF8534073510A10541CD60AA8CFFA76DD2809EC433DD85D0CE2_1591690480039_image.png)
**名前が表示される場所**
| ![](https://paper-attachments.dropboxusercontent.com/s_6795225DCE27591860A973A86454ED62124F0CDD794D06FAA7E5AEE1C01CA196_1671192916718_image.png) | ![](https://paper-attachments.dropboxusercontent.com/s_6795225DCE27591860A973A86454ED62124F0CDD794D06FAA7E5AEE1C01CA196_1671192923404_image.png) |
|-|-|
|**オペレータ名**<br>ノード名として表示される。|**オペレータラベル**<br>タブメニューに表示される。|

## **オペレータ名**

- **ネームスペース::ベースのオペレータ名**にします。
- ネームスペースはユーザー前など他と被らないであろう物にします。
- ベースのオペレータ名は半角英数字と_(アンダースコア)のみにします。
- 単語の区切りにアンダースコアを使うかどうかは好みで良いと思いますが、私は公式に倣って付けていません。
    **例：koidtaka::mynode**

:::note info
**ネームスペースを入れる理由**
ネームスペースを入れる事で、公式ノードや他のHDAと名前が被る心配が無くなります。
**koidtaka_mynode**のように書けば良いと思うかもしれませんが、ネームスペースの場合はノードを作成した際に表示されないので、すっきりとした見た目になります。
またPythonから処理する場合もネームスペースとそれ以外の文字を分離して取得出来るため、処理がしやすくなります。
:::
![](https://paper-attachments.dropboxusercontent.com/s_6795225DCE27591860A973A86454ED62124F0CDD794D06FAA7E5AEE1C01CA196_1671193393823_image.png)

- HDAに互換性のない変更を行う際は**ネームスペース::メインの名前::バージョン**にします。
- バージョンは公式に倣って、**2.0、3.0など少数第一位までの記述にします。**
- 最初にHDAを作る際はバージョンを入れず、最初にバージョンを入れるのは2.0からにします。
    **例：koidtaka::mynode::2.0**

:::note info
**バージョンを入れる理由**
バージョンを入れる事で、すでにシーン内で使われてるHDAは変えず、新規で作成する物のみ新しいバージョンで作成する事が出来ます。
:::
バージョンの切り替えは**Windows > Asset Manager > Configurationタブ > Asset Bar**の設定を**Display Menu of All Definitions**にすることで、ノードにバージョンを切り替えるためのプルダウンメニューが表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332597/3c8460dd-df7f-81e3-6b37-41bd51507592.png" width=41%> <img src="https://paper-attachments.dropboxusercontent.com/s_6795225DCE27591860A973A86454ED62124F0CDD794D06FAA7E5AEE1C01CA196_1671253749896_image.png" width=58%>
ネームスペースとバージョンについての詳しい説明は下記をご覧下さい。
- [デジタルアセットのバージョンとネームスペース](https://www.sidefx.com/ja/docs/houdini/assets/namespaces.html)

## **オペレータラベル**

- 単語は大文字で始めて単語の区切りには半角スペースを使って区切ります。
- オペレータに限らずパラメータラベルなどユーザーに表示する名前は、最も視認性が高いこの規則で書いてます。Houdiniに限らず他ソフトでも表示名は基本この規則で書かれてます。
- グループを作るHDAは**Group～**、アトリビュートを作るHDAは**Attribute～**というように目的を最初にした命名にします。タブで検索したときに上位に並んで表示されるので、分かりやすいです。
- 会社の場合は後ろに(会社名)を入れると社内ツールだと分かりやすくなると思います。
    **例：My Node**

## **HDAファイル名**

- 自分の場合は公式に倣い、アッパーキャメルケースにしています。
- 最後にコンテキスト名を入れてます。
    **例：MyNodeSop.hda**

# ユーザビリティ

HDAを作る際は分かりやすさと使いやすさについて意識しましょう。

## **処理速度を出来るだけ速くする**

ノードネットワークの可読性は大事ですが、HDAに関しては処理速度を優先します。
特にHoudini Engineを使う前提の物は処理速度がイテレーション速度に大きく関わってくるため、出来る限り速くなる工夫を行いましょう。
基本的には使用するノード数を極力少なくなるように心がけます。

:::note info
**処理速度を上げるには**
- Performance Monitor(Alt + Y)を使用し、処理が重いノードを確認します。
- Wrangleで置き換え可能な処理はWrangleに置き換えます(全体をトランスフォームする処理はTransformノード、削除する処理はBlastノードの方が速いのでそちらを使いましょう)
- For Eachの代わりにPacked Geometryを使えば済むケースはPackしてWrangleで処理します。
- For Eachで繰り返し数が多い場合はCompile Blockを使う事で処理速度を上げることが出来ます。
- Wrangle内でアトリビュートやグループを設定する場合は@構文を使う。setpointattribなどset~よりも@構文を使ってアトリビュートやグループ作った方が速いです。
:::

## **インプットラベル**

HDAのインプットラベルを分かりやすい名前に変更します。
ここの文字はノードの入力にカーソルを合わせたときに表示されるので、ユーザーのヒントになります。
<img src="https://paper-attachments.dropboxusercontent.com/s_6795225DCE27591860A973A86454ED62124F0CDD794D06FAA7E5AEE1C01CA196_1671196092843_image.png" width=50%> 
特にインプットが2つ以上あるものはどういう役割かを必ず書くようにします。
<img src="https://paper-attachments.dropboxusercontent.com/s_DBF2762C36208CF8534073510A10541CD60AA8CFFA76DD2809EC433DD85D0CE2_1591689325402_image.png">
設定場所はType PropertiesのInput/Outputタブにあります。

## **Tabのサブメニュー**

タブを押してノードを出す際に表示されるメニュー欄を設定します。
デフォルトは**Digital Assets**になってますが、分かりやすいカテゴリ名にします。カテゴリは/で区切ることで階層化する事が出来ます。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332597/266fd8fe-cad3-2090-c28f-ae33db94e58f.png)
設定場所は**Type Properties > Interactiveタブ > Shelf Toolsタブ > Contextタブ > TAB Submenu Path**にあります。

## **状態に合わせてパラメータを非表示、使用不可にする**

特定の条件の時にのみ必要なパラメータは非表示にするか使用不可にします。
![](https://paper-attachments.dropboxusercontent.com/s_DBF2762C36208CF8534073510A10541CD60AA8CFFA76DD2809EC433DD85D0CE2_1669865415119_DisableWhen.gif)
設定方法等は下記をご覧ください。

- [Disable When/Hide Whenの構文](https://www.sidefx.com/ja/docs/houdini/ref/windows/optype.html#conditions)
- [Houdini:Dissable When/Hide When](http://nomoreretake.net/2016/07/02/houdini_dissable-whenedit-parameter-interface/)

## **パラメータのデフォルト値**

パラメータのデフォルト値を設定します。
デフォルト値には主に結果が全く変わらない値にするか、パラメータを変更しなくても適切な結果が出る値にします。
どの値にすれば良いかを判断するのが難しい時はありますが、そのノードの目的を考え、使いやすいであろう値を想定しデフォルト値を決めると良いでしょう。
![](https://paper-attachments.dropboxusercontent.com/s_DBF2762C36208CF8534073510A10541CD60AA8CFFA76DD2809EC433DD85D0CE2_1591689299410_image.png)
設定場所は**Type Propertiesのパラメータ欄 > Channelsタブ**にあります。

## **パラメータの範囲を決める**

パラメータの最小値、最大値を設定する事で見た目が分かりやすくなり、スライダーで値を変える時に操作しやすくなります。
例えば角度を決めるパラメータは0～360もしくは-180～180までにする、割合を制御する場合は0～100にするなどです。
| ![](https://paper-attachments.dropboxusercontent.com/s_6795225DCE27591860A973A86454ED62124F0CDD794D06FAA7E5AEE1C01CA196_1671254010460_image.png) | ![](https://paper-attachments.dropboxusercontent.com/s_6795225DCE27591860A973A86454ED62124F0CDD794D06FAA7E5AEE1C01CA196_1671254022849_image.png) |
| - | - |
| 角度の設定例 | 割合の設定例 |

基本的に範囲のロックをする必要はありませんが、その範囲を超えるとエラーになったり、落ちる原因になる可能性がある場合はロックしましょう。
| ![](https://paper-attachments.dropboxusercontent.com/s_6795225DCE27591860A973A86454ED62124F0CDD794D06FAA7E5AEE1C01CA196_1671254041784_image.png) | ![](https://paper-attachments.dropboxusercontent.com/s_6795225DCE27591860A973A86454ED62124F0CDD794D06FAA7E5AEE1C01CA196_1671254048292_image.png) |
|-|-|
| パラメータ範囲の設定欄 | ロックオンで範囲内の値のみ入力可能になる |

## **パラメータにプルダウンメニューを付ける**

アトリビュートやグループを指定する場所などにはプルダウンメニューを設定します。
例えばポイントアトリビュートを設定するパラメータ欄にはポイントアトリビュートのリストをメニューに表示する事で、入力の手間を省くことが出来ます。
![](https://paper-attachments.dropboxusercontent.com/s_DBF2762C36208CF8534073510A10541CD60AA8CFFA76DD2809EC433DD85D0CE2_1669865699373_ParameterPullDown.png)
すでにプルダウンメニューが設定されてるパラメータはHDAにコピーした時点で自動で設定されますが、そうでない場合はPythonで設定します。
Pythonを使ったプルダウンメニューの設定方法については下記をご覧下さい。

- [パラメータメニュースクリプト](https://www.sidefx.com/ja/docs/houdini/hom/locations.html#parameter_menu_scripts)
- [HoudiniのParameter Interfaceで使えるPython ①](https://qiita.com/yuya_torii/items/9ae1248380c47b79efa3#menu-script-sample)

## **パラメータはカテゴリごとにフォルダにまとめる**

パラメータをカテゴリごとにフォルダパラメータの中に入れる事で分かりやすくなります。
基本的にはフォルダ設定はSimpleを使うと良いと思いますが、カテゴリに合わせてTabやCollapsibleを使うと良いでしょう。
<img src="https://paper-attachments.dropboxusercontent.com/s_DBF2762C36208CF8534073510A10541CD60AA8CFFA76DD2809EC433DD85D0CE2_1591690028308_image.png" width=45%> <img src="https://paper-attachments.dropboxusercontent.com/s_DBF2762C36208CF8534073510A10541CD60AA8CFFA76DD2809EC433DD85D0CE2_1591690039765_image.png" width=53%>

## **グループを作成するノードはプレビュー出来るようにする**

グループを作成するHDAはシーンビューでプレビューされるようにします。
方法としては一番最後にGroup Createを繋げ、図の設定にするのが一番簡単な方法だと思います。
<img src="https://paper-attachments.dropboxusercontent.com/s_DBF2762C36208CF8534073510A10541CD60AA8CFFA76DD2809EC433DD85D0CE2_1591690095790_image.png" width=59.5%> <img src="https://paper-attachments.dropboxusercontent.com/s_6795225DCE27591860A973A86454ED62124F0CDD794D06FAA7E5AEE1C01CA196_1671194781204_image.png" width=39%>

## **ヘルプを付ける**

作ったHDAにヘルプページとパラメータのツールチップを付けます。
![](https://paper-attachments.dropboxusercontent.com/s_DBF2762C36208CF8534073510A10541CD60AA8CFFA76DD2809EC433DD85D0CE2_1669865799509_HDAHelp.gif)
ヘルプとツールチップの作成方法は下記をご覧下さい。

- [**HDAにヘルプを付ける方法(Pythonスクリプトのおまけ付き)**](https://qiita.com/d658t/items/1737cb4e820b45f28723)

## **アイコンを付ける**

アイコンを設定する事でその視覚的にHDAを区別し、どういうHDAかも分かりやすくなるので、出来る限り設定しましょう。
場所は**Type Propeties > Basicタブ > Icon**にあります。
![](https://paper-attachments.dropboxusercontent.com/s_DBF2762C36208CF8534073510A10541CD60AA8CFFA76DD2809EC433DD85D0CE2_1591690190530_image.png)
### **Houdini内に入ってるアイコンを確認する方法**
Houdini内に入ってるアイコンは下記の場所に入ってるので、エクスプローラ上で確認する事が出来ます。
**Houdiniインストールディレクトリ\houdini\config\Icons\icons.zip**
またHoudiniにデフォルトで入ってるアイコンを一覧化し、検索、名前の取得、編集、書き出しが出来るツールを公開してるので、是非ご活用ください。
ダウンロードはこちら→[**Houdini Icon Browser**](https://github.com/TakashiKoide/HoudiniIconBrowser)
![](https://user-images.githubusercontent.com/50489494/208280012-6bde2aa1-8e6d-42c7-83f9-a198c98a5129.png)

# **メンテナンス性**

HDAの修正のしやすさや、バグやミスが起きないように気を付けてることについてです。

## **ネットワークの整理**

ネットワークは整理しましょう。ネットワーク整理のポイントは次の通りです。

- 不要ノードの削除。
- ワイヤーが出来る限り絡まない配置にする。
- 処理内容をノード名に付ける。
- 大きな処理や使いまわす処理はSubnetにまとめる。
- 処理ごとにNullノードを使い、何が入力されてるか明確にする。
- ネットワークボックスやスティッキーノートで注釈を入れる。

|![](https://paper-attachments.dropboxusercontent.com/s_DBF2762C36208CF8534073510A10541CD60AA8CFFA76DD2809EC433DD85D0CE2_1591689124087_image.png)|
|-|
|**ネットワークサンプル(Voronoi Fractureの中身)**|

:::note info
**名前を付けるノード**
私もネットワーク内のノードに全て名前を付けるのは面倒なので、行っていません。
ただし下記のノードには名前を付けるようにしています。
- Attribute Wrangle、Python、Group Expressionなどコードを扱うノード。
- Attribute VOP、Subnetworkなど中の処理が見えないノード。
- Object Mergeノード
- Swicthノード

これらのノードに処理内容を名前として書くことで可読性が高くなり、修正もしやすくなります。
:::

## **余計なアトリビュートやグループを追加しない**

アウトプットに必要のないアトリビュートやグループを追加、上書きしないようにしましょう。

- アウトプットするジオメトリに一時的なアトリビュートやグループを追加する際は**__(アンダースコア二つ)**を名前の前に付けます。
- 自分で明示的に作成するアトリビュート以外にもConnectivityなど自動でアトリビュートが付加される物も上書きしないように**__(アンダースコア二つ)**を名前の前に付けて、上書きしないようにします。
    **例：__class**
- 追加した一時的なアトリビュートやグループは最後にAttribute DeleteやGroup Deleteを使用し、パラメータ欄に__*と入力し削除します。
<img src="https://paper-attachments.dropboxusercontent.com/s_6795225DCE27591860A973A86454ED62124F0CDD794D06FAA7E5AEE1C01CA196_1671195654365_image.png" width=49.5%> <img src="https://paper-attachments.dropboxusercontent.com/s_6795225DCE27591860A973A86454ED62124F0CDD794D06FAA7E5AEE1C01CA196_1671195893679_image.png" width=49.5%>

## **WrangleやPythonのコード内で外部パラメータを参照させない**

コード内に直接パラメータ名を書いて参照すると、参照先のパラメータ名が変わると参照が途切れてしまいます。
またDependencyにも表示されない為、ネットワークの可読性が下がります。
WrangleやPythonノードでパラメータを参照する場合はStringパラメータを追加し、そこにPaste Relative Referencesを行います。
| ![](https://paper-attachments.dropboxusercontent.com/s_6795225DCE27591860A973A86454ED62124F0CDD794D06FAA7E5AEE1C01CA196_1671195517190_image.png) | ![](https://paper-attachments.dropboxusercontent.com/s_6795225DCE27591860A973A86454ED62124F0CDD794D06FAA7E5AEE1C01CA196_1671195525895_image.png) |
|-|-|
| コードで外部パラメータを参照させた場合 | 自身のパラメータにリンクさせた場合 |

:::note info
**自身のパラメータに参照させるメリット**
自身のパラメータに参照させ、Dependencyを可視化する事でどのパラメータを参照してるかが分かりやすくなり、参照してるパラメータの名前を変更したとしてもパラメータの参照が壊れる事が無くなります。
:::

## **ノードやパラメータを参照する場合は相対パスで参照する**

ノードやパラメータを絶対パスで参照すると階層やノード名が変わると参照が壊れるため、相対パスで記述します。
| ![AbsPath.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332597/ec9ad2f7-400e-83be-73b6-10c2f7619489.png) | ![RelativePath.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332597/1b159b34-0e05-d12e-85e8-ab060234f023.png) |
|-|-|
|**絶対パスで参照**<br>階層やノード名が変わると参照が壊れる|**相対パスで参照**<br>階層やノード名に依存しなくなる|

## **Outputノードの作成**

HDAの結果として表示したいノードにOutputノードを接続します。そうする事でディスプレイフラグを付けていなくても必ずOutputノードが表示されます。
Outputノードが無い場合はネットワーク内のディスプレイフラグが付いたノードがアウトプットになり、意図しない結果になってしまう事があります。
![](https://paper-attachments.dropboxusercontent.com/s_DBF2762C36208CF8534073510A10541CD60AA8CFFA76DD2809EC433DD85D0CE2_1591689480828_image.png)

## **HDAの中だけで使うHDA**

HDA内でしか使わないHDAはコンテキスト設定を変えてタブメニューに表示されないようにします。
こうする事で、そのノードはユーザーから見えなくなり、内部でのみ使うHDAとして利用出来るようになります。
![](https://pbs.twimg.com/media/EaNjuw2UMAAA5hq?format=png&name=900x900)

# 最後に

以上HDAのガイドラインについてでした。
この記事が皆様のHDA作成時に少しでもお役に立てば幸いです。