Build and verify the candidate-only FreeCAD naming bridge and OCCT worker path, including three-stage StringHasher restoration. Add Datum, ShapeBinder, attachment-mode, and PartDesign structure oracles plus offline SDK build plans and CI boundary checks.
57 KiB
完整 FreeCAD 对标实施方案
本文是“功能完全对标 FreeCAD”的工程基线和任务分解,不把当前已有的页面、MockFacade 或少量 OCCT 特征误报为完成。所有“支持”都必须经过锁定版本 FreeCAD 的行为黄金测试和文件互操作测试。
全模块、逐领域任务 ID、执行波次和统一退出条件以 FreeCAD 1.1.1 全功能对标主任务账本 为准;本文保留架构决策、专项设计和阶段门。两者不一致时,能力状态以
config/compatibility-matrix.json为机器可读真值,范围和待办以主任务账本为准。
1. 目标与边界
1.1 目标
以 FreeCAD 1.1.1 官方发布标签为首个兼容基线,精确源码提交为 0108fd4b4850cc46e625b60e53cea7a7bbe69f8d。实现可在浏览器运行的 CAD 应用:React 负责 FreeCAD 风格界面,Three.js 最新锁定版本负责三维显示,Bitbybit 是唯一入口,FreeCAD/OCCT 业务逻辑在 WASM Worker 中运行,SQLite WASM + OPFS 负责项目、文档、对象、事务和资源存储。
1.2 唯一入口原则
对 React 和页面公开的唯一业务入口是 BitBybitWebCadFacade。页面不得直接导入 Three.js、OCCT、OCCT Worker、SQLite 或 OPFS;这些实现只能由 Facade 适配器和 Worker 使用。新增工作台、命令、属性、文件格式和诊断,必须先扩展版本化 Facade 合同,再接入页面。
Bitbybit 必须被充分用作几何、Worker、IO、三角化和缓存的首选实现层。对 Bitbybit 1.1.1 npm 包未暴露但 FreeCAD 对标必需的能力,允许锁定 Bitbybit 与 OCCT 源码提交后扩展绑定并用 Emscripten 自构建 WASM;不得以现成包 API 不足作为降低功能范围的理由。自构建 provider 与现有 provider 必须共享 Facade/Worker 合同、能力探测、句柄生命周期、取消/诊断和黄金测试。
1.3 “完整对标”的可验收定义
| 等级 | 含义 | 允许的产品表述 |
|---|---|---|
exact |
与基线 FreeCAD 在输入、状态、结果、错误、选择和持久化语义上逐项一致 | “已对标” |
compatible |
结果和核心交互一致,允许明确记录的浏览器呈现差异 | “兼容” |
read-only |
可读取、可显示、可导出,但不能安全编辑和重算 | “只读” |
proxy |
保留未知对象、属性或 Shape 资产,不能保证语义重算 | “代理” |
unsupported |
有意拒绝并生成结构化诊断 | “不支持” |
没有黄金测试、差异报告和迁移策略的功能,不得标记为 exact 或 compatible。浏览器限制必须体现为能力矩阵和用户可见诊断,不能静默删除 FreeCAD 行为。
1.4 全量范围和清册门禁
锁定源码 src/Mod 的 34 个目录全部纳入范围:AddonManager、Assembly、BIM、CAM、Cloud、Draft、Fem、Help、Idf、Import、Inspection、JtReader、Material、Measure、Mesh、MeshPart、OpenSCAD、Part、PartDesign、Plot、Points、ReverseEngineering、Robot、Sandbox、Show、Sketcher、Spreadsheet、Start、Surface、TechDraw、TemplatePyMod、Test、Tux、Web。同时覆盖 App、Base、Gui、Main 暴露的文档、Property、事务、选择、视图、参数、命令、Python 控制台、宏、偏好、快捷键、多文档、剪贴板和打印行为。
P0-02/INV-01..06 未完成以前,“全部功能”范围仍视为未冻结。源码模块中的测试、模板或开发设施可以被分为开发等价能力或明确 unsupported,但不得遗漏;Python、宏、插件、外部求解器和后处理器必须有沙箱与权限决策。
项目 Node/npm 命令统一经 ./npmw 执行;系统 npm 的结果不得用作阶段门证据。
本机 FreeCADCmd 可作为第一层行为 oracle:./npmw run probe:freecad-reference 采集版本、提交、已加载模块和核心 Property 元数据;当前构建是无界面 Part/Material/Measure 子集。完整桌面/工作台回放必须另行启用 FreeCAD 原生模块,不能将 headless probe 的可用性扩展到未构建的工作台。
2. 当前差距与解决策略
| 领域 | 当前切片 | 达到对标还缺少的核心能力 | 主任务包 |
|---|---|---|---|
| 拓扑命名 | 有 SubshapeRef 类型和句柄生命周期 |
历史映射、持久名称、歧义检测、版本迁移 | TSN |
| Sketcher | 有轮廓输入验证 | 几何/约束模型、Planegcs 求解、编辑器交互、外部几何 | SK |
| Expression/单位 | Property metadata 可声明单位 | 词法/语法、Quantity、维度检查、引用、循环和 locale | EXU |
| 依赖 DAG/重算 | 有事务和版本号 | Link 图、SCC、调度、取消、增量结果、错误传播 | DAG |
| Part/PartDesign | 已有部分 Primitive/Boolean/Pad/Pocket/Revolution | 完整特征、Body/Tip、附着、模式、失败恢复 | PD/PART |
| 工作台 | manifest 和界面骨架 | Draft、TechDraw、Spreadsheet、Assembly、BIM、CAM、FEM、Mesh 等业务 | WB |
| 文件 | 项目 schema v1、资源对象 | FCStd 读写、BREP/GuiDocument、扩展/代理、格式导入导出 | FC |
| 质量 | Facade Node 测试和部分浏览器矩阵 | FreeCAD 对照回放、几何黄金、压力、跨浏览器和安全门禁 | QA |
3. 总体架构与不可破坏的约束
3.1 分层
- Presentation:React 页面、FreeCAD 菜单/工具栏、Combo View、Tasks、Property editor、Report view、快捷键和无障碍。
- Facade:
App/Gui/Workbench/Command/Selection/Task/Project/Viewport合同、权限、前置条件、请求上下文、诊断、事件和版本。 - Domain kernel:Document、DocumentObject、Property、Link、Expression、Sketch、Feature、Body/Tip、事务、DAG、重算。
- Geometry:Bitbybit OCCT API 和必要的 FreeCAD/OCCT C++ 模块 WASM 化;B-Rep 句柄仅在 Worker 内部存在。
- Workers:几何、求解、重算、持久化各自独占 Worker;消息带
requestId、documentId、documentVersion、取消和诊断。 - Persistence:SQLite WASM OPFS 单写者、项目迁移、资源内容寻址、事务日志、恢复和导入导出。
3.2 领域不变量
- 对象 UUID、内部名称和子形状名称永不使用显示 Label 代替。
- 所有长度、角度、面积、体积在内部使用有维度的 Quantity;数据库保存规范单位和原始表达式。
- 任何重算结果只有在请求版本仍等于当前文档版本时才能提交;过期结果必须丢弃。
- 依赖循环、求解冲突、拓扑歧义和未知文件对象必须显式失败并保留诊断。
- Undo/Redo、自动保存和资源引用计数必须以同一事务边界提交。
- Worker 结果不可直接改变 React 状态,必须经 Facade 校验和事件投影。
- 几何能力按
reuse-bitbybit、extend-bitbybit-binding、custom-occt-binding三档登记;后两档必须锁定源码、补丁、ABI、Emscripten 工具链、许可证和 WASM hash,并完成 Bitbybit/FreeCAD 三方差分。
4. 专项一:稳定子形状命名(TSN)
4.1 目标
实现与 FreeCAD 特征历史可比的 TopoRef:面、边、顶点、壳、实心体和 Compound 在特征重算、参数编辑、保存/加载、布尔操作和导出后仍能被稳定引用;无法唯一判断时返回 ambiguous,绝不把错误的面静默绑定给另一个面。
4.2 技术措施
- 在 OCCT Worker 内保留每次特征的输入 Shape、输出 Shape、历史对象和拓扑签名;使用
Generated/Modified/Deleted历史关系生成映射。 - 为每个子形状计算规范签名:拓扑类型、几何类型、解析几何参数、几何中心/长度/面积/体积、邻接度数、方向、局部坐标和量化容差。签名必须区分“用于匹配的特征”与“仅用于诊断的数值”。
- 采用分层命名:
documentId/objectUuid/featureRevision/subshapeKind/localOrdinal,再绑定跨版本映射记录;不使用 OCCT transient hash 或三角网格索引作为持久 ID。 - 对对称、重复和布尔切分结果建立候选集合和评分;最高分不超过唯一阈值时返回歧义,并在 UI 的选择/任务面板显示候选。
- 保存
TopoRef的来源特征版本、签名、映射算法版本和容差;加载旧版本先迁移,迁移失败保留原引用和报告。 - 将面/边选择、附着、Fillet/Chamfer、Pocket up-to-face、TechDraw 投影、测量和表达式引用全部改用
TopoRef。
4.3 任务分解
| ID | 任务与交付物 | 前置 | 验收 |
|---|---|---|---|
| TSN-01 | 从基线 FreeCAD 采集拓扑命名、选择和错误行为 | P0 | 30 个模型有输入/输出映射 |
| TSN-02 | 定义 TopoRef、状态和迁移 JSON Schema |
P1 | exact/ambiguous/deleted 均可序列化 |
| TSN-03 | OCCT 历史捕获适配器 | P3 | Pad/Pocket/Boolean 产生 Generated/Modified/Deleted 集 |
| TSN-04 | 规范几何/邻接签名库 | TSN-02 | 相同 B-Rep 重放签名稳定,网格精度变化不影响 |
| TSN-05 | 一对一匹配和评分算法 | TSN-03/04 | 平移、参数编辑和重算保持引用 |
| TSN-06 | 对称/重复拓扑歧义检测 | TSN-05 | 低置信度拒绝错误绑定并给出候选 |
| TSN-07 | 布尔与多实体历史映射 | TSN-03 | Union/Cut/Common 后选择引用可迁移 |
| TSN-08 | 引用持久化、版本迁移和回滚 | FC-02 | 保存/加载后 UUID 与状态不变 |
| TSN-09 | Facade 选择、附着和任务 API 接入 | TSN-02 | React 无内部拓扑 API 导入 |
| TSN-10 | 拓扑黄金回放与随机变异测试 | QA-02 | 100 个黄金模型、1000 次参数变异通过 |
5. 专项二:Sketcher 求解器(SK)
5.1 目标
达到 FreeCAD Sketcher 的约束建模和交互语义:几何创建/编辑、约束、自由度、冗余/冲突诊断、拖拽、外部几何、支持的曲线类型、B-spline、块约束、构造几何、投影和编辑事务。
5.2 技术路线
- 优先将 FreeCAD Sketcher 的
planegcs/相关 C++ 求解器以独立 WASM 模块编译,固定编译器、Emscripten、浮点和异常策略;Bitbybit Facade 只调用类型化求解服务。 - 若某一模块无法直接编译,先做等价 C++/WASM 端口并建立逐案例差异报告;禁止用页面 JavaScript 中的近似求解器冒充兼容。
- 求解 Worker 采用确定性输入排序、固定容差、最大迭代次数和取消点;输出几何、自由度、约束状态、冲突集合、残差和诊断。
5.3 任务分解
| ID | 任务与交付物 | 前置 | 验收 |
|---|---|---|---|
| SK-01 | 采集 Sketcher 几何/约束/快捷键/错误 manifest | P0 | 覆盖所有基线命令和约束类型 |
| SK-02 | 定义 Sketch 文档对象、几何索引和构造标志 | P1 | SQLite/Facade 可往返 |
| SK-03 | 编译 planegcs 求解器 WASM POC | P0-RT | 直线/圆/弧约束结果与 FreeCAD 一致 |
| SK-04 | 确定性求解协议和 Worker 生命周期 | SK-03 | 取消/过期版本不会提交 |
| SK-05 | PARTIAL:点、线、圆、弧可由基础 solver 处理;椭圆、B-spline(次数、控制点、权重、节点、周期标志)已进入深拷贝/持久化领域模型 |
SK-02 | 椭圆/B-spline 求解与编辑器仍依赖 SK-03/SK-10,基础 provider 对其返回明确 unsupported 诊断,不静默计算 |
| SK-06 | 基础约束:Coincident、Horizontal、Vertical、Distance、Angle | SK-04/05 | 自由度和残差黄金一致 |
| SK-07 | 高级约束:Tangent、Equal、Symmetric、Block、Diameter、Radius | SK-06 | 冲突/冗余分类一致 |
| SK-08 | PARTIAL:构造几何标志、外部投影记录、版本化 TopoRef 和 topo-ref DAG 边已进入 Facade/持久化 |
TSN-09 | 上游对象可触发草图分支重算;真实 OCCT 投影、引用迁移 UI 与黄金行为仍待完成 |
| SK-09 | 拖拽、自动约束、约束编辑器和任务面板 | SK-06 | 鼠标/键盘回放与桌面行为一致 |
| SK-10 | B-spline 编辑、节点/权重和约束限制 | SK-07 | 支持范围明确,无静默降级 |
| SK-11 | Sketch 支持 Pad/Pocket/Revolution 和附着面 | TSN-07/DAG-07 | 轮廓修改触发正确重算 |
| SK-12 | Sketch 黄金文件和求解压力套件 | SK-01..11 | 500 个模型、冲突/欠约束/过约束覆盖 |
6. 专项三:Expression 与单位系统(EXU)
6.1 目标
与 FreeCAD Quantity/Expression 语义对齐:单位后缀、复合单位、维度检查、对象/属性引用、Spreadsheet 别名、函数、常量、locale 显示、表达式错误和循环诊断。数据库必须同时保留规范 Quantity 与用户输入表达式。
6.2 技术措施
- 词法、解析、类型检查和求值在独立 Worker 完成;UI 只显示 token、候选和诊断。
- 采用有理数/高精度数值表示可精确保存单位换算;几何内核边界再转换为固定精度浮点。
- 单位注册表包含维度向量、规范单位、别名、比例/偏移转换和显示格式;所有单位表有版本号。
- 表达式解析产生依赖边,和对象 Link 一起进入统一 DAG;禁止通过字符串扫描绕开依赖和循环检测。
- 序列化使用规范 locale(
.小数、显式单位 ID),显示 locale 只在 Presentation 层转换。
6.3 任务分解
| ID | 任务与交付物 | 前置 | 验收 |
|---|---|---|---|
| EXU-01 | 采集 FreeCAD 单位 schema、表达式函数和错误 | P0 | 建立可机器读取清单 |
| EXU-02 | Quantity/Unit/Dimension 类型与 SQLite schema | P1/FC-02 | 长度、角度、面积、体积可往返 |
| EXU-03 | 表达式 tokenizer/parser AST | EXU-01 | 运算符优先级和函数错误一致 |
| EXU-04 | 维度推导、转换和舍入规则 | EXU-02/03 | mm+inch、角度/长度混用按基线拒绝 |
| EXU-05 | 对象属性、Spreadsheet alias 和子形状引用 | TSN-02/DAG-02 | 引用重命名不丢失 |
| EXU-06 | 循环、未知符号、过期引用诊断 | DAG-04 | 错误包含对象/属性/表达式位置 |
| EXU-07 | locale 显示、自动完成和属性编辑器 | EXU-03 | 显示变化不改变规范序列化 |
| EXU-08 | 表达式迁移、导入导出和黄金测试 | FC-05 | 1000 条表达式跨版本一致 |
7. 专项四:依赖 DAG 与重计算(DAG)
7.1 目标
实现 FreeCAD 文档对象的依赖、Touched/Copy/Recompute 状态和事务语义:Link、Expression、子形状、Body/Tip、外部文档和视图依赖都进入统一有向图;重算按稳定拓扑序执行,循环和失败按对象传播。
7.2 技术措施
- 图节点为
DocumentObject的计算版本,边包含 Link、Expression、TopoRef、Container 和 View 依赖类型。 - 每次参数事务生成 immutable snapshot、dirty set 和 recompute generation;使用 Tarjan/Kosaraju 检测 SCC,循环节点不运行几何。
- 调度器按依赖层级把可并行节点分发给 Geometry/Solver Worker;结果带 generation 和输入 hash,只有匹配时提交。
- 一个节点失败不覆盖上一次有效 Shape;下游进入
UpstreamFailed,Report view 可定位根因。 - Undo/Redo 恢复参数、图、状态和 Shape 资源引用;保存只提交已确认版本。
7.3 任务分解
| ID | 任务与交付物 | 前置 | 验收 |
|---|---|---|---|
| DAG-01 | Link/Expression/TopoRef 统一边模型 | TSN-02/EXU-05 | 图可解释每条边的来源 |
| DAG-02 | 对象注册、删除传播和反向索引 | P4-01 | 删除前显示受影响对象 |
| DAG-03 | Touched/Up-to-date/Error 状态机 | P4-04 | 状态转换与 FreeCAD 回放一致 |
| DAG-04 | SCC 循环检测和诊断 | DAG-01 | 循环不进入 OCCT/Sketch 求解 |
| DAG-05 | 稳定拓扑排序和并行层 | DAG-04 | 相同输入顺序可复现 |
| DAG-06 | generation、取消和过期结果丢弃 | P1-03 | 快速连续编辑不回写旧结果 |
| DAG-07 | Body/Tip、容器、Feature 链和支持映射 | DAG-05/TSN-07 | PartDesign 链正确显示 Tip |
| DAG-08 | 失败保留、下游传播和恢复 | DAG-07 | 修复上游后仅重算必要节点 |
| DAG-09 | 事务/Undo/Redo/Autosave 原子提交 | P2-04 | 崩溃恢复不出现半个图 |
| DAG-10 | DAG 可视化、诊断和性能计数器 | DAG-08 | 用户可定位耗时/失败节点 |
| DAG-11 | 1000 对象、长链、宽图、随机图基准 | DAG-01..10 | 记录内存、吞吐、取消和尾延迟 |
8. 专项五:核心业务对象与剩余工作台(WB)
8.1 共通实施规则
每个工作台都必须完成四份资产:workbench-manifest.json(菜单、命令、快捷键、任务面板和前置条件)、对象/属性 schema、Facade API、FreeCAD 黄金回放集。只有页面按钮存在而命令状态、选择过滤、重算和文件兼容未完成时,状态仍为 ui-only。
8.2 工作台分解
| 工作台 | 业务范围 | 主要任务 | 进入条件 |
|---|---|---|---|
| PartDesign | Body、基准、草图、Pad/Pocket、Dress-up、Pattern、Boolean、Additive/Subtractive | PD-01..PD-18:附着、支持面、两长度、Draft、Fillet/Chamfer、Hole、Pattern、Thickness、Tip | SK、TSN、DAG |
| Part | 原语、布尔、管道、阵列、变换、检查/修复、导入导出 | PART-01..PART-16:ShapeBinder、CompSolid、Refine、Make compound、容差和修复 | TSN、DAG |
| Sketcher | 见 SK 专项 | SK-01..SK-12 | Solver WASM |
| Draft | 2D 绘图、尺寸、阵列、图层、Working Plane、BIM 辅助 | DRAFT-01..DRAFT-14:吸附、网格、文本、样条、偏移和参数化 | EXU、DAG |
| TechDraw | 页面、视图、投影、尺寸、模板、SVG/PDF 导出 | TD-01..TD-15:隐藏线、剖视、链接视图、模板兼容和打印比例 | TSN、FC |
| Spreadsheet | 单元格、公式、别名、格式、链接和导出 | SS-01..SS-10:表达式依赖、循环、CSV/XLSX 边界和大表性能 | EXU、DAG |
| Assembly | 组件、连接器、约束、求解、变体、BOM | ASM-01..ASM-16:组件链接、joint solver、装配树、碰撞和导出 | DAG、TSN |
| BIM/Arch | 结构/建筑对象、材料、楼层、墙/梁/窗、IFC | BIM-01..BIM-20:属性集、族、空间、IFC2x3/IFC4 映射和代理 | FC、EXU |
| FEM | 材料、网格、边界、求解器、结果 | FEM-01..FEM-18:网格接口、求解器 WASM 构建、结果场和单位 | EXU、WB 安全门 |
| Mesh | 网格导入、修复、布尔、简化、分析和导出 | MESH-01..MESH-14:法向、非流形、误差、LOD 和大网格 Worker | FC、QA |
| Surface | 曲面创建、偏移、放样、填充、修剪、缝合 | SURF-01..SURF-14:NURBS/BSpline 参数、边界和缝合容差 | OCCT 扩展、TSN |
| CAM | Job、刀具、路径、后处理、仿真和 G-code | CAM-01..CAM-20:刀具库、碰撞、后处理器沙箱、单位和输出黄金 | FEM/Mesh 可选,安全门 |
| Inspection/Measure | 测量、剖切、偏差、标注和报告 | INSP-01..INSP-10:TopoRef 选择、精度、报告和导出 | TSN、EXU |
| 数据/交换模块 | Import、Points、ReverseEngineering、OpenSCAD、IDF、JT、Material、MeshPart | IMP/PTS/RE/OSC/IDF/JT/MAT:格式、单位、颜色、代理、几何转换和往返 | FC、QA |
| 应用/扩展模块 | Start、Help、AddonManager、Cloud、Show、Web | APPMOD/ADDON:最近项目、离线帮助、扩展治理、分享/云和安全边界 | P0 manifest、安全门 |
| Robot/Plot | 机器人、轨迹、运动学、数据绘图和结果输出 | ROBOT-01..12、PLOT-01..06 | DAG、EXU、QA |
| 脚本/宏/桌面通用 | Python 控制台、宏、插件、偏好、自定义、剪贴板、打印、多文档 | SCRIPT/GUI-REST:沙箱、权限、等价 Web 工作流或逐项不支持诊断 | P0 manifest、安全门 |
| 开发/测试模块 | Sandbox、TemplatePyMod、Test、Tux | DEV-01..06:保留开发/自动化等价入口或明确非产品能力 | P0 manifest |
8.3 工作台交付顺序
先完成 PartDesign + Part + Sketcher 的参数化闭环与 FCStd 双向往返,再做 TechDraw/Spreadsheet/Draft/Plot,随后做 Assembly/BIM/Mesh/Surface,最后处理 FEM/CAM/Robot/Inspection、数据交换模块、应用/扩展模块和脚本/桌面通用能力。每个工作台在进入下一层前必须通过对象创建、编辑、重算、撤销、保存、加载和导出七项门禁。
9. 专项六:文件兼容与迁移(FC)
9.1 兼容范围
- FCStd 读取:ZIP 容器、
Document.xml、GuiDocument.xml、BRep/Shape 资源、缩略图、对象属性、Expression、Link、视图状态和未知扩展。 - FCStd 写入:生成 FreeCAD 1.1.1 可打开的最小等价文件;写入前完成 schema、内核和工作台能力检查。
- 项目格式:继续维护
.webcadmanifest、SQLite schema、OPFS 资源包和迁移版本;FCStd 与.webcad不混用语义。 - 交换格式:STEP/IGES/BREP、STL/OBJ/PLY、SVG/PDF、DXF、glTF、IFC、CSV;每种格式记录精度、颜色、单位、拓扑和只读限制。
- 未知对象:保留原始 XML/资源和 proxy Shape,显示兼容报告;禁止执行 FCStd 中的 Python、宏或任意代码。
9.2 任务分解
| ID | 任务与交付物 | 前置 | 验收 |
|---|---|---|---|
| FC-01 | 采集 FCStd 文件结构和 FreeCAD 读写样例 | P0 | 每个核心对象有最小/复杂样例 |
| FC-02 | .webcad/SQLite schema v2 与迁移框架 |
P2 | 迁移可回滚、旧版本可读 |
| FC-03 | ZIP 安全读取、大小/路径/压缩比限制 | FC-01 | zip bomb、路径穿越、恶意 XML 被拒绝 |
| FC-04 | Document/GuiDocument XML 映射 | P4/DAG | 树、属性、视图状态可往返 |
| FC-05 | BRep/Shape 资源读写和精度策略 | P3 | 体积、拓扑数和几何容差有报告 |
| FC-06 | Expression/Unit/Link/TopoRef 序列化 | EXU/TSN/DAG | 保存后可重算或明确 proxy |
| FC-07 | 未知对象/扩展 proxy 和差异报告 | FC-04 | 不丢原始资源、不假称可编辑 |
| FC-08 | STEP/IGES/BREP 导入导出 | PART | 100 个模型几何黄金通过 |
| FC-09 | Mesh/DXF/SVG/PDF/glTF/IFC/CSV 适配 | WB | 单位、颜色、精度和失败诊断正确 |
| FC-10 | FreeCAD↔WebCAD round-trip 测试 | FC-04..09 | 读→改→写→读的语义差异可解释 |
| FC-11 | 大文件、损坏文件和中断恢复 | FC-03 | 2 GB 级别按能力矩阵降级,不崩溃 |
10. 实施阶段与依赖
| 阶段 | 必须完成的结果 | 依赖 | 阶段门 |
|---|---|---|---|
| F0 基线冻结 | FreeCAD 提交/构建容器、Bitbybit/OCCT、Three、SQLite、浏览器、许可证和黄金样例 | 无 | G0:版本、来源、SBOM 完整 |
| F1 Facade/文档核心 | DocumentObject、Property、事务、选择、任务、诊断和 schema | F0 | G1:React 仅能通过 Facade 编译 |
| F2 表达式/单位/DAG | Quantity、Expression、统一依赖图、SCC、重算和恢复 | F1 | G2:1000 对象图和循环/错误黄金通过 |
| F3 稳定拓扑命名 | 历史映射、歧义、安全引用和迁移 | F2 + OCCT | G3:参数编辑/布尔/保存加载引用稳定 |
| F4 Sketcher | Solver WASM、约束、编辑器、外部几何和轮廓输出 | F2/F3 | G4:欠约束/冲突/拖拽/回放通过 |
| F5 Part/PartDesign 闭环 | Body/Tip、基准、特征、附着、DAG、Undo、FCStd | F3/F4 | G5:核心参数化建模闭环 |
| F6 TechDraw/Spreadsheet/Draft | 页面、投影、公式表、2D 参数化 | F2/F3/F5 | G6:核心生产文档可保存导出 |
| F7 Assembly/BIM/Mesh/Surface | 工作台对象、求解/几何和互操作 | F3/F5/F6 | G7:各工作台七项门禁 |
| F8 FEM/CAM/其余模块 | 数值库、后处理器、仿真和明确能力矩阵 | F0/F7 | G8:每个模块 exact/compatible/read-only/proxy |
| F9 发布验收 | 全量回放、跨浏览器、性能、安全、迁移和回滚 | F0..F8 | G9:无未解释的 unsupported 核心路径 |
11. 详细任务包(跨领域共通)
| ID | 任务 | 交付物 | 验收标准 |
|---|---|---|---|
| P0-01 | IN PROGRESS:已固定 FreeCAD 源码提交、原生编译器/依赖版本、无界面 Part 构建脚本与产物哈希;依赖镜像 digest 尚未完成 |
lock、容器、构建日志 | 同一输入产生相同版本信息 |
| P0-02 | 生成 UI/命令/对象/Property/工作台 manifest | JSON manifest | 每条能力有来源和等级 |
| P0-03 | IN PROGRESS:声明式契约、FreeCADCmd driver/比较器和首批 5 个 Part 成功样例已通过;100 个黄金文件与 50 个错误文件尚未达到 |
fixtures、expected | 桌面结果可复现 |
| P0-04 | 固定浏览器能力矩阵和 COOP/COEP | browser matrix | Chrome 最新两个版本有结果 |
| P0-05 | 许可证、供应链、WASM 安全评审 | SBOM、许可证清单 | 无未知二进制和高风险漏洞 |
| API-01 | Facade API 版本化和 JSON Schema | src/facade 合同 |
破坏性变更有迁移和弃用期 |
| API-02 | 统一请求上下文、取消、进度和诊断 | protocol types | 过期结果无法提交 |
| API-03 | 事件溯源与状态投影 | event log/reducer | 刷新后状态可重建 |
| APP-01 | Document/Object/Property 完整模型 | schema + adapter | Data/View、只读、隐藏、枚举、Link 全覆盖 |
| APP-02 | Transaction/Undo/Redo/Autosave 原子化 | transaction service | 崩溃点恢复无半提交 |
| APP-03 | Body/Container/Group/Link/Extension | object types | 树与依赖图一致 |
| GEO-01 | OCCT C++/WASM 构建和版本隔离 | build scripts | 资源、符号、许可证可追溯 |
| GEO-02 | Shape 生命周期、引用计数和 Worker 回收 | handle service | 长会话无不可控增长 |
| GEO-03 | B-Rep→Three 网格、选择和增量缓存 | viewport adapter | 选择不重建无关对象 |
| GEO-04 | 几何精度、容差和确定性 | tolerance policy | 体积/面积/拓扑黄金稳定 |
| QA-01 | 单元/属性/解析器/图算法测试 | tests | 分支和错误分类达标 |
| QA-02 | FreeCAD CLI/GUI 回放对照器 | comparator | 差异含输入、版本、对象和数值 |
| QA-03 | 浏览器 E2E、视觉和几何黄金 | Playwright fixtures | Chrome 能力结果可审计 |
| QA-04 | 性能/内存/取消/恢复压力 | benchmark reports | P95、峰值内存、失败率达门槛 |
| QA-05 | 安全测试和 fuzzing | corpus/reports | 文件、表达式、Worker 消息不可越权 |
12. 每个功能的开发模板
- 在基线 manifest 登记 FreeCAD 命令、对象、属性、选择前置和错误。
- 先写 Facade 类型、请求上下文、诊断和事件,再写 Worker/domain 实现。
- 添加最小成功、失败、取消、Undo/Redo、保存/加载和过期结果测试。
- 建立 FreeCAD 对照 fixture,记录几何容差、单位、拓扑和状态差异。
- 接入 React 页面和 FreeCAD 风格任务面板;页面不直接访问内部实现。
- 更新 SQLite migration、
.webcad/FCStd 映射、兼容矩阵和文档。 - 通过阶段门后才把状态从
experimental提升为compatible或exact。
13. 质量门禁与发布阻断条件
发布必须同时满足:./npmw run verify、Facade-only 依赖守卫、所有核心黄金回放、FCStd round-trip、跨浏览器 OPFS/Worker、几何精度、长会话内存、安全 fuzzing 和许可证检查。下列任一项阻断发布:
- 旧版本/未知对象被静默删除或当作可编辑对象;
- 过期 Worker 结果覆盖新版本文档;
- 子形状歧义被强行绑定;
- Expression 单位错误、循环或 locale 转换被静默吞掉;
- FCStd 读取后保存造成未报告的对象、属性、Shape 或视图丢失;
- 任一页面绕过
BitBybitWebCadFacade导入内部 Worker、OCCT、Three 或 SQLite; - 性能/内存超出能力矩阵而没有明确降级和诊断。
14. 下一轮实际执行顺序
- 使用项目本地 Node 运行时完成 P0-RT、依赖安装和验证,清除引擎警告。
- 继续完成 P0-01/P0-03:在已验证的提交、原生构建和 5 个黄金样例上补齐 digest 锁定构建容器、100 个黄金文件、50 个错误文件和 GUI 回放。
- 实现
DAG-01..DAG-06与EXU-01..EXU-06,让属性修改从“Touched 标记”升级为可解释的依赖重算。 - 实现
TSN-02..TSN-07,再把附着、Pocket up-to-face、测量和 TechDraw 选择切换到TopoRef。 - 编译/验证
SK-03,然后按基础约束→高级约束→编辑器→PartDesign 轮廓的顺序推进。 - 以 PartDesign 核心闭环为第一条完整垂直链,随后完成 FCStd 对象/属性/Shape/视图双向读写和 round-trip。
- 按
TD→SS→DRAFT/PLOT→ASM/BIM/MESH/SURF→FEM/CAM/ROBOT/INSP顺序完成工作台七项门禁。 - 完成 Import/Points/ReverseEngineering/OpenSCAD/IDF/JT/Material、Start/Help/AddonManager/Cloud/Show/Web、Python/宏/插件和桌面通用能力的逐项兼容决策与实现。
- 完成跨浏览器、OPFS 故障、性能/内存、安全 fuzzing、a11y/i18n、PWA、升级回滚、SBOM 和发布差异报告。
15. 完成定义
“完整 FreeCAD 对标”只有在 F0-F9 全部阶段门通过、核心与扩展工作台均有兼容等级、稳定子形状命名/Sketcher/Expression/单位/DAG/重算/FCStd 均有黄金报告、跨浏览器和安全门禁通过,并且发布文档列出所有差异后才能使用。当前仓库仍处于核心 Facade、OCCT 几何和属性编辑的进行中阶段,下一工作目标按第 14 节执行。
完整对标还要求 34 个源码模块和 App/Base/Gui 通用能力全部进入机器可读清册;任何尚未登记的命令、对象、属性、格式、Python/宏/插件入口都会阻断 G9。详细关闭条件见主任务账本第 3、11、13 节。
16. 已实现切片与剩余边界
本轮已完成 EXU-02..EXU-06 的基础版本:Quantity 以 mm/deg 等规范单位保存,表达式支持四则运算、对象属性引用和维度错误;已完成 DAG-01..DAG-06 的领域版本:Link/Expression 边、下游传播、SCC 循环检测、稳定拓扑计划、generation 和 recompute 状态已进入 Facade 与 SQLite schema v3。还未把每个 DAG 节点接入真实 OCCT/Sketcher 计算 Worker,因此当前是可验证的业务调度层,不是完整几何重算。
属性领域合同现覆盖标量、枚举、颜色、Vector、Placement、ObjectLink、ObjectLinkList/StringList 和版本化 SubshapeLink。Placement/Vector 使用结构化值并做有限数、角度范围及非零旋转轴校验,复合值深拷贝进入 Undo/Redo 与持久化。Facade 的对象级几何重算已在 Shape 生成后执行 Placement,并对恒等变换、畸形结构、变换失败释放和最近有效缓存保留给出测试证据;这不是 FreeCAD Body/Tip、Support、AttachmentOffset 或特征局部坐标链的等价实现,File/Shape 摘要和多选 mixed 编辑也仍未完成。
TSN 已完成面/边/顶点量化签名、邻接指纹消歧和匹配 API,并挂接到实际重算 generation。成功 Shape 会产生对象拓扑快照、迁移 matches、signature-fallback/occt-native 历史和 schema v1 ElementMap;提交阶段自动写回 LinkSub 与草图外部几何,稳定引用更新 generation,歧义/删除引用保持显式状态、标脏所有者并产生修复诊断。候选替换 Facade 事务验证当前拓扑和 kind 后原子写入 stable TopoRef,重建 DAG、进入 Undo/Redo;属性面板和诊断页均通过 Facade 调用。schema v7 保存拓扑快照和稳定原生对象标签。Three.js 已支持多对象 Mesh 注册、OCCT analytic 面/边/顶点点击、预选、完整边折线高亮、window/crossing 框选和诊断聚焦闪烁;普通单向 Pad/Pocket/Revolution/Groove 已接入已有 OCCT Generated/Modified/Deleted provider,其余复合模式仍显式回退。
Sketcher 已有 Facade 事务模型和基础求解器适配器:Sketch 几何/约束快照进入 DocumentObjectSnapshot,新增几何、约束和求解会更新 ConstraintStatus、历史、自动保存与 SQLite schema v4;基础约束现覆盖 Diameter、Symmetric、Tangent。该适配器的职责是验证数据模型和提供可替换协议;它不宣称已经等价于 FreeCAD planegcs。SK-03 的 planegcs WASM、SK-07 的完整约束分类、SK-09 的交互回放和 SK-10 的 B-spline 仍是兼容门禁。
Bitbybit 的 OCCT filletEdges 与 chamferEdges 已进入 Geometry Facade,支持全边或显式索引、参数验证、句柄版本和 Worker 隔离。由于 OCCT 瞬时边索引不是持久命名,当前接口仍不能作为 FreeCAD PartDesign 的长期选边引用;必须等 TSN 的边级 TopoRef、历史映射和参数化重算完成后,才能标记为 compatible。
Geometry Facade 还接入了 Bitbybit IO 的 STEP 和 ASCII STL 导出,作为 FC-08/FC-09 的第一条交换格式垂直切片。导出数据仍只代表当前 Shape;对象树、Expression、Sketch 约束、TopoRef 和重算历史必须由 FCStd/.webcad 格式任务独立保存,不能因“能导出 STEP”而宣称参数化文件兼容。
PartDesign Mirrored 已形成 experimental whole-shape 垂直切片:Facade 验证并调用 OCCT 平面法向镜像,文档对象/Task 保存 Base、XY/XZ/YZ 原点平面和 Fuse,重算 union 后释放临时副本并进入 generation 拓扑写回。这不是 FreeCAD 局部特征历史镜像;DatumPlane/Sketch axis/TopoRef 平面、单实体规则、跨 Body 支持和 Mirrored 的原生历史映射仍未完成。
本轮又补齐了拓扑和恢复边界:面之外增加了由 BitBybit 网格端点派生的 edge/vertex 签名,并通过 geometry.topology() 返回面/边/点引用,签名使用量化坐标、长度/端点而不使用面索引;这仍不是 OCCT Generated/Modified/Deleted 历史。FCStd inspection 现在同时生成只读 proxyDocument,对象属性带有 recognized/proxy/blocked 状态;SQLite/OPFS Project API 增加 recovery(documentId),报告完整性、schema、最后保存版本和降级警告。持久化写入现在在支持的浏览器使用 Web Locks 跨标签页互斥,并通过 BroadcastChannel 广播保存版本;无 Web Locks 环境明确报告 local-queue,不能解释为跨标签页安全。代理文档和恢复报告都不能被解释为 FCStd 参数化写回或崩溃恢复已经完成。
17. 本轮后续实现记录与下一批任务
本轮继续执行了重算、文件安全和命令能力三个关键边界。实现与验收必须按下面的定义理解,不能把“接口存在”解释成“FreeCAD 业务已完成”:
| 任务 | 实施措施 | 验证结果 | 剩余边界 |
|---|---|---|---|
| P1-03 / DAG-06 重算执行器 | RecomputeCoordinator 为每次运行分配 generation;后发运行取消前发;节点完成后校验 AbortSignal、文档 ID/版本和当前 generation;结果状态为 completed/failed/cancelled/stale;按 DAG levels 使用 Promise.all 并行执行同层节点,并按稳定计划顺序合并结果和进度;可选的 createFacadeGeometryRecomputeExecutor 在 OCCT Worker ready 时执行真实 Pad/Pocket/Revolution/Fillet/Chamfer |
取消、过期版本、依赖失败传播、独立节点并行、闭合 Sketch 特征链、Revolution 角度/反向和 Facade 提交测试通过 | 默认数据模型仍不持久化 ShapeHandle;Up to face、拓扑历史映射、每节点独立 Worker 和完整 PartDesign 特征仍待实现;失败时缓存保留最近有效 Shape |
| DAG-08 失败/抑制传播 | 上游 error 将下游置为 upstream-failed;Feature 的可持久化 Suppressed 属性将自身置为 suppressed、下游置为 upstream-suppressed,不误报重算失败;抑制时释放缓存 Shape,解除后只重算依赖闭包;重算错误映射为带版本、generation、根因、依赖路径和修复动作的诊断树 |
上游失败、抑制跳过、Shape 释放、保存恢复、根因树、对象定位和解除错误后的最小闭包修复测试通过 | 多配置抑制、Body Tip 重定向、最近有效 Shape 显式回滚和完整 FreeCAD 状态机仍待实现 |
| P4-06 任务提交与重算闭包 | Task 草稿在 Facade 事务内写入 Boolean Base/Tool 等链接;新对象和依赖闭包进入 touched/dirty,React OK 通过 recomputeAsync() 提交并反馈结果;Facade diagnostics 提供根因树和定位/闭包重算/合法抑制修复,Diagnostics 页面只做事件投影 |
Boolean Task 链接/依赖测试、Task dirty 快照、根因路径和修复后诊断清理通过 | Apply 预览仍未持久化临时 Shape;多选选择集、Shape 回滚和完整 FreeCAD Task 校验仍待实现 |
| DAG-07 Body/Tip 与来源链接 | Part Design 特征提交时按来源类型绑定 Profile/Base,更新只读 Body.Tip,并将 Body 与新特征一并纳入 dirty/recompute 闭包;Undo/Redo 恢复 Tip | Pad Task、Body.Tip、Undo/Redo 回归测试通过 | 单实体规则、Tip 抑制/重定向、复杂容器和跨 Body 支持仍待实现 |
| SK-04 求解器边界 | DONE:版本化请求/响应、provider 能力探测、取消/过期 generation 隔离和回放合同已落地 |
基础 provider 回放、并发取消和文档版本过期测试通过 | 当前是基础 TypeScript solver;planegcs-wasm provider 明确报告 unavailable,不虚报 SK-03 完成;高级约束、拖拽、外部几何和 B-spline 未完成 |
| FC-03 ZIP 安全读取 | 先读中央目录再解压;限制 archive/entry/total 字节、压缩比、条目数;拒绝路径穿越、重复路径、加密项、ZIP64 和 XML entity | 缺 Document.xml、路径穿越、压缩炸弹测试通过 | 尚未恢复 BRep/Shape、视图、表达式和参数化对象 |
| FC-04/FC-07 只读报告 | project.fcstd.inspect() 解析 Document.xml 对象声明、Label、属性数量和类型;未知类型为 proxy,Python 类型为 blocked;脚本资源只告警且不执行 |
recognized/proxy/blocked 分类和 Facade-only 测试通过 | metadata-compatible 仅表示 XML 元数据可读,不表示 FCStd 可编辑或 round-trip |
| P2-04 Project list/load | project.list() 暴露 SQLite/内存快照摘要,app.document.load() 将选定快照作为活动 Document 事务恢复,清理旧重算/Shape/Task 状态、保留 Undo 边界并按完整对象图异步重算;Projects 页面按 documentId 调用 Facade API |
列表摘要、保存→修改→加载后属性恢复、选择清空、任务清空和加载重算调用通过测试 | FCStd 导入仍是只读 metadata/proxy;跨文档 ShapeHandle 和 Shape 持久化仍待完成 |
| P2-01/P2-02 Migration/write pressure | schema v7 与统一事务 migration runner;v6 新增对象拓扑快照 JSON,v7 新增稳定原生对象标签;失败 rollback;写队列严格串行并在失败后继续 | migration 排序/跳过/回滚测试、真实 Chrome OPFS v1→v7、标签重开/checkpoint 往返及 1000 次队列压力通过 | 跨发布降级、断电 journal 恢复和用户数据备份仍待完成 |
| P2-03 Resource/recovery fallback | SQLite Worker 在无 OPFS 时使用内存资源表;OPFS 模式增加配额预留、重复内容免写、缺失文件重建和孤儿/零引用/缺失文件对账清扫;Facade 暴露 sweep 报告 | quota/sweep 纯策略、fallback API、Worker 类型检查和生产构建通过 | 真实 OPFS 孤儿清扫、QuotaExceeded、大文件压力及浏览器崩溃注入仍待完成 |
| P2-04 Version checkpoints | 文档规范化保存与完整 JSON checkpoint 同事务;每文档保留最近 5 版;Recovery 列出版本,Facade 可加载指定/最新 checkpoint | 7 版保存后仅保留 3..7、指定版本/最新版加载、过期版本删除和深克隆测试通过 | 当前测试使用 transient fallback;SQLite/OPFS 断电点恢复和保留策略 UI 待完成 |
| PART-07 Shape check | check-shape 使用 Facade geometry.topology() 生成面/边/顶点数量和 SHAPE_CHECK_PASSED 信息诊断;空缓存、空拓扑和 Worker 错误分别返回结构化失败诊断 |
无 Shape、错误选择前置和拓扑调用边界通过测试/构建 | 当前是网格派生拓扑检查,不等价于 OCCT BRepCheck_Analyzer,完整修复建议和自交诊断仍待实现 |
| P1-02 命令准确性 | manifest 仍可完整展示;Part primitive/union/cut/intersection 与 Part Design 核心命令已有 Facade executor;命令状态同时检查工作台和对象类型选择谓词;其余未接入 executor 的命令返回 disabled 与 COMMAND_UNIMPLEMENTED,不再静默完成 |
Part 基本体/布尔 Shape 缓存、选择不兼容时的禁用原因、additive-loft 未实现状态与诊断测试通过 |
其余工作台要逐项增加真实 executor、Task 参数和黄金回放后才能启用 |
| P3-05 Pattern 实验切片 | linear-pattern 和 polar-pattern 通过 Part Design 选择谓词、Task 和类型化属性创建对应对象;Linear 按总 Length 等距平移,Polar 在小于 360° 时覆盖首末角、360° 时不复制重合端点;两者均由 OCCT union 合并并释放临时副本 |
线性间距/方向、圆周完整/部分角度分布、联合输入、句柄释放、非法参数诊断、Base 链接、Body.Tip、属性校验和任务提交回归测试通过 | 当前为 FreeCAD 1.0+ 的 Transform body 近似,只复制整个 Base Shape;未实现 Transform tool shapes、连接单实体过滤、稳定 TopoRef、历史映射、反向轴和引用轴,因此保持 experimental |
| P3-07 MultiTransform 实验切片 | multi-transform 使用结构化有序 Linear/Polar/Mirrored 步骤,Task 与属性面板共用编辑器;重算逐步扩展 whole-shape 实例并最终 union,限制最多 6 步和 100 个组合实例 |
6 实例组合、方向/平面映射、故障注入、中间 Shape 完整回收、最近有效缓存、深拷贝、Undo/Redo、fallback 保存恢复与任务提交测试通过 | 不是 FreeCAD 局部 Transform feature history;未实现特征列表、Datum/TopoRef 轴面、单实体规则与原生拓扑历史,保持 experimental |
| P3-05 Hole 基础切片 | hole 创建 PartDesign::Hole,用 32 边圆形 Profile 或圆锥刀具调用现有 OCCT Pocket/Cut;支持 Diameter、DepthType/Depth、Position/Direction、Reversed、Flat/Angled DrillPoint、DrillForDepth、Tapered/TaperedAngle 以及 Dimension/ThroughAll,校验正尺寸并纳入 Base 链接和 Body.Tip |
圆孔 Profile、有限深度调用、位置/方向、90 度基准锥度、包含钻尖总深度、非法直径/方向诊断、Task 属性提交和 Tip 更新测试通过;Counterbore/Countersink/Counterdrill、Angled drill point 和 Tapered 由 Bitbybit 圆柱/圆锥刀具加 Boolean Cut 组合执行,并有 Chrome 非空 mesh 与 0/0 release 证据 | 仍未实现 Threaded/ModelThread、标准尺寸、Support/Profile 面定位和完整局部特征历史;螺纹保持显式 HOLE_THREADING_UNSUPPORTED,能力保持 experimental |
| TSN-02/05/06/08 TopoRef 基础迁移 | topologyReferences 提供 schema v1 创建、序列化、安全解析、解析和跨版本迁移;重复几何通过邻接指纹唯一消歧,一旧多新不会错误继承;匹配按 kind 隔离并用形状尺度归一化几何评分支持纯平移;对象快照附带 schema v1 ElementMap;新增原生 ElementMap2 v1 token AST/schema v2 writer,以及 StringHasher v1 AST/schema v2 codec |
round-trip、瞬时索引拒绝、resolved/ambiguous/deleted、重复拆分、邻接唯一/对称回归、FaceN/EdgeN/VertexN 写出和持久化通过;FreeCAD 1.1.1 的 30 模型、91 个 ElementMap2、11 个 StringHasher 表完成解析、写回和引用闭合 | Web 拓扑仍不能凭最终几何生成 FreeCAD 私有算法未提供的历史 token/StringID;对称 Boolean 的同构子形需要原生候选证据才能消歧 |
| TSN-08/09 LinkSub 文档接线 | PropertyValue 支持 schema v1 TopoRef;重算 generation 自动迁移 LinkSub/草图外部几何,歧义/删除不强绑;schema v7 保存对象拓扑快照、ElementMap 与稳定原生对象标签;Facade 候选替换事务验证当前同 kind persistentId,重建 DAG 并支持 Undo/Redo;属性/诊断 UI 可替换;Three.js 多 Mesh 场景已将对象/OCCT analytic 面边点拾取、预选、完整曲线折线高亮、诊断闪烁和 window/crossing 框选回调 Facade;Pocket 暴露 UpToFace 槽;Pocket/Groove/Hole/MultiTransform 及双侧线性/角度特征可携带内部 builder 的 STEP/topology/history stage;ElementMap2 writer 可从 MappedNameRef/StringID 证据生成 FreeCAD 1.1.1 token,FCStd reader/writer 会校验 StringHasher 引用闭包 |
非法瞬时索引/候选拒绝、DAG 边、稳定/歧义/删除迁移、邻接消歧、候选替换、Undo/Redo、保存加载、无三角对角线的 BRep 边拾取、多选集合、真实双对象穿越框、诊断聚焦事件、live ElementMap、Pocket 双侧、Revolution/Groove 双角 Chrome 回放及 30 模型 naming-evidence gate 通过 | 未提供逐阶段 Shape/history 或 MappedNameRef/StringHasher 证据的算法继续保守回退;同构子形无唯一原生证据时不宣称 exact |
| TSN-03/07 历史适配器回退 | Bitbybit 1.1.1 绑定仅有 HasGenerated(),没有逐 Shape 的 Generated/Modified/IsDeleted;独立 native provider 已接入普通及双侧 Pad/Pocket/Revolution/Groove 参数路由与既有 Boolean/Pattern/Dress-up 子集;协议新增显式 input/stage、sourceStage/resultStage、一对多 resultIndexes、有序 feature sides 和 rotate stage,可向后兼容旧 object/tool 载荷;stage capture 按各自产生结果解释 index 并以邻接唯一性约束同构候选 |
平移修改、新增/删除/重复面、邻接唯一消歧、跨对象竞争、generation 写回、采集失败隔离、Up-to-face 有效距离、Two sides/Midplane/Two angles 路由通过;Groove 双角按 FreeCAD profile offset + 单 sweep + Cut 得到 native valid 单 solid;30 模型 history/ElementMap2/StringHasher exact gate 与 Facade 182/182 通过 |
provider 仍通过 STEP/BREP 跨 WASM;同构候选和未提供私有 builder/命名证据的算法仍需逐项黄金模型后才能声明 exact |
原生历史 provider 适配器现已进入重算执行器:当 Geometry Worker 暴露 topologyHistory() 且 Base/Tool/Profile 有拓扑快照时,Facade 将真实输入/输出 Shape 和记录交给 captureNativeTopologyHistoryStages(),再由 composeNativeTopologyHistoryLineage() 把上游对象 stage 接入当前关系;普通 Pad/Pocket/Revolution/Groove、Up-to-face 有效长度以及双侧/Midplane/Two angles 会进入同一参数协议。Pocket、Hole、MultiTransform 和双侧 builder 保存中间 STEP/拓扑/记录;Groove TwoAngles 按 FreeCAD 语义保存 rotate -> revolution -> cut 的 BREP/history,并已通过 native BRepCheck Chrome 黄金门。provider 不声明组成 operation 时保留单响应兼容路径。exact 判定仍必须同时拥有逐阶段 Shape/history 与 MappedNameRef/StringHasher 命名证据,任一缺失都不能由最终几何补推。
后续按以下顺序连续开发:
P4-06/DAG-08:同步/异步重算已共享抑制传播和根因诊断语义,并支持定位、解除错误后的最小闭包重算与合法特征抑制;继续补齐多配置抑制、Body Tip 重定向、最近有效 Shape 显式回滚和性能计数器。Shape 缓存已进入 Facade,但尚未持久化。P3-04/P3-05:Pad/Pocket/Revolution/Fillet/Chamfer 已有 OCCT Worker 输入适配和 Shape 缓存回写;Up-to-face 实际距离、Part 双向 Extrude/Revolution、PartDesign Two sides/旧 TwoLengths 与 Revolution/Groove Midplane/Two angles 已进入原生协议,Groove 双角的 FreeCAD 单 sweep 语义和结构有效性已闭合。继续扩展锥度逐阶段 history、局部 feature-list 重算、螺纹/标准尺寸及稳定 Support;未通过黄金 Shape/history 的能力保持 compatible 或 experimental。TSN-03/07/08:TopoRef schema、面/边/点签名、基础迁移和歧义处理已落地;继续补齐 OCCT Generated/Modified/Deleted、邻接/曲率签名、跨布尔历史和数据库属性接线;任何 transient index 不得写入持久引用。SK-03/SK-06/SK-07:编译和验证 planegcs WASM,按基础/高级约束建立 FreeCAD 黄金回放;基础 solver 维持 experimental。P2-04/P2-05/P2-06:完成保存点恢复报告、迁移回滚、配额回收和 BroadcastChannel 单写者冲突。FC-04/05/06/10:增加 XML/Shape/Expression/Link 映射,未知字段原样保留,完成 WebCAD↔FCStd↔FreeCAD 差异报告。P6-03/P8-02:把 disabled 原因、重算进度/取消、FCStd 报告和能力矩阵接入 React,并通过目标浏览器回放和视觉基线。
启用规则:RecomputeExecutionResult.status=completed 只表示已注册节点成功;FCStd metadata-compatible 只表示安全元数据可读;只有 FreeCAD 对照黄金测试、取消/失败/只读、保存/加载和跨浏览器门禁都通过,才能把对象或命令从 experimental 提升到 compatible,exact 还要求锁定版本后的逐项差异为零。
20. 命名证据与系统级 exact 评估(2026-08-09)
运行时命名证据必须来自 native provider 的 MappedNameRef/StringHasher 或逐阶段 builder capture。NativeStageNamingEvidence 对缺失证据写出 final-shape-only,对只有原始表而没有可重建回调的 FCStd 资源写出 opaque-preserved;两者都不能仅凭最终 Shape 生成新 FreeCAD token。跨阶段 ElementMap2 映射保存 sourceStageId、来源集合和 ambiguous 候选,校验失败直接阻断写回。
FreeCADPrivateNamingABI v1 已定义为版本化 Embind/JSON 合同,并接入 direct provider 与真实 Worker:请求携带 operation、输入 STEP、最终 STEP/BRep、阶段 DAG 和原生 history,响应必须同时提供 MappedNameRef、StringHasher 与 ElementMap2,且逐项通过 stage/result 绑定、大小上限、schema、StringID 和引用闭包校验。生产运行时声明 freecad-private-v1-optional-worker,mock 明确为 not-exposed;未导出三项回调、版本/锁定提交不符、证据不闭合或 operation 未声明时均 fail-closed 到 final-shape-only,禁止合成 token。当前仓库随附的 native/occt-history 仍是 OCCT-only artifact,没有链接 FreeCAD 私有实现,因此这里只完成 ABI 与传输边界,不把浏览器实时私有命名提升为 exact。
ABI 输入现同时携带文档 objectId、FCStd 原生正整数 object tag、上一阶段命名证据、明确的 result object/tag 和阶段 DAG;object tag 会从 Document.xml 的 Object.id 导入,按稳定值写回 FCStd,并通过 SQLite schema v7、OPFS 重开和 checkpoint 往返。build:freecad-naming-worker 是独立的 fail-closed 构建入口,只接受锁定提交、Emscripten 3.1.69、wasm Qt/Python、FreeCADBase/FreeCADApp/Part 静态库及三回调 bridge 的哈希清单;普通 build:occt-history 继续是 OCCT-only。check:occt-history-artifact 会实际实例化 WASM 并探测三回调,当前结果为 unavailable,因此 EX-TSN-02=in_progress 与 systemExact=false 保持不变。
Qt 前置条件已按独立、可离线复现的链路落地:build:qt6-wasm-core 使用 Emscripten 3.1.69 构建 QtBase 6.8.2 静态 wasm Qt6Core,下载使用 USTC 国内镜像,但必须先通过 Qt 发布包官方 SHA-256;离线模式缺包时直接失败,不允许回退联网。build:freecad-naming-source-probe 进一步锁定 FreeCAD 提交及 IndexedName.cpp、MappedName.cpp、StringHasher.cpp、MappedElement.cpp、ElementNamingUtils.cpp、ElementMap.cpp、Base/Handle.cpp 七个原始编译单元的内容哈希,并验证它们能与 wasm Qt6Core 一起生成和执行 wasm32 探针。运行时覆盖名称解析、StringHasher 去重/SHA-1 阈值/索引引用、ElementMap 编码/双向查找/历史/保存恢复以及 MappedElement 稳定排序;真实 ElementMap 保存体和 StringHasher 表还会经过 Web 侧 ElementMap2 parser、引用闭包及严格 FreeCADPrivateNamingABI 校验。探针只导出隔离的 freecadNamingCandidate* 名称,持久化流、Python 包装、类型系统、日志和 Application/Document 生命周期仍由适配头提供;FreeCADApp/Part/Python 静态库、真实文档集成、OCCT builder 上下文和生产 bridge 均未链接。因此它证明的是锁定私有源码子集与 ABI 数据可交叉编译/运行,不构成生产命名实现。
check:freecad-private-naming-boundary 同时读取 ABI 合同、兼容性矩阵和 exact 计划,固定校验 shippedWorkerImplementation=not-linked、freecadNamingBuild.status=contract-only、EX-TSN-02=in_progress 与 systemExact=false;该检查已进入默认 verify、真实 wasm lane 和离线 smoke。只有生产 OCCT Worker 实际链接锁定的 FreeCAD 私有静态库/bridge,且制品探针取得三项回调和完整命名证据后,才能在后续批次修改这些状态。
生产 SDK 前置已有完整候选闭包。七个锁定命名编译单元仍保留 libFreeCADPrivateNamingProbe.a 作为源码先决条件;实际 bridge 则链接真实 FreeCADBase/FreeCADApp/Part、QtCore、CPython 及 21 个传递依赖,并初始化真实 App::Application。check:freecad-naming-sdk-readiness 解析所有静态 ar 成员并拒绝宿主 ELF;generate:freecad-naming-sdk-manifest 还锁定 C++20、pthread、兼容头、host adapter 和预加载的 Python wasm stdlib。完整 check:freecad-naming-sdk 对库、源码和运行时文件逐项复算 SHA-256。
隔离 bridge 的 Node 烟测已用真实 ElementMap/MappedName/StringHasher 生成首阶段和链式证据,并验证 $#id:index 与 StringHasher 闭包。独立 pthread OCCT 候选模块进一步在 Node 和真实 Chrome 中执行 OCCT cut history,再从同一 wasm 调用三项 FreeCAD 私有命名回调;Chrome 执行与报告检查分开,检查器会拒绝与当前 JS/WASM/DATA 哈希不一致的旧报告。该候选强制写入 .cache/candidates 且 OCCT_HISTORY_PUBLISH=0,没有替换仓库随附生产 Worker。因此候选 SDK/Worker 验证完成不等于生产链接完成,shippedWorkerImplementation=not-linked、EX-TSN-02=in_progress 与 systemExact=false 仍保持不变。
Sketcher/PartDesign 的 Web 支持范围新增可执行参数合同:Sketcher 覆盖 FreeCAD 1.1.1 FCStd 表面的 9 类 geometry、19 类 constraint 和 10 类 InternalAlignment 语义;PartDesign 覆盖 Facade 已支持的 21 个 family、202 个属性槽和 72 个语义分区,并在对象创建及属性编辑时执行跨字段校验。check:freecad-sketcher-partdesign-abi 会从实现重算这些计数并拒绝陈旧报告;该“完整”限定于 supported Web Facade,不包含尚未实现的 FreeCAD PartDesign TypeId,也不表示 basic TypeScript solver 已求解全部圆锥曲线约束。
逐 feature 等级目前由 config/compatibility-matrix.json 的 facadeCapabilities.geometry.featureLevels 管理:Pad/Pocket/Revolution/Groove/Boolean 为有 native history 子集的 compatible,Fillet/Chamfer/MultiTransform 保持 experimental。systemExactEvaluation.exact 必须在所有 feature 的阶段 Shape/history、私有 token 证据和同构来源都闭合后才允许改为 true;当前值固定为 false,阻断项为私有 FreeCAD token 算法、没有原生 builder stage、以及无唯一同构来源。
21. 全功能 exact 计划(2026-08-09)
全功能对标不再沿用已经 83/83 completed 的 compatible 发布 WBS 作为完成判据。config/freecad-web-exact-parity-plan.json 建立 EX01..EX10、52 项 exact 任务,覆盖 34 模块、15 格式、6 入口,详细依赖和验收见 docs/freecad-full-parity-execution-wbs.zh-CN.md 第 20 节。优先顺序为原生 oracle -> kernel/history/naming -> document/property -> Sketcher/Part/PartDesign -> FCStd/formats -> GUI -> 生产/工程/平台工作台 -> 跨浏览器质量 -> exact 签名发布。
check:freecad-web-exact-parity-plan 与旧 execution-plan gate 一起进入默认 verify。开放任务必须保留 exactBlockedBy,完成任务必须具有已登记的可执行 evidence 且不能继续带阻断项;34 模块和 21 个格式/入口必须逐项映射到任务。最终 EX-REL-01 只有在所有任务完成、34 模块均为 exact、八项零差异指标成立时才允许关闭。当前状态为 1/52 completed,系统仍为 exact=false。
check:freecad-web-exact-promotion 进一步阻止直接编辑 claim.exact 或能力矩阵来“提升”版本:在 exact=false 状态只输出 fail-closed;只有 EX-REL-01 完成并提交结构化 promotion report,报告同时满足 52/52、34/34、八项指标全零和八类证据,才允许 promotion gate 通过。
详细实施手册见 docs/freecad-exact-promotion-runbook.zh-CN.md,报告结构见 config/freecad-web-exact-promotion-report.schema.json。手册按七个阶段规定输入、任务、命令、退出条件和失败回退,防止把规划状态、兼容子集或静态清册当成 exact 证据。
22. 参数 mutation 与阶段命名证据闭合规则(2026-08-10)
EX-ORA-02 的 mutation corpus 由 config/freecad-parameter-mutation-plan.json 定义为五项独立证据:nominal 参数、非法边界、两个以上显式参数快照、真实编辑-重算-恢复事务,以及无差异 FCStd 往返。config/freecad-parameter-mutation-report.json 必须由现有黄金证据生成,check:freecad-parameter-mutations 会逐字节重算并拒绝陈旧或手工提升的报告。当前只有 1/35 family 完整,因此 EX-ORA-02 保持 in_progress。
30 个复合模型的 219 个文档阶段已通过 FreeCAD 运行时 getElementMappedName/getElementIndexedName/getElementHistory 获得直接命名证据,并由两个门禁逐阶段验证。此处的 native-evidence=219/219 不等于内部 builder exact:219 个阶段都有 IndexedName,但只有 74 个阶段的全部子形有 MappedName,145 个阶段只有原生索引身份;当前识别出的 42 个操作阶段仍为 internalBuilderEvidence=0。没有内部 builder Shape/history 时,最终几何不能用于制造中间 Generated/Modified/Deleted;没有实际 StringHasher/MappedNameRef 时也不能制造私有 token;同构候选没有唯一原生来源时继续持久化为 ambiguous。