RhinocerosとGrasshopperでPythonを使う方法

# はじめに
RhinoceroやGrasshopperではPythonでコーディングすることができます。
（いろいろなことができますが、Rhinoに関するすべてのことができるわけではありません。）
その方法やライブラリのメモをまとめておきます。

:::note
2024.10 Rhino8に合わせて加筆修正
2022.10 Rhino7に合わせて加筆修正
2017.11 Rhino5
:::

### 参考記事
- [Applicraft Grasshopperコンポーネント：Rhino8新規追加 ](https://www.applicraft.com/ghcp_rhino8/)
- [Rhinoceros / Grasshopperでコーディングしたい人のためのレファレンス参照先](https://qiita.com/jhorikawa/items/c450a558af9a0fda82ec)
- [What is Rhino.Python?](http://developer.rhino3d.com/guides/rhinopython/what-is-rhinopython/)
- [Grasshopper / Pythonでライノオブジェクトをスクリプトでコントロールするための準備](https://qiita.com/jhorikawa/items/827a83033083507bed91)

# RhinoにおけるPythonコーディングの方法
大きく分けると，

- Rhinoで使うかGrasshopperで使うか
- （Rhinoが動いている.NET Framework上で動作する）ironPythonか（自分でインストールしている普通の）Python(cPython)を使うか

|           |RhinoPythonEditor|IronPython2|Python3|
|----------:|:---------------:|:------:|:--------:|
| 実行アプリ | Rhinoceros | Grasshopper | Grasshopper |
| 実行エンジン | IronPython 2.x | IronPython 2.x | cPython 3.x  |
| Rhino関係ライブラリimport | OK | OK | OK |
| Python関係ライブラリimport | NG | NG | OK | 

で分けられます。
IronPython(アイアンパイソン）はあまり聞きなれないかもしれませんが、
.NET Frameworkのライブラリがつかえるそうです。ただしPython2系であり、ふだん利用しているNumpyなどのライブラリをimportすることは（ふつうには）できません。
Python3コンポーネントではrhinoscriptsyntaxが実行できないこともあります。（使ってみた感じ）

## Rhinocerosのeditor
コマンド
`EditPythonScript`
![01.PNG](https://qiita-image-store.s3.amazonaws.com/0/122102/c056ffc5-3337-576a-e8b4-f16b172495e8.png)

左側カラムから使用可能なライブラリとそれらのリファレンスがあるのでわかりやすい。
たとえば次のように使う。

```python
import rhinoscriptsyntax as rs
plane = rs.WorldXYPlane()
plane = rs.RotatePlane(plane, 45.0, [0,0,1])
rs.AddArc( plane, 5.0, 45.0 )
```
三角形の再生マークを押せば実行されます。
またはコマンド`RunPythonScript`でファイルを指定して直接実行することもできます。

## Grasshopper GHPython
~~food4rhinoからダウンロードしてコンポーネントを使う。~~

:::note info
Rhino6からデフォルトで入っているのでインストール不要です。
:::
http://www.food4rhino.com/app/ghpython?ufh=
github
https://github.com/mcneel/ghpython

Mathsタブに入っています。
![スクリーンショット 2024-10-11 11.31.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122102/9c4db6d6-62b4-b650-0761-d9a2d4e10c76.png)


コンポーネントをダブルクリックするとエディターが出ます。
![02.PNG](https://qiita-image-store.s3.amazonaws.com/0/122102/77340b53-cf07-0d69-ced3-524dcb9c6847.png)

### GHのitem-list-treeとPythonのlistの関係
このコンポーネントの変数はアイテムか、リストごとに読み込むか、ツリー全体で読み込むか選択できます。
GHのlistはそのままPythonのlistになります。type()では<type 'list'>が返されます。
GHのtreeはtypeで返すと<type 'DataTree[object]'>になります。つまりイテレータとして使えません。（for i in tree:とかができません）
treeをinput，outputとして扱うためには，`ghpythonlib.treeheplers`を使うとよいです。
https://developer.rhino3d.com/guides/rhinopython/grasshopper-datatrees-and-python/


### GUIDとオブジェクト
Grasshopperのネットワークでは、基本的にguid（オブジェクトごとに割り振られたid）が渡されます。
Geometry（形態）を渡したつもりでも、じつはguidの文字列がわたされていて、エラーになることがあります。
このために、itemのジオメトリー種別を指定しておけば自動的にguidをgeometryに変換
してくれます。

自分で変換するときは、たとえばLineに変換するとき

```python
import rhinoscriptsyntax as rs
x =  rs.coerceline(guid)
```

でできます。
https://discourse.mcneel.com/t/how-do-i-get-an-object-from-guid/33305



# 利用可能なRhinocerosのライブラリ

## rhinoscriptsyntax

rhinoのほとんどのコマンドが簡単に利用できる。
ただしpython3コンポーネントでは（まだ）動かないものもあるかも。
~~5とWIP（work in progress）の6で多少ことなるようですがリファレンスは以下。~~
https://developer.rhino3d.com/
http://developer.rhino3d.com/api/RhinoScriptSyntax/


## ghpythonlib
grasshopperのコンポーネントがつかえる？
ghpythonlib.parallelとか使えそう。

https://discourse.mcneel.com/t/new-version-of-ghpythonlib-components/34619

## scriptcontext
https://discourse.mcneel.com/t/understanding-scriptcontext/7175

## Rhino (RhinoCommonと呼ばれる）
もっとも原初的なクラス。
基本的にrsなどはこれらを利用していると思われます。
rsにないことをやりたいときに、かゆいところに手が届く場合も。
### API ドキュメント
https://developer.rhino3d.com/api/RhinoCommon/html/R_Project_RhinoCommon.htm

例えば`Point3d`を見るとC#とVBだけだが，Pythonも推測できる。
https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Geometry_Point3d.htm
https://developer.rhino3d.com/guides/rhinopython/python-rhinoscriptsyntax-point-vector-methods/

### ガイド
https://developer.rhino3d.com/guides/rhinopython/
http://developer.rhino3d.com/guides/rhinocommon/what-is-rhinocommon/
http://developer.rhino3d.com/guides/rhinopython/using-rhinocommon-from-python/

# 今後調べるべきもの
Rhino-inside
https://www.rhino3d.com/jp/features/rhino-inside/