【 #Houdini 18.5】近くの点の数を数えるpcopen関数を解剖

Rebuild Factoryzの礒です。
今回はポイントクラウド(点群)用に作られたと思われるpcopen関数について書いていきたいと思います。
建築で部屋の数などを数える際に使ったことがあるので、備忘録として残しておきます。


さて、pcopen関数は公式ではなんと説明されているのでしょうか。

この関数は、ポイントクラウドファイル(.pc)を開いて、そこに含まれているポイントへのアクセスのキューを作成します。 そして、pcunshadedpciterateによってポイントを繰り返すことができます。

この関数の最初の2つのバージョンは、Pchannelで見つかったポイントポジションに基づいて特定の位置Pからradius以内のポイントのキューを作成します。 指定した半径内で一番近いmaxpoints個のみのポイントのキューが作成されます。

https://www.sidefx.com/ja/docs/houdini/vex/functions/pcopen.html

何言ってるのかわかりません!

ということでシンプルな例を用意したので、そちらでどんな動作をしてくれるものなのか見ていきましょう。

今回使う検証用VEXコード

int handle = pcopen(0, "P", @P, 1, 10);
 handle = pcnumfound(handle);
 if(handle == 1){
     @Cd= {0,1,0};
 }else if(handle == 2){
     @Cd= {1,0,0};
 }else if(handle == 3){
     @Cd= {0,0,1};
 }
 printf("%d\n", handle);

まずint型の変数handleを宣言し、それにpcopen()関数を代入しています。

pcopen(INPUT, おまじないの”P”, おまじないの@P, 検索半径, 検索最大数);

公式のヘルプ見てもいまいちだったので、自分で書いてみました。
INPUTはwrangleノードのInput0に点群をつないでる場合0と入力します。
あとはおまじないのPと@P。

次に大事なのは検索範囲の半径と最大数です。
この関数は各点同時にそれぞれ検索をかけます。
半径1なら自分を含めた半径1ユニット以内の点を、最大数の許す限り検索し続けます。

handle = pcnumfound(handle);

次にpcnumfound()関数を使うのですが、これは説明不要なレベルで、pcopne()関数で拾った点の数を引っ張ってきてくれるだけの関数です。
なので引数に最初に宣言したhandle変数を入れて、再度handleに代入してます。

代入先の変数は別に用意してもよかったのですが、行数増やすのもアレかなと思いhandle変数を流用。

あとはif文の説明なんですが、やってることは、見つけた点の数によって色を変えるという単純なことをやってるだけです。

printf()関数はデバッグ用に書いてるだけなので、通常業務ならいらないですね。

点が1個の場合

Addノードで原点に点を一個生成して、それをwrangleにつないでます。
すっごく見づらいですが、点が緑色になってます。

検索した結果、その点しかなかったため、結果は1だったということですね。

点が複数ある場合

ではLineで点を複数作ってみましょう。
今回は1ユニットごとに1つの点が配置されるようにしてみました。

結果は「233332」と返ってきましたね。
色もついてます。

端点であるLineの始点と終点では半径1ユニットで検索しても、点の数は自分を含めて2個しかなかったのがこれによってわかります。

それ以外の点については、半径1ユニットで検索した結果、自分を含めて3個見つけたということで青く表示されてます。

このことから、周囲の点の数によってジオメトリの自動生成を制御するのに利用できたりするのです。

実用例

点を等間隔にばらまいてCopy to PointsでBoxを並べることを目的としたものを引っ張ってきました。
WrangleノードはBypassして動作しないようにしてます。

この状態でCopy to Pointsを表示すると、上の画像のようになります。
一番手前のBoxだけ他と違うのお分かりいただけるでしょうか。
これが建物であるとイメージした場合、エッジしか連結していない部分はいらないですよね。

これでは廊下も敷くことができません。
ということでこういうあぶれ者を排除したいと思います。

ではWrangleノードを起動しましょう。
VEXは、pcopne()関数で拾ってきた点の数が2以下の場合、その点を削除するというコードを書きました。

これでエッジだけが連結しているようなBoxは排除することができました。

乱数をいじってもきちんと面で連結している状態を保つことができます。

まとめ

pcopen()関数は指定した半径で点の数を数えてくれる。

pcopne()関数を用いることで、ジオメトリ自動生成の際にジオメトリのコピーを都合のいい形で操作することが可能。

他にも使い道ありそう。

終わり

では今回はこれで終わります。

投稿者: Rebuild Factoryz 礒

Rebuild Factoryzの礒です。 現在は3DCGのモデリングやレンダリング、そしてUnityでのVR環境構築の仕事をしております。 アスペルガー症候群とADHD、双極性障害、解離性障害(記憶障害)を持っています。障害を持っているとは思っていなかった少年時代はいじめ問題に悩まされて生きてきました。今は障害を持ちながら、適度に社会と交流しながら生活していければ良いなと思っています。普通の人とは違う価値観をブログ等で発信していけたら幸いです。 趣味は3DCGモデリングと読書、そしてブログです。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

%d人のブロガーが「いいね」をつけました。