mcpField
R
rhino3d-scripts

rhino3d-scripts

github.com/githubクリエイティブ・メディア40.5k92 回インストール1 日前に更新
リポジトリ

rhino3d-scripts について

rhino3d-scripts は、Rhinoceros 3D のスクリプトを作成、編集、デバッグする開発者向けのスキルです。RhinoScript、RhinoPython、RhinoCommon、コマンドマクロを扱い、作業手順やトラブルシューティングも説明します。

主な機能

  1. 013種類の Rhino スクリプト方式に対応
  2. 02スクリプトとマクロの選び方
  3. 03ジオメトリ操作のコード例
  4. 04スクリプトの読み込みと配布方法
  5. 05一般的な問題と対処法

活用シーン

  1. 01RhinoPython スクリプトの作成やデバッグ
  2. 02VBScript または RhinoScript の保守
  3. 03Rhino オブジェクトの一括変更
  4. 04起動スクリプトやツールバーボタンの設定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/github/awesome-copilot --skill rhino3d-scripts

インストール後、Claude Code で/rhino3d-scriptsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
macros-and-loading.md
rhinocommon-map.md
rhinoscriptsyntax-cheatsheet.md
vbscript-quirks.md

詳細

Rhino 3D スクリプト作成スキル

Rhinoceros 3D 用の本番品質のスクリプトを作成します。3 つのスクリプト環境(RhinoScript/VBScript、RhinoPython、RhinoCommon .NET の直接利用)と、Rhino 8 以降の Script Editor を扱います。

このスキルを使う場面

  • Rhino スクリプトの .rvb、.vbs、.py ファイルの作成、編集、デバッグを依頼された場合
  • Rhino のコマンドマクロの作成や、Rhino コマンドの一連の操作の自動化を求められた場合
  • コードからジオメトリ、レイヤー、ブロック、マテリアル、ビューポート、注釈を操作したい場合
  • rhinoscriptsyntax、scriptcontext、RhinoCommon、Rhino.Geometry、RhinoDoc、Script Editor に言及された場合
  • Rhino 内でオブジェクトを選択したり、入力を求めたり、小規模な UI を構築したい場合
  • スクリプトの読み込み、実行、配布方法(起動時スクリプト、エイリアス、ツールバーボタン)を尋ねられた場合

スクリプト環境の選択

好みではなく、タスクに応じて環境を選びます。新規作業では、デフォルトで Python を推奨します。

環境選択する場面ファイル拡張子
RhinoPython(rhinoscriptsyntax + RhinoCommon)新しいスクリプトのデフォルトです。エコシステムが充実しており、読みやすく、RhinoCommon に完全にアクセスできます。.py
RhinoScript(VBScript)既存の .rvb/.vbs ファイルの保守や、VBA/COM との連携に使います。.rvb、.vbs
Script Editor 経由の RhinoCommon(C#/.NET)パフォーマンスが重要なループ、複雑なジオメトリ、.NET ライブラリの活用に使います。.cs
コマンドマクロ既存の Rhino コマンドだけを使う単純な一連の操作に使います。ロジックは含みません。toolbar/alias

マクロはスクリプトではありません。コマンドラインに入力する文字列です(例:! _-Line 0,0,0 10,0,0 _Enter)。変数、ループ、条件分岐が必要になった時点で、スクリプトを使ってください。

前提条件

  • Rhino 7 以降(Rhino 8 を強く推奨します。統合 Script Editor では、1 つのウィンドウで Python 3、VB、C# を使用できます)。
  • Script Editor:_ScriptEditor(Rhino 8)、または _EditPythonScript/_EditScript(旧バージョン)と入力します。
  • 保存したファイルをコマンドラインから実行するには、_-RunPythonScript、または _LoadScript + _RunScript を使います。

基本パターン

Python:最小限のひな形
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

def main():
    obj_id = rs.GetObject("Select a curve", filter=rs.filter.curve, preselect=True)
    if not obj_id:
        return
    length = rs.CurveLength(obj_id)
    print("Length: {0:.4f}".format(length))

if __name__ == "__main__":
    main()
Python:RhinoCommon を直接使用する
import Rhino
import scriptcontext as sc

doc = sc.doc  # Rhino.RhinoDoc.ActiveDoc
tol = doc.ModelAbsoluteTolerance

circle = Rhino.Geometry.Circle(Rhino.Geometry.Point3d(0, 0, 0), 5.0)
curve_id = doc.Objects.AddCircle(circle)
doc.Views.Redraw()
VBScript:最小限のひな形
Option Explicit

Call Main()

Sub Main()
    Dim strObject
    strObject = Rhino.GetObject("Select a curve", 4)  ' 4 = curve filter
    If IsNull(strObject) Then Exit Sub
    Rhino.Print "Length: " & Rhino.CurveLength(strObject)
End Sub
カスタムフィルターを使ったオブジェクトの選択(Python、RhinoCommon)
import Rhino
import scriptcontext as sc

go = Rhino.Input.Custom.GetObject()
go.SetCommandPrompt("Select breps")
go.GeometryFilter = Rhino.DocObjects.ObjectType.Brep
go.SubObjectSelect = False
go.GetMultiple(1, 0)
if go.CommandResult() != Rhino.Commands.Result.Success:
    pass
else:
    ids = [go.Object(i).ObjectId for i in range(go.ObjectCount)]

手順ごとのワークフロー

多数のオブジェクトをすばやく一括変更する
  1. 再描画を無効にします:rs.EnableRedraw(False)。
  2. 変更を 1 つの取り消し記録で囲みます:undo = doc.BeginUndoRecord("My Op") … doc.EndUndoRecord(undo)。
  3. ループ内では RhinoCommon を直接使います(rhinoscriptsyntax のオーバーヘッドを省きます)。
  4. クラッシュでビューポートがフリーズしたままにならないよう、try/finally 内で再描画を有効にし、doc.Views.Redraw() を呼び出します。
チームメイトにスクリプトを配布する
  1. .py/.rvb ファイルをディスク上の任意の場所に保存します。
  2. Rhino が名前でスクリプトを見つけられるよう、フォルダーを Options → Files → Search paths に追加します。
  3. ツールバーボタンまたはエイリアスを作成し、マクロに次のいずれかを設定します。
    • Python:! _-RunPythonScript "MyScript.py"
    • RhinoScript:! _-LoadScript "MyScript.rvb" _-RunScript MySubName
  4. 先頭の ! は実行中のコマンドをキャンセルします。- はコマンドをスクリプト(ダイアログなし)モードで実行します。
Rhino の起動時にコードを実行する
  1. .rvb/.py ファイルを検索パスに配置します。
  2. Tools → Options → RhinoScript(または Python)→ Startup リストに追加します。ファイルはセッションごとに 1 回実行されます。

注意点

  • rhinoscriptsyntax は GUID を返し、RhinoCommon はオブジェクトを返します。 混在して使っても問題ありませんが、doc.Objects.Find(guid) が rs.* の ID から RhinoObject への橋渡しになります。
  • 座標の形式はサーフェスによって異なります。 Python では (x, y, z) タプルまたは Rhino.Geometry.Point3d を使い、VBScript では3要素の Array(x, y, z) を使います。COM 経由で Python のリストを VBScript ヘルパーに渡してはいけません。
  • VBScript ではデフォルトで Option Explicit が無効です。 タイプミスをしても、黙って新しい変数が作成されます。.rvb ファイルの先頭には必ず Option Explicit を追加してください。
  • VBScript にはブロックスコープがありません。 Sub 内のすべての Dim は、プロシージャの先頭に繰り上げられます。ループカウンターはスコープ外にも残ります。
  • VBScript では Nothing、Empty、Null はそれぞれ異なる値です。 Rhino.GetObject の失敗には IsNull、未初期化の Variant には IsEmpty、オブジェクト参照には Is Nothing を使ってください。
  • 括弧によって VBScript の呼び出しの意味が変わります。 Call Foo(a, b) と Foo a, b は有効ですが、Foo(a, b)(Call なしで括弧あり)は Sub の呼び出しではありません。複数引数の Sub では構文エラーになり、単一引数の場合は強制的に ByVal になります。
  • 許容差はドキュメントごとに異なります。 0.001 をハードコードせず、必ず doc.ModelAbsoluteTolerance を読み取ってください。ユーザーは mm、m、インチなど、さまざまな単位で作業しています。
  • 長いループでは Rhino.RhinoApp.EscapeKeyPressed を確認し、ユーザーがキャンセルできるようにしてください。 そうしないと、Rhino がフリーズしたように見えます。
  • GUID 文字列と System.Guid は別のものです。 rhinoscriptsyntax はどちらも受け付けますが、RhinoCommon では System.Guid が必要です。必要に応じて System.Guid(str_id) で変換してください。
  • 高頻度で繰り返すループ内では doc.Views.Redraw() を呼び出さないでください。 再描画の切り替えはループの外で一度だけ行ってください。
  • .rvb は、Rhino 固有の拡張子に変更した .vbs ファイルにすぎません。 Rhino の LoadScript が認識できるようにするためのものです。VBScript エンジンは同じです。
  • 古い Rhino 8 ビルドには Rhino.RhinoApp.IsHeadless が存在しない場合があります。 getattr(Rhino.RhinoApp, "IsHeadless", None) を使い、使用前に None でないことを確認してください。フォールバックとしてヒューリスティック(例:sc.doc.Views.Count == 0)を使うか、GUI があるものとして扱ってください。
  • RhinoMath は Rhino.DocObjects.RhinoMath ではなく Rhino.RhinoMath にあります。 Rhino.DocObjects.RhinoMath にアクセスすると AttributeError が発生します。
  • doc.Objects.AddBrep() は失敗すると System.Guid.Empty を返します。 Rhino 8 CPython では System 名前空間を直接インポートできない場合があります。戻り値を文字列として確認してください:str(obj_id) == "00000000-0000-0000-0000-000000000000"。
  • rhinoscriptsyntax には型スタブがありません。 静的解析ツール(Pylance/Pyright)は import rhinoscriptsyntax as rs を解決できないと警告します。モジュールは Rhino の実行時には常に利用できるため、インポート行に # type: ignore を付けて抑制してください。
  • Python 標準ライブラリのモジュールと同じ名前をスクリプトに付けないでください(例:random.py、math.py、os.py)。IronPython 2.7(_-RunPythonScript)は標準ライブラリより先にスクリプトのディレクトリを検索するため、標準ライブラリ内での import random(例:tempfile は内部で random をインポートします)も、代わりに自分のファイルを見つけて Cannot import name <X> で失敗します。CPython 3(rhinocode)には影響ありません。スクリプト名を変更するか、名前が衝突するモジュールを読み込むモジュールのインポートを避けてください。
  • Em ダッシュなどの非 ASCII 文字は、_-RunPythonScript(IronPython 2.7)を気付かれないまま壊します。 rhinocode script は CPython 3(デフォルトで UTF-8)を使うため、同じファイルがそちらでは動作し、問題が分かりにくくなります。IronPython 2.7 では、最初に問題となるバイト位置で SyntaxError: Non-ASCII character '\xe2' が発生します。最もよくある原因は em ダッシュ です(多くのエディターが -- を自動的に -- に変換します)。両方のランタイムで実行する必要があるすべてのスクリプトの1行目に # -*- coding: utf-8 -*- を追加し、字形上の文字を ASCII 相当の文字に置き換えてください:em ダッシュは --、矢印は ->、乗算記号は x。

トラブルシューティング

症状対処方法
rs.GetObject がすぐに None を返すユーザーが Escape キーを押したか、filter がすべてを除外しています。rs.filter.* フラグを確認してください。
名前を指定して実行すると「Unable to find script」と表示されるフォルダーが Options → Files → Search paths に含まれていません。
VBScript で座標に対して Type mismatch が発生する2 要素の配列を渡しています。Rhino では 3 要素の Array(x, y, z) が必要です。
Python で ImportError: No module named Rhino が発生するRhino の外部で CPython を実行しています。RhinoCommon を利用できるのは、Rhino に組み込まれた Python のみです(読み取り専用のファイル操作には rhino3dm を使用できます)。
作成したジオメトリが表示されないdoc.Views.Redraw() を呼び出していないか、rs.EnableRedraw(False) を再度有効にしていません。
一括処理のオブジェクトが最後の 1 つしか元に戻せない一括処理を BeginUndoRecord / EndUndoRecord で囲んでください。
スクリプト単体では動作するのに、スタートアップスクリプトとしては失敗するスタートアップスクリプトはドキュメントが開く前に実行されます。早めに終了するか、sc.doc is None の場合はドキュメントに依存する処理をスキップしてください。
rs.Command("...") が False を返すマクロ文字列の形式が正しくありません。先頭に ! と - を付け、各プロンプトの末尾に _Enter または値を指定してください。
AttributeError: type object 'RhinoApp' has no attribute 'IsHeadless'このプロパティは、後の Rhino 8 ビルドで追加されました。getattr(Rhino.RhinoApp, "IsHeadless", None) を使用し、None の場合に備えて処理してください。
rhinocode script がスクリプトパス以降の引数を無視するrhinocode は追加のトークンをファイル URI に連結します。一時ファイルまたは Rhino のダイアログを介してデータを渡してください。references/macros-and-loading.md を参照してください。
_-RunPythonScript の実行時に、標準ライブラリ内(例:tempfile、os)で Cannot import name <X> が発生するスクリプトのファイル名が標準ライブラリのモジュール名と競合しています(例:random.py は random の名前を隠します)。IronPython 2.7 は標準ライブラリより先にスクリプトのディレクトリを検索します。スクリプト名を変更するか、競合するモジュールを読み込む import を削除し、直接的な代替手段に置き換えてください(例:import tempfile の代わりに os.environ を使って %TEMP% を読み取る)。
SyntaxError: Non-ASCII character '\xe2' ... but no encoding declaredIronPython 2.7(_-RunPythonScript)が、em dash などの文字に遭遇しています。1 行目に # -*- coding: utf-8 -*- を追加するか、その文字を置き換えてください。em dash は --、矢印は -> に置き換えます。同じファイルでも rhinocode(CPython 3)では問題が発生しません。

参考資料

上流のドキュメント

コメント