{"id":"96ffc468-ef45-4b22-ac37-e1219828fd6e","shortId":"aY9aN5","kind":"skill","title":"rhino3d-scripts","tagline":"Authoring and debugging scripts for Rhinoceros 3D (Rhino 8 and later). Use when asked to write RhinoScript (VBScript / .rvb / .vbs), RhinoPython, or RhinoCommon-based scripts; automate Rhino modeling tasks; build command macros; manipulate Rhino geometry, layers, blocks, or docum","description":"# Rhino 3D Scripting Skill\n\nWrite production-quality scripts for Rhinoceros 3D. Covers the three scripting surfaces (RhinoScript/VBScript, RhinoPython, direct RhinoCommon .NET) and the Rhino 8+ Script Editor.\n\n## When to Use This Skill\n\n- User asks to write, edit, or debug a `.rvb`, `.vbs`, or `.py` Rhino script\n- User wants a Rhino **command macro** or wants to automate a sequence of Rhino commands\n- User wants to manipulate geometry, layers, blocks, materials, viewports, or annotations from code\n- User mentions `rhinoscriptsyntax`, `scriptcontext`, `RhinoCommon`, `Rhino.Geometry`, `RhinoDoc`, or the Script Editor\n- User wants to pick objects, prompt for input, or build a small UI inside Rhino\n- User asks how to load, run, or distribute a script (startup scripts, aliases, toolbar buttons)\n\n## Choosing a Scripting Surface\n\nPick the surface based on the task, not preference. Recommend Python by default for new work.\n\n| Surface | When to choose | File ext |\n|---|---|---|\n| **RhinoPython** (`rhinoscriptsyntax` + RhinoCommon) | Default for new scripts. Best ecosystem, readable, full RhinoCommon access. | `.py` |\n| **RhinoScript** (VBScript) | Maintaining legacy `.rvb`/`.vbs` files; integrating with VBA/COM. | `.rvb`, `.vbs` |\n| **RhinoCommon (C#/.NET) via Script Editor** | Performance-critical loops, complex geometry, leveraging .NET libraries. | `.cs` |\n| **Command macro** | Pure sequence of existing Rhino commands; no logic. | toolbar/alias |\n\nA macro is **not** a script — it is a string of command-line input (e.g. `! _-Line 0,0,0 10,0,0 _Enter`). Use a script the moment you need a variable, loop, or conditional.\n\n## Prerequisites\n\n- Rhino 7 or later (Rhino 8 strongly recommended — unified Script Editor supports Python 3, VB, and C# in one window).\n- Script Editor: type `_ScriptEditor` (Rhino 8) or `_EditPythonScript` / `_EditScript` (older).\n- Run a saved file from the command line with `_-RunPythonScript` or `_LoadScript` + `_RunScript`.\n\n## Core Patterns\n\n### Python: minimal scaffold\n\n```python\nimport rhinoscriptsyntax as rs\nimport scriptcontext as sc\nimport Rhino\n\ndef main():\n    obj_id = rs.GetObject(\"Select a curve\", filter=rs.filter.curve, preselect=True)\n    if not obj_id:\n        return\n    length = rs.CurveLength(obj_id)\n    print(\"Length: {0:.4f}\".format(length))\n\nif __name__ == \"__main__\":\n    main()\n```\n\n### Python: working with RhinoCommon directly\n\n```python\nimport Rhino\nimport scriptcontext as sc\n\ndoc = sc.doc  # Rhino.RhinoDoc.ActiveDoc\ntol = doc.ModelAbsoluteTolerance\n\ncircle = Rhino.Geometry.Circle(Rhino.Geometry.Point3d(0, 0, 0), 5.0)\ncurve_id = doc.Objects.AddCircle(circle)\ndoc.Views.Redraw()\n```\n\n### VBScript: minimal scaffold\n\n```vbscript\nOption Explicit\n\nCall Main()\n\nSub Main()\n    Dim strObject\n    strObject = Rhino.GetObject(\"Select a curve\", 4)  ' 4 = curve filter\n    If IsNull(strObject) Then Exit Sub\n    Rhino.Print \"Length: \" & Rhino.CurveLength(strObject)\nEnd Sub\n```\n\n### Picking objects with a custom filter (Python, RhinoCommon)\n\n```python\nimport Rhino\nimport scriptcontext as sc\n\ngo = Rhino.Input.Custom.GetObject()\ngo.SetCommandPrompt(\"Select breps\")\ngo.GeometryFilter = Rhino.DocObjects.ObjectType.Brep\ngo.SubObjectSelect = False\ngo.GetMultiple(1, 0)\nif go.CommandResult() != Rhino.Commands.Result.Success:\n    pass\nelse:\n    ids = [go.Object(i).ObjectId for i in range(go.ObjectCount)]\n```\n\n## Step-by-Step Workflows\n\n### Bulk-modify many objects fast\n\n1. Disable redraw: `rs.EnableRedraw(False)`.\n2. Wrap mutations in a single undo record: `undo = doc.BeginUndoRecord(\"My Op\")` … `doc.EndUndoRecord(undo)`.\n3. Use RhinoCommon directly inside the loop (skip `rhinoscriptsyntax` overhead).\n4. Re-enable redraw and call `doc.Views.Redraw()` in a `try`/`finally` so a crash never leaves the viewport frozen.\n\n### Distribute a script to a teammate\n\n1. Save the `.py` / `.rvb` somewhere on disk.\n2. Add the folder to `Options → Files → Search paths` so Rhino can find it by name.\n3. Create a toolbar button or alias whose macro is:\n   - Python: `! _-RunPythonScript \"MyScript.py\"`\n   - RhinoScript: `! _-LoadScript \"MyScript.rvb\" _-RunScript MySubName`\n4. The leading `!` cancels any running command; `-` runs the command in script (no-dialog) mode.\n\n### Run code at Rhino startup\n\n1. Place a `.rvb`/`.py` in a search path.\n2. `Tools → Options → RhinoScript` (or `Python`) → add to **Startup** list. The file executes once per session.\n\n## Gotchas\n\n- **`rhinoscriptsyntax` returns GUIDs, RhinoCommon returns objects.** Mixing them is fine, but `doc.Objects.Find(guid)` is the bridge from a `rs.*` id to a `RhinoObject`.\n- **Coordinates differ by surface.** Python uses `(x, y, z)` tuples *or* `Rhino.Geometry.Point3d`; VBScript uses 3-element `Array(x, y, z)`. Never pass a Python list to a VBScript helper through COM.\n- **`Option Explicit` is off by default in VBScript.** Typos silently create new variables. Always add `Option Explicit` at the top of `.rvb` files.\n- **VBScript has no block scope.** All `Dim`s inside a `Sub` are hoisted to the top of the procedure. Loop counters leak.\n- **`Nothing`, `Empty`, and `Null` are different** in VBScript. Use `IsNull` for `Rhino.GetObject` failure, `IsEmpty` for uninitialized `Variant`, `Is Nothing` for object refs.\n- **Parentheses change calling semantics in VBScript.** `Call Foo(a, b)` and `Foo a, b` are valid; `Foo(a, b)` (no `Call`, with parens) is **not** a call to a Sub — it’s a syntax error for multi-arg subs and a forced `ByVal` for single-arg.\n- **Tolerance is per-document.** Always read `doc.ModelAbsoluteTolerance` rather than hardcoding `0.001`; users work in mm, m, inches, etc.\n- **Long loops should poll `Rhino.RhinoApp.EscapeKeyPressed`** so the user can cancel. Otherwise Rhino appears frozen.\n- **GUID strings vs `System.Guid`.** `rhinoscriptsyntax` accepts either; RhinoCommon wants `System.Guid`. Convert with `System.Guid(str_id)` if needed.\n- **Don’t call `doc.Views.Redraw()` inside a tight loop.** Toggle redraw once outside the loop.\n- **`.rvb` is just `.vbs` renamed** with a Rhino-specific extension so Rhino’s `LoadScript` recognizes it. Same VBScript engine.\n\n## Troubleshooting\n\n| Symptom | Fix |\n|---|---|\n| `rs.GetObject` returns `None` immediately | The user pressed Escape, or your `filter` excludes everything. Re-check `rs.filter.*` flags. |\n| “Unable to find script” when running by name | The folder isn’t in `Options → Files → Search paths`. |\n| VBScript `Type mismatch` on coordinates | You passed a 2-element array. Rhino requires 3-element `Array(x, y, z)`. |\n| Python `ImportError: No module named Rhino` | You’re running CPython outside Rhino. RhinoCommon is only available in Rhino’s embedded Python (or via `rhino3dm` for read-only file work). |\n| Created geometry doesn’t appear | You forgot `doc.Views.Redraw()`, or `rs.EnableRedraw(False)` was never re-enabled. |\n| Undo undoes only the last object of a batch | Wrap the batch in `BeginUndoRecord` / `EndUndoRecord`. |\n| Script works alone but fails as a startup script | Startup runs before any document is open — return early or skip document-dependent work when `sc.doc is None`. |\n| `rs.Command(\"...\")` returns `False` | The macro string is malformed. Prefix with `!` and `-`, end every prompt with `_Enter` or a value. |\n\n## References\n\n- [references/rhinoscriptsyntax-cheatsheet.md](references/rhinoscriptsyntax-cheatsheet.md) — most-used `rs.*` functions by category.\n- [references/rhinocommon-map.md](references/rhinocommon-map.md) — which namespace to import for which task.\n- [references/macros-and-loading.md](references/macros-and-loading.md) — command-line macro syntax, `LoadScript` / `RunScript`, search paths.\n- [references/vbscript-quirks.md](references/vbscript-quirks.md) — VBScript-only traps relevant to RhinoScript.\n\n### Upstream docs\n\n- RhinoScript landing: <https://docs.mcneel.com/rhino/8/help/en-us/information/rhinoscripting.htm>\n- Developer hub: <https://developer.rhino3d.com/>\n- RhinoCommon API index: <https://mcneel.github.io/rhinocommon-api-docs/api/RhinoCommon/html/R_Project_RhinoCommon.htm>\n- Example scripts repo: <https://github.com/mcneel/rhino-developer-samples/tree/8/rhinoscript>","tags":["rhino3d","scripts","awesome","copilot","github","agent-skills","agents","custom-agents","github-copilot","hacktoberfest","prompt-engineering"],"capabilities":["skill","source-github","skill-rhino3d-scripts","topic-agent-skills","topic-agents","topic-awesome","topic-custom-agents","topic-github-copilot","topic-hacktoberfest","topic-prompt-engineering"],"categories":["awesome-copilot"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/github/awesome-copilot/rhino3d-scripts","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add github/awesome-copilot","source_repo":"https://github.com/github/awesome-copilot","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 33270 github stars · SKILL.md body (8,160 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:52:24.226Z","embedding":null,"createdAt":"2026-05-15T06:52:29.718Z","updatedAt":"2026-05-18T18:52:24.226Z","lastSeenAt":"2026-05-18T18:52:24.226Z","tsv":"'/.net':214 '/mcneel/rhino-developer-samples/tree/8/rhinoscript':1104 '/rhino/8/help/en-us/information/rhinoscripting.htm':1089 '/rhinocommon-api-docs/api/rhinocommon/html/r_project_rhinocommon.htm':1098 '0':256,257,258,260,261,358,387,388,389,455 '0.001':806 '1':454,481,536,599 '10':259 '2':486,544,608,925 '3':289,500,560,663,930 '3d':10,45,55 '4':413,414,510,578 '4f':359 '5.0':390 '7':277 '8':12,69,281,301 'accept':833 'access':198 'add':545,614,694 'alia':566 'alias':157 'alon':999 'alway':693,800 'annot':116 'api':1094 'appear':826,970 'arg':785,794 'array':665,927,932 'ask':17,78,146 'author':4 'autom':30,100 'avail':951 'b':756,760,765 'base':28,167 'batch':990,993 'beginundorecord':995 'best':193 'block':41,112,706 'brep':448 'bridg':640 'build':34,139 'bulk':476 'bulk-modifi':475 'button':159,564 'byval':790 'c':213,292 'call':402,516,749,753,767,773,847 'cancel':581,823 'categori':1053 'chang':748 'check':897 'choos':160,183 'circl':383,394 'code':118,595 'com':679 'command':35,95,105,228,235,251,312,584,587,1066 'command-lin':250,1065 'complex':222 'condit':274 'convert':838 'coordin':648,921 'core':319 'counter':723 'cover':56 'cpython':945 'crash':524 'creat':561,690,966 'critic':220 'cs':227 'curv':342,391,412,415 'custom':433 'debug':6,83 'def':335 'default':176,189,685 'depend':1019 'develop':1090 'developer.rhino3d.com':1092 'dialog':592 'differ':649,730 'dim':406,709 'direct':63,370,503 'disabl':482 'disk':543 'distribut':152,530 'doc':378,1084 'doc.beginundorecord':495 'doc.endundorecord':498 'doc.modelabsolutetolerance':382,802 'doc.objects.addcircle':393 'doc.objects.find':636 'doc.views.redraw':395,517,848,973 'docs.mcneel.com':1088 'docs.mcneel.com/rhino/8/help/en-us/information/rhinoscripting.htm':1087 'docum':43 'document':799,1010,1018 'document-depend':1017 'doesn':968 'e.g':254 'earli':1014 'ecosystem':194 'edit':81 'editor':71,129,217,286,297 'editpythonscript':303 'editscript':304 'either':834 'element':664,926,931 'els':460 'embed':955 'empti':726 'enabl':513,981 'end':427,1036 'endundorecord':996 'engin':878 'enter':262,1040 'error':781 'escap':889 'etc':813 'everi':1037 'everyth':894 'exampl':1099 'exclud':893 'execut':620 'exist':233 'exit':421 'explicit':401,681,696 'ext':185 'extens':869 'fail':1001 'failur':737 'fals':452,485,976,1027 'fast':480 'file':184,206,309,550,619,702,914,964 'filter':343,416,434,892 'final':521 'find':556,902 'fine':634 'fix':881 'flag':899 'folder':547,909 'foo':754,758,763 'forc':789 'forgot':972 'format':360 'frozen':529,827 'full':196 'function':1051 'geometri':39,110,223,967 'github.com':1103 'github.com/mcneel/rhino-developer-samples/tree/8/rhinoscript':1102 'go':444 'go.commandresult':457 'go.geometryfilter':449 'go.getmultiple':453 'go.object':462 'go.objectcount':469 'go.setcommandprompt':446 'go.subobjectselect':451 'gotcha':624 'guid':627,637,828 'hardcod':805 'helper':677 'hoist':715 'hub':1091 'id':338,350,355,392,461,644,842 'immedi':885 'import':325,329,333,372,374,438,440,1059 'importerror':937 'inch':812 'index':1095 'input':137,253 'insid':143,504,711,849 'integr':207 'isempti':738 'isn':910 'isnul':418,734 'land':1086 'last':986 'later':14,279 'layer':40,111 'lead':580 'leak':724 'leav':526 'legaci':203 'length':352,357,361,424 'leverag':224 'librari':226 'line':252,255,313,1067 'list':617,673 'load':149 'loadscript':317,574,873,1070 'logic':237 'long':814 'loop':221,272,506,722,815,852,858 'm':811 'macro':36,96,229,240,568,1029,1068 'main':336,364,365,403,405 'maintain':202 'malform':1032 'mani':478 'manipul':37,109 'materi':113 'mcneel.github.io':1097 'mcneel.github.io/rhinocommon-api-docs/api/rhinocommon/html/r_project_rhinocommon.htm':1096 'mention':120 'minim':322,397 'mismatch':919 'mix':631 'mm':810 'mode':593 'model':32 'modifi':477 'modul':939 'moment':267 'most-us':1047 'multi':784 'multi-arg':783 'mutat':488 'myscript.py':572 'myscript.rvb':575 'mysubnam':577 'name':363,559,907,940 'namespac':1057 'need':269,844 'net':65,225 'never':525,669,978 'new':178,191,691 'no-dialog':590 'none':884,1024 'noth':725,743 'null':728 'obj':337,349,354 'object':134,430,479,630,745,987 'objectid':464 'older':305 'one':294 'op':497 'open':1012 'option':400,549,610,680,695,913 'otherwis':824 'outsid':856,946 'overhead':509 'paren':769 'parenthes':747 'pass':459,670,923 'path':552,607,916,1073 'pattern':320 'per':622,798 'per-docu':797 'perform':219 'performance-crit':218 'pick':133,164,429 'place':600 'point3d':386,660 'poll':817 'prefer':172 'prefix':1033 'prerequisit':275 'preselect':345 'press':888 'print':356 'procedur':721 'product':50 'production-qu':49 'prompt':135,1038 'pure':230 'py':88,199,539,603 'python':174,288,321,324,366,371,435,437,570,613,652,672,936,956 'qualiti':51 'rang':468 'rather':803 're':512,896,943,980 're-check':895 're-en':511,979 'read':801,962 'read-on':961 'readabl':195 'recogn':874 'recommend':173,283 'record':493 'redraw':483,514,854 'ref':746 'refer':1044 'references/macros-and-loading.md':1063,1064 'references/rhinocommon-map.md':1054,1055 'references/rhinoscriptsyntax-cheatsheet.md':1045,1046 'references/vbscript-quirks.md':1074,1075 'relev':1080 'renam':863 'repo':1101 'requir':929 'return':351,626,629,883,1013,1026 'rhino':11,31,38,44,68,89,94,104,144,234,276,280,300,334,373,439,554,597,825,867,871,928,941,947,953 'rhino-specif':866 'rhino.commands.result.success':458 'rhino.curvelength':425 'rhino.docobjects.objecttype.brep':450 'rhino.geometry':124,385,659 'rhino.geometry.circle':384 'rhino.getobject':409,736 'rhino.input.custom.getobject':445 'rhino.print':423 'rhino.rhinoapp.escapekeypressed':818 'rhino.rhinodoc.activedoc':380 'rhino3d':2 'rhino3d-scripts':1 'rhino3dm':959 'rhinocero':9,54 'rhinocommon':27,64,123,188,197,212,369,436,502,628,835,948,1093 'rhinocommon-bas':26 'rhinodoc':125 'rhinoobject':647 'rhinopython':24,62,186 'rhinoscript':20,200,573,611,1082,1085 'rhinoscript/vbscript':61 'rhinoscriptsyntax':121,187,326,508,625,832 'rs':328,643,1050 'rs.command':1025 'rs.curvelength':353 'rs.enableredraw':484,975 'rs.filter':898 'rs.filter.curve':344 'rs.getobject':339,882 'run':150,306,583,585,594,905,944,1007 'runpythonscript':315,571 'runscript':318,576,1071 'rvb':22,85,204,210,540,602,701,859 'save':308,537 'sc':332,377,443 'sc.doc':379,1022 'scaffold':323,398 'scope':707 'script':3,7,29,46,52,59,70,90,128,154,156,162,192,216,244,265,285,296,532,589,903,997,1005,1100 'scriptcontext':122,330,375,441 'scripteditor':299 'search':551,606,915,1072 'select':340,410,447 'semant':750 'sequenc':102,231 'session':623 'silent':689 'singl':491,793 'single-arg':792 'skill':47,76 'skill-rhino3d-scripts' 'skip':507,1016 'small':141 'somewher':541 'source-github' 'specif':868 'startup':155,598,616,1004,1006 'step':471,473 'step-by-step':470 'str':841 'string':248,829,1030 'strobject':407,408,419,426 'strong':282 'sub':404,422,428,713,776,786 'support':287 'surfac':60,163,166,180,651 'symptom':880 'syntax':780,1069 'system.guid':831,837,840 'task':33,170,1062 'teammat':535 'three':58 'tight':851 'toggl':853 'tol':381 'toler':795 'tool':609 'toolbar':158,563 'toolbar/alias':238 'top':699,718 'topic-agent-skills' 'topic-agents' 'topic-awesome' 'topic-custom-agents' 'topic-github-copilot' 'topic-hacktoberfest' 'topic-prompt-engineering' 'trap':1079 'tri':520 'troubleshoot':879 'true':346 'tupl':657 'type':298,918 'typo':688 'ui':142 'unabl':900 'undo':492,494,499,982,983 'unifi':284 'uniniti':740 'upstream':1083 'use':15,74,263,501,653,662,733,1049 'user':77,91,106,119,130,145,807,821,887 'valid':762 'valu':1043 'variabl':271,692 'variant':741 'vb':290 'vba/com':209 'vbs':23,86,205,211,862 'vbscript':21,201,396,399,661,676,687,703,732,752,877,917,1077 'vbscript-on':1076 'via':215,958 'viewport':114,528 'vs':830 'want':92,98,107,131,836 'whose':567 'window':295 'work':179,367,808,965,998,1020 'workflow':474 'wrap':487,991 'write':19,48,80 'x':654,666,933 'y':655,667,934 'z':656,668,935","prices":[{"id":"aca9517d-d2de-47f4-ad30-72b7e813b1c9","listingId":"96ffc468-ef45-4b22-ac37-e1219828fd6e","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"github","category":"awesome-copilot","install_from":"skills.sh"},"createdAt":"2026-05-15T06:52:29.718Z"}],"sources":[{"listingId":"96ffc468-ef45-4b22-ac37-e1219828fd6e","source":"github","sourceId":"github/awesome-copilot/rhino3d-scripts","sourceUrl":"https://github.com/github/awesome-copilot/tree/main/skills/rhino3d-scripts","isPrimary":false,"firstSeenAt":"2026-05-15T06:52:29.718Z","lastSeenAt":"2026-05-18T18:52:24.226Z"}],"details":{"listingId":"96ffc468-ef45-4b22-ac37-e1219828fd6e","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"github","slug":"rhino3d-scripts","github":{"repo":"github/awesome-copilot","stars":33270,"topics":["agent-skills","agents","ai","awesome","custom-agents","github-copilot","hacktoberfest","prompt-engineering"],"license":"mit","html_url":"https://github.com/github/awesome-copilot","pushed_at":"2026-05-18T01:26:59Z","description":"Community-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.","skill_md_sha":"d7b467b06dfb525380c013e9d704cb64e7ce34b1","skill_md_path":"skills/rhino3d-scripts/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/github/awesome-copilot/tree/main/skills/rhino3d-scripts"},"layout":"multi","source":"github","category":"awesome-copilot","frontmatter":{"name":"rhino3d-scripts","description":"Authoring and debugging scripts for Rhinoceros 3D (Rhino 8 and later). Use when asked to write RhinoScript (VBScript / .rvb / .vbs), RhinoPython, or RhinoCommon-based scripts; automate Rhino modeling tasks; build command macros; manipulate Rhino geometry, layers, blocks, or document objects; pick objects from the viewport; control redraw and undo; or load and run scripts from the Rhino Script Editor. Covers `rhinoscriptsyntax`, `scriptcontext`, the `Rhino.*` RhinoCommon namespaces (`Rhino.Geometry`, `Rhino.DocObjects`, `Rhino.Input`, `Rhino.UI`, `Rhino.Display`, `Rhino.FileIO`), and the Rhino 8 unified Script Editor."},"skills_sh_url":"https://skills.sh/github/awesome-copilot/rhino3d-scripts"},"updatedAt":"2026-05-18T18:52:24.226Z"}}