てんちょーの技術日誌

自分がつまづいたこととかメモ

[Houdini] Vellum Constraints を読んでみた その11

概要

こちらの続きです

shop-0761.hatenablog.com

環境

OS: Windows 10
Houdini: 19.0.622
Redshift: redshift_v3.0.62 (たぶん)

一部下記で確認しています
Geforce Game Ready ドライバー 526.98 Houdini 19.0.796 (daily)

Vellum Open CL Error on new install | Forums | SideFX

読んでいく

scale_stretch_constraints

色々やっています

Attach To Geometry かつ Tangent Stiffness が有効なとき 以外

type が attachnormal のときです

@stiffness *= Stretch の Stiffiness の 乗数 をしています

Cloth かつ Enable Warp(縦糸) / Weft(横糸) が有効のとき

warpWeftScale にて、
対象の線分と materialuv 空間上でのx軸がなす角 (degree) を求め、0 ~ 90 に変換します

45度未満、以上で scale の計算式を変えています

その後、logscaleStiffness にて、
stiffness = e^(scale * log(stiffness + 1)) - 1 とします
このとき、負 or +∞ にならないよう clamp しておきます


scale_stretch_constraints に戻りまして、
stiffness を attribute で scale する場合は反映しつつ
先程と同様に logscaleStiffness も使います
(damping も 同様にここで scale しています)

Stretch の Enable Plasticaly が有効な場合、下記も scale します
(全て attribute での scale です)

  • plasticthreshold
  • plasticrate
  • plastichardening

後続の scale_bend_constraints では引数を bend のものに変えて、同じ処理をします

Tips

matrix の初期化

どうやらいくつか初期化方法があるようです

3@m1 = 1;

 \begin{pmatrix}
1&0&0\\
0&1&0\\
0&0&1
\end{pmatrix}

3@m2 = set(1, 2, 3);

 \begin{pmatrix}
1&1&1\\
2&2&2\\
3&3&3
\end{pmatrix}

3@m3 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
3@m3 = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };

 \begin{pmatrix}
1&2&3\\
4&5&6\\
7&8&9
\end{pmatrix}

参考

www.sidefx.com

primgroupmask

パターンに一致する group名を space 区切りの文字列で取得するやつ

www.sidefx.com

まとめ

これで、 contraint の出力分まで読みました
あとは guide を読めば終わるはず...

何かあれば Twitter までお気軽にどうぞ~ twitter.com

[Houdini] Vellum Constraints を読んでみた その10

概要

こちらの続きです

shop-0761.hatenablog.com

環境

OS: Windows 10
Houdini: 19.0.622
Redshift: redshift_v3.0.62 (たぶん)

一部下記で確認しています
Geforce Game Ready ドライバー 526.47
Houdini 19.0.796 (daily)

Vellum Open CL Error on new install | Forums | SideFX

読んでいく

hair

ドキュメントより

エッジ上の距離とエッジ間の屈曲で構成された拘束を生成します。 この屈曲には、エッジの捻じれも含まれるので、Torsion(ねじり力)効果を出すことができます。

参考

www.sidefx.com


add_stretch_shear_constraints

__stretchsrc を対象に

  • 対象の point が 1つの prim にのみ属している
  • ポリゴンである
  • ポリゴンが開いている (閉じていない)

を満たす point を見つけます
その point と隣接する point を結ぶ polyline を追加し下記を設定します

  • __stretchconstraints (group)
  • restlength (polyline の長さ) * Rest Angle Scale (Stretch の Rest Length Scale の値)
  • type (ここでは stretchshear)
  • stiffness (Stretch の Stiffiness の値)
  • damping Ratio (Stretch の Damping Ratio の値)

add_bend_twist_constraints

__bendsrc を対象に point と隣接する point を結ぶ polyline を追加し下記を設定します

  • __bendconstraints (group)
  • restvector * Rest Length Scale (Bend の Rest Length Scale の値)
  • type (ここでは bendtwist)
  • stiffness (Bendの Stiffiness の値)
  • damping Ratio (Bend の Damping Ratio の値)

TODO: computeBendTwistRestVector の中身はあんまり分からず...
知っている方がいましたら、教えてほしいです...

この辺かな...

encyclopediaofmath.org

archive.lib.msu.edu

branchweld attribute を持っていたら、createBranchWeldConstraints を呼びます


createBranchWeldConstraints

まず weld と 対象の point を polyline で結び、下記を設定します
値はコードベタ書きです

  • restlength : 0
  • stiffness : 1e20 ( 1.0 * 1020 )
  • dampingratio : 0.001
  • type : branchstitch

その後、bend / twist に適切な point を探します
weld に隣接 point (neighbours) のうち、下記を満たすものです

  • n → weld に向かう half edge のときの n
  • neighbours が 1つしかないとき

見つかれば、computeBendTwistRestVector を用いて restVector を計算します

角度上限を反映し、先程の2点を polyline で結び下記を設定します

  • restvector
  • __bendconstraints (group)

余談ですが、角度上限の条件式を軽く下記のようなコードで検証しました

float maxang = radians(180);

float rad = radians(179);
vector4 restvec = quaternion(rad, set(0, 1, 0));
vector4 v = qconvert(restvec);
float length = length(v);

printf("q %f \n", restvec);
printf("v %f \n", v);
printf("length: %d, maxang: %d\n", length, maxang);

q {0.000000,0.999962,0.000000,0.008727}
v {0.000000,3.124139,0.000000,1.000000}
length: 3.28028, maxang: 3.14159

と、想定している角度比較と計算誤差があるような...
(len がもう少し小さくなってほしいはず)

rad を 171 にすると length と等しくなります

まとめ

これでようやく肝になる部分は読み終わったはず...!
わからないところはいくつかありますが...

以後は Constraint の Output / GUIDE 周りの話になるかと思います

何かあれば Twitter までお気軽にどうぞ~ twitter.com

[Houdini] Vellum Constraints を読んでみた その9

概要

こちらの続きです

shop-0761.hatenablog.com

環境

OS: Windows 10
Houdini: 19.0.622
Redshift: redshift_v3.0.62 (たぶん)

一部下記で確認しています
Geforce Game Ready ドライバー 526.47
Houdini 19.0.796 (daily)

Vellum Open CL Error on new install | Forums | SideFX

読んでいく

Triangle Stretch

ドキュメントより

各三角形は、指定した剛性に応じて伸びや捻じれを除去することで三角形をAs-Rigid-As-Possible(ARAP:可能な限り硬く)に維持する拘束に変換されます。

Clothに行きたかったんですが、前段としてこちらを把握しておく必要があります

Triangle Stretch には下記のようにエネルギーモデルがあり、
迷ったら Scale-Invariant ARAP にするのが良さそうです

Scale-Invariant ARAP
解を求める時に三角形の面積や四面体の体積を考慮することで複数のスケールでも剛性値が同じような挙動になるAs-Rigid-As-Possibleモデル。 通常では、このオプションがたいていの材質(皮膚や筋肉など有機的な材質を含む)に対して最善の選択肢となります。

ほぼ computeTetFiberRestLength と同じですが、
computeTriRestMatrix 部分だけ異なります


fromTriangleSpaceXform

p0, p1, p2 からなる面からワールド座標系に変換するための matrix を計算します


computeTriRestMatrix

fromTriangleSpaceXform の結果は直交行列のため、
転置を取ると逆行列と同値になります
ここではパフォーマンスの観点から invert ではなく、
transpose を使っているようです

その後、xy平面へ変換し行列式と、restMatrix を詰めておしまいです

2x2 の行列の行列式は、下記のように平行四辺形の面積と同義のため、
1/2 倍することで三角形の面積を求めています

余談ですがこの関数自体がたぶんどこかのコードのコピペなので、
matrix2 M を作るときの transpose は不要なんじゃないかな...?


すべて済むと下記を設定しています

  • restlength (三角ポリゴンの面積)
  • restvector (restlength の計算に用いた 2x2 の行列を vector4 として保持)
  • type (ここでは triarapnl or triarap or triarapnorm 前述のエネルギーモデルを考慮しての命名)
  • __stretchconstraints (group)
  • stiffness (Stretch の Stiffiness の値)
  • damping Ratio (Stretch の Damping Ratio の値)

www.sidefx.com

cloth

ドキュメントより

Distance Along Edges 拘束と Bend Across Triangles 拘束の両方で構成された拘束を生成します。

Stretch Type によって、
Distance Along Edges / Triangle Stretch のどちらかの設定を引き継ぎます

その後、Bend Across Triangles と同様の設定をします

まとめ

Triangle Stretch 自体は constraint type のうち、早めに見ていたんですが
どうしても内容が分からず合間に行列の勉強をちまちましていました...

いざ身構えて cloth を改めて見に行ったら、以前やった内容の流用だったので
あっさり終わってしまいました...

何かあれば Twitter までお気軽にどうぞ~ twitter.com

[Houdini] Vellum Constraints を読んでみた その8

概要

こちらの続きです

shop-0761.hatenablog.com

環境

OS: Windows 10
Houdini: 19.0.622
Redshift: redshift_v3.0.62 (たぶん)

読んでいく

途中で出てくる Model については Triangle Stretch の項でまとめて紹介します

Tetrahedral Fiber

ドキュメントより

各四面体が、ポイント上のmaterialWで指定された方向(このアトリビュートがなければ{0, 0, 1})に沿って平坦化を試みる拘束に変換されます。 これらの拘束をVellum Constraint Propertyを使って、シミュレーション中にそれがアニメーションされるほどに弱い剛性を設定することで、ボリュームの収縮効果をシミュレーションすることができます。

注) Houdini 19.0.622, 19.0.720 では Tetrahedral Fiber を含む Vellum Solver を
実行するとHoudini がクラッシュする可能性があります
(手元の環境の問題かもしれないですが)


2022/11/13 追記

どうやらグラボのドライバーとのかみ合わせが悪いようです
とりあえず手元では下記で動いているっぽいです

Geforce Game Ready ドライバー 526.47
Houdini 19.0.796 (daily)


事前準備として、まず Tet Conform でポリゴンを四面体にしておきます
次に materialW Attribute を作成します(Attributeがない場合は自動で {0,0,1} で作成されます )
この materialW は最終的にジオメトリの local space に変換されることに注意です

実際の処理は、対象となる point が

  • 四面体 (typeId == 21) である
  • __constraintsrc 属している
  • 4点からなる prim に属している

ときに行われます


computeTetRestMatrix

ここでは p3 を各点から打ち消す (p3 を原点に戻す) ことで、四面体の体積の公式である

 \frac{1}{6} | det M |

に落とし込むことができます
(Mを転置しているのはおそらくこの後の計算で便利だからかな...?)

  | det M | = 0 の場合は、 逆行列が存在しないので打ち切ります

参考

www.headboost.jp

そして、 restMatrix : M の逆行列、 volume: 四面体の体積、として値を返します


computeTetFiberRestLength

materialW について軽く触れておきます

ここでは materialW がすでにあれば、各頂点の値を全て足して正規化します

その後、material W は restM の転置行列と掛け算することで、座標変換されます


すべて成功した場合、4点は tet として addprim されます
その prim に対して下記を設定します

  • __stretchconstraints (group)
  • restlength (四面体の体積)
  • type (ここでは Non-LinearARAP なら tetfiber, それ以外なら tetfibernorm)
  • Stiffness (Stretch の Stiffiness の値)
  • Damping Ratio (Stretch の Damping Ratio の値)
  • restvector (materialW)

Tetrahedral Stretch

Model によって type が変わります

  • Non-Linear ARAP : tetarapnl
  • Linear ARAP : tetarap
  • Scale-Invariant ARAP : tetarapnorm

さらに Preserve Volume が有効になっていれば、 上記文字列の末尾に vol が付与されます

処理内容は computeTetFiberRestLength とほぼ同じです
差は Stretch の Rest Length Scale が考慮されるくらいです

  • __stretchconstraints (group)
  • restlength (四面体の体積) * Rest Length Scale (Stretch の Rest Length Scale の値)
  • type (Modelによって異なる)
  • Stiffness (Stretch の Stiffiness の値)
  • Damping Ratio (Stretch の Damping Ratio の値)
  • restvector ({0, 0, 0, 1})

Tips

Softbody

www.sidefx.com

ドキュメントより

各四面体は、指定した剛性に応じて伸びや捻じれを除去することで四面体をAs-Rigid-As-Possible(ARAP:可能な限り硬く)に維持する拘束に変換されます。 Preserve Volume が有効になっている場合、 Tetrahedral Volume 拘束の動作方法と同様に、この拘束は、さらに非常に強い内部剛性を使いつつ、指定した Damping Ratio を使って体積の維持を試みます。

まとめ

ようやく Constraint Type ごとの分岐に終わりが見えてきました...

何かあれば Twitter までお気軽にどうぞ~ twitter.com

[Houdini] Vellum Constraints を読んでみた その7

概要

こちらの続きです

shop-0761.hatenablog.com

環境

OS: Windows 10
Houdini: 19.0.622
Redshift: redshift_v3.0.62 (たぶん)

読んでいく

Weld Points

ドキュメントより

これ自体は拘束ではありませんが、weldアトリビュートを編集して、計算用にポイントを論理的に単一ポイントに結合します。 しかし、それらのポイントは独立したポイントの状態のままです。 さらに、これは、論理的に結合されたエッジの箇所にBend拘束を構築して、その結果を一枚の平坦なピースのように作用させることができます。 Vellum Post Process SOPは、シミュレーション後のそれらのWeld頂点を、レンダリングでジオメトリが繋がっているように見えるように繋ぎ直すことができます。

他と比べるとややノード量があります

create_welds

Constrain to Closest Point が有効なときは nearpoint で、そうでないときは自身の ptnum を使って __targetsrc グループから point を探し出します

すでに有効な weld or id を持っているときは、それを使います
なければ 上記で見つけた point を設定します

id Attribute がある : weld は point ID
id Attribute がない : weld は ptnum

値が1または自身を参照している場合は、接合なしを意味しますが、他のポイントからは、このポイント に 接合することができます。 idアトリビュートが存在しなかった場合は、この値はポイント番号を意味します。存在すれば、それはポイントIDです。

www.sidefx.com

collapse_welds

id があり、有効な ptnum が見つかれば、その値で weld を上書きします 自身と結合しようとしている weld を無効化しておきます

scale_stretch_breaking2

__stretchsrc に属しており、有効な weld がある場合に下記を設定します

  • breakthreshold (設定に応じてScaleする)
  • breaktype (Breaking の Type)

add_bend_constraints3

createDihedralConstraintFromNewlyWeldedPrimitives の話ですが、
Bend Across Triangles の createDihedralConstraint とほぼ同じ内容なので省略します

copy_bend_attributes

対象 prim から取得した point が属する prim を対象に __bendconstraints に属していない かつ type が bend のprimが持つ値を
合算し平均を取ったものを設定します

  • stiffness
  • dampingratio

reset_welded_restvectors

以前から少し出ていた restVector ですが、ここで再計算しておくようです

Struts

ドキュメントより

各ポイントが、自身のピースのメンバーで真っ直ぐな見通し線の方向にある反対側のポイントを検索します。 Struts(支柱)は、各ポイントとそのポイントの間にDistance拘束を構築します。 これは、完全にFEMによる解法を使わずに、オブジェクトの剛性と体積を表現した内部支柱のような、たくさんの楊枝を構築します。

  1. 対象としている point から Direction Attribute ( N ) から ray を飛ばし、
    最初に交差した prim を見つけます
  2. その prim が持つ point のうち対象と同一 class ではない (自身でもない) もので
    一番近い point (bestpt) を取得します
    Test Normals が有効な場合、
    bestpt の normal と Direction Atttribute の内積が 0 以上のものを採用します

対象としている point と bestpt を結び、下記を設定します

  • __stretchconstraints (group)
  • restlength (対象としている point と bestpt の距離) * Rest Length Scale (Stretch の Rest Length Scale の値)
  • type (ここでは distance)
  • Stiffness (Stretch の Stiffiness の値)
  • Damping Ratio (Stretch の Damping Ratio の値)

remove_duplicates にて、__stretchconstraints を対象に
primpoints で取得できるポイント番号が完全に一致するものを削除しておきます

Tips

各略称

tgt : target

Wrangle の Enforce Prototypes

houdinifx.jp

idtopoint

id Attribute があれば、その値をもとに ptnum を返します なければ、ptnumがidとして使用され、大体のケースはptnumがそのまま返ってきます

www.sidefx.com

Rewire Vertices

Fuse より自由に再接続できるノード

www.sidefx.com

まとめ

過去に見てきた処理と重複するとこがちらほら出てきました
思ったよりこのシリーズが長くなってきましたが、引き続き読んでいこうと思います

何かあれば Twitter までお気軽にどうぞ~ twitter.com

[Houdini] Vellum Constraints を読んでみた その6

概要

こちらの続きです

shop-0761.hatenablog.com

環境

OS: Windows 10
Houdini: 19.0.622
Redshift: redshift_v3.0.62 (たぶん)

読んでいく

Shape Match

ドキュメントより

Define Pieces パラメータによって決定された各ピースに対して、ポイントを元々の(静止)形状まで引っ張り戻す拘束を作成します。 この拘束を使用することで、例えばCloth拘束などの既存拘束に剛性を足したり、この拘束自体で他のVellumジオメトリと相互作用できるほぼ剛体のオブジェクトを作成することができます。


Tip Shape Match拘束は、通常では Mass を Calculate Uniform に設定し、整合性の取れたサイズのジオメトリで非常に上手く動作します。 この類のジオメトリを生成したいのであれば、Remesh SOPを使用すると良いでしょう。


Tip この拘束タイプを使用した効果的なワークフローは、シミュレーション出力に対してExtract Transform SOPを使用してピース毎に向きを持ったポイントを生成してから、 Transform Pieces SOPを使用してオリジナルのレンダージオメトリをそれらのポイントまでトランスフォームさせることです。 このワークフローだと、拘束がコリジョンポイントまたはピンにおいて剛性の維持に失敗した際の何かしらの小さな変形が起きるのを回避することもできます。

内容としては Pressure に近いです
各 piece ごとに全頂点を polyline で結び、下記を設定します

  • __stretchconstraints (group)
  • restlength (各頂点の座標) * Rest Length Scale (Stretch の Rest Length Scale の値)
  • type (ここでは shapematch)
  • Stiffness (Stretch の Stiffiness の値)
  • Damping Ratio (Stretch の Damping Ratio の値)
  • restVector ({0, 0, 0, 1})

Glue

ドキュメントより

各ポイントが、自身のピースのメンバーでない隣接ポイントを検索します。 これは、各ポイントをその隣接に維持させるDistance拘束を構築します。 これは、プロキシミティ(近接度)で自動的にポイント間を接着させるシステムを構築する時、特に分離を結合させる時に役立ちます。

cluster attribute を使う場合、 piece attribute を持っている必要があります

createGlueConstraints はちょっと長いですが、
大半は不正チェックとランダム性を出すための処理です
コメントが詳しいので詳細はそちらに譲ります

対象の point から nearpoints で良さそうな point を見つけられたら、polyline を結び
下記を設定します

  • __stretchconstraints (group)
  • restlength (対象の point と 良さそうなpoint の距離) * Rest Length Scale (Stretch の Rest Length Scale の値)
  • type (ここでは stitch)
  • Stiffness (Stretch の Stiffiness の値)
  • Damping Ratio (Stretch の Damping Ratio の値)

Constraints Per Point より多い分は prim を削除しておきます

Tips

公式チュートリアル

今更ですがチュートリアルを見つけたので貼っておきます

www.sidefx.com

Group Name を $OS で指定する

こうしておくとちゃんとノードの名前を変えるようになるし、
opname で指定するときの視認性もよさそうです (手元では preset 登録しました)

まとめ

VEX を見ていると各 preset でもコードの書き方が違うので
複数人で作ってるのが読み取れます
VEXのコーディング規約出してほしいな...

何かあれば Twitter までお気軽にどうぞ~ twitter.com

[Houdini] Vellum Constraints を読んでみた その5

概要

こちらの続きです

shop-0761.hatenablog.com

環境

OS: Windows 10
Houdini: 19.0.622
Redshift: redshift_v3.0.62 (たぶん)

読んでいく

Stitch Points

ドキュメントより

Distance拘束を使って同じジオメトリ内のポイントを縫合します。 これらのポイントは、実際には幾何学的に繋がっている必要はありません。 これは、ジャケットを閉じた状態に維持したり、ポケットがひらひらしないようにするのに役立ちます。

詳細な機能紹介

www.sidefx.com

create_stitch_constraintsノード までは Attach To Geometrycreate_target_constraintsノード とほぼ同じです

createStitchConstraintcreateAttachConstraint とほぼ同じです

共通設定は以下の通りです

  • __stretchconstraints (group)
  • Stiffness (Stretch の Stiffiness の値)
  • Damping Ratio (Stretch の Damping Ratio の値)

__stretchsrc かつ TargetGroup な point を対象に下記を調べます

Use Closest Location on Primitive / Constrain to Closest Point が共に有効なとき

xyzdist で今見てる point から一番近い primtive を取得します
このときの primitive は三角ポリゴンである必要があります

またポリゴンが閉じていないときは UV を remap しておきます

  • restlength (xyzdist の戻り値) * Rest Length Scale (Stretch の Rest Length Scale の値)
  • type (ここでは ptprim)

Constrain to Closest Point のみ有効のとき or 共に無効のとき

  • Constrain to Closest Point が有効 : nearpoint で一番近い point を取得
  • 共に無効 : AttachするジオメトリのTargetGroup な point の中から、
    対応する index の point を見つけようとする

  • restlength (一番近いpointまでの距離) * Rest Length Scale (Stretch の Rest Length Scale の値)

  • type (ここでは stitch)

良さそうな動画を見つけたので貼っておきます

Vellum Constraint Features | John Lynch | H18 Masterclass - YouTube

サンプルの hip ファイルもあります

www.sidefx.com

Pressure

ドキュメントより

Define Pieces パラメータによって決定された各ピースに元々の体積を記録し、その体積を維持する(多くのポイントで定義された)拘束を構築します。 この拘束は全体的に適用されるので、風船のように1箇所を圧搾すると他の箇所が膨張します。 pressurescalePointアトリビュートを使用することで、ポイント毎に圧力拘束の効果をスケールさせることができます。 このアトリビュートを使用すれば面白い膨張効果を表現することができますが、例えばピン留めされていない風船のpressurescaleが片側だけほぼゼロになっていた場合だと不均衡なフォースを発生してしまうので注意して使用してください。

詳細な機能紹介

www.sidefx.com

はじめに、 connectivity で point に attribute を付与します
(事前に自分でやっておいてもよいです)

add_pressure_constraints1 にて、各 class attribute に相当する group ごとに処理をします 下記を設定します
volume attribute はかなり前にcompute_volume ノードで計算済みです

  • __stretchconstraints (group)
  • restlength (各頂点の volume attribute の和) * Rest Length Scale (Stretch の Rest Length Scale の値)
  • Stiffness (Stretch の Stiffiness の値)
  • Damping Ratio (Stretch の Damping Ratio の値)

Tips

Attribute VOP の Vex Source

こうすることで、 既存の Wrangle の処理を参照して実行できるようです
Reference Copy でもいいような気もしますが...

nuniquevals

expression で見たことないやつが出てきたので貼っておきます
固有の値の数...という日本語がわかりにくいのですが、
例えば name attribute が piece0, piece1, piece2 とあったときに
nuniquevals では 3 が返ります

www.sidefx.com

uniqueval

vex だと nuniqueval と組み合わせて for を回して走査する使い方っぽいです
今回は wrangle が Numbers で nuniquevals で回数指定しているケースを見ました

www.sidefx.com

printf

さすがにそろそろ困ってきたので、ログ出力したいな...とおもったらありました

参考

www.sidefx.com

Group 構文 @__class=0 ^!__constraintsrc

これは @__class=0 かつ __constraintsrc に属するもの
という意味です

個人的に分かりにくかったので図を用意しました

スペースを開けて条件を並べると結合(和集合)される
というのがポイントです (積集合だと思ってました)

そのため、 ^ を使い前のパターン条件を引き継ぎながら、
! で打ち消すというやや遠回りな解決方法になっています

構文を日本語に直すなら、下記のような感じでしょうか

@__class=0 のグループから、__constraintsrc をではない部分を差し引く

www.sidefx.com

まとめ

今まで手元で雑に各 Constraints の設定をしていたんですが、
ちゃんとサンプルデータを元にしたほうが実挙動を把握する上で
便利そうなのでちゃんと用意しようと思いました...

数学で頭を抱えるならまだしも(?)
Houdini でも知らない技がたくさん出てきますね...

何かあれば Twitter までお気軽にどうぞ~ twitter.com