HDA製作のひっかかりポイント解説~Multi化への憧れ~

こちらは、 [Houdini Apprentice Advent Calendar 2024](https://qiita.com/advent-calendar/2024/happrentice) の4日目の記事になります。

# HDA製作の引っかかりポイント解説！
みなさん、HDA製作していますか？
HDAを使えるようになると便利なことがたくさんありますが、実装内容によっては**つまずきポイント**がたくさんあります。
本記事では、その中で個人的に引っかかったポイントを、`HDA`を作成しながら解説していきます。

最終的に完成する`HDA`はこんな感じになります。最後に`HDA`のダウンロードリンクも載せているので、ぜひ最後まで見ていってください！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1041568/1c90ae5e-bfb5-6d48-95d2-1f63f12b73bc.png)



### 1. シンプルなもので作成
まず始めに、シンプルな状況でHDAを構築していきます。
`Input_Geometry`から`maskfromgeometrySOP`でマスクを作成し、そのマスクを元に`colorSOP`で色付けして、`attribcopySOP`で`Cdアトリビュート`のみ元のジオメトリに戻しています。
`attribcopySOP`で必要なアトリビュートのみ戻す方法は(トポロジが変わらない場合に限り)非常に便利で重要なテクニックです。HDAでよく使われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1041568/fa16a9eb-9108-9c44-1a12-ba5c2bbe362e.png)

### 2. Subnet化
`Input_geometry`と`Mask Geometry`以外を`Subnet`にまとめ(右側のNetwork)、パラメータを**D＆D**して`Subnet`にまとめました。
<font color="DarkGray">(パラメータ一つ一つ追加でもできますが、後半めんどくさいことになるので必ずD&Dでまとめてください)

画像の通りですが、`maskfromgeometrySOP`と`colorSOP`のパラメータを`Subnet`に登録しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1041568/b8031bbb-0b51-6701-0e50-80b0db12ecd6.png)

### 3. Multi化
`Subnet`のパラメータをすべて一つのフォルダにまとめ、`Folder Type`を`Multiparm Block (list)`にすることで、マルチパラメータにできます。
そのままだと見にくいので、一番下に`Separator`を入れています。
ここで、Multi化によってパラメータの`name`が変わるので、`Subnet`の中のパラメータリンクが切れ、機能しなくなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1041568/9b31842b-4f7b-4c60-8c53-244455a236c7.png)

### 4. パラメータのMulti化対応
`Subnet`の`Multiパラメータ`に、内部のノードを対応させていきます。ここがけっこうミソです。
Multi化によってSubnetの各パラメータの`name`には番号が後付けされています。これに`ForLoop`ノードを使って対応させました。

`BlockEndSOP`の`Iterations`に`Multiset`を`RelativeCReference`しました。
`Forloop`の回数を取得したいので`BlockBeginSOP`の`CreateMetaimportNode`から`Metada`ノードを作成し、各ノードに`AddSpareInput`でリンクしました。

そして各パラメータに、` + (detail(-1, "iteration", 0)+1)`を挿入します。これによって、`Forloop`ごとに回数が取得できます。`Subnet`の方のパラメータを見ればわかりますが、1始まりなので`+1`しています。

`ReferenceGroupType`や`DistanceMetric`などのパラメータは、パラメータ右クリック→`Expression`→`EditExpression`で編集できます。
ひっかかりやすいですが、`color`パラメータの場合順番が違うので、`ch("../color" + (detail(-1, "iteration", 0) + 1) + "r")`となります。もちろん残り`G`と`B`も同様に対応させてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1041568/ca897c05-4407-5ed2-c4a5-6c35604993e6.png)

### 5. アクションボタンのMulti化対応
`Subnet`に戻ってみて、`ReferenceGroup`の右の矢印マークを押すとエラーが出ます。これもMulti化対応しなければなりません。
<font color="DarkGray">(下三角マークは問題なく動くはずです。こちらはSubnet内の`maskfromgeometrySOP`の機能をコピーしてるようで、問題なく挙動します。)

`ActionButton`は`ReferenceGroup`パラメータの`ActionButton`で修正できます。2行目に` + str(kwargs["script_multiparm_index"]`と挿入してください。
`kwargs[]`とはこういったpython側からノードやパラメータなどの情報を取得できる辞書で、この場合は`multiparm`の番号を取得しています。詳しくは[こちら](https://www.sidefx.com/ja/docs/houdini/hom/locations.html#parameter_callback_scripts)をご参照ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1041568/b9aae3a2-c8d4-a6af-d166-4b2196f96232.png)

### 6. Disable When のMulti化対応
よく見たら`DisableMetric`の`DisableWhen`の挙動がおかしかったので修正しなければなりません。
ただし、`DisableWhen`や`HideWhen`は`#`で対応するので、それを追加するだけで問題なく機能します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1041568/fdb3ab33-491c-af5c-5605-131ad957871f.png)

### 7. HDA化！
遂に`HDA化`です。お好きな名前にして、任意の場所に保存してください。
その後、`HDA`を右クリック→`Type Properties`→`Basic`→`Icon`に`SOP_color`と入力するとアイコンが反映されます(お好きなものを入れてください)。
`Node`タブ→`Guide Geometry`→`Input_Mask`と入れることで`Guide`に`Mask_Object`が出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1041568/1ddad349-d174-1e23-79c9-f80caa126e5a.png)

# 終わりに
以上、HDA製作解説でした！
個人的に、`HDA`製作でかなり困ってたことをしっかり解説できたと思っています。この記事で救われる人がいることを祈ります…
話変わりますが、この`HDA`若干重いですね。`mask`ノードが重いので、`Forloop`で何回も計算するとかなり重くなります。
根本的な解決には至りませんが、ちょっとした工夫で少しだけ改善できる点があります。気づいている人もいるとは思いますが、`ColorSOP`を`Forloop`の外側に出せば、色変えのみであれば毎回`mask`ノードの処理を挟まなくて済みます。ではその実装をどうすればいいか？
それは考えてみてください…答えはこちらの[HDA](https://drive.google.com/file/d/1-GOX8WDojBb3w2WJyRJEWTgYf3RCDAGc/view?usp=drive_link)の中に入れておきます。
<font color="DarkGray">(リンク先切れておりましたらお手数ですが[TwitterDM](https://x.com/lethe_movie)にご連絡ください)

ということで、良きHoudiniライフをお過ごし下さい～！