From 8831112b8c9080dc57ca3d52c6a0365bc02cf6c5 Mon Sep 17 00:00:00 2001 From: Zhaowenlong Date: Wed, 20 May 2026 19:16:43 +0800 Subject: [PATCH] =?UTF-8?q?docs/A=E6=96=B9=E6=A1=88FCStd=E8=B5=84=E4=BA=A7?= =?UTF-8?q?=E6=B5=81=E8=BD=AC=E8=AE=BE=E8=AE=A1-zwl-0520?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/2D-3D交换协议.md | 31 +- docs/FreeCAD 二次开发说明.md | 15 + ...子显示连线保存回写开发文档.md | 24 ++ ...6-05-20-freecad-fcstd-asset-flow-design.md | 265 ++++++++++++++++++ 4 files changed, 333 insertions(+), 2 deletions(-) create mode 100644 docs/superpowers/specs/2026-05-20-freecad-fcstd-asset-flow-design.md diff --git a/docs/2D-3D交换协议.md b/docs/2D-3D交换协议.md index b0d1474..ac29600 100644 --- a/docs/2D-3D交换协议.md +++ b/docs/2D-3D交换协议.md @@ -10,7 +10,7 @@ 这些内容统一放在: -- [数据库设计.md](D:\project\LightWork3D\FreeCAD\docs\数据库设计.md) +- [数据库设计.md](D:\LightWork3D\docs\数据库设计.md) --- @@ -317,7 +317,34 @@ 让 FreeCAD 只负责消费结果。 -### 7.4 为什么这里允许同时带 `parts_3d` +### 8.5 `.FCStd` 设备资产支持 + +A 方案下,`.FCStd` 是正式可复用设备资产格式。QET 导出时不需要解析 `.FCStd` 内部内容,只需要把设备资产路径解析成 `resolved_model_path` 交给 FreeCAD。 + +示例: + +```json +{ + "element_uuid": "elem-1001", + "device_id": 123, + "parts_3d": "models/mccb/MCCB_1P.FCStd", + "resolved_model_path": "C:/Users/Admin/Documents/MingTuProject/models/mccb/MCCB_1P.FCStd" +} +``` + +FreeCAD 根据 `resolved_model_path` 的扩展名导入 `.FCStd`,并在导入后的设备组内优先扫描 `Role="Terminal"` 的 LCS 作为模板端子槽位。 + +如果 QET 侧已经在 `device_3d_asset.format` 中保存了资源格式,可以在后续协议中追加可选字段: + +```json +{ + "format": "fcstd" +} +``` + +第一版 FreeCAD 不应强依赖该字段,避免旧版本 JSON 缺少 `format` 时无法导入。 + +### 8.6 为什么这里允许同时带 `parts_3d` 注意: diff --git a/docs/FreeCAD 二次开发说明.md b/docs/FreeCAD 二次开发说明.md index 72656f6..20e8017 100644 --- a/docs/FreeCAD 二次开发说明.md +++ b/docs/FreeCAD 二次开发说明.md @@ -268,6 +268,21 @@ Terminal_P2 这些对象表示模型上 P1/P2 的真实接线位置和方向,但不保存某个工程里的 `terminal_uuid`。项目导入时,FreeCADExchange 再根据 `2d_to_3d.json` 把工程端子 UUID 绑定到模板槽位上。 +### 13.2 A 方案下 zwl 与 FreeCAD 的文件职责 + +A 方案要求 `D:\code\zwl` 支持 `.FCStd` 作为设备 3D 资产格式,但不要求 zwl 解析 `.FCStd` 文件。 + +职责划分如下: + +- zwl/QET:选择 `.FCStd`、复制到工程资产目录、保存到 `device_3d_asset`、导出 `resolved_model_path`。 +- FreeCADExchange:导入 `.FCStd`、扫描模板内 `Role="Terminal"` 的 LCS、创建工程端子对象、保存 3D 装配和手动连线。 + +也就是说,`.FCStd` 内部的端子、LCS、动态属性和装配结构都是 FreeCAD 侧语义;zwl 只把 `.FCStd` 当作一种可流转的 3D 资源文件。 + +详细设计见: + +- `docs/superpowers/specs/2026-05-20-freecad-fcstd-asset-flow-design.md` + ## 14. 电气柜与设备装配 除了端子与接线,电气柜场景通常还会遇到另一个基础问题: diff --git a/docs/FreeCAD 端子显示连线保存回写开发文档.md b/docs/FreeCAD 端子显示连线保存回写开发文档.md index 863d6a3..7208208 100644 --- a/docs/FreeCAD 端子显示连线保存回写开发文档.md +++ b/docs/FreeCAD 端子显示连线保存回写开发文档.md @@ -182,6 +182,29 @@ FCStd 设备模板用于解决“这个模型本身就带端子语义”的问 4. 保存为 `.FCStd` 设备模板。 5. 后续 LightWork3D 工程引用该 `.FCStd` 后,自动识别模板端子并生成工程端子对象。 +### 3.3 A 方案资产流转约定 + +A 方案下,`.FCStd` 是正式可复用设备资产,STEP / STP / STE 只作为模板制作的原始几何输入。 + +完整流转固定为: + +```text +STEP / STP / STE 原始几何 + -> FreeCAD 中添加端子 LCS 和模板语义 + -> 保存为 FCStd 设备模板 + -> zwl/QET 选择该 FCStd 作为设备 3D 资产 + -> 3D 视图导出 2d_to_3d.json + -> FreeCAD 导入 FCStd 并绑定工程端子 + -> 手动连线并保存 scene.FCStd + -> 生成 3d_to_2d.json +``` + +zwl/QET 侧只需要支持 `.FCStd` 的选择、复制、保存和导出路径,不解析 `.FCStd` 内部的 LCS、端子属性或装配结构。`.FCStd` 的内部语义由 FreeCADExchange 读取。 + +详细设计见: + +- `docs/superpowers/specs/2026-05-20-freecad-fcstd-asset-flow-design.md` + ## 4. 为什么要先落地设备模板 这里的“设备模板”不是要求先把所有设备都建完,而是要先有一个稳定样板,证明端子显示和连线可以依附在真实设备上。 @@ -549,4 +572,5 @@ ManualWiring.py - 2026-05-20:补上手动连线对象归属到设备 `QETWires_*` 组,连线树结构现在和设备模板一致;已用单元测试验证。 - 2026-05-20:明确 A 方案:STEP/STP/STE 只作为原始几何输入,正式可复用设备资源统一保存为带 LCS 电气端子的 FCStd 模板;后续设计 `TemplateAuthoring.py` 做模板制作工具。 - 2026-05-20:新增 FCStd 设备模板制作基础能力,支持把模型上的点位创建为带 `Role="Terminal"`、`CanWire=true`、`QetTemplateSlotName` 的模板端子 LCS;已用单元测试验证端子语义写入和模板校验逻辑。 +- 2026-05-20:补充 A 方案资产流转设计,明确 `.FCStd` 为正式设备资产;zwl/QET 只负责选择、保存、导出 `.FCStd` 路径,FreeCADExchange 负责读取 LCS 端子语义并生成工程端子。 ``` diff --git a/docs/superpowers/specs/2026-05-20-freecad-fcstd-asset-flow-design.md b/docs/superpowers/specs/2026-05-20-freecad-fcstd-asset-flow-design.md new file mode 100644 index 0000000..1e68c56 --- /dev/null +++ b/docs/superpowers/specs/2026-05-20-freecad-fcstd-asset-flow-design.md @@ -0,0 +1,265 @@ +# FreeCAD FCStd 设备资产流转 A 方案设计 + +## 1. 设计目标 + +A 方案把 `.FCStd` 定义为正式的 3D 电气设备资产格式。 + +完整链路是: + +```text +STEP / STP / STE 原始几何 + -> FreeCAD 模板制作 + -> 添加端子 LCS 和电气语义 + -> 保存为 FCStd 设备模板 + -> zwl/QET 选择该 FCStd 作为设备 3D 资产 + -> 3D 视图导出 2d_to_3d.json + -> FreeCAD 导入 FCStd 并绑定工程端子 + -> 手动连线并保存 scene.FCStd + -> 生成 3d_to_2d.json +``` + +这个设计解决的问题是:模型文件交给别人、换工程使用、重新打开工程时,端子位置和接线语义仍然跟着模型走。 + +## 2. 职责边界 + +### 2.1 LightWork3D / FreeCAD 负责 + +- 导入 STEP / STP / STE 原始几何。 +- 在模型真实接线位置创建模板端子 LCS。 +- 给模板端子写入: + - `Role = "Terminal"` + - `CanWire = true` + - `QetTemplateSlotName` + - `QetTerminalLabel` + - `QetTerminalType` +- 保存为 `.FCStd` 设备模板。 +- 项目导入时读取 FCStd 模板里的端子 LCS。 +- 根据 `2d_to_3d.json` 把工程级 `terminal_uuid` 绑定到 3D 端子对象。 +- 在 FreeCAD 文档里保存设备位姿、装配状态、端子位置和手动连线。 + +### 2.2 D:\code\zwl / QET 负责 + +- 支持选择 `.FCStd` 作为设备 3D 资产。 +- 将 `.FCStd` 保存到 `device_3d_asset`,格式识别为 `fcstd`。 +- 继续通过 `device_3d_asset.uri` 优先提供 3D 资源路径。 +- 导出 `2d_to_3d.json` 时保持 `parts_3d` 和 `resolved_model_path`。 +- 启动 FreeCAD 并传递: + - `QET_2D_TO_3D_JSON` + - `QET_FREECAD_SCENE_FILE` + +zwl 不解析 `.FCStd` 内部结构,不读取 LCS,不判断端子位置。`.FCStd` 内部端子语义由 FreeCADExchange 读取。 + +## 3. 模板与工程实例的区别 + +### 3.1 FCStd 设备模板保存通用槽位 + +模板中的端子表示“这个设备模型哪里可以接线”,例如: + +```text +电流互感器.FCStd + ModelGeometry + Terminal_P1 + Terminal_P2 +``` + +模板端子保存: + +```text +QetTemplateSlotName = P1 +QetTerminalLabel = P1 +Role = Terminal +CanWire = true +``` + +模板端子不保存: + +```text +QetProjectUuid +QetElementUuid +QetTerminalUuid +QetInstanceId +``` + +### 3.2 工程场景保存真实绑定 + +工程打开 3D 视图后,FreeCAD 根据 `2d_to_3d.json` 创建或更新工程端子对象。 + +工程端子保存: + +```text +QetProjectUuid +QetElementUuid +QetTerminalUuid +QetInstanceId +Role = Terminal +CanWire = true +``` + +这样同一个 FCStd 模板可以被多个工程复用,而不会把某个工程的端子 UUID 写死在模板里。 + +## 4. zwl 侧需要支持的最小改动 + +### 4.1 设备 3D 资产选择 + +`D:\code\zwl\sources\DeviceManager\deviceeditor.cpp` 中的设备 3D 文件选择过滤器需要加入 `.fcstd`: + +```text +3D 文件 (*.fcstd *.FCStd *.step *.stp *.iges *.igs *.stl *.obj) +``` + +提示文案从“STEP/IGES 文件”改成“3D 模型文件”,避免用户以为 FCStd 不是合法资产。 + +### 4.2 格式识别 + +`detect3dFormat(...)` / `normalize3dFormatFromPathInternal(...)` 需要把: + +```text +.fcstd / .FCStd -> fcstd +``` + +写入 `device_3d_asset.format`。 + +### 4.3 资产复制 + +当前设备编辑器选择工程外文件时会复制到工程 3D 资产目录。该流程应继续适用于 `.FCStd`。 + +如果源文件旁边存在 sidecar JSON,可以继续复制;但对正式 A 方案来说,FCStd 内 LCS 是优先来源,sidecar 只作为过渡兼容。 + +### 4.4 导出给 FreeCAD + +`FreeCADExchangeExportService.cpp` 已经导出: + +```json +{ + "parts_3d": "...", + "resolved_model_path": "..." +} +``` + +`.FCStd` 第一版不需要额外字段也能工作,因为 FreeCAD 可从 `resolved_model_path` 的扩展名判断格式。 + +后续可以把 `device_3d_asset.format` 作为可选调试字段导出: + +```json +{ + "format": "fcstd" +} +``` + +但第一版不应让 FreeCAD 依赖这个字段,避免旧 JSON 失效。 + +### 4.5 旧 3D 空间对象入口 + +`qetdiagrameditor.cpp` 里旧的空间对象 STEP/IGES 选择入口属于旧 3D 场景功能。A 方案第一版不建议把它作为设备模板主入口。 + +如果后续仍要用它给机柜、导轨、安装板选择模型,可以单独扩展为: + +```text +空间对象模型 (*.fcstd *.FCStd *.step *.stp *.iges *.igs) +``` + +但它不负责设备端子语义。 + +## 5. FreeCAD 侧需要保持的读取优先级 + +项目导入设备后,端子槽位解析顺序固定为: + +1. FCStd 模板内已有的 `Role="Terminal"` LCS。 +2. STEP 同目录 sidecar JSON。 +3. bbox fallback 临时端子。 + +长期目标是让常用设备都进入第 1 类。第 3 类只用于没有模板时打通流程,不能作为正式端子位置。 + +## 6. 手动连线与保存回写 + +手动连线只允许从工程端子对象连到工程端子对象。 + +连线对象保存在 `scene.FCStd`,第一版不把导线几何路径写入数据库。 + +保存时 `3d_to_2d.json` 只回写最小绑定: + +```json +{ + "schema_version": "1.0", + "project_uuid": "string", + "instances": [ + { + "element_uuid": "string", + "instance_id": "string" + } + ], + "terminals": [ + { + "terminal_uuid": "string", + "instance_id": "string" + } + ] +} +``` + +这符合当前数据库约束:第一版只依赖 `project_2d3d_symbol_binding` 和 `project_2d3d_terminal_binding`,不依赖旧 3D 场景表。 + +## 7. 用户流程 + +### 7.1 制作设备模板 + +1. 打开 FreeCAD。 +2. 导入厂家 STEP / STP / STE 模型。 +3. 在真实接线位置添加端子,例如 `P1`、`P2`。 +4. 执行模板端子校验。 +5. 保存为 `设备名.FCStd`。 + +### 7.2 在 zwl/QET 中使用模板 + +1. 打开设备管理或设备属性。 +2. 选择 3D 资产。 +3. 选择刚制作好的 `.FCStd`。 +4. 保存设备资产绑定。 +5. 在工程中点击 `3D视图`。 +6. zwl 导出 `2d_to_3d.json` 并启动 FreeCAD。 +7. FreeCAD 导入 `.FCStd`,读取模板端子,生成工程端子对象。 +8. 用户选择端子并创建手动连线。 +9. 保存 FreeCAD 工程,生成 `3d_to_2d.json`。 + +## 8. 第一版验收标准 + +- zwl 设备 3D 资产选择框能选择 `.FCStd`。 +- `.FCStd` 能写入 `device_3d_asset`,格式为 `fcstd`。 +- `2d_to_3d.json` 中 `resolved_model_path` 指向 `.FCStd`。 +- FreeCAD 能导入该 `.FCStd`。 +- 模板中的 LCS 端子优先用于工程端子创建。 +- 工程端子对象带真实 `terminal_uuid`。 +- 用户能选择两个端子生成手动连线。 +- 保存 FreeCAD 后生成 `3d_to_2d.json`。 +- 不依赖 `project_3d_scene_instance`、`project_3d_space_object`、`project_2d3d_link`、`start_end_terminal_matches`。 + +## 9. 实施顺序 + +1. 在 zwl 侧补 `.FCStd` 文件过滤、格式识别和提示文案。 +2. 确认 `.FCStd` 资产复制、哈希、保存流程不被阻断。 +3. 确认 `2d_to_3d.json` 能输出 `.FCStd` 的 `resolved_model_path`。 +4. 在 FreeCAD 中用现有 `TemplateAuthoring.py` 制作一个样板设备。 +5. 用该 FCStd 样板设备跑通导入、端子显示、手动连线、保存回写。 +6. 再补更友好的模板端子编辑 UI。 + +## 10. 风险和处理 + +`.FCStd` 无法被 zwl 预览尺寸: + +- 不阻断资产绑定。 +- 尺寸字段可以为空或由后续 FreeCAD 侧读取后回填。 + +模板端子槽位与 2D 端子数量不一致: + +- 第一版按数量顺序匹配可用槽位。 +- 后续再引入显式槽位映射 UI。 + +用户误选普通 STEP: + +- 仍允许导入,但只能走 sidecar 或 bbox fallback。 +- 文档和提示中明确“正式可复用资产推荐 FCStd”。 + +旧空间对象入口和新设备模板入口混淆: + +- 第一版设备端子语义只走设备 3D 资产入口。 +- 旧空间对象入口只作为柜体、导轨、安装板模型入口。