feat: recompute geometry after document load
This commit is contained in:
@@ -331,7 +331,7 @@ Geometry Facade 还接入了 Bitbybit IO 的 STEP 和 ASCII STL 导出,作为
|
||||
| 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 |
|
||||
| P2-04 Project list/load | `project.list()` 暴露 SQLite/内存快照摘要,`app.document.load()` 将选定快照作为活动 Document 事务恢复,清理旧重算/Shape/Task 状态并保留 Undo 边界;Projects 页面按 documentId 调用 Facade API | 列表摘要、保存→修改→加载后属性恢复、选择清空、任务清空测试通过 | FCStd 导入仍是只读 metadata/proxy;跨文档 ShapeHandle 和恢复后自动几何重算仍待完成 |
|
||||
| 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-03 Resource/recovery fallback | SQLite Worker 在无 OPFS 的浏览器中使用内存资源表,保留 SHA-256 身份和引用计数;恢复报告区分数据库完整但目标文档缺失的 `unavailable`;销毁 Worker 时清空临时资源 | Worker 类型检查、生产构建通过 | 内存资源会随刷新丢失;配额回收、持久资源校验和大文件压力仍待实现 |
|
||||
| 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 缓存、选择不兼容时的禁用原因、`linear-pattern` 状态与诊断测试通过 | 其余工作台要逐项增加真实 executor、Task 参数和黄金回放后才能启用 |
|
||||
|
||||
@@ -1595,7 +1595,7 @@ P0 基线/治理
|
||||
| P2-03 OPFS 资源管理 | `IN PROGRESS` | Worker 已提供 SHA-256 内容寻址、`bitbybit-assets` 目录、引用计数、读取和释放;浏览器验证通过,配额治理、垃圾回收扫描和大资源压力仍待补齐 |
|
||||
| Worker memory resource fallback | `PASS` | Worker 在 SQLite WASM 无 OPFS 时使用 transient content-addressed resource map,保持 `put/get/release` 引用计数语义;不再把资源 API 错误地绑定到 OPFS |
|
||||
| P2-04 自动保存调度 | `IN PROGRESS` | `ProjectAutosaveScheduler` 在 Facade 文档事务后按空闲窗口合并最新版本,显式 Save 仍立即写入;`project.recovery(documentId)` 已提供 SQLite/内存完整性、最后保存版本和警告报告,崩溃点检测和用户可配置策略仍待补齐 |
|
||||
| Document list/load/recovery transaction | `PASS` | `project.list()` 从 SQLite/内存快照返回 documentId、版本、对象数、dirty/readOnly 和更新时间;`app.document.load(documentId)` 通过 Project Facade 恢复快照,取消旧重算、释放缓存 Shape、清空选择/任务并提交可撤销的活动文档;Recovery 对“数据库完整但目标快照不存在”返回 `unavailable`,工程管理页按真实 ID 打开 |
|
||||
| Document list/load/recovery transaction | `PASS` | `project.list()` 从 SQLite/内存快照返回 documentId、版本、对象数、dirty/readOnly 和更新时间;`app.document.load(documentId)` 通过 Project Facade 恢复快照,取消旧重算、释放缓存 Shape、清空选择/任务、提交可撤销的活动文档并按完整对象图异步重算;Recovery 对“数据库完整但目标快照不存在”返回 `unavailable`,工程管理页按真实 ID 打开 |
|
||||
| P2-05 多标签页写入协调 | `DONE (降级可观测)` | `SqliteProjectPersistence` 在保存和资源写入外包 `navigator.locks` 独占锁,成功保存通过 `BroadcastChannel` 广播文档版本,Facade 暴露 `project.subscribeExternalChanges()`;无 Web Locks 的运行时能力标记为 `local-queue`,不宣称跨标签页互斥 |
|
||||
| P5-01 Three.js 视口适配器 | `IN PROGRESS` | `src/facade/threeViewport.ts` 使用 `three@0.185.1`,已挂载 WebGL2 场景和资源释放;React 视口通过 Facade OCCT 预览链生成 Pad/Pocket Mesh |
|
||||
| P3-01 Bitbybit OCCT WASM 运行时 | `IN PROGRESS` | 精确锁定 `@bitbybit-dev/occt-worker@1.1.1`,专用 Worker 可加载 34,524,750 字节 OCCT WASM;尚未建立 FreeCAD/OCCT 自构建脚本,不能标记完成 |
|
||||
|
||||
@@ -472,6 +472,7 @@ export function createMockFacade(): BitBybitWebCadFacade {
|
||||
clearFeatureShapes()
|
||||
const document = cloneDocumentSnapshot(loaded)
|
||||
commit({ ...state, document, selectedObjectId: '', task: null })
|
||||
await recomputeDocumentAsync({ dirtyObjectIds: document.objects.map((object) => object.id) })
|
||||
notify(`Loaded ${document.label}`)
|
||||
return getState().document
|
||||
}
|
||||
|
||||
@@ -683,6 +683,7 @@ test('project persistence remains behind the facade contract', async () => {
|
||||
facade.app.document.setProperty({ objectId: 'pad', propertyName: 'Length', value: 61 })
|
||||
const restored = await facade.app.document.load('doc-pump-housing')
|
||||
assert.equal(restored?.objects.find((object) => object.id === 'pad')?.properties.find((property) => property.name === 'Length')?.value, 55)
|
||||
assert.equal(restored?.recompute?.status, 'completed')
|
||||
assert.equal(facade.selection.getObjectId(), '')
|
||||
assert.equal(facade.task.getActive(), null)
|
||||
assert.equal(facade.project.capabilities().mode, 'sqlite-memory')
|
||||
|
||||
Reference in New Issue
Block a user