diff --git a/docs/freecad-full-parity-plan.zh-CN.md b/docs/freecad-full-parity-plan.zh-CN.md index a2a4883..0062fd1 100644 --- a/docs/freecad-full-parity-plan.zh-CN.md +++ b/docs/freecad-full-parity-plan.zh-CN.md @@ -326,10 +326,11 @@ Geometry Facade 还接入了 Bitbybit IO 的 STEP 和 ASCII STL 导出,作为 |---|---|---|---| | 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`,保存错误根因和 dirty 闭包;成功后只提交当前文档版本 | 上游失败和下游跳过测试通过 | 抑制对象、最近有效 Shape、完整 FreeCAD 状态机和 Report 树仍待实现 | +| P4-06 任务提交与重算闭包 | Task 草稿在 Facade 事务内写入 Boolean Base/Tool 等链接;新对象和依赖闭包进入 `touched/dirty`,React OK 通过 `recomputeAsync()` 提交并反馈结果 | Boolean Task 链接/依赖测试、Task dirty 快照和完整验证通过 | Apply 预览仍未持久化临时 Shape;多选选择集、抑制对象和完整 FreeCAD Task 校验仍待实现 | | SK-04 求解器边界 | Sketch 节点通过可替换 executor 求解;冲突/无效约束阻止下游,求解结果作为对象更新返回 | 基础 Sketch solve 与异步对象更新测试通过 | 当前是基础 TypeScript solver,不是 `planegcs` WASM;高级约束、拖拽、外部几何和 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 | -| P1-02 命令准确性 | manifest 仍可完整展示;Part `primitive/union/cut/intersection` 与 Part Design 核心命令已有 Facade executor;其余未接入 executor 的命令返回 disabled 与 `COMMAND_UNIMPLEMENTED`,不再静默完成 | Part 基本体/布尔 Shape 缓存、`linear-pattern` 状态与诊断测试通过 | 其余工作台要逐项增加真实 executor、Task 参数和黄金回放后才能启用 | +| P1-02 命令准确性 | manifest 仍可完整展示;Part `primitive/union/cut/intersection` 与 Part Design 核心命令已有 Facade executor;命令状态同时检查工作台和对象类型选择谓词;其余未接入 executor 的命令返回 disabled 与 `COMMAND_UNIMPLEMENTED`,不再静默完成 | Part 基本体/布尔 Shape 缓存、选择不兼容时的禁用原因、`linear-pattern` 状态与诊断测试通过 | 其余工作台要逐项增加真实 executor、Task 参数和黄金回放后才能启用 | 后续按以下顺序连续开发: diff --git a/docs/web-cad-implementation-plan.zh-CN.md b/docs/web-cad-implementation-plan.zh-CN.md index 051be70..4b1f524 100644 --- a/docs/web-cad-implementation-plan.zh-CN.md +++ b/docs/web-cad-implementation-plan.zh-CN.md @@ -1585,7 +1585,7 @@ P0 基线/治理 | P0-02 运行时版本基线 | `IN PROGRESS` | `config/runtime-baseline.json` 已建立;Three.js 锁定 `0.185.1`,Bitbybit OCCT Worker/OCCT/Base 锁定 `1.1.1` 并记录 WASM SHA-256;FreeCAD 自构建内核仍待锁定 | | P0-03 兼容矩阵 | `DONE` | `config/compatibility-matrix.json` 覆盖 13 个工作台和命令状态 | | P1-01 Facade 最小合同 | `DONE` | `src/facade/types.ts` 定义 App/Gui/Command/Selection/Task/Viewport 合同 | -| P1-02 命令状态和选择前置 | `DONE` | MockFacade 根据工作台、选择对象和命令清单返回 enabled/disabled 原因 | +| P1-02 命令状态和选择前置 | `DONE` | MockFacade 根据工作台、选择对象类型和命令清单返回 enabled/disabled 原因;Part 布尔/检查仅接受 Shape-producing 对象,Sketcher 求解仅接受 Sketch,Part Design 特征拒绝文件夹和无几何对象 | | P1-03 请求上下文、事件和诊断 | `DONE` | 命令事件携带 API 版本、请求 ID、文档 ID/版本和工作台;禁用命令生成结构化诊断 | | P1-05 MockFacadeAdapter | `DONE` | `src/facade/mockFacade.ts`,React 工作区已通过事件投影工作台、选择、文档树和通知 | | P1-06 Facade-only 依赖守卫 | `DONE` | `scripts/check-facade-boundary.mjs`,禁止 UI 绕过入口导入 Three.js/SQLite/OPFS/Worker | @@ -1693,7 +1693,9 @@ DocumentSnapshot 现在区分模型树投影与 `DocumentObjectSnapshot` 真值 | View/Data 分离 | `PASS` | Visibility 等 View 属性提交文档事务但不把几何对象标记 Touched | | 类型控件 | `PASS` | View 标签由 metadata 生成 1 个 checkbox、2 个 enumeration、2 个 numeric、2 个 color 控件 | | Part primitive Task | `PASS` | Part 工作台任务可选择 Box/Cylinder/Sphere/Cone,尺寸和角度草稿写入 `Part::*` 对象属性并进入 OCCT 重算 | +| Part Boolean Task | `PASS` | Union/Cut/Intersection 任务提供 Base/Tool 对象选择槽,链接写入对象依赖图;确认后将新对象及其依赖闭包标记 dirty 并触发异步重算 | | Part Design Task | `PASS` | Pad/Pocket/Revolution/Fillet/Chamfer 任务草稿写入 Length/Type/Angle/Reversed/Midplane/Radius/Distance 属性,确认后仍通过 Facade 历史边界提交 | +| 选择谓词 | `PASS` | 选择 Origin/文件夹后 Part Union/Check geometry 被禁用;选择非 Sketch 对象后 Sketcher Solve 被禁用,并返回可解释原因 | | 校验 | `PASS` | 负 Length、越界 Percent、未知 Enumeration、无效颜色、缺失 Link、只读 Property 在 Facade 拒绝 | | Undo/Redo | `PASS` | Length 42→50 可撤销回 42、重做至 50,Property 和树投影同步 | | SQLite/OPFS | `PASS` | Chrome `sqlite-opfs` 保存 v19 后重新加载 Length=61、Status=Touched、tree state=dirty | diff --git a/src/App.tsx b/src/App.tsx index 2d8fa74..ab52f9d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -360,7 +360,16 @@ function TaskPanel({ workbench, facade, showNotice }: { workbench: Workbench; fa } const currentFeatureField = activeTask?.commandId ? featureFields[activeTask.commandId] : undefined const activeCommand = activeTask?.commandId - return