跳至正文
App — OpenGemCutting 架构调研:技术栈、几何内核与业务流程

OpenGemCutting 架构调研:技术栈、几何内核与业务流程

https://github.com/yuyou-dev/OpenGemCutting

AI 参与说明(Agent:Grok / Grok Bot):本文最初对照公开仓库 OpenGemCutting 的 tag v1.1.1(commit 1b76273882a9f1daeda6ce36d592b926d45c22f1,提交时间 2026-09-12 +08)源码与 docs/ 契约文档整理。初稿资料整理于 2026-09-14。运行记录:模型标识与 reasoning effort 未取得完整运行记录;执行入口为 Blog 助手的 Grok Bot executor。文中区分源码/官方文档已证实的事实与工程归纳;未实测真实切磨收益,也未把 Live Demo 与源码版本强行等同。

标签整理(2026-10-16,Agent:Codex):本次仅补齐分类标签并核对元数据,未改写或重新校验原文技术结论。运行记录:模型 gpt-6.1-sol,reasoning effort ultra,执行入口 Codex Desktop,提供方 openai;CLI 版本 0.162.0-alpha.17.2(不代表桌面 App 版本)。

技术栈修订(2026-10-10,Agent:Codex):对照 main commit e8cfa6c906001c3a28fc6f786a437cbbf3a07e2e(2026-10-08,package.json 版本 2.1.0)更新依赖、WebGPU / WebGL2、JSCAD 凹切、IndexedDB、实验室与 MCP 边界。依赖版本取自对应 lockfile,事实来源为公开源码与上游契约,另通过 Context7 核对 p5.js 官方文档。运行记录:模型 gpt-6.1-sol,reasoning effort ultra,执行入口 Codex Desktop,提供方 openai,CLI 版本 0.162.0-alpha.17.2(不代表桌面 App 版本)。本次为静态源码调研,未运行上游完整测试或实测 GPU 性能;文章的构建与网页渲染单独验收。

归档修订(2026-10-15,Agent:Codex):本文从 Posts 归入 App 栏目,保留原有正文、日期与标签;原有公开 URL 保持不变。运行记录:模型 gpt-6.1-sol,reasoning effort ultra,执行入口 Codex Desktop,提供方 openai;CLI 版本 0.162.0-alpha.17.2(不代表桌面 App 版本)。

OpenGemCutting 是浏览器本地运行的参数化宝石琢型工作台,产品标识沿用 SUVA / Facet 96。读它的技术栈,最有用的切入点是把界面、几何计算、图形显示和可选 AI 接入分别看清:React 组织交互,领域模块计算真实几何,多个渲染器消费同一份结果,MCP 把外部 Agent 接到已有设计操作上。

先认识几个贯穿下文的词:

英文术语中文名称简要解释
CUT / CUT STACK切割工序 / 切割栈带角度、深度、分度等参数的平切工序及其完整序列
Mesh网格顶点和面片描述的材料边界,可以包含凹槽、孔和分离组件
CSG构造实体几何通过实体的交、并、差表达加工结果;这里主要用于凹切差集
WebGPU / WebGL2浏览器图形 API将几何与光学显示计算交给 GPU 的两条实现路径
WGSL / GLSL着色语言分别用于 WebGPU 与 WebGL2 的 GPU 程序
Meet / Jump会合构造 / 候选跳转用已有顶点或棱定位切面,并浏览可解候选
IndexedDB浏览器本地数据库项目与实验记录的当前持久化入口
MCPModel Context Protocol,模型上下文协议让外部 Agent 调用本地工作台设计操作的可选协议入口
Index wheel分度盘用齿数描述旋转刻度;96 齿是默认值

OpenGemCutting is a browser-first React application with a shared geometry core and an optional local MCP bridge. 它的主要计算在浏览器内完成;手动工作台不要求 Codex、MCP、账号或 API Key。当前公开源码基线为 commit e8cfa6c。上游 README 将 2.1.0 标为发布候选,不能仅凭源码版本认定 Live Demo 已同步更新。

技术栈总览

下面列的是这次源码快照中 lockfile 实际锁定的版本;例如 package.json 的 p5 范围是 ^2.3.2,对应锁定值是 2.3.2。来源:根依赖声明、根 lockfile、MCP lockfile。

层技术与版本实际职责
源码语言JavaScript、JSX、ES Modules应用、领域模块、工具与测试;图形程序另用 WGSL / GLSL
UIReact / React DOM 19.2.0工作台、项目列表、格式中心、实验室与弹窗
构建Vite 6.4.3、@vitejs/plugin-react 5.0.4开发服务、React 编译与静态前端构建
样式与图标自写 CSS / CSS variables;Tabler Icons 3.46.0设计变量、组件样式与图标
字体Noto Sans SC、IBM Plex Mono 字体包均为 5.3.0中文界面与等宽参数文字;PDF 另加载字体资源
工程视口p5.js 2.3.2 的 WEBGL renderer实体、切割平面、机械臂、Gizmo 与交互标记
全抛光光学@vgpu/core 0.5.0 + 原生 WebGPU + WGSLGPU 光线追踪显示;失败回退 WebGL2
光学兼容与磨砂原生 WebGL2 + 自写 GLSL兼容后端;磨砂表面有独立采样、累积与降噪路径
平切几何项目自身的凸体 / 索引 Mesh 内核;vendored Earcut 3.0.2半空间裁切、截面三角化与保孔拓扑
凹切几何@jscad/modeling 2.13.0经独立 adapter 对实体做 CSG 差集
后台几何浏览器 module Worker凹切预览计算与主线程 UI 分离
本地保存IndexedDB、BroadcastChannel项目 / 实验记录、事务提交、跨标签页通知
报告pdf-lib 1.17.1、@pdf-lib/fontkit 1.1.1技术报告、矢量视图与可搜索中文文字
可选 MCPNode.js;MCP SDK 1.32.1、ws 8.21.3stdio 工具服务、本地 HTTP / WebSocket 与网页桥接
测试Node.js Test Runner、自有测试入口;Ajv 8.20.0、fake-indexeddb 6.2.5领域规则、文档 schema、数据库、安装与桥接测试
部署GitHub Actions → GitHub Pages;另有 Static Assets Worker 壳发布静态前端;生产平台按使用路径选择

前端应用源码主要是 .js / .jsx。UI 在 src/styles.css 和组件 CSS 中定义样式;页面切换由 App.jsx 的 page state 管理,当前值包括 home、editor、lab、formats。状态主要使用 React Hooks:WorkbenchEditor 以 useState 持有命令历史,以 useReducer 驱动 CUT 会话。其根依赖没有采用 Three.js、React Three Fiber、Tailwind CSS、Redux 或 Zustand。App 与页面切换、编辑器状态、样式。

分层:界面和 Agent 共用设计规则

仓库的业务分层集中在 src/domain/ 与 src/application/。前者负责文档、CUT、Meet、几何与交换格式,后者提供设计操作、实验室宿主和数据库等应用入口;React 组件负责把这些入口变成可交互工作台。

flowchart TB
  UI["React / WorkbenchEditor"] --> App["application 设计操作"]
  Agent["外部 Agent"] --> MCP["本地 Node.js MCP"]
  MCP --> Bridge["WebSocket 网页桥接"]
  Bridge --> App
  App --> Domain["domain 文档与几何规则"]
  Domain --> Solid["派生实体"]
  Solid --> Eng["p5 WEBGL 工程视口"]
  Solid --> Opt["WebGPU / WebGL2 光学"]
  UI --> DB["IndexedDB 项目保存"]
  UI --> Export["JSON / PDF / ASC / GCS"]

图中的 MCP 写入最终仍回到网页的命令入口。当前文档与撤销历史由 WorkbenchEditor 持有;MCP 服务端处理协议、连接、请求关联与静态服务,不另设一份正在编辑的文档或项目数据库。工具参数和设计语义从 application 层的统一契约取得。MCP 架构、全局状态契约。

这使手动操作与 Agent 请求能够共用提交规则。例如二者都必须判断新 CUT 是否真的产生有效面、最终实体是否有效,以及请求所依据的项目 revision 是否仍是当前版本。

多条渲染管线:工程视口与光学视口

The engineering viewport and the optical viewport use separate rendering pipelines. 前者服务参数编辑、几何检查与刀具定位;后者服务材质、折射、反射与亮暗比较。两者读取同一份当前实体,但 GPU 程序和交互状态独立。

工程视口的入口是 GemViewport.jsx:动态 import("p5"),以 p5 instance mode 创建 WEBGL canvas。p5.js 官方文档确认 createCanvas(width, height, WEBGL) 用于三维绘制;因此这里的 p5 是图形 renderer,几何真值仍由 domain 层计算。视口源码、p5.js createCanvas。

光学部分有三条需要区分的路径:

场景实现回退与范围
全抛光显示opticsWebgpuRenderer.js + opticsShader.wgslWebGPU 默认优先;初始化失败、绘制失败或 device lost 后重新建 canvas,切到 WebGL2
WebGL2 兼容显示opticsWebglRenderer.js直接创建 WebGL2 context,使用 GLSL ES 3.00;可用 ?opticsBackend=webgl2 强制选择
按设计表面的磨砂显示opticsSurfaceRenderer.js当前走独立 WebGL2 采样路径;没有对应 WGSL 版本

@vgpu/core 在 WebGPU renderer 中提供 Device、Shader、Buffer、Queue 等对象;源码同时直接操作原生 canvas context、render pipeline 与 bind group。因此,把它概括为“借助 @vgpu/core、自写 WebGPU 光学 renderer”更准确。WebGPU renderer、后端切换、磨砂实现范围。

自写 shader 包含 Fresnel 反射与折射、全内反射、吸收,以及 RGB 分通道的色散近似。凸体使用半空间求交,Mesh 使用 stackless BVH 加速光线求交。显示采用像素预算、渐进分辨率、几何缓存等控制计算成本;它帮助在相同观察条件下比较设计,不能作为真实切磨收益或材料光学等级的测量结果。WGSL、Mesh BVH、像素预算。

几何内核:平切与凹切分别求值

设计输入分成三部分:不可变初始晶体 stock、平切参数 facets、凹切参数 concaveCuts。documentGeometry.evaluateDocument 先计算平切实体,再扣除启用的凹切刀具:

text
final solid = (stock ∩ facet halfspaces) − enabled concave tools

平切构造依赖原始 stock 与平切工序,凹切三角片不成为另一套平切约束来源。这样,调参、重算、撤销和助手回放都能从参数文档重建结果。documentGeometry.js。

flowchart TB
  Stock["stock 初始晶体"] --> Planar["facets 平切求值"]
  Facets["CUT STACK 参数"] --> Planar
  Planar --> Diff["CSG 差集"]
  Tools["启用的 concaveCuts"] --> Diff
  Diff --> Solid["最终实体"]
  Solid --> View["工程与光学显示"]
  Solid --> Effective["最终有效面 / 报告"]

平切:半空间裁切与保孔 Mesh

一条 CUT 把行业角、深度、分度、重复与镜像展开为多个裁切平面。凸体路径按半空间裁切多面体;导入的 Mesh 使用索引裁切内核,保留非凸边界、孔、内腔壳层和分离组件。

裁切时计算顶点到平面的有符号距离,在跨平面边上插入交点,重建截面边界环,再封口。截面的非凸轮廓与内孔通过 vendored Mapbox Earcut 3.0.2 三角化。Mesh 核心改编自作者的 MIT 实验项目 GemstoneCuttingSystem,工程中另补身份、导入与 embedding 校验。Mesh 内核说明与归属、截面处理。

cube 的瞬时预览可走索引 / 批量求交路径,提交、Meet 来源与施工回放保留顺序精确内核;Mesh 预览与保存共用保孔索引内核。错误会阻断无效草稿,不以凸包代替原石凹槽或通孔。CUT 性能、状态契约。

96 齿现在是默认分度,而非全部项目的固定值;界面预设齿数为 32、64、72、77、80、84、88、96、99、120、360,领域函数接受 1–360 的整数齿数。每层保留自己的 indexTeeth,换盘沿统一领域入口处理,既有平面的几何数值保持不变。圈层、弧形、网格及复合刀具负责生成参数化平面,仍交给同一几何求值入口。分度规则、几何契约。

凹切:JSCAD adapter 与 Worker

JSCAD 的使用集中在 src/domain/mesh/boolean.js:adapter 将 Mesh 转成实体表示,做 BSP 差集,再还原并验证材料边界。依赖固定为 2.13.0,上游说明 adapter 使用了内部 BSP API,升级需要重新做兼容性验证。boolean.js、adapter 约束。

刀具包括 sphere、cylinder、v-wheel、triangular-prism。曲面以面片近似:默认 24 段,允许 12–64 段且为 4 的倍数;工序、重复次数和估算面片都有预算。这属于 tessellated solid CSG,精度会受离散分段与数值容差影响。凹切参数与预算、适用范围。

编辑器创建一个 module Worker 执行凹切预览。scheduler 只允许一项计算在途,并保留最新一项待处理输入;快速拖动时合并中间请求,避免为每个指针事件重复计算。这里的并发是 UI 与后台几何计算分离,没有采用 Worker pool。Worker、创建入口、scheduler。

CUT 会话与文档历史

CUT 会话仍只有 idle、create、edit、group 四态,由 cutSession.js 的事件驱动状态机管理。Meet / Jump 是会话内的构造状态;视口、实验室或刀具选择不额外增加 CUT 状态。cutSession.js、状态契约。

动作写入设计文档与撤销历史
选层、浏览候选、调参预览不写;草稿与 helper 消费同一版输入
Meet / Jump 求解与锁定暂存在会话;提交后才保存构造 metadata
加入 CUT / 保存编辑统一门禁通过后写一条文档命令
冠 / 亭群组升降、比例或旋转一次预览,一次提交与撤销
凹切参数预览与确认加入预览不提交;确认后进入文档命令
切割助手回放 / 光学视角变化只改变显示状态
光学物理材质设置通过文档命令保存;纯视图参数另行管理

CUT STACK 保留完整参数化工序,后续工序覆盖了早先切面也不删除其参数。最终有效面统一从最终实体派生;移除覆盖工序后,早先的面可恢复。新 CUT 零有效面、无效几何或空实体会阻断;覆盖既有层则给出警告并保留参数,当前规则不再要求对整层消面另做确认。统一提交与有效面规则。

助手按已提交平切序列逐步回放,再按启用的凹切层顺序回放;最终结果与完整文档的几何求值一致。Meet 的来源身份和签名失效时明确标记 stale,不凭最近坐标自动续接。助手与 Meet 契约。

持久化:IndexedDB 与修订冲突

Current project writes use IndexedDB; legacy project records are imported from localStorage. 项目数据库为 facet96-projects,实验数据库为 facet96-experiments。两者共享事务生命周期工具,但分别维护记录;localStorage 另用于语言偏好,并导入旧项目和实验记录,当前项目写入没有 localStorage 回退或镜像。projectDatabase.js、labDatabase.js。

项目保存以已提交 document 为快照,不把当前 CUT 会话、相机、视图状态或命令历史一起写入。自动保存会合并连续提交,正常使用约 300 ms 延迟;只有事务完成才确认该快照已落盘。快照边界、保存编排。

并发写入在同一 readwrite transaction 中比较 expectedRevision,匹配后更新记录并递增 revision。冲突时停止自动覆盖,保留内存中的设计,允许重新载入、另存为项目或导出 JSON。BroadcastChannel 通知其他标签页刷新项目记录;它负责通知,真正阻止覆盖的是数据库事务中的 revision 检查。事务保存、跨标签页通知。

实验记录另外保存来源快照、模块与契约版本、配方、候选和带回回执。候选需重新导入、重算实际几何后才能带回,带回创建独立项目。当前实验室体系已有图案等实际模块;冠亭预设实验室的构造入口已合并到编辑器“圈层组合”刀具,旧实验稿继续兼容。这些行为应按当前实验室登记与契约理解。实验室公共契约、状态与宿主边界。

浏览器存储仍按 origin 隔离,更换浏览器或端口不会自动迁移。要长期保存或转移设计,导出 JSON 比只保留浏览器记录更稳妥;未提交预览和未落盘内存不能视为已经备份。

文件与报告:主文件和交换格式各有职责

格式用途与保留内容使用边界
JSON保存 stock、完整 CUT STACK、已提交 Meet、凹切、材质与可兼容扩展继续参数化编辑的主文件;活动草稿不因导出而隐式提交
PDF多视图、尺寸、有效面表、加工说明与中文 / 英文报告面向阅读与沟通,不代替可编辑主文件
GemCAD .asc交换最终有效平切面与可支持的材质字段重复 / 镜像展开;构造意图等按预检列出损失
GemCAD .gem格式中心读取既有文件只读
Gem Cut Studio .gcs格式中心导入 / 导出交换设计逐项解释保留、简化与丢失信息,并对导出文件读回核对
OBJ导入真实初始晶体 Mesh必须通过闭合、朝向、退化与自交预检

Mesh 原石项目或启用凹切的项目不能导出 ASC / GCS,避免输出丢失真实几何的替代形状。多级角度、深度的工序可以按交换格式拆为多个层,几何保留但参数化刀具的编辑意图可能丢失。外部文件还有明确资源预算:20 MiB 文件上限、4096 个 CUT 平面等,导入错误不替换当前设计。文件与设计边界、格式中心契约。

PDF 通过 pdf-lib 与 fontkit 生成,和浏览器图形显示的职责分离;界面语言、用户命名与设计序列化也分别管理,切换显示语言不改变几何或项目 revision。PDF 源码、语言与状态契约。

MCP:本地工具协议与网页桥接

可选 MCP 在 mcp/ 下独立管理依赖。服务端以 stdio 与 MCP 客户端通信,同时在 127.0.0.1 提供本地 HTTP / WebSocket 桥接;网页通过显式启动链接建连,连接检查包括 origin 与 token。普通静态网页不自动尝试连接本地服务,也不加载 Node.js MCP SDK。MCP 包、server.mjs、MCP 架构。

写请求需要携带读取到的 projectId 和 revision。手动编辑、撤销、项目切换或页面重挂载会使旧请求失效;批量方案先预检,通过后作为一次文档命令提交。有活动 CUT、隐藏层、模态流程、助手 / 光学模式或非编辑页面时,外部写入会暂停并返回原因,Agent 不能自动取消人工草稿。操作一致性契约。

仓库提供设计 Skill、MCP、插件与安装模块,模型服务由 Codex 等外部客户端提供。技术上值得复用的是“Agent 经既有 application 操作进入编辑器”的方式:领域规则、文档历史与持久化保持同一个来源,避免自动化路径另造一套设计状态。

构建、测试与本地启动

Node.js 要求为 ^20.19.0 || >=22.12.0。下面固定本次调研 commit,适用于有 Git、npm 和匹配 Node.js 的本地环境;这些是经配置核对的复现命令,本次未运行上游安装与完整检查。

bash
git clone https://github.com/yuyou-dev/OpenGemCutting.git
cd OpenGemCutting
git checkout e8cfa6c906001c3a28fc6f786a437cbbf3a07e2e
npm ci
npm run dev

开发服务绑定 127.0.0.1,打开终端打印的地址即可。npm run build 生成 dist/client/,并追加设计构建标记与 Static Assets Worker 的构建准备;npm run build:pages 设置 /OpenGemCutting/ base。GitHub Pages workflow 在 main 推送时构建并发布 dist/client/。Vite 配置、构建脚本、Pages workflow。

仓库另有 worker/index.js,负责从 env.ASSETS 提供静态文件与 SPA 的 index.html 回退。它是部署壳,项目保存与几何计算仍在浏览器;不能据此推断项目已有云端设计数据库或模型调用后端。Worker。

根 npm run check 包含测试入口、公开性扫描、文档、安装、领域、设计契约、Companion 插件、构建与 Worker 检查。MCP 单独安装依赖,再通过 check:mcp 加入连接与版本检查:

bash
# 静态前端与工程检查
npm run build
npm run check

# 可选 MCP 检查
npm ci --prefix mcp
npm run check:mcp

测试主体使用 Node.js Test Runner;fake-indexeddb 支持数据库测试,Ajv 用于开发期 schema 验证。根包没有采用 Vitest 或 Jest。需要完整 Codex 对话工作台时,按上游 INSTALL.md 走安装流程,单机网页入口本身不要求安装这些对话组件。

如何读这套源码

如果目标是理解和复用架构,建议按下面顺序读,而非先从大型视口组件开始:

  1. package.json、vite.config.mjs:确认运行环境、依赖与前端产物。
  2. docs/architecture/state-contract.md:厘清文档、草稿、历史、视图和保存的 owner。
  3. src/domain/documentGeometry.js、src/domain/mesh/:理解参数文档如何生成真实实体,以及平切与 CSG 的边界。
  4. src/WorkbenchEditor.jsx、src/application/:看手动命令、预检、事务和外部操作如何汇合。
  5. GemViewport.jsx、opticsWebgpuRenderer.js、opticsWebglRenderer.js:分别阅读工程显示和光学管线。
  6. docs/mcp/architecture.md、mcp/server.mjs:最后接入外部 Agent,观察 revision 与人工操作保护。

工程判断是:它可作为“参数化文档 + 浏览器几何工具 + 可选 Agent 操作”的参考,主要复杂度集中在几何正确性、GPU 兼容和编辑状态一致性。要修改核心能力,先补对应领域与契约测试,再核对工程视口、光学显示、导出与 MCP 是否仍消费同一份设计。

关联阅读:Web 3D 基础概念:从 Mesh 到 GLB · Three.js 与 Blender 入门 · 前端工具链专题。

博客助手

正在打开博客助手…