こちらのチュートリアルは下記に公開されている「Extruding Building Shapes from OSM Data」を元にしています。
https://sidefx.com/tutorials/osm-importer/
「OSM Importer SOPを使用する」をご参照いただき、OSM Impoterを通して、OSMデータをHoudiniにロードします。
Blastを接続し、下記のように設定します。
ビューポートで確認すると、Buildingアトリビュートに値をもっている部分だけが残ります。
polyExtrudeを接続し、Distanceに50と入力します。
ビューポートを確認すると、面が裏返ってる部分があり、その部分が逆に押し出されていることに気がつきます。
そこで、BlastとPolyExtrudeの間にNormalを追加し、Add Normals to を「Point」にします。
Normalの後にBlastを追加し、Normalが-1方向を向いているポイントだけを抽出します。
ビューポートでみると@N=-1に該当する部分だけが残っていることがわかります。
次に、今作成したBlastをAltキーを押しながらドラッグすることで複製します。
複製したBlastの「Dlete Non Selected」をオフにします。
これで、先ほどのBlastとは逆の結果を抽出することができました。
次にノーマルが裏返っている部分を抽出したBlastにReverseを接続します。
更にNormalを追加して、頂点法泉の角度を整えておきます。(これを行わないと面が暗くなるため)
ノーマルの反転を修正したものと元々反転していなかった部分をMergeします。
これで全ての面が同じ方向を向くようになりました。
Mergeの結果を最初に作成したpolyExtrudeに接続して確認します。
この時点では全てのビルが同じ高さになります。そのため、高さをランダムに設定するためにAttribute Wrangleを使用します。
mergeノードの下にAttbiute Wrangleを追加します。
下記のように記述します。
Run OverをPrimitivesに変更します。
Run Overは変更するアトリビュートクラスを指定します。
VExpressionに下記のように記述します。
f@extrudescale=fit01(rand(@hou_id),10,60);
VExpressionに、@variable_nameとすることでジオメトリアトリビュートにアクセスすることができます。
Vex Expressionに関しては、下記に詳細が記載されています。
http://www.sidefx.com/docs/houdini/vex/snippets
今回はfloatのextrudescaleとアトリビュートをPrimitivesに追加します。そのため、「f@extrudescale=」からはじめます。
次にfit01というVex Funxtionを使用しています。これは範囲(0、1)の値を受け取り、新しい範囲(nmin、nmax)の対応する値にシフトします。fit01に必要な引数は3つで、fit01(float value, float nmin, float nmax)となります。
1つ目の引数にここでは@hou_idを取得しています。この@hou_idは、OSM Importerで持っているアトリビュートで、それぞれ固有の数字が割り当てられています。ただし、下記のように0-1の値に収まっているわけではありません。
そこで、rand(@hou_id)とすることで、@hou_idを元に0-1の間に収まる乱数を取得することができます。
取得した0-1の間の数字をfit01で10-60の間の値にシフトさせ、その結果をextrudescaleアトリビュートに代入します。
Attbiute Wrangleの出力を最初のpolyExtrudeに接続します。
polyextrudeのLocal Controlタブを開き、Distance Scaleを有効にして、先ほど追加したextrudescaleを指定します。
Distanceで決定された値がDistance Scaleでスケーリングされます。
Distaneを1にしました。
(ノーマルがソフトエッジだと見えにくかったため、polyextrudeの後にNormalを追加し、VertexNormalを60にしています)
これにより、非常に大きな都市のベースを作成することができました。