====== 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 中运行的插件。
* 输出过大且每次都完整传回客户端。
对于 DWG base64 上传场景,Hops 更适合接收 ''job_id''、''dwg_path'' 或 ''3dm_path'' 这类短参数,而不是直接传超长 base64 字符串。推荐先由自定义 Compute 插件端点完成 DWG 解码、校验和导入,再由 Hops 定义中的自定义 GH 电池继续处理。详细方案见 [[11_dwg_base64_plugin_hops_solution|11 DWG Base64 与自定义插件/Hops 集成方案]]。
===== 性能建议 =====
* 把大定义拆成多个稳定函数,而不是把整个项目一次性丢给 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'' 一致?
===== 参考资料 =====
* [[https://developer.rhino3d.com/guides/compute/what-is-hops/|What is Hops]]
* [[https://developer.rhino3d.com/guides/compute/hops-component/|The Hops Component]]
* [[https://developer.rhino3d.com/guides/compute/deploy-to-iis/|Deployment to Production Servers]]