LoginSignup
22
8

More than 3 years have passed since last update.

ジオメトリからポリライン抽出あれこれ -Various Methods to Extract Polyline from Geometry-

Last updated at Posted at 2020-12-06

Houdini Advent Calendar 2020 6日目 の記事です

はじめに

背景TAになって1年目、TAらしい良い記事を書こうとひねり出したテーマは"ポリラインの抽出"です
Houdini歴0-2年ぐらいの方に向けて書いたつもりです

ポリラインはポリゴンに比べて単純な構造で、プロシージャルに制御するのにハードルが低いと思います
ジオメトリから欲しいポリラインを適切に抽出できれば、様々なシーンで活躍します
この記事を読んで生成されたポリライン達が、皆さんのHoudiniライフの一助となれば幸いです

また、抽出したポリラインの変換については、↓↓こちらのページにわかりやすくまとまっています
https://issekinichou.wordpress.com/2020/03/01/houdini-curve-editing/

※英題について
英語でも同じテーマで最新の情報がまとまった記事は存在しないと感じ、少しでも多くのHoudinistにリーチしてほしいと思ったからです
カッコつけではありませんw

動作環境

Houdini Apprentice 18.5.351
Labs 18.5.417

Primitive毎にエッジからポリラインを抽出

Ends,Primitive,Carve、これら3つのSOPは大体同じことができますが微妙に違います
image.png

Ends

エッジを一周する一つのポリラインを、プリミティブ毎に生成します
PrimitiveSOPでも同じことができますが、新しそうなこちらが推奨です

CloseU>Unroll with New Pointsを選べば端点が繋がっていないポリライン
image.png
CloseU>Unroll with Shared Pointsを選べば端点が繋がっていないポリライン
image.png
を得ることができます

Primitive

EndsSOPの親玉的SOPで、特別な事情が無い限り基本使わないことを推奨
恐らくWrangle登場以前の古いノードで、最近のシーンファイルではあまり見かけません(Wrangleでやっちゃうから)
image.png
Face/Hull>CloseU のプルダウンから
Unroll with New Pointsを選べば端点が繋がっていないポリライン
Unroll with Shared Pointsを選べば端点が繋がっていないポリライン
をそれぞれ作成することができます(EndsSOPと同じ)

端点について

なお、EndsSOPもPrimitiveSOPもポリラインの端点は必ず元のプリミティブの頂点番号0が参照するポイントになります
任意で指定することはできないので、端点を変更したい場合はReverseSOPのVertex>Shiftで対処してください
image.png
※PrimitiveSOP内にも同じパラメータがありますがうまく行かないので注意!
image.png

Carve

端点をパラメトリック座標から始点終点を指定してポリラインを生成できます
前述の2つのSOPと違い、必ず端点は繋がってない状態でポリラインが出力されます
ポリゴンエッジをポリラインにする目的でCarveSOPを使う場合、FirstU,SecondUのみを使用します
image.png
FirstUのみ設定すると、EndsSOPのUnroll with New Pointsと同じ挙動をしますが…
image.png
FirstUを設定することで、端点を任意に指定できます(ポイント及びVtxは増えるので注意)
image.png
FirstU,SecondUを設定すると、始点終点をそれぞれ指定できます
image.png
※パラメトリック座標についてよく理解していない場合は、以下を参照
プリミティブのパラメトリック空間(暗黙的なUV): https://www.sidefx.com/ja/docs/houdini/model/primitive_spaces.html
何度読んでも難しい…

Facet

上記3つのSOPに共通する事項として
入力ポリゴンのエッジを構成するポイントがPrimitive間で共有されていれば、出力されるポリラインもポイントが共有されます
つまりポリラインがダブっている箇所があるのに、ジオメトリとしては切り離せないということになります
基本回避したい状況だと思いますので、FacetSOPを繋いでUniquePointsをチェックしてプリミティブ同士を切り離してから接続するようにしましょう
image.png
見かけでは分かりづらいので注意!

※ポイントと頂点についてよく理解していない場合は、以下を参照
ポイントと頂点: https://www.sidefx.com/ja/docs/houdini/model/points.html

各エッジでダブらないポリラインを抽出

ConvertLine,PolyPathは、上記3つと違ってダブらないポリラインを生成します
image.png

ConvertLine

各エッジに一つのポリラインを生成します
入力ジオメトリでポイントが共有されている場合は、ジオメトリとして繋がって出力されます
バラバラのポリラインにしたい場合は、FacetSOPを使用しましょう
image.png
FacetSOPの位置で挙動が変わります
右の結果はEndsSOPなどの出力結果と似ていますが、すべてのエッジが独立したポリラインになっている点で異なります
image.png
ちなみにダブルクリックで中を覗けます
image.png
結構シンプルな作りでわかりやすいです(こちらのVEX関数については後で説明します)
ポイント番号で駆動しているので、ポリラインの向きの制御が難しいです
image.png
向きのそろったポリラインが欲しい時は仕方なくVEXを書きます(VEX関数を参照)

PolyPath

できるだけ繋がったポリラインを生成します
左がConvertLineSOP,右がPolyPathSOPで、プリミティブごとに色分けしています
image.png
Sweepしたいときに良いです
image.png
こちらもダブルクリックで中を覗けます
image.png
trace_edgesというAttributeWrangleがキモです…が難しくてよくわかりません
いつか追記するかもしれません

VEX関数

addprim: https://www.sidefx.com/ja/docs/houdini/vex/functions/addprim.html
addvertex: https://www.sidefx.com/ja/docs/houdini/vex/functions/addvertex.html
の2つでとりあえずポリラインが作れます

↓↓に簡単なサンプルを用意しました
image.png
Wrangleの中身はこんな感じ

addprim_sample(RunOverはPrimitiveで)
//プリミティブの構成ポイント番号を配列で取得
int primpts[] = primpoints(0,@primnum);

//プリミティブの重心にポイントを作成
int newpt = addpoint(0,@P);

//構成ポイント毎に重心までのポリラインを作成
foreach(int ptnum;primpts){
int polyline = addprim(0,"polyline",newpt);
addvertex(0,polyline,ptnum);
}

//元のポリゴンを消去
removeprim(0,@primnum,1);

もっとこの辺りのVEXを詳しく知りたい方はこちらこちらなどを参照してください

おまけで、Vtxの並び方が綺麗にパラメトリック座標に反映されたポリライン
image.png

addprim_eachedge(RunOverはPrimitiveで)
//プリミティブの構成ポイント番号を配列で取得
int primpts[] = primpoints(0,@primnum);


//構成ポイント毎にエッジを生成する
foreach(int ptnum;primpts){
int hedge = pointhedge(0, ptnum);
int ptnum_next = hedge_dstpoint(0,hedge);
addprim(0,"polyline",ptnum,ptnum_next);
}

//元のポリゴンを消去
removeprim(0,@primnum,1);

image.png

addprim_eachPrim(RunOverはPrimitiveで)
//プリミティブの構成ポイント番号を配列で取得
int primpts[] = primpoints(0,@primnum);
//終点用に配列に始点を追加
push(primpts,primpts[0]);

//空のポリラインを作成
int polyline = addprim(0,"polyline");

//ポリラインに頂点を追加
foreach(int ptnum;primpts){
addvertex(0,polyline,ptnum);
}

//元のポリゴンを消去
removeprim(0,@primnum,1);

以下今月中に随時追記予定…

ジオメトリを切断して抽出

Boolean,Surfsect,Profile

Clip,VoronoiFracture

PolyCut

EdgeGroupから抽出

EdgeGrouptoCurves,Dissolve

PolyExtrude

グリッド構造からアイソカーブを抽出

Convert

VEX

Sim用のSOPを使って抽出

ConnectAdjecentPieces

TetConform(旧SolidConform)

TetEmbed(旧SolidEmbed)

Labsのツール

StraightSkelton2D

StraightSkelton3D

ExtractBorders

ExtractSilhouette

最短距離,測地線

FindShortestPath

DistanceAlongGeometry

おまけ

Trail

DrawCurve

22
8
1

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
22
8