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

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 与源码版本强行等同。

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

OpenGemCutting(产品线标识 SUVA · FACET 96)是浏览器本地优先的参数化宝石琢型工作台:同一份设计可由人手在网页编辑,也可经可选本地 MCP 由对话式 Agent 预览与提交。它不是通用三维建模器,也不是生产级光学计量工具。

核心结论可以先记四条:

  1. 双视口分工明确:工程编辑视口用 p5(WEBGL 模式)画几何与 CUT 机械臂;光学仿真视口用原生 WebGL2 做材质与光线相关显示。
  2. 几何真值在 domain/mesh:切割是确定性半空间裁切;mesh 原石走保孔洞的索引内核,不以凸包偷偷替换凹槽与通孔。
  3. 人工与 MCP 共用 application → domain:文档与撤销历史的唯一 owner 是网页侧 WorkbenchEditor;MCP 不另建第二套 CUT 会话或持久化库。
  4. 导出格式按职责拆分:JSON 是完整主文件;PDF 服务阅读与沟通;ASC 交换最终有效切面,并显式预检信息损失。
英文术语中文名称简要解释
CUT切割工序 / 切层一条带行业角、深度、分度与对称参数的参数化切割;完整序列称 CUT STACK
CUT STACK切割栈已提交的参数化工序列表;被后续覆盖的层仍保留,便于撤销后恢复
Mesh网格实体由顶点与面片描述的闭合材料边界;可含凹槽与孔
Meet会合构造用已有顶点或棱上比例点求解深度(及双点时的角度)的定位方式
Jump候选跳转在可解会合候选之间浏览,再原子应用角度/深度
MCPModel Context Protocol可选本地协议入口;工具语义与网页共用同一套设计契约
ASCGemCad ASCII与 GemCad 交换最终有效切面的文本格式,不是完整项目格式
Index wheel分度盘本项目固定 96 齿;显示上 96 与 0 等价
Optical Lab光学实验室独立页面入口;当前仅为空白骨架,实验工具尚未实现
localStorage浏览器本地存储按 origin 隔离的项目库;草稿与撤销历史不跨刷新自动恢复

技术栈与仓库分层

package.json(v1.1.1)声明:

层选型作用
UIReact 19.2.0 + React DOM主页、工作台、对话框与页面 chrome
构建Vite 6.4.3 + @vitejs/plugin-react开发服务与 dist/client 静态构建
工程视口p5 ^2.3.2GemViewport 动态 import("p5"),createCanvas(..., WEBGL)
光学视口原生 WebGL2OpticsViewport / meshTechnicalRenderer 直接 getContext("webgl2")
报告pdf-lib + @pdf-lib/fontkitA4 矢量技术报告与可搜索中文字体
图标 / 字体Tabler Icons、Noto Sans SC、IBM Plex Mono界面与等宽参数显示
运行时Node ^20.19.0 || >=22.12.0npm run dev / build / check / check:mcp

可选对话能力在仓库的 mcp/ 目录独立维护依赖;根目录安装与静态 Pages 构建不要求安装 MCP。README 的依赖关系可以概括为:

text
src/domain + src/application  →  同一套几何与设计规则
              ↑                         ↑
        浏览器手动编辑             可选本地 MCP
flowchart TB
  UI["React UI / WorkbenchEditor"] --> AppLayer["application 设计操作"]
  MCP["可选 MCP server"] --> AppLayer
  AppLayer --> Domain["domain 文档 / CUT / Meet"]
  Domain --> Mesh["domain/mesh 平面裁切内核"]
  UI --> EngVP["GemViewport · p5 WEBGL"]
  UI --> OptVP["OpticsViewport · WebGL2"]
  Domain --> Persist["projectLibrary · localStorage"]
  Domain --> Export["JSON / PDF / ASC"]

本地启动(官方 README):

bash
git clone https://github.com/yuyou-dev/OpenGemCutting.git
cd OpenGemCutting
git checkout v1.1.1   # 或等价 commit 1b76273
npm ci
npm run dev

npm run build 产出独立前端 dist/client/;GitHub Pages 使用 npm run build:pages。完整工程门禁是 npm run check;加上 MCP 时用 npm run check:mcp。

双视口:工程几何 vs 光学显示

Engineering viewport and optical viewport do not share one renderer. 工程视口要服务 CUT 机械臂、分度盘、Meet 标记与正交预览;光学视口要服务折射率、色散、Fresnel 与多次内反射一类的显示参数。二者读取的是同一份当前可见实体,但绘制管线分离。

视口实现入口图形 API典型内容
工程编辑src/components/GemViewport.jsxp5 WEBGL实体/X-ray、切割平面、Gizmo、正交缩略图数据源
光学仿真src/components/OpticsViewport.jsx原生 WebGL2材质预设、观察位、检查器;无 WebGL2 时明确提示
技术预览辅助meshTechnicalRenderer.js原生 WebGL2mesh 技术线框/深度缓冲类绘制

画布左上的视口模式切换组在 编辑 / 切割助手 / 光学仿真 之间互斥切换。切割助手与光学仿真都会挂起/恢复编辑现场,但只读,不提交草稿、不写入撤销历史。Escape 退出当前模式并恢复进入前的 CUT 会话对象。

独立页面 Optical Lab(OpticalLabPage.jsx)目前只提供导航、当前项目名和「实验工具准备中」空态;README 与状态契约均写明:独立光学实验室仍为开发中入口。光学仿真的主入口在编辑画布模式切换组,不要把空白实验室页理解成已交付的实验平台。

几何原理:确定性平面裁切与保孔 Mesh

Facet 96 的分度常量在 src/domain/faceting.js:

  • INDEX_TEETH = 96
  • DEGREES_PER_TOOTH = 360 / 96
  • 显示上 index 96 是 0 的别名

一条 CUT 把行业角、深度、基分度、重复与镜像展开为一条或多条裁切平面,再按序作用于初始晶体(document.stock)。最终实体是派生结果,不是另一份可漂移的“手工网格”。

Mesh 内核(src/domain/mesh/,注释标明改编自 gemcut-core 实验内核,MIT)对多面体做半空间裁切:

  1. 计算顶点相对平面的有符号距离(带容差归零)。
  2. 保留内侧顶点,在跨平面边上插值交点。
  3. 重建截面边界环;非凸预览路径用 earcut 三角化截面,并在环归属中保留 holes。
  4. 写入带稳定 face id 的封口面片,再压缩未使用顶点。

docs/cut-performance.md 与状态契约写明:

  • 旧 cube 来源:预览可用共享索引裁切;提交、Meet 来源与助手重放仍走原顺序精确核。
  • mesh 项目:预览与保存共用保孔洞的索引内核;错误阻断该草稿并允许拖回,不以凸包替代凹槽/通孔。

因此,“确定性”指同一输入平面序列应得到同一拓扑结果;“保孔”指截面三角化显式处理外环与内孔,而不是把通孔实体偷偷凸化。导入 OBJ 初始晶体另有资源预算(例如源多边形与分解后面片上限),见 docs/limits.md。

flowchart TB
  Stock["stock:cube 或 mesh 原石"] --> Planes["按序展开 CUT 平面"]
  Planes --> Clip["mesh.cut / 半空间裁切"]
  Clip --> Solid["派生实体 displaySolid"]
  Solid --> Eng["工程视口 / 正交预览"]
  Solid --> Opt["光学仿真"]
  Solid --> Report["PDF / 有效面统计"]
  Planes --> Stack["CUT STACK 仍保留完整参数层"]

CUT 业务流程

CUT 会话只有四态:idle / create / edit / group(实现见 src/domain/cutSession.js)。Meet / Jump 是新建或编辑中的构造子状态,不是第五态。

阶段行为是否入撤销历史
浏览 / 选层恢复已保存参数与构造,不改实体否
调参预览草稿派生未保存实体;helper 与实体必须同一版草稿否
Meet / Jump会话内求解深度/角度;锁定后写入构造 metadata 需待提交否
保存 CUT经统一提交门禁写入文档命令是(一条历史)
群组变换ΔZ、高度比例、整数齿旋转一次预览、一次提交是
切割助手回放只读重放已提交序列否
光学仿真进出只改视图态否;材质修改若走文档命令则入历史

提交前评估(状态契约)大致分为:零有效面/仅接触可定位但禁止提交;普通冠/亭部分消面可提交并提示;整层消失需显式确认;结构层失效或实体为空则硬阻断。确认后的提交与普通提交一样只产生一条文档历史。

CUT STACK 保存完整参数化工序;被后续层完全覆盖的工序不得从文档删除。最终有效面从完整实体派生,因此撤销或移除覆盖层后,早先工序的面可以自动恢复。面数、切割指令、ASC 与 PDF 面表只消费最终有效面;JSON 继续保存完整栈。

MCP 与人工:同一套业务规则和撤销历史

docs/mcp/architecture.md 给出边界:

  • MCP 只处理协议、静态服务和请求关联,不拥有当前文档、不复制几何算法。
  • 参数与工具语义的唯一注册表在 application 层设计契约;服务端直接导入,不复制 schema。
  • 批量计划是绑定当前 revision 的临时计算快照,不是第二套 CUT 会话,不写 JSON/项目存储。
  • 网页用原生 WebSocket;只有 127.0.0.1 上含显式连接片段的启动链接才建连。普通静态页不尝试连接、不加载 Node SDK。

人工保存 CUT 与自动化批量提交共用同一套提交准备逻辑(如 preparePatternCommit);群组变换共用同一 transformGroup。文档写入要求当前 projectId 与不透明 revision;手动编辑、撤销、会话变化或页面重挂载会使旧计划失效。有活动手动草稿时,能力约束会阻断外部写入,MCP 不会自动取消设计师的草稿。

The workbench remains usable without Codex, MCP, accounts, or API keys. AI 是可选创作入口,不是运行前提。

持久化:localStorage 项目库

项目库实现于 src/domain/projectLibrary.js,键前缀为 facet96:project:v1:,经 localStorage 读写,并可用 navigator.locks 做同名项目的读写互斥。

已核实的行为边界:

  • 自动保存只写入已提交文档及物理材质/计算参数;默认合并写入,页面隐藏/切换时冲刷。
  • 不跨刷新恢复:未保存 CUT/群组预览、相机、VIEW ONLY 参数与旧撤销历史。
  • 按浏览器 origin 隔离:换端口、换浏览器或清理站点数据不会自动迁移。
  • 修订冲突:记录层 revision 不一致时停止自动覆盖,提供重新载入、另存为新项目或导出 JSON;不做几何自动合并。
  • 重要设计应导出 JSON 作为长期归档;备份条目不是文件下载的替代品。

JSON / PDF / ASC 的职责

格式角色保留什么明确不保留或限制
JSON完整主文件stock、完整 CUT STACK(含被覆盖层)、Meet 快照、光学材质等导出的是已提交文档;活动草稿不会被导出动作隐式提交
PDF技术报告 / 沟通多视图、尺寸与有效面表;可搜索中文面向阅读,不替代可再编辑主文件
ASCGemCad 交换最终有效切面与折射率等交换字段展开重复/镜像;省略 Meet 意图、预形标记、撤销历史、毛坯定义;mesh 原石项目阻断导出

docs/limits.md 与 ASC 说明强调:需要继续改型时以 JSON 为准;ASC 预检会列出信息损失,导入/导出前应读完诊断再确认。

Optical Lab 与光学仿真的区别

入口状态(v1.1.1)用途
画布「光学仿真」模式已实现的聚焦视图比较材质、冠亭比例与亮暗;显示效果不代表实际切磨收益
顶栏「光学实验室」页面空白三栏骨架导航占位;文案为「实验工具准备中」

不要把 Optical Lab 页面上的空态解读成“光学功能未做”——光学仿真在编辑器内;实验室页是尚未交付的独立实验工作区。

可核查结论与验证边界

以下结论均可在 tag v1.1.1 / commit 1b76273 的源码或 docs/ 中核对:

  1. React + Vite 单页应用;工程视口为 p5 WEBGL,光学视口为原生 WebGL2。
  2. 96 齿分度;CUT 会话四态;mesh 裁切保孔;cube/mesh 预览与提交内核策略按契约区分。
  3. MCP 与网页共用 application/domain;撤销历史 owner 在 WorkbenchEditor。
  4. 项目持久化在 localStorage;JSON/PDF/ASC 职责分离;Optical Lab 未实现实验工具。

本文未声称:

  • 已在本机跑通完整 check:mcp 或设计师验收清单(上游 docs/validation.md 记录了维护者侧的验收,读者应自行复验)。
  • 仿真亮度/火彩等于真实切磨收益或材料等级。
  • GitHub Pages Live Demo 与某一 commit 字节级一致(源码版本 ≠ 站点已更新)。

动手命令速查

bash
# 固定调研版本
git fetch --tags
git checkout v1.1.1
npm ci

# 仅网页
npm run dev
npm run build
npm run check

# 含 MCP(需先安装 mcp 依赖)
npm ci --prefix mcp
npm run check:mcp

对话安装另见仓库根目录 INSTALL.md / UPGRADE.md;那是 Codex 侧的维护入口,与静态网页路径正交。

参考资料

本文共 3430 字,创建于 Sep 14, 2026

相关标签:Frontend, 可视化, ByAI

博客助手

正在打开博客助手…