2020年11月27日金曜日

【Grasshopper_38】無限につながる凹凸形状の作り方


久々のGrasshopperネタを一つ。

トップ画像は真ん中の四角の部分を上下左右に移動コピーした状態ですが、上下、左右がそれぞれ連続してつながる形状になっています。

継ぎ目が若干目立つので改善の余地がありますが、無限につながるパターンの作り方を紹介します。

Step.1 XY平面上に枠を作る

まずはXY平面上にRectangleを使って四角い枠を作ります。
とりあえず、大きさは300x300で。

Step.2 サーフェス化する

Step.1で作った枠にNetwork Srfを使ってサーフェスにします。
判別しやすいように、Network Srfの出力端子をBase_Srfとしておきます。

Step.3 ランダムな点を作成する

Step.1で作った枠の中に、ランダムな点をPopurate 2Dを使って作成します。
個数はとりあえず200個で。

Step.4 Base_Srfの分割

Step.2で作ったBase_Srfを左右で半分に分割します。
やり方は何通りかあると思いますが、今回はUVを使って分割しています。
求めた半分のエリアをそれぞれ、LH_Area、RH_Areaとしておきます。

Step.5 ドロネー図形による三角形を作る

続きまして、Step.3で作ったランダムな点を使って、三角形を作ります。
ここで使うのは、Delaunay Edgesコンポーネント、ドロネー図形と呼ばれる物です。
ここで作られるのは閉じた三角形ではなく、それぞれが単純な直線となっています。

Step.6 ドロネー図形を閉曲線にする

Step.5で作ったドロネー図形の直線を、後工程で加工するために、閉じた曲線にします。
やり方は、Step.2で求めたBase_SrfをStep.5で作ったDelaunay Edgesの出力で分割し、それぞれ分割されたサーフェスのエッジをBrep Edgesで抽出し、Join Curvesで結びます。
名称は、Joined_Edgesとしておきます。

Step.7 ドロネー図形を左右に分割する

Step.6で求めたドロネー図形による閉曲線を、左右に分割します。
Step.4で求めたLH_Area、RH_Areaを使ってRegion_Intersectionによる抽出で左右に分けることができます。

並行して、RH_Areaの横幅を計測しておきます。(次の工程で使います)

Step.8 LH側をRH側の右に移動させ、すべての点を求める

Step.7で分割したドロネー図形のうち、LH側をX方向に移動させ、RH側の右に来るようにします。
MoveコンポーネントのT入力にあるExpression欄にx*2を入力し、移動ベクトルをLH_Areaの横幅の2倍にしています。

移動が終わったら、Explodeコンポーネントにつなぎ、ドロネー図形のすべての角の点を求めて、一つにまとめます。これをAll_Ptという名称にしておきます。

Step.9 中央付近の点を間引く

All_Ptの中央部分が若干、点の密度が高いので間引きます。
All_Ptの後ろでremoveDuplicatePtsコンポーネント(kangarooにあります)を使ってダブリ点を削除し、その後、Rectangleで中央付近を囲い、Point In Curveにより内外判定をし、Cull Patternsで枠の内側にある点を削除します。

Step.10 再度、ドロネー図形を作る

再びドロネー図形を作ります。
この時点で、左右方向が繰り返し形状になっています。
名称をとりあえず、Delaunay_2としておきます。

Step.11 上下に範囲を分割する

Step.6での作業と同様、閉曲線化を行います。
また、Step.7と同様の作業を、今度は上下方向で実施します。
つなぎ方は上の図のようになります。
三角形の閉曲線をJoined_Edge_2、上側の範囲をUpper_Area、下側の範囲をDown_Areaという名称にしておきます。

Step.12 下のドロネー図形を上に移動させてすべての点を求める

Step.8と同様に、Down_Area側のドロネー図形をUpper_Area側の上に移動させ、すべての点を抽出します。再びこれをAll_Ptという名称にします。

Step.13 上下中央付近の点を間引く

Step.9と同様に、中央付近の点を間引く処理をします。

Step.14 再びドロネー図形を作る

再び、ドロネー図形を作ります。
ひとまず、2D作業はこれで完成です。名称はDelaunay_Fullとしておきます。
ここから、3D化作業に入ります。

Step.15 Base_Srfの移動

まずは、Base_Srfを、Step.14で完成させたドロネー図形にぴったり合うよう、移動させませしょう。
Base_Srfの1辺の長さを半分にした量をX,Yそれぞれの方向に移動させます。
これを、Base_srf_movedという名称にします。

Step.16 ドロネー図形の閉曲線化

Spte.15で移動させたBase_srf_movedを、Step.14で求めたドロネー図形を使って、サーフェスのエッジを抽出して閉曲線を求めます。
その後、Explodeコンポーネントを使って点を抽出します。これをEdge_Pointという名称にしておきます。

Step.17 高さの数値を格納するための、仮の数列を作る

いよいよ、これより凹凸の高さの数値を求めて行きます。
まずは手始めに、高さの数値を格納するための、仮の数列を作ります。

Step.16で求めたEdge_Pointは、三角形一つ一つの角の点を求めているため、上の図のPanel左側のように、階層ごとに4つの点の座標が格納されています。そこで、SeriesコンポーネントとList Lengthコンポーネントを使い、0から3までの数列を作ります。上の図の、Panel右側のような中身になります。これを、Base_Indexという名称にします。

Step.18 Base_srf_movedの外周エッジのオフセットを求める

続いて、Base_srf_movedのエッジ曲線上にある点と、エッジ曲線よりも内側にある点を分類するための曲線を求めます。
Base_srf_movedのエッジをほんの僅かに内側にオフセットさせるだけでOKです。
これをOffset_Edgesという名称にしておきます。

Step.19 外周上にある点とインデックスを分離する

上の図のようにつなぎ、Step.18で求めたオフセット曲線の内側に点が有る/無いの判定をPoint In Curveコンポーネントで行い、Cull Patternで分類します。
Cull PatternコンポーネントのP入力の上で右クリックし、Invertを選択することで、TrueとFalseの反転ができます。
名称はわかりやすいように、上の図のように名前をつけておきます。
内側の点がEdge_Pt_CTR、内側のインデックスがIndex_Ctr、エッジ曲線上の点がEdge_Pt_OUT、そのインデックスがIndex_Outとしておきます。

Step.20 4隅の点を分類するための曲線を作る

続きまして、今度はStep.19で求めたエッジ曲線上にある点のうち、隅の4点を分類するための曲線を作ります。隅の4点が分類さえできれば形は何でもOKですが、参考として、上の図のように組みます。名称は、4_Pt_separatedとしておきます。
また、後の工程で使うため、上の図のように、Join Curvesコンポーネントから取り出した曲線をBase_srf_Edgeとしています。

Step.21 外周上の4隅の点のインデックスを分離

まずは、エッジ曲線上の点を、4隅の点とそれ以外に分離します。
上の図のようにつなげばOKです。
ちなみに、4隅の点は、インデックスのみあればOKです。

Step.22 外周上の点を上下と左右で分離する

次に、4隅の点を除いたエッジ曲線上の点を上下と左右に分離します。ここで使う曲線はStep.20で求めたBase_srf_Edgeです。名前は上の図のようにつけます。

Step.23 枠内部の点の高さを求める

高さ値を求める部分です。まずは、枠の内部の点の高さを求めます。
Step.19で求めたEdge_Pt_CTRを使って、Base_Srf_movedの面上のUV座標を求めます。UとVの座標を、Deconstruct Pointコンポーネントを使って個別に分離し、それぞれにGraph Mapperコンポーネントを使ってランダム風に値をばらけさせます。
グラフの種類は、なるべく変化の激しい方がよりランダムに見えるため、今回はPerlinを選択しています。
このとき、Deconstruct PointのP入力にFlattenを設定し、すべての点が同時にPerlinで変換されるようにしています。
取り出したUとVのPerlin変換した値を足し算し、その値をRemapコンポーネントを使って所定の範囲に収めます。今回は、最大高さを10mmとしています。
最後に、これより後の工程では元の階層に戻したほうが都合がいいので、Unflattenコンポーネントを使って、いったんFlattenで平たん化した階層を元に戻します。
求めた高さはCTR_Heightという名称にします。

Step.24 外周上の点の高さを求める

今後は、エッジ曲線上の、4隅以外の点(上下および左右)の点の高さを求めます。
Step.22で分離した点をそれぞれ使います。
高さそのものはStep.23と同じくGraph MapperのPerlinとRemapコンポーネントの組み合わせを使います。
また、4隅の点の高さは、とりあえず10mmの半分にしておきますので、スライダーの数値を1/2にした値を取り出しておきます。

Step.25 すべての点の高さをまとめる

すべての点の高さをまとめます。
Step.17で作った、仮の高さの数値を、Replace Itemsコンポーネントを使って入れ替えて行きます。これまでに求めた、枠の内側の点の高さとそのインデックス、4隅の点の高さとそのインデックス、エッジ曲線上の点のうち、上下の点の高さとそのインデックス、同じく左右の点の高さとそのインデックスを使って入れ替えます。

Step.26 Z方向に点を移動させて面化する

Step.16で求めたEdge_Pointを、Z方向に移動させ、PolyLineで閉曲線にしたあと、Boudary Surfaceで面を張ったら完成です!

隣同志のエッジの形状が同一なので、完全にくっつきます。

0 件のコメント:

コメントを投稿

【Grasshopper_98】SporphとSurface Morphingの特徴、違いなどについて

今年もまたGWに突入しましたね。コロナ明けに円安、インバウンド特需のおかげで東京から郊外に出かけると例年以上に混雑に巻き込まれそうなので、昨年と同様、連休中は家に籠ってブログを更新します。今回のテーマは、Surface MorphingとSporphの違いについてまとめてみました。