LoginSignup
0
0

More than 3 years have passed since last update.

【Houdini】選択されたフェイスの外周ポイントのみを取得する

Posted at

またまたノードではなく vex でやってみようメモシリーズです。
フェイスの選択範囲から外周のポイントを抽出してます。

下準備

image.png

このように用意したグリッドから group1 を作成します。説明でわかりやすいように 選択個所は color SOP で色を付けてあります。

実処理

image.png
まず Primitive wrangle SOP を作成し、プリミティブ(フェイス)のグループをポイントのグループに変換します。赤い文字でポイント番号が表示されているのが新たに作られた around グループです。まだ、外周だけの状態になってはいません。

if(inprimgroup(0, "group1", @primnum)){
    int points[] = primpoints(0, @primnum);
    foreach(int pt;points) {
        setpointgroup(0, "around", pt, 1);
    }
}

プリミティブがグループに含まれているかの判定に inprimgroup 関数を使っていますが、ノードの Group パラメータ欄に入力した方が簡単です。ここではあえて vex の処理としています。グループの指定も @group_around のようなアトリビュート方式はとらず、setpointgroup 関数をあえて使っています。これは、それぞれが外部パラメータとして入ってくることをみこしたコード例とするためです。(ハードコードを避けやすくしている。)

image.png
さらに Point Wrangle SOP を繋ぎ、外周だけを抽出しました。

if(inpointgroup(0, "around", @ptnum)) {
    int prims[] = pointprims(0, @ptnum);
    int same_group_cnt = 0;
    int numprim = len(prims);
    foreach(int prim;prims) {
        if(inprimgroup(0,"group1", prim)) {
            same_group_cnt++;
        }
    }
    if(same_group_cnt > 2 && same_group_cnt == numprim) {
        setpointgroup(0, "around", @ptnum, 0);
    }
}

ロジックとしては、まずグループ化された各ポイントに関連している複数フェイス(この例の場合1ポイントに最大4つ)を pointprims 関数で抜き出し 、そのうち元の group1 に属している数をカウント ( same_group_cnt ) します。全てのフェイスが group1 に属している場合は選択範囲の内側の点であると判断して around グループ方取り除きます。ただし関連フェイス数が1の場合は全体の角のポイント、2の場合は全体の外周のポイントなのでそのまま残しています。

image.png
上記ロジックで複雑な選択状態や、三角ポリゴンを交えて試しましたが処理はうまくいっているようです。(5角形以上のいわゆるnゴンは利用する予定がないため確認していません。)

まとめ

なるべく1つの wrangle ノードで対応したかったのですが、2つに分けた方が楽だったのでそうしました。detail あたりで処理を回せばできなくはない気もしますが、SIMDで並列処理させたいのと Compile SOP で囲むこともできたのでこれでいいかなと思います。あと同じことができる SOPノードを探したのですが見つかりませんでした。ご存じの方おれば教えてください。グループノード系の設定次第で軽くできちゃいそうな予感もします。

0
0
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0