君はお隣さん？一番近い点？それとも座標？

Houdini Apperentice Advent Calenderの三日目の記事になります。
１０日の時点で三日目の枠が埋まっていなかったので急遽書くことにしました。

## 今回は近傍系のVEX関数についてです
SideFXの公式のヘルプによると近傍系のVEX関数は全部でこれだけあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/f541022e-fbf3-d70d-352d-4f77c8d84751.png)
それぞれ引数や返り値が座標であったりPoint番号であったり、使用条件が接続、非接続など異なっていたりします。
動作は関数名から推して知るべしではあるのですが急いでいたりド忘れしたり英語の細かいニュアンスが分からなかったり
そんな人の為に挙動をまとめている一覧があっても良いのかなということで書いていきます。

### nearpoint系
**[nearpoint](https://www.sidefx.com/ja/docs/houdini/vex/functions/nearpoint.html)** と **[nearpoints](https://www.sidefx.com/ja/docs/houdini/vex/functions/nearpoints)** の2つでこれらは単純に距離で判定し接続されていなくても動作します。

| VEX関数名 | 挙動 |
|:-:|:-:|
| **nearpoint**  | 指定された座標から一番近い点の番号を返す  | 
| **nearpoints**  | 指定された座標から一番近い点から順に指定された半径と個数の範囲内で番号の配列を返す  |
nearpointのイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/99020210-da18-2ae9-ef2b-5a673bb17098.png)
nearpointsのイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/0fbd57cd-7f40-36fe-24dd-28239742ce10.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/949cb5d3-4d0f-e9b5-b803-e9a34dae6cd7.png)


### neighbour系
**[neighbour]()**、**[neibours]()**、**[neighbourcount]()**の3つです。
接続された隣接点を探して返します。メッシュやポリラインで動作しますが離散的な点群では動作しません。
隣接していないと-1を返します。

| VEX関数名 | 挙動 |
|:-:|:-:|
| neighbour | 指定された頂点番号から n+1番目に近い点の頂点番号を返す |
| neighbours | 指定された頂点番号の全てのお隣さんの頂点番号の配列を返す|
| neighbourcount | 指定された頂点番号のお隣さんの数を返す |
neighbourのイメージ
![neighbour.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/c73891c4-082e-94ab-806c-fb7cc27199b7.gif)
neighboursのイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/24ebb6ba-797d-c923-0153-834e843b205f.png)
neighbourcountのイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/82abba33-7379-b7b6-5f74-26bc3eb78479.png)

### minpos
**[minpos](https://www.sidefx.com/ja/docs/houdini/vex/functions/minpos.html)**は座標とメッシュを指定すると座標とメッシュ上の一番近い座標を返します。
引数で範囲、prim groupなどを追加指定する事も出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/60fdfd78-d494-69ff-9471-f818f0f692c9.png)

### xyzdist
distの名の通り **[xyzdist](https://www.sidefx.com/ja/docs/houdini/vex/functions/xyzdist.html)** は距離を返します。
minposと使い方は似ているのですが追加の`&prim`や`&uv`などの引数を指定するとメッシュ上のプリミティブ番号や
パラメトリックUV(通常のUV値とは異なりジオメトリが持っている一意なUV)の値も参照渡しの様な形で取得出来ます。
**[primuv](https://www.sidefx.com/ja/docs/houdini/vex/functions/primuv.html)**関数にパラメトリックUVを渡すことでアトリビュートを取得する事が出来ます。
他の関数とは違い多機能な関数です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/600b82bf-bbe0-1e54-72e1-e5064326a1ed.png)

### polyneighbours
**[polyneighbours](https://www.sidefx.com/ja/docs/houdini/vex/functions/polyneighbours.html)** は指定したプリミティブのエッジが隣り合うプリミティブの配列を返します。
polyneighboursのイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/a1f477d4-a122-a272-2833-df465eeab80a.png)


### surfacedist
**[surfacedist](https://www.sidefx.com/ja/docs/houdini/vex/functions/surfacedist.html)** はポイントからのエッジやサーフェスに沿った距離を返すH17で追加された関数です。
同時H17にsurfacedist関数が内部で使用されていた**[FallOff](https://www.sidefx.com/ja/docs/houdini/nodes/sop/falloff.html)**というSOPも作られたのですがH18になって廃止され今では
**[Distance Along Geometry](https://www.sidefx.com/docs/houdini/nodes/sop/distancealonggeometry.html)**という名前に変わっています。
挙動としては**[Edge Transport](https://www.sidefx.com/ja/docs/houdini/nodes/sop/edgetransport)**や**[Find Shortest Path](https://www.sidefx.com/ja/docs/houdini/nodes/sop/findshortestpath)**といったノードに近いです。
エッジ距離をポイントアトリビュートに保存した例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/54d4d82a-0896-5214-883b-89aa00c1121f.png)
サーフェース距離をポイントアトリビュートに保存した例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/ac6bbb9b-837d-e7f5-773a-71b6a9d1666f.png)


### ptlined
**[ptlined](https://www.sidefx.com/ja/docs/houdini/vex/functions/ptlined.html)** は指定された２点を結ぶ線と３つ目の引数に指定された座標との最短距離を返します。
ptlined(P0,P1,Q)の挙動は図にするとこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/2ca05804-60d2-5e27-c614-6e6725921693.png)


## まとめ
私もいくつか知らないものがあったので学習も兼ねて見ていきました。
(※ポイントクラウド系とtet_adjacentは時間の都合上割愛させて頂きます。)
思いついたアルゴリズムやアイデアを実現する為の強力で高速なVEX関数群が用意されているのもHoudiniの強みですね。
それらを活かして快適に作業を進めていきましょう。

## 配布物
単なる関数の紹介なので必要かどうか分かりませんが今回お話した内容の[hip](https://drive.google.com/file/d/1hF1mA_w0zTNyFTHFyck49o_3CLkOA4f8/view?usp=sharing)はここにあります。