VEX&VOP チートシート

これは [Houdini Apprentice Advent Calendar 2019](https://qiita.com/advent-calendar/2019/happrentice) 1日目の記事です。
初日から奇を衒った内容になってしまいましたが、vex/vopの比較表をまとめてみます。
毎年似たようなこと書いている気がしなくもないです。

# はじめに
VOP は VEX のラッパーです。Houdini は実質、 SOP(VOP)+DOP です。
MEL 無しで Maya を使う辛さほどではないと思いますが、VEX なしで Houdini を使いこなすのも難しいです。
DSL(と数学)の実力がそのままDCCアプリケーションでの表現に反映される感覚をひしひし感じます。

参考のチュートリアルを見ていると、VEX と VOP が混ざって結構混乱します。
VOP の操作を VEX でどうするのか都度調べてたりするので、表にまとめてみました。
優劣や使用頻度はともかく、類似度で並べています。
もっと良い方法、比較対象があれば、ご指摘頂けると嬉しいです。


## 対応表
- Houdini Apprentice 17.5.391

|         | VOP | VEX | ノード |
|:-----------------|:------------------:|:------------------:|:------------------:|
| SOP      | Attribute SOP | Attribute Expression, Group Expression, Attribute Wrangle SOP | <img width="678" alt="スクリーンショット 0001-11-23 18.02.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48607/7879afa7-4422-3db2-7e98-98e323a032f4.png"> |
| DOP      | Geometry VOP, Gas Field VOP | Geometry Wrangle, Gas Field Wrangle SOP | <img width="852" alt="スクリーンショット 0001-11-23 18.03.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48607/41b88724-bd02-6d9e-7a07-9c6cd0242a9d.png"> |
| COP      | VOP COP2 Filter, VOP COP2 Generator COP | VEX Filter, VEX Generator COP | <img width="663" alt="スクリーンショット 0001-11-23 18.04.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48607/8030d561-b9bc-5576-c5b6-ae479f1859cf.png"> |
| 構造体    | Struct VOP | `$HIP/vex/include` にヘッダーを配置 | <img width="100" alt="vop__0003_レイヤー-5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48607/9ee1bb31-ddfd-a974-38c1-13c1a9305026.png"> |
| フロー制御 | if, for-loop, while VOP | `if, for, while`文 | <img width="100" alt="vop__0000_レイヤー-3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48607/4551b7a8-2729-4f92-956e-dae870ef9466.png"> |
| パラメータ | Bind VOP, Parameter VOP | `ch`関数 | <img width="60" alt="vop__0002_レイヤー-4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48607/be431a57-6ef0-d43c-478c-fdba45c52a65.png"> |
| 相互運用   | inline code VOP, snippet VOP | `vopwritevfl` (Save VEX to Code file) | <img width="60" alt="vop__0001_レイヤー-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48607/b3aa1502-6674-bdc7-5437-4910c339dc15.png"> |
| ポイントクラウド   | Point Cloud Open VOP | `pcopen/pclose`関数 | |
| アトリビュート   | Attribute Create SOP | `addvariablename` | |
| デバッグ   | なし(Geometry Spreadsheet) | `printf`関数, `assert`マクロ | |
| Python   | `node.createNode` | `node.parm("snippet").set` | |
| HDK   | `VOP_Node`クラス | `VEX_VexOp` or `CVEX_Context::run()` | |

並べてみると、四則演算や制御文をVOPでやる意味はほとんどありません。


### HOM (Houdini Object Model)
基本的なノードの操作は以前まとめてみました。VEX の文字列を Python で書いてみます。
余談ですが`textwrap`モジュールで書き込めば、VEXもきれいに整形されます。

```python:vex.py
import hou
import textwrap

def set_vex():
	vex = textwrap.dedent("""\
	// Average Neighbouring Points
	int n[] = neighbours(0, @ptnum);
	vector avgP = @P;

	// Loops over all elements of n, setting pt
	// to be the value of each element
	foreach (int pt; n)
	{
		avgP += point(0, "P", pt);
	}
	""")
	wrangle = hou.node("/obj/geo1").createNode("attribwrangle")
	wrangle.parm("snippet").set(vex)
```

書けるといえば書けるのですが、そこまで重要ではないですね。
Python AST から VEX にトランスパイルするぐらいでないとインラインで
VEX書き込んでもあまり...


### まとめ
ノードベースの弱点は、他人へ技術や知識を移植し辛いことだと思います。
上級者のhip見ろってことだと思いますが...
単発機能だけじゃなく一覧で見るのも理解が深まっていいですね。