- 数据库:SafeCreateIndex/EnsureColumnExists 防御旧schema;去掉无用PRAGMA user_version;去掉重复throw;清理注释编号 - 剖面盒导出:修复NWF多Model无统一根节点时空白子树泄露(RootItem级隐藏) - 崩溃修复:去掉LayerManagementViewModel中两处Task.Run,消除COM跨线程STA违规 - 重构:SectionBoxExporter新增ExportSectionBoxFromActiveView统一业务入口;LayerManagementViewModel删ExportSectionBoxToNwdAsync;删死代码ExportToJson(Document)/ShowSaveFileDialog - deploy-plugin.bat: powershell→pwsh;AGENTS.md补充编译部署调用说明
4.3 KiB
数据库兼容性 / 剖面盒导出修复报告
修复目标
- 打开旧版本数据库时崩溃(schema 不兼容)
- NWF 多文档剖面盒导出时,无命中子树泄露到导出文件
- 反复剖面盒导出后崩溃(COM 跨线程访问)
问题一:数据库 schema 不兼容导致启动崩溃
现象
打开带有旧版本 .db 文件的模型时,插件初始化报错:
SQL logic error: no such column: DetectionRecordId
根因
CreateTables() 使用 CREATE TABLE IF NOT EXISTS + CREATE INDEX IF NOT EXISTS 组合。旧数据库表已存在但 schema 是旧版(缺 DetectionRecordId 列),CREATE TABLE IF NOT EXISTS 静默跳过,紧随的 CREATE INDEX ... ON ...(DetectionRecordId) 直接炸。
同时 PathDatabase.InitializeDatabase() 还有以下问题:
PRAGMA user_version只写入、从未读取CreateTables()无异常保护BatchQueueItems的ALTER TABLE ADD COLUMN用裸try-catch吞异常PathPlanningManager.DatabaseInitialize()的catch里throw;导致同一错误双重日志
修复
PathDatabase.cs:
- 新增
SafeCreateIndex()方法:建索引前用PRAGMA table_info检查列是否存在,缺列记 warning 跳过,不崩 - 新增
EnsureColumnExists()方法:用PRAGMA table_info检查列,缺了才ALTER TABLE ADD COLUMN,不吞其他异常 - 删除无用的
PRAGMA user_version写入 InitializeDatabase()内用try-catch包裹CreateTables()+EnsurePathRoutesTableExtended(),失败时关闭连接- 清理注释中重复/杂乱的编号
CollisionDetectionRecords建表处加外键依赖注释
PathPlanningManager.cs:
- 去掉
catch后的throw;,外层OnModelsCollectionChanged已有独立日志
问题二:NWF 多文档剖面盒导出时空白子树泄露
现象
NWF 文件引用多个 NWD(各为一个独立 Model),剖面盒只覆盖其中一个子树的元素,导出后其他平行子树仍然出现在 NWD 中。
根因
SectionBoxExporter.CalculateHiddenItems() 通过"兄弟节点算法"确定隐藏项:收集可见项(剖面盒内元素及其祖先)的父节点,隐藏同父节点下的不可见兄弟。当模型有多个平行 RootItem(来自不同 Model)时,完全空白的子树没有任何节点进入 visibleSet,其 RootItem 不会出现在 uniqueParents 中,整棵子树被遗漏。
修复
SectionBoxExporter.GetObjectsAndHiddenItems():
在 CalculateHiddenItems() 之后补一步——遍历所有 document.Models 的 RootItem,不在 visibleSet 中的直接加入 ItemsToHide。SetHidden 会级联隐藏所有后代,无需递归。
问题三:反复剖面盒导出崩溃
现象
连续多次"设置剖面盒 → 导出"操作,前几次正常,后续某次崩溃(无 managed 异常日志)。
根因
LayerManagementViewModel 中有两处不必要的 await Task.Run():
GetObjectsAndHiddenItems()被包在Task.Run中,在后台线程调用 Navisworks COM API(Model.HasGeometry、BoundingBox()等)NwdExportHelper.ExportToNwdWithPrecomputedHiddenItems()同样被包在Task.Run中
Navisworks COM API 要求 STA 线程访问,跨线程调用在少量使用时不崩,多次使用后触发 STA 违规导致进程崩溃。
修复
LayerManagementViewModel.cs:
- 去掉
GetObjectsAndHiddenItems外的await Task.Run()包装,直接在 UI 线程调用 - 去掉
ExportToNwdWithPrecomputedHiddenItems外的await Task.Run()包装,该方法内部已有Dispatcher.Invoke,无需外层再切换线程
涉及文件
| 文件 | 改动 |
|---|---|
src/Core/PathDatabase.cs |
新增 SafeCreateIndex、EnsureColumnExists;InitializeDatabase 加 try-catch;删除 user_version;清理注释 |
src/Core/PathPlanningManager.cs |
去掉 DatabaseInitialize catch 中的 re-throw |
src/Core/SectionBoxExporter.cs |
GetObjectsAndHiddenItems 补空白 RootItem 隐藏逻辑 |
src/Utils/NwdExportHelper.cs |
调试日志(已清理) |
src/Utils/VisibilityHelper.cs |
调试日志(已清理) |
src/UI/WPF/ViewModels/LayerManagementViewModel.cs |
去掉两处 Task.Run |
deploy-plugin.bat |
powershell → pwsh(兼容环境) |
AGENTS.md |
补充编译/部署调用方式说明 |