Houdini Group Work
Houdini でのグループ操作の備忘録をまとめました。ショートカットキーなどはWindows版となっています。
グループの確認
Viewport上で[9]キーで、グループ選択ディスプレイ(?)のON/OFFができます。
point や primitive などのコンポーネントの変更は、歯車マークから。
ハイライト色が見づらければ、右側の色の付いた四角をクリックすると変更できます。
ノード名をグループ名にする
Group (Group Create) SOP の Group Name 欄に、以下のように入力すると、ノード名がグループ名となります。
`opname(".")`
この方法は「gametutor」で知りました。
http://www.gametutor.com/live/home-live/
`$OS
上記でも同様の効果があります。
こちらは杉村さんのワークショップで知りました。ありがとうございます。:)
基本のGroup
各手法の Enable にチェックを入れると設定項目が表示されます。
- Base Group
point番号 や prim番号 などを入力してグループ化ができます。
Viewportでコンポーネントを手動選択してから Group SOP を作成すると、その 番号 が入力された Group SOP になります。
ただ、上流でトポロジが変化すると番号が変わってしまいますので、番号を直接指定することはあまりしません。
$F などのローカル変数や、 @P.y>0 などのアトリビュートを使った構文で指定することが多いです。
インディゾーンさんのブログや、Houdiniのリファレンスにもあるように、VEXとは違って@構文にスペースを入れるとエラーになるので注意が必要です。
【参考1】
Group geometry node - "@ syntax does not allow spaces."
http://www.sidefx.com/docs/houdini/nodes/sop/groupcreate.html
【参考2】
グループの所でアトリビュートを直で指定 | インディゾーンHoudini情報日本語ブログ
Group Expression SOP を使えば、構文にスペースが入っていても大丈夫なようです。
- Keep in Bounding Regions
グループにしたい箇所の位置が分かっていて、計算式を考えるのが面倒なときは、いつもバウンディングで指定しています。
パラメータを使ってバウンディングを作っても良いですが、input の 2つめに Object を入力し、プルダウンを「Bounding Object (points only)」(もしくはVolume) にします。
また、(points only)と書いてあるように、point のグループしか作れないようなので、Group Type を「Points」にします。
グループ位置をアニメーションさせたい時などは、この手法が一番良いのかも?
- Keep by Normals
法線方向でグループ化できます。
下記は、Direction が「0,1,0」で Spread Angle が「60」の場合です。
使った事なかったのですが、「Backface from」は特定のオブジェクトから見て背後になるメッシュをグループ化するようです。
基準となるノードをパスで指定するのですが、この場合に指定するノードはSOPノードではなく、GeometryなどのObjectノードのようです。
従って、指定したgeoノード内の Transform は反映されず、純粋にObjectノードのポジションを見るようです。
おそらく Camera からの Backface culling などのために使われるものと思われます。
「Non-Planar Polys」は、tolerance を加味しつつ非平面のポリゴン primitive をグループ化します。
- Include by Edges
ボーダーエッジのみをグループにする時によく使います。
「Unshared Edges」 にチェックを入れるだけです。
Group Type を 「Edge」 にすればボーダーエッジとしてグループ化できます。point や primitive にも対応しています。
エッジの長さ指定などもできるので、色々工夫できそうです。
Wrangle でのグループ処理
グループは Attribute の亜種として扱われているようで、スプレッドシートから確認することができます。
そのグループに属していれば「1」、属していなければ「0」となります。
//戻り値int setpointgroup(インプット番号, グループ名, ポイント番号, 属しているかどうか) int newpointNum = 0; setpointgroup(0, "groupname", newpointNum, 1);
当然 setedgegroup 、 setprimgroup もあります。ただ、エッジグループについては、スプレッドシートから確認する方法が無いような気がします。
グループの中身を配列で取得する時は expandpointgroup を使います。
グループは、他のアトリビュートと同様に、宣言しなくても唐突に作ることができます。
また、 i@group_グループ名 を使って、「1」「0」だけで追加や除外ができます。
if (@P.x>0){ i@group_test = 1; }
この場合、グループ「test」が作成されて、x座標がプラスのポイントがそのグループに属します。
Wrangle でグループを作った時は、Bindings タブの Output Selection Group にグループ名を入れる事でハイライトできます。
Subdivide した時の分割線をグループにする
1枚の板ポリを Subdivide SOP で四分木(Quadtree)に割った後の、縦もしくは横のpoint群のグループ化です。
Subdivide SOP で直接グループを作成してくれれば楽なのですが、そういった機能は見つけられませんでした。(Edge divide も)
サーフェスノードのバウンディング重心を返す centroid エクスプレッション関数を使いました。
@P.y==`centroid("../split1",D_Y)`
@P.y>0 などとは違って、エクスプレッション関数部分を「`」でかこまないといけませんでした。
詳細はよく分からなかったのですが、そういうものなのでしょうか?
このケースでは、 Subdivide 処理した板ポリはメッシュ群のうちの1枚なので、splitでそれを抽出し、split SOP からバウンディングを取っています。
何かもっとスマートな方法もありそうな…。
ループを使った複数グループのリネーム
For-Loop を使用して、大量にあるグループのリネームを行います。
サフィックスがナンバリングで、そのリネームおよびソートを行うケースです。
「aaa_0」「aaa_2」「bbb_0」「bbb_1」とある場合に「aaa_*」だけを「ccc_0」「ccc_1」にしたい。
1.
For-Loop with Feedback SOPを作成します
2.
repeat_end ノード の Iteration に以下のエクスプレッションを記入します。
argc(pointgrouplist("../null1"))
3.
repeat_begin ノード の「Create Meta Import Node」ボタンを押下して repeat_begin_metadata ノード を生成します。これが"iteration"アトリビュートを持っています。
4.
ループ内に Group Rename SOP を入れ、以下のエクスプレッションを記入します。
Group:
`arg(pointgroupmask("../null1","aaa*"),detail("../repeat_begin1_metadata1", "iteration", 0))`
New Name:
ccc_`detail("../repeat_begin1_metadata1", "iteration", 0)`
5.
「ccc_0」「ccc_1」「bbb_0」「bbb_1」となりました。
エクスプレッションmemo(1)
argc(pointgrouplist("../null1"))
- argc(line) …文字列lineをスペースで区切った時の単語数を返します。
- pointgrouplist(surface_node) …指定したノードのpointグループ名をスペース区切りにした文字列を返します。
null1ノードのpointグループには「aaa_0」「aaa_2」「bbb_0」「bbb_1」が存在するので、
pointgrouplistによって文字列「aaa_0 aaa_2 bbb_0 bbb_1」が返されます。
↓
argc(aaa_0 aaa_2 bbb_0 bbb_1)
↓
4
↓
Iteration 回数は「4」になります(ぴったりグループ数ぶんだけ反復する)
エクスプレッションmemo(2)
ccc_`detail("../repeat_begin1_metadata1", "iteration", 0)`
repeat_begin1_metadata1 ノードには、ループ時のみ使用される特殊なアトリビュートがあり、
そのうちの"iteration"(現在の反復回数)を取得しています。
↓
リネーム後の名前は「ccc_」+「現在の反復回数」
↓
「ccc_0」「ccc_1」にリネームされる
エクスプレッションmemo(3)
`arg(pointgroupmask("../null1","aaa*"),detail("../repeat_begin1_metadata1", "iteration", 0))`
- arg(line, argNum) …文字列lineをスペースで区切った時のNum番目の単語を返します。
- pointgroupmask(surface_node, pattern) …指定したノードのうちパターンにマッチするpointグループ名を、スペース区切りにした文字列で返します。
pointgroupmaskで"aaa*"にマッチするグループ名を文字列で取得(「aaa_0 aaa_2」)
↓
「aaa_0 aaa_2」のうち「現在の反復回数」番目の単語を取得(反復1回目なら「aaa_0」)
↓
グループ名に「aaa_0」や「aaa_2」が入る
Game Development Toolset にもグループ関連のSOPがあったので、ついでにそちらも確認してみました。
Group Expand
グループの拡張と縮小ができます。
- 任意のグループを作成します。
- Group Expand SOP を作成し、グループ名を選択します。
- 「Iterations」をプラスに増やすとグループが拡張し、マイナスにすると縮小します。
Group Edge Loop
エッジループとエッジリングのグループを作成します。
- 任意のエッジを2本選択し、グループ化します。
- Group Edge Loop SOP を作成し、グループ名を選択します。
- 2本のエッジが水平にあれば、エッジループになります。2本のエッジがパラレルであれば、エッジリングになります。
- 「Step」を増やすと、1つ飛ばしや、2つ飛ばしの選択になります。
公式のチュートリアルムービーでは、1つのエッジだけを選択しているようですが、現在の仕様(ver.1.8)では、2つのエッジを選択していないとエラーになるようです。
また、エッジを3本以上選択して階段状のエッジグループなども作れましたが、場合によっては Fatal Error で落ちました…。鋭意開発中という感じですね。
以上となります。
その他の Group 関連の記事は、インディゾーンさんで詳しく書かれています。
houdini.indyzone.jp