本記事では、GrasshopperでPythonを使う方法について解説します。
本記事で使用するGrasshopperデータのダウンロードはこちら
Python 3 Scriptとは

Python 3 Scriptは、GH上でPythonコードを実行するためのコンポーネントです。
このコンポーネントを使うことで、RhinoScriptSyntaxなどのライブラリを利用したモデリングが行えます。
Python 3 Scriptの配置方法
まずは、GHにPython 3 Scriptを配置する方法を紹介します。

Rhino上のコマンドで、「Grasshopper」と入力します。
もしくは、上の画像の緑のアイコンをクリックします。

すると、上の画像のように、Grasshopperが起動します。

「Python 3 Script」コンポーネントを配置します。
画面を左ダブルクリックし、「Python 3 Script」と入力し、enterキーを押します。

これにより、「Python 3 Script」コンポーネントが配置されます。

もしくは、上の画像のように、「Math」タブの「Script」から、「Python 3 Script」コンポーネントを選んで配置することもできます。
基本的な使い方
「Python 3 Script」の基本的な使い方を順番に解説します。
コードの実行
簡単なコード例を使い、コードを実行してみます。

「Python 3 Script」をダブルクリックすると、エディタが開きます。

ここにPythonコードを書くことで、処理を実行できます。
今回は、原点の(0,0,0)に点を作成するコードを記述しています。

一番左上のボタンでは、入力したコードを保存することができます。
緑色の三角のボタンでは、入力したコードを実行できます。
import rhinoscriptsyntax as rs # Rhinoで使う機能を読み込む
pt = rs.AddPoint(0, 0, 0) # (0,0,0)の位置に点を作る
a = pt # 作った点の情報をaに入れる今回のコードの最低限の説明です。
import rhinoscriptsyntax as rsRhinoScriptSyntaxを、使う準備をしています。
pt = rs.AddPoint(0, 0, 0) (0,0,0)の位置に点を作り、その点の情報をptに入れています。
a = pt作った点の情報を、aに入れています。
初期状態では、「Python 3 Script」の右下の端子の名前が「a」です。
a = ptとすることで、「Python 3 Script」の「a」端子から、作成した点データが出力されるようになります。
現時点では、なんとなく理解で問題ありません。

コードを実行すると、上の画像のように、点が作成されました。
このように、コードを実行することができます。
GH上のデータをPythonの変数・引数として渡す方法
次に、GH上のデータをPythonの変数・引数として渡す方法を解説します。

最初の例では、上の画像のように、2つの点をつなぐ1つの直線を作成します。
ここでは、2つの点をGH上で作成します。

使用コンポーネント 1: Construct Point 2: Python 3 Script 3: Curve
import rhinoscriptsyntax as rs # Rhinoで使う機能を読み込む
a = rs.AddLine(x, y) # 指定した2点から直線を作成するGH上のデータをPythonの変数として渡すには、渡したいデータを、「Python 3 Script」の左側の端子に接続します。

GH上のデータを変数・引数として使う場合、「Python 3 Script」の左側の端子の名前とコード上の変数名・引数名を一致させる必要があります。
今回の場合、2つの点を2つの「Construct Point」で作成しています。
2つの「Construct Point」を、「Python 3 Script」のxとy端子につなげています。
そして、コード内の a = rs.AddLine(x, y) の xとyには、GH上の点データが、引数として使用されています。
また、a = rs.AddLine(x, y) の変数名aと、「Python 3 Script」の右端子の1つは、aという同じ名前です。
これにより、「Python 3 Script」のa端子からは、rs.AddLine(x, y)の結果の直線データが出力されています。

端子名を変更する場合、変更したい端子を右クリックし、一番上の入力欄で名前を変更します。
上の画像では、「x」から「pt1」に名前を変更しています。

変更が完了すると、上の画像のように、端子名が変わります。

端子名とコード内の変数名・引数名が違う場合、エラーになります。

端子名とコード内の変数名・引数名を同じにすると、エラーが解消しました。
このように、端子名と変数名・引数名を一致させることが重要になります。

入力・出力端子を、増やしたり減らしたりすることもできます。
「Python 3 Script」に向かってズームすると、+と-のアイコンが表示されます。
+を押すと、端子を追加することができます。
-を押すと、端子を減らすことができます。
データ構造
GH上のデータを変数・引数として渡す際に、データを構造の種類を設定することも重要です。
データ構造の種類の設定が異なると、エラーが起きます。

入力するデータ構造の種類を設定するには、入力する端子を右クリックし、下側に表示される緑の3つの項目から任意のデータ構造の種類を選択します。

3つの項目は、「Item Access」、「List Access」、「Tree Access」の3つです。
Item Access
Item Accessは、関数の引数に1つの値だけを渡す設定(単一要素入力)です。

今回も、上の画像のように、2つの点をつなぐ1つの直線を作成します。

使用コンポーネント 1: Construct Point 2: Python 3 Script 3: Curve
GH上では、2つの「Construct Point」で、2つの点を作成しています。
import rhinoscriptsyntax as rs # Rhinoで使う機能を読み込む
line = rs.AddLine(pt1, pt2) # 指定した2点から直線を作成する「Python 3 Script」には、上記のコードが記述されています。
rs.AddLine関数は、各引数に単一の点(アイテム)を取ります。

そのため、引数に1つの値だけを渡す設定の「Item Access」を、左側の入力端子を設定します。

逆に、rs.AddLine関数はリスト(複数データ)を渡しません。
試しに、リスト(複数データ)「List Access」に設定してみます。

rs.AddLine関数はリスト(複数データ)を受け付けないので、エラーになりました。

端子を「Item Access」の状態で、複数のアイテムを含むリストを渡した例を見てみます。

追加コンポーネント 1: Series
今回は、「Series」で10ずつ増加する数値を5つ作成し、5つの点を2セット作成しています。
import rhinoscriptsyntax as rs # Rhinoで使う機能を読み込む
line = rs.AddLine(pt1, pt2) # 指定した2点から直線を作成するコードは、先程と内容は同じです。
この場合、端子が「Item Access」の状態で、複数のアイテムを含むリストであっても、問題なく実行されます。
これは、Item Accessでは、リストは自動的に1要素ずつ処理されるため、複数アイテムでも実行できるためです。

次に、Item Accessの状態で、ツリー構造のデータを使用した場合も見てみます。

追加コンポーネント 1: Unit Y 2: Move 3: Entwine
上の例では、先程作成した2セットの点を、「Unit Y」と「Move」でY方向に移動し、「Entwine」でツリー構造ができるように点をまとめています。
import rhinoscriptsyntax as rs # Rhinoで使う機能を読み込む
line = rs.AddLine(pt1, pt2) # 指定した2点から直線を作成する今回のコードも、先程と内容は同じです。
ツリー構造の場合でも、Item Accessでは各ブランチごとに要素が1つずつ取り出され、対応するブランチ構造に基づいて処理されるため、問題なく実行されます。
List Access
List Accessは、関数の引数にリスト(複数データ)をそのまま渡す設定です。

今回の例では、上の画像のように、3つの点をつなぐ直線を作成します。
3つの点は、GH上で作成します。

追加コンポーネント 1: Construct Point 2: Merge 3: Python 3 Script 4: Curve
import rhinoscriptsyntax as rs # Rhinoで使う機能を読み込む
line = rs.AddPolyline(pts) # 複数点をつなぐ直線を作成する今回のコードでは、rs.AddPolyline関数を使用しています。
rs.AddPolyline関数は、複数の点を順番に並べたデータ(リストなど)を引数に取ります。
今回は、3つの「Construct Point」で作成した3つの点を、「Merge」で1つのリストにまとめ、「Python 3 Script」につなげています。

今回は、rs.AddPolyline関数が複数の点を順番に並べたデータ(リストなど)を引数に取るため、「List Access」に入力端子を設定することで、正しく実行できます。

逆に、rs.AddPolylineで入力端子を「Item Access」にし、点が1つずつ渡される状態にしてみます。

すると、複数点を必要とするrs.AddPolylineはエラーになります。
このように、リストデータを扱うには、「List Access」にする必要があります。

List Accessの状態で、ツリー構造の場合も見てみます。
今回は、上の画像のように、3つの点をつなぐ直線を2セット作成します。

追加コンポーネント 1: Unit Y 2: Move 3: Entwine
import rhinoscriptsyntax as rs # Rhinoで使う機能を読み込む
line = rs.AddPolyline(pts) # 複数点をつなぐ直線を作成する今回のコードも、先程と内容は同じです。
GH上では、作成した3つの点をまとめた「Merge」を、「Unit Y」と「Move」でY方向に移動して複製しています。
その後、「Entwine」で、3つの点が2セットの階層状態になるようにしています。
Item Accessの時と同様に、List Accessでは、ツリー構造でも各ブランチのリスト単位で処理されるため、リストを受け取る関数であれば正しく動作します。
Tree Access
Tree Accessは、データツリー(階層構造)をそのまま扱う設定です。
特に、各ブランチごとのデータを個別に処理したい場合に有効です。

Tree Accessの例として、各ブランチ内の任意の点を取得し、取得した点をつなぐ直線を作成します。

使用コンポーネント 1: Series 2 Construct Point 3: Move 4: Entwine 5: Python 3 Script 6: Curve
最初にGH上の説明をします。
「Series」で、10ずつ増加する数値を、5つ作成しています。
「Construct Point」で、5つの点を作成しています。
「Move」で、5つの点を移動させて複製しています。
「Entwine」で、5つの点が2セットのブランチ構造になるようにまとめています。
import rhinoscriptsyntax as rs
# Rhinoで使う機能を読み込む
pt1 = pts.Branch(0)[1]
# ブランチ {0} の 1番目の点を取り出す
pt2 = pts.Branch(1)[3]
# ブランチ {1} の 3番目の点を取り出す
line = rs.AddLine(pt1, pt2)
# 指定した2点から直線を作成する「Python 3 Script」では、上記のコードが記述されています。
pts.Branch関数では、()内で指定したブランチ名の中から、[]で指定した番号の点を取得します。
pt1 = pts.Branch(0)[1]では、ブランチ {0} の 1番目の点を取り出しています。
pt2 = pts.Branch(1)[3]では、ブランチ {1} の 3番目の点を取り出しています。
rs.AddLine(pt1, pt2)では、取得した2つの点を引数として使用し、直線を作成しています。

今回は、ブランチを指定し、さらに指定したブランチ内のアイテムを指定するという処理です。
このような場合、入力端子を「Tree Access」にすることで、ツリー構造をそのまま維持して、複雑な処理をすることができます。

今回の処理では、ブランチ {0} の 1番目の点と、ブランチ {1} の 3番目の点を取り出しています。

そのため、上の画像のように、下側では1番目の点(0番目が始まりの数)、上側では3番目の点をつなぐ直線が作成されています。
このように、データツリー(階層構造)をそのまま扱いたい場合や、各ブランチごとのデータを個別に処理したい場合、Tree Accessに設定します。
Type Hints
Type Hintは、GHから渡されるデータを、Python内でどの型(点・数値・ベクトルなど)として扱うかを指定する設定です。
データの型を設定することで、渡される型の曖昧さを防ぎ、エラーの発生を抑えることができます。

データの型の設定方法です。
入力する端子を右クリックし、「Type Hints」を選択します。
すると、様々なデータの型の選択肢が表示されます。
入力するデータがサーフェスの場合は「Surface」、メッシュの場合は「Mesh」、数値の場合は「int」や「float」のように設定します。
初期設定では、「ghdoc Object」に設定されています。
初期設定の「ghdoc Object」では、そのオブジェクトを指すID(GUID)が渡されます。
そのため、rs関数との相性が良く、柔軟に処理することができます。
しかし、型が明確でない場合もあるため、必要に応じてType Hintで明示的に型を指定することをおすすめします。
「ghdoc Object」に似た設定に、「No Type Hint」があります。
「No Type Hint」は、GHから渡されるデータを特定の型に変換せず、そのままのオブジェクトとして扱うため、こちらも柔軟に処理することができます。
ただし、型が明確でない場合もあるため、必要に応じてType Hintで明示的に型を指定することをおすすめします。

型が違う場合の結果を見てみます。
「Python 3 Script」の各端子には、1つの点データを接続しています。
この場合、「Point3d」に設定するのが正しいです。
しかし、あえて「Curve」に設定しています。

すると、型が異なるので、エラーになりました。
このように、型をしっかりと設定する必要があります。
Type Hintsの特殊な使い方
Type Hintsには、特殊な使い方があります。
使用するデータによっては、データの型を変えると、エラーになるのではなく、関係する別のデータを出力する場合があります。

今回の例として、上の画像のサーフェスを使用します。

使用コンポーネント 1: Surface 2: Python 3 Script 3: Area
「Surface」には、Rhinoで作成したサーフェスを格納しています。
「Area」では、サーフェスの面積を出力しています。
import rhinoscriptsyntax as rs # Rhinoで使う機能を読み込む
a = surface # surfaceの値をaに入れる「Python 3 Script」には、上記のコードが記載されています。
コード内容はシンプルで、surface端子から入力したデータを、a端子から出力できるようにしています。

「Type Hints」が「Surface」の場合、サーフェスデータが出力されます。

しかし、「Type Hints」を「Curve」に変更した場合、曲線データが出力されました。

Rhino上で確認しても、曲線データが出力されていることがわかります。

今度は、「Type Hints」を「float」に設定しました。
すると、今度は、サーフェスの面積データが出力されました。
これらのように、データによってはデータ型を変えると、関連する他のデータが出力されます。




Comment