RhinoDev
Rhinoceros二次开发实用注解
RhinoDeveloper官网有非常丰富的文档,用于指导开发者快速上手二次开发工作。本文是对其常见问题及底层逻辑的注解,有助于开发者更好地使用相关API。当前内容为零散笔记,尚未完成系统化整理,有待后续完善。现有内容主要包括: Common/OpenNurbs/Inside/Compute/Shim等常用技术。
编辑中...
RhinoCommon
- RhinoCommon的特性
- 主要版本为.Net-RhinoCommon
- 通常需要在Rhino环境下运行
- 相比CGAL等通常的计算几何库,抽象程度较低,容易上手许多
- python-Rhino的特性
- python-Rhino是和.Net-RhinoCommon基本同构的包装
-
需要使用非python常用类型(rhino3dm同理)
import Rhino.Geometry as rg from System.Collections.Generic import List points = List[rg.Point3d]() points.Add(rg.Point3d(0,7,0)) points.Add(rg.Point3d(5,7,0)) points.Add(rg.Point3d(10,7,0)) return rg.Curve.CreateControlPointCurve(points2, 3)
- python-rhinoscriptsyntax的特性
- rhinoscriptsyntax是和.Net-RhinoCommon不同构的包装
- 采用RhinoScript风格,可以理解为命令集»RhinoScript»rhinoscriptsyntax;上次技术咨询会会原厂专家也说到这个事儿…
- (存疑,也许并不是…)由于rhinoscriptsyntax库内的命令和ActiveDoc是强绑定,在云端执行的时候如果没有相应的RhinoDoc,理论上在AddToDoc和redraw的时候就会报错
OpenNurbs
- OpenNurbs的特性
- 开源,在常规环境下可以运行.
- 相比于RhinoCommmon阉割了一些功能:Intersection/Loft/…
- 支持的语言包括C# / Python / js.
- 命名空间和RhinoCommon同构(C#/Python)
- python-rhino3dm的特性
- rhino3dm库的使用不依赖于Rhino环境,但非要在Rhino环境中运行也是可以的(这和c#中两个库的互斥性略有一些不一样,很有意思…)
-
示例:
# env: C:\...\env_name\Lib\site-packages # 安装rhino3dm的虚拟环境 import rhino3dm ...
- 一个BUG: 入参类型识别无效
-
示例:期望得到1.0,输出为0.73,原因是把切向量识别为点坐标并触发了错误的构造函数
import rhino3dm as rh arc3=rh.Arc( pointA=rh.Point3d(0,0,0), tangentA=rh.Vector3d(0,1,0), pointB=Point3d(1,1,0)) print(arc3.Radius) -
python使用Rhino(Rhinocommon)时没有这个问题 不论是否使用Rhinoinside加载都可以输出正确值,输出为1.0
# 在Rhino中作为脚本运行 / 在Rhino外启动rhinoinside import Rhino.Geometry as rg arc=rg.Arc(rg.Point3d(0,0,0), rg.Vector3d(0,1,0),rg.Point3d(1,1,0)) print(arc.Radius) -
C#-Rhino3dm也没有这个问题,输出为1
using Rhino.Geometry; Arc arc=new Arc(new Point3d(0,0,0),new Vector3d(0,1,0),new Point3d(1,1,0)); Console.WriteLine(arc.Radius);
-
RhinoInside
- RhinoInside的特性
- 在非Rhino环境的程序进程中加载RhinoCore并调用RhinoAPI.
- .NET和Python都有对应版本.
- .NET适用于net48/net7.0-windows等版本, 其中-windows不宜省去.
- .NET版本功能最全,例如通过windows的指针查找调用RhinoView.
- 并完全不等同于在Rhino内运行script,例如不支持rhinoscriptsyntax.
- RhinoInside用于后端服务
- 在Windows系统启动一个.NET或Python的后端服务,并在服务中引用RhinoInside,就能得到一个基于RhinoCore的几何计算后端服务——这也是RhinoCompute的基本原理.
-
提供一个服务测试(python-flask)作为参考示例
from flask import Flask, request, jsonify, render_template import rhinoinside rhinoinside.load() import Rhino.Geometry as rg # 可以使用 import rhinoscriptsyntax # 不受支持 app = Flask(__name__) # 具体函数省略... @app.route('/') def index(): return render_template('index.html') @app.route('/calculate', methods=['POST']) def calculate_intersection(): ... return jsonify({...}) if __name__ == '__main__': app.run(debug=True)
- 继发性Common版本冲突问题
- RhinoInside自动从nuget加载的RhinoCommon版本与本地Rhino版本不一致,在编译/运行时报错
-
报错示例:
CSC : error CS1705: ... uses RhinoCommon, Version=8.7.24134.3001 ... which has a higher version than referenced assembly RhinoCommon, Version=8.0.23304.9001 ... -
解决方法: 改为本地.dll引用, 避免自动从nuget载入包
<Reference Include="Rhino.Inside"> <HintPath>..\..\lib\Rhino.Inside.dll</HintPath> <Private>true</Private> </Reference>
RhinoCompute
- Compute的特性
- 基于Rhinoinside实现;rhinocompute ≈ rhinoinside + web service
- 支持Grasshopper Definition (.gh)
- 支持EndPoints自定义(原生2400+), 可以在.rhp加载时注册(嫌麻烦的话就直接自己写服务…)
- Compute
- 请求端
- 请求端
- 自行部署的服务端 run .rhp/.rhproj/.gh
Shim
- Shim的特性
- 用于解除Rhinoceros相关开发中的重启动需求,即测试.rhp和.gha时需要反复重新启动Rhinoceros软件的问题
- 在加载更多库的情况下,会出现一些莫名其妙的毛病,慎用…
- Shim的测试流程
- dotnet build shim/TestRhpShim/Name.Shim.csproj
- Rhinoceros load shim/TestRhpShim/bin/Debug/net48/Name.Shim.rhp
- dotnet build shim/TestRhp/Name.TestRhp.csproj
- Rhinoceros run command Name+TargetCommandName
Paradigms @RhinoDev
| Lang | Format | Name | Note |
|---|---|---|---|
| C# | .cs | RhinoCommand | |
| C# | .csproj | RhinoPlugin | |
| C# | .csproj | Rhino Test | |
| C# | .cs | GrasshopperComponent | |
| C# | .csproj | GHAssembly | include GHComponent |
| C# | .csproj | GH2Plugin | |
| C# | .cs-like |
GHScript | ScriptInstance |
| C# | .cs | RhinoCodeScript | |
| py | .py-like |
GHScript | |
| py | .py | RhinoCommand | |
| py | .py | RhinoCodeScript | |
| - | .rhproj | ScriptPlugin |
- GH|ScriptInstance(类/电池)
- LANG: C#
- LANG: Python
- GH|Component(类/文件) - Assembly(项目模板)
- LANG: C# 调试不是特别方便,要用的话需要再研究和建构(比如.cs-.csproj-consoleapp-rhinoinside)
- RH|Scripting
- LANG: C#
- LANG: Python
- RH|Command(类/文件) - Plugin/Assembly(项目模板) - Test(项目模板)
- LANG: C# C# Command是单独的.cs文件,可以是某个插件Plugin中的一个命令Command Plugin是Rhino插件的项目模板,体现为.csproj文件和对应的目录,编译后为.rhp文件 Test是Rhino插件测试的项目模板,体现为.csproj文件和对应的目录,编译后为可执行文件
- LANG: Python Python对项目结构的要求相对灵活,Command要求单个文件遵循模板并存储在特定目录,没有Plugin和Test项目模板。Command的运行机制和Scripting没有很大区别
- 几何数据结构/几何计算/几何可视化…三者关系/分离看待的必要性/在rhino中产生混淆的原因/…