はじめに
Grasshopperは、Rhinoと呼ばれる3Dモデリングソフトウェアに組み込まれたビジュアルプログラミング環境で、ユーザーが直感的に3D形状を生成するためのツールです。Pythonを使用することで、Grasshopperの機能を拡張し、より複雑な処理やデータ操作を行うことができます。本記事では、曲線同士の重なりを検出し、重ならない曲線だけを抽出するコンポーネント「CurveOverlapFilter」について詳しく解説します。
CurveOverlapFilterの概要
CurveOverlapFilterは、Rhino内で指定された曲線(Crv1)が他の曲線(Crv2、Crv3)と重ならないかどうかをチェックし、重ならない曲線だけをリストとして出力するコンポーネントです。このコンポーネントは、都市計画や建築設計などのプロジェクトにおいて、曲線が交差しないようにデザインを調整するために役立ちます。
コード全文
import Rhino.Geometry as rg
import scriptcontext as sc
# GUIDをRhinoのCurveオブジェクトに変換する関数
def guid_to_curve(guid):
obj = sc.doc.Objects.Find(guid)
if obj and isinstance(obj.Geometry, rg.Curve):
return obj.Geometry
return None
# 入力 (Crv1, Crv2, Crv3)はすべてリストで提供されると仮定
# Crv1: List of curves (as GUIDs) to be filtered
# Crv2, Crv3: Lists of curves (as GUIDs) to check for overlap
# Tolerance: 衝突判定の許容誤差
def curves_overlap(crv, crvs, tolerance):
# GUIDからCurveに変換
crv_geom = guid_to_curve(crv)
if crv_geom is None:
return False
# 曲線間の交差をチェック
for other_crv in crvs:
other_crv_geom = guid_to_curve(other_crv)
if other_crv_geom is None:
continue
# 曲線間の交差イベントを取得
intersections = rg.Intersect.Intersection.CurveCurve(crv_geom, other_crv_geom, tolerance, tolerance)
if intersections.Count > 0:
return True
return False
# 許容誤差 (交差の判定に使用)
tolerance = 0.001
# 結果を保持するリスト
filtered_curves = []
# Crv1から重ならない曲線をフィルタリング
for crv in Crv1:
if not curves_overlap(crv, Crv2, tolerance) and not curves_overlap(crv, Crv3, tolerance):
filtered_curves.append(crv)
# 出力
Crv = filtered_curves
コンポーネントの仕組み
3.1 GUIDからRhinoオブジェクトへの変換
Rhinoでは、すべてのオブジェクトはGUID(Globally Unique Identifier)という一意の識別子で管理されています。このGUIDを使って曲線オブジェクトにアクセスするための関数が以下です。
def guid_to_curve(guid):
obj = sc.doc.Objects.Find(guid)
if obj and isinstance(obj.Geometry, rg.Curve):
return obj.Geometry
return None
- 説明:
sc.doc.Objects.Find(guid)を使用して、指定されたGUIDからRhinoのオブジェクトを検索します。- そのオブジェクトが曲線であれば、Rhinoの曲線オブジェクトとして返します。
- もし曲線でない場合やオブジェクトが見つからなければ、
Noneを返します。
3.2 曲線の重なり判定
次に、曲線が他の曲線と重なっているかどうかを確認する関数があります。
def curves_overlap(crv, crvs, tolerance):
crv_geom = guid_to_curve(crv)
if crv_geom is None:
return False
for other_crv in crvs:
other_crv_geom = guid_to_curve(other_crv)
if other_crv_geom is None:
continue
intersections = rg.Intersect.Intersection.CurveCurve(crv_geom, other_crv_geom, tolerance, tolerance)
if intersections.Count > 0:
return True
return False
- 説明:
- まず、
guid_to_curve関数を使って、crv(チェック対象の曲線)をRhinoの曲線オブジェクトに変換します。 - 次に、リスト
crvs内の各曲線と交差を検出します。交差が1つでも見つかれば、その曲線は重なっていると判断されます。
3.3 メイン処理
重ならない曲線をフィルタリングするためのメイン処理は以下の通りです。
filtered_curves = []
for crv in Crv1:
if not curves_overlap(crv, Crv2, tolerance) and not curves_overlap(crv, Crv3, tolerance):
filtered_curves.append(crv)
- 説明:
Crv1内の各曲線に対して、Crv2およびCrv3との重なりをチェックします。- 重なりがなければ、その曲線を
filtered_curvesリストに追加します。
使用方法
- Grasshopperにコンポーネントを追加: このPythonコードをGrasshopperのPythonスクリプトコンポーネントに入力します。
- 入力:
- Crv1: 重ならない曲線を抽出したい曲線のGUIDリスト。
- Crv2: 重なりをチェックしたい曲線のGUIDリスト。
- Crv3: 同上。
- Tolerance: 曲線間の交差を判断するための許容誤差。
- 出力: 重ならない曲線が含まれるリスト
Crvが出力されます。
カスタマイズのポイント
- 許容誤差 (Tolerance): この値を調整することで、交差の判定を厳しくしたり、緩くしたりできます。プロジェクトに応じて適切な値に設定しましょう。
- 入力の拡張:
Crv2やCrv3のリストを増やすことで、より多くの曲線と交差をチェックすることが可能です。
応用アイデア
- 都市計画: 道路や敷地境界が交差しないようにチェックし、デザインを最適化します。
- プロダクトデザイン: 複数の部品が干渉しないように確認し、製品設計を効率化します。
- 建築設計: 建物や構造物のレイアウトが重ならないか確認する際に活用できます。
まとめ
CurveOverlapFilterは、Rhinoの曲線間の重なりを検出し、プロジェクトに必要なデザインをサポートする非常に便利なコンポーネントです。初心者でも簡単に使用できるように設計されており、プロジェクトの品質を向上させるために活用できます。このコンポーネントを使うことで、デザインの自由度を高め、作業の効率化を図ることができます。