SurfaceDomainSurfaceEvaluateSurfaceDomain関数とSurfaceEvaluate関数で、サーフェスのドメイン・情報を取得することができます。
本記事のGrasshopperファイルのダウンロードはこちら

今回は、上の画像のように、サーフェスから情報を取得し、作業平面を作成し、円柱をサーフェス上に作成します。

使用コンポーネント 1: Python 3 Script 2: Surface 3: plane 4: Brep
import rhinoscriptsyntax as rs
# RhinoをPythonから操作するためのライブラリを読み込む
pts = [(0,0,0),(10,0,5),(10,10,0),(0,10,5)]
# サーフェスを作成するための4点座標を定義
surface = rs.AddSrfPt(pts)
# 4点を使ってサーフェス(面)を作成する
domainU = rs.SurfaceDomain(surface, 0)
# サーフェスのU方向のドメイン範囲を取得する
domainV = rs.SurfaceDomain(surface, 1)
# サーフェスのV方向のドメイン範囲を取得する
u_norm = 0.2
# U方向の正規化された位置を定義(0〜1の範囲)
v_norm = 0.2
# V方向の正規化された位置を定義(0〜1の範囲)
u = domainU[0] + u_norm * (domainU[1] - domainU[0])
# 正規化した値を、実際のUパラメータ範囲へ変換する
v = domainV[0] + v_norm * (domainV[1] - domainV[0])
# 正規化した値を、実際のVパラメータ範囲へ変換する
srf_eva = rs.SurfaceEvaluate(surface, (u, v), 1)
# 指定したUV位置の情報を取得する
# 「1」を指定することで、点情報に加えて接線ベクトルも取得する
plane = rs.PlaneFromFrame(srf_eva[0], srf_eva[1], srf_eva[2])
# 取得した点と接線ベクトルを使って作業平面を作成する
cylinder = rs.AddCylinder(plane, 5, 1)
# 作成した平面を基準に円柱を作成する「Python 3 Script」には、上記のコードが記載されています。
順番に、コードの解説をしていきます。
pts = [(0,0,0),(10,0,5),(10,10,0),(0,10,5)]pts = [(0,0,0),(10,0,5),(10,10,0),(0,10,5)] では、サーフェスを作成するための4点座標を、リストで定義しています。
surface = rs.AddSrfPt(pts)AddSrfPt 関数で、4点を使ってサーフェス(面)を作成しています。
domainU = rs.SurfaceDomain(surface, 0)
domainV = rs.SurfaceDomain(surface, 1)SurfaceDomain 関数で、サーフェスのU方向とV方向のパラメータ(ドメイン)範囲を取得しています。
第1引数では、サーフェスを指定します。
第2引数では、0 の場合はU方向のドメイン範囲、1 の場合はV方向のドメイン範囲を取得できます。
u_norm = 0.2
v_norm = 0.2u_norm = 0.2 と v_norm = 0.2 では、U方向とV方向の位置を、0〜1の範囲で定義しています。
今回は、どちらも0.2の位置にしています。
これは、GrasshopperのReparameterizeと同様のことをするためです。
u = domainU[0] + u_norm * (domainU[1] - domainU[0])
v = domainV[0] + v_norm * (domainV[1] - domainV[0])この計算は、「0〜1で指定した割合の値」を、実際のサーフェスのUV範囲へ変換するための計算です。
例として、domainU = (5.0, 15.0) のようなドメイン範囲があるとします。
これは、U方向が5〜15の範囲であることを意味しています。
実際のUV値を直接扱うと、u = 8.245 のようになり、直感的ではありません。
そこで、u_norm = 0.2 のように、0〜1の範囲で考えるようにします。
これは、
0→ 始点側0.5→ 中央1→ 終点側
という意味になります。
つまり、u_norm = 0.2 は、「U方向の20%位置」という意味になります。
しかし、SurfaceEvaluate 関数では、実際のUVパラメータ値が必要になります。
実際のUVパラメータ値に戻すための式が、u = domainU[0] + u_norm * (domainU[1] - domainU[0]) になります。
例えば、domainU = (5.0, 15.0) とすると、
この範囲の最小値は 5 、最大値は 15 です。
範囲の長さは、15 - 5 = 10 になります。
もし、u_norm = 0.2 なら、「全体の20%位置」を求めたいことになります。
まず、u_norm * (domainU[1] - domainU[0]) を計算すると、0.2 * (15 - 5) = 2 になります 。
これは、「開始位置から2だけ進んだ位置」という意味です。
ただし、この 2 は「範囲内の移動量」でしかありません。
実際のU値にするには、開始位置 5 を足す必要があります。
u = 5 + 2 = 7 になります。
つまり、u = domainU[0] + u_norm * (domainU[1] - domainU[0]) は、「範囲の始点から、指定割合だけ進んだ位置」を求めている計算です。
srf_eva = rs.SurfaceEvaluate(surface, (u, v), 1)SurfaceEvaluate 関数では、指定したUV位置のサーフェス上の点座標や方向ベクトルを取得できます。
第1引数にはサーフェスデータ、第2引数にはUV値を指定します。
第3引数に 0 を指定した場合、点情報のみが取得されます。
第3引数に 1 を指定すると、点情報だけでなく、U方向・V方向の接線ベクトルも取得しています。
点、接線ベクトルのように複数データを取得する場合、リストとしてまとまったデータが出力されます。
plane = rs.PlaneFromFrame(srf_eva[0], srf_eva[1], srf_eva[2])PlaneFromFrame 関数では、点情報と2つのベクトルから、作業平面を作成しています。
第1引数には点データ、第2引数にはx軸のベクトル、第3引数にはy軸のベクトルを指定します。
今回の場合、srf_eva のリストの最初に点データ、2つ目と3つ目にベクトルデータがあります。
そのため、srf_eva[0] では1つ目の点データ、srf_eva[1] では2つ目のベクトルデータ、srf_eva[2] では3つ目のベクトルデータを取得しています。
cylinder = rs.AddCylinder(plane, 5, 1)AddCylinder 関数で、作成した作業平面上に、円柱を作成しています。
第1引数には作業平面データ、第2引数には高さの数値、第3引数には半径の数値を指定します。
「Python 3 Script」の右側の端子名を「surface」に設定するとサーフェスデータ、「plane」に設定すると作業平面データ、「cylinder」に設定すると円柱データがGH上に出力されます。




Comment