这是本文档旧的修订版!
05 Grasshopper 与 Hops 工作流
Hops 的核心思想
Hops 把一个外部 Grasshopper 定义变成当前画布上的“函数组件”。这个外部定义可以保存在本地、网络路径、远程服务器,也可以是 REST 端点。
在教学中可以把 Hops 理解成:
外部 .gh 文件 = 函数定义 Context Get = 函数输入 Context Print / Context Bake = 函数输出 Hops 组件 = 函数调用 RhinoCompute = 执行函数的服务器
为什么使用 Hops
- 拆分大型 Grasshopper 画布,降低复杂度。
- 把重复逻辑封装为可复用定义。
- 团队共享同一组参数化函数。
- 把耗时求解交给远程服务器。
- 支持异步和并行求解,减少主画布阻塞。
安装 Hops
在 Rhino 命令行输入:
PackageManager
搜索 Hops 并安装。安装后,在 Grasshopper 的 Params > Util 中可找到 Hops 相关组件。
创建 Hops 函数
一个可被 Hops 调用的 Grasshopper 定义通常分三段:
- 输入定义区:使用 Context Get 组件,例如 Get Number、Get String、Get Curve。
- 计算逻辑区:普通 Grasshopper 组件、脚本组件、插件组件。
- 输出定义区:使用 Context Print 或 Context Bake。
命名规则很关键:
- Context Get 组件的名称会变成 Hops 输入参数名。
- Context Print/Bake 的输入参数名会变成 Hops 输出参数名。
- 命名应稳定、简短、语义明确,例如
width、height、floor_count。
最小示例
目标:输入半径,输出圆面积。
- 新建 Grasshopper 定义。
- 放置
Get Number,命名为radius。 - 用圆或表达式计算面积。
- 放置
Context Print,输入命名为area。 - 保存为
circle_area.gh。 - 在另一个 Grasshopper 文件中放置 Hops 组件。
- 右键 Hops,选择
Path,指向circle_area.gh。 - Hops 组件会自动生成
radius输入和area输出。
配置远程 Compute
在 Grasshopper 中打开:
File -> Preferences -> Solver
配置:
| 配置项 | 说明 |
|---|---|
| Hops-Compute server URL | 本地或远程 Compute URL,例如 http://localhost:6500/ 或 http://server-ip:80/。 |
| API Key | 与服务器 RHINO_COMPUTE_KEY 匹配的 key。 |
| Max Concurrent requests | 异步时的最大并发请求数。 |
| Hide Rhino.Compute Console Window | 本地排错时建议取消勾选,方便看控制台日志。 |
| Launch Local Rhino.Compute at Start | 本地 Hops 自动启动 Compute 时使用。 |
| Child Process Count | 远程或本地 Compute 子进程数量。 |
Hops 组件设置
右键 Hops 组件可看到常用选项:
| 选项 | 用途 |
|---|---|
| Path | 设置 GH 文件、网络路径或 REST URL。 |
| Show Input: Path | 把 Path 暴露成输入,便于动态选择定义。 |
| Show Input: Enabled | 用布尔值控制是否求解。 |
| Asynchronous | 异步求解,不阻塞 Rhino/Grasshopper UI。 |
| Parallel Computing | 对列表项尝试并行求解。 |
| Cache In Memory | 本地缓存相同输入的结果。 |
| Cache On Server | 服务端缓存,具体可用性取决于部署和服务能力。 |
适合放进 Hops 的定义
适合:
- 输入输出清晰。
- 计算过程无人工交互。
- 不依赖当前 Rhino 文档选择集。
- 文件路径和外部资源可配置。
- 插件依赖能在服务端安装和授权。
不适合:
- 依赖鼠标选择、弹窗、视口状态。
- 依赖本机临时路径或用户桌面文件。
- 使用只能在有界面 Rhino 中运行的插件。
- 输出过大且每次都完整传回客户端。
性能建议
- 把大定义拆成多个稳定函数,而不是把整个项目一次性丢给 Hops。
- 对频繁调用的纯函数开启缓存。
- 对耗时定义使用异步,但要控制最大并发。
- 远程部署时,子进程数量不要简单等于 CPU 核心数,还要考虑 Rhino/Grasshopper 插件的内存占用。
- 第一次求解可能较慢,因为 Rhino、Grasshopper、脚本环境或插件需要初始化。
教学练习
练习 1:把“输入长宽高,输出盒子体积和 Brep”的定义封装成 Hops 函数。
练习 2:把同一 Hops 函数分别指向本地 Compute 和远程 Compute,比较第一次求解和第二次求解耗时。
练习 3:关闭 API Key 或输入错误 API Key,观察 Hops 组件和 Compute 日志中的错误表现。
本章检查点
- 你是否能说明 Context Get 和 Context Print/Bake 的作用?
- 你是否能配置 Hops 指向远程 Compute URL?
- 你是否知道 Hops API Key 要和服务器
RHINO_COMPUTE_KEY一致?