AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗Rhino.Scripting is a complete re-implementation of the original RhinoScript syntax in and for F# (and C#). Before this repo, the high-level RhinoScript API was only available for VBScript and (Iron-)Python. This repo enables the use of the RhinoScriptSyntax in F# and C# together with all the great coding experience and editor tooling that come with F# and C#, like:
RhinoScript provides application scripting for the Rhino3D CAD app. RhinoScript has more than 900 functions to control all kinds of aspects of automating Rhino3D. It was originally implemented in 2002 in VBScript. Extensive documentation on the original VBScript-based version is available here.
In 2010, all functions from RhinoScript were reimplemented in IronPython (Python running on .NET). This allowed the use of a modern, rich, and dynamically typed programming language with a huge standard library and also access to all functions of the underlying .NET Framework as well as the RhinoCommon SDK.
This repo has all original RhinoScript functions reimplemented in F#. It is literally a translation of the open-source IronPython rhinoscriptsyntax implementation to F#. You can see all 900+ methods in this repo in the docs.
A few minor bugs from the Python implementation are fixed and a few extra methods and optional parameters were added. I have been using this library extensively for my own professional scripting needs since 2019. If you have problems, questions, or find a bug, please open an issue.
The recommended scripting use case is via Fesh, the dedicated F# scripting editor for Rhino. However, you can use this library just as well in the new Rhino 8 ScriptEditor with C# or in independently compiled F#, C#, or VB.net projects.
First reference the assemblies.
#r "RhinoCommon"
#r "nuget: Rhino.Scripting"
The main namespace is Rhino.Scripting.
The main class of this library is called RhinoScriptSyntax it has all ~900 functions as static methods.
In F# you can create an alias like this:
open Rhino.Scripting
type rs = RhinoScriptSyntax
then use any of the RhinoScript functions like you would in Python or VBScript.
The CoerceXXXX functions will help you create types if you are too lazy to fully specify them.
let pl = rs.CoercePlane(0 , 80 , 0) // makes World XY plane at point
rs.AddText("Hello, Fesh", pl, height = 50.)
For F# scripting the Rhino.Scripting.Fsharp provides useful extensions and curried functions for piping and partial application.
You can use it via the new Rhino 8 ScriptEditor. First reference the assemblies.
#r "nuget: Rhino.Scripting"
The main namespace is Rhino.Scripting.
The main class of this library is called RhinoScriptSyntax it has all ~900 functions as static methods.
In C# you can create an alias like this:
using rs = Rhino.Scripting.RhinoScriptSyntax;
then you can use it like the RhinoScriptSyntax in Python:
var pt = rs.GetObject("Select an Object");
rs.ObjectColor(pt, System.Drawing.Color.Blue);
Many RhinoScript functions take variable types of input parameters. This is implemented with method overloads. Many RhinoScript functions have optional parameters. These are also implemented as optional method parameters. Many RhinoScript functions are getters and setters at the same time. Depending on if an argument is provided or not, the function acts as a getter or setter. This is also implemented with method overloads.
For example rs.ObjectLayer can be called in several ways:
To get the layer of one object, returns a string:
rs.ObjectLayer(guid)
To set the layer of one object (fails if layer does not exist), no return value:
rs.ObjectLayer(guid, string)
To set the layer of one object, and create the layer if it does not exist yet, no return value:
rs.ObjectLayer(guid, string, createLayerIfMissing = true )
To set the layer of several objects (fails if layer does not exist), no return value:
rs.ObjectLayer(list of guids, string)
To set the layer of several objects, and create the layer if it does not exist yet, no return value:
rs.ObjectLayer(list of guids, string, createLayerIfMissing = true )
These are implemented with 3 overloads and Optional and DefaultParameterValue parameters:
///<summary>Returns the full layer name of an object.
/// parent layers are separated by <c>::</c>.</summary>
///<param name="objectId">(Guid) The identifier of the object</param>
///<returns>(string) The object's current layer.</returns>
static member ObjectLayer(objectId:Guid) : string = //GET
let obj = RhinoScriptSyntax.CoerceRhinoObject(objectId)
let index = obj.Attributes.LayerIndex
State.Doc.Layers.[index].FullPath
///<summary>Modifies the layer of an object ,
/// optionally creates layer if it does not exist yet.</summary>
///<param name="objectId">(Guid) The identifier of the object</param>
///<param name="layer">(string) Name of an existing layer</param>
///<param name="createLayerIfMissing">(bool) Optional,
/// Default Value: <c>false</c> Set true to create Layer
/// if it does not exist yet.</param>
///<param name="allowAllUnicode">(bool) Optional,
/// Allow Ambiguous Unicode characters too </param>
///<param name="collapseParents">(bool) Optional,
/// Collapse parent layers in Layer UI </param>
///<returns>(unit) void, nothing.</returns>
static member ObjectLayer( objectId:Guid
, layer:string
,[<OPT;DEF(false)>]createLayerIfMissing:bool
,[<OPT;DEF(false:bool)>]allowAllUnicode:bool
,[<OPT;DEF(false:bool)>]collapseParents:bool) : unit = //SET
let obj = RhinoScriptSyntax.CoerceRhinoObject(objectId)
let layerIndex =
if createLayerIfMissing then
UtilLayer.getOrCreateLayer(
layer,
UtilLayer.randomLayerColor,
UtilLayer.ByParent,
UtilLayer.ByParent,
allowAllUnicode,
collapseParents
).Index
else
RhinoScriptSyntax.CoerceLayer(layer).Index
obj.Attributes.LayerIndex <- layerIndex
obj.CommitChanges() |> ignore
State.Doc.Views.Redraw()
///<summary>Modifies the layer of multiple objects, optionally creates
/// layer if it does not exist yet.</summary>
///<param name="objectIds">(Guid seq) The identifiers of the objects</param>
///<param name="layer">(string) Name of an existing layer</param>
///<param name="createLayerIfMissing">(bool) Optional,
/// Default Value: <c>false</c> Set true to create Layer
/// if it does not exist yet.</param>
///<param name="allowUnicode">(bool) Optional,
/// Allow Ambiguous Unicode characters too </param>
///<param name="collapseParents">(bool) Optional,
/// Collapse parent layers in Layer UI </param>
///<returns>(unit) void, nothing.</returns>
static member ObjectLayer( objectIds:Guid seq
, layer:string
, [<OPT;DEF(false)>]createLayerIfMissing:bool
, [<OPT;DEF(false:bool)>]allowUnicode:bool
, [<OPT;DEF(false:bool)>]collapseParents:bool) : unit = //MULTISET
let layerIndex =
if createLayerIfMissing then
UtilLayer.getOrCreateLayer(
layer,
UtilLayer.randomLayerColor,
UtilLayer.ByParent,
UtilLayer.ByParent,
allowUnicode,
collapseParents
).Index
else
RhinoScriptSyntax.CoerceLayer(layer).Index
for objectId in objectIds do
let obj = RhinoScriptSyntax.CoerceRhinoObject(objectId)
obj.Attributes.LayerIndex <- layerIndex
obj.CommitChanges() |> ignore
State.Doc.Views.Redraw()
goswinr.github.io/Rhino.Scripting
The NuGet package contains builds for .NET Framework 4.8, .NET 8.0 and .NET 10.0.
Each .NET build can only be loaded when Rhino runs on that .NET runtime or a newer one (see the Rhino command SetDotNetRuntime).
For Rhino 7, and for Rhino 8 running on .NET Framework, use the .NET Framework 4.8 build.
This library should work on Rhino for Mac just as well as on Windows.
To build this library from source you need the .NET SDK 10 installed (see global.json)
Then just run in the root folder:
dotnet build ForPublishing.fsproj -c Release
This will first combine all Scripting_*.fs files into one file and compile it.
This is needed because F# type extensions are not visible from C# editor tooling.
While having all 900 methods on one class in one file is needed for publishing via ForPublishing.fsproj
it is not ideal for editing.
The source is split into several files imitating the structure of the original Python implementation.
Open the project ForEditing.fsproj to edit the source.
see CHANGELOG.md
While the main Rhino Document is officially not thread safe, this library can be used from any thread. If running async this library will automatically marshal all calls that affect the UI to the main Rhino UI thread and wait for switching back till completion on UI thread. Modifying the Rhino Document from a background thread is actually OK as long as there is only one thread doing it. The main reason to use this library async is to keep the Rhino UI and Fesh scripting editor UI responsive while doing long running operations.
Contributions are welcome even for small things like typos. If you have problems with this library please submit an issue.