|
|
|
@ -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 资产入口。
|
|
|
|
|
|
|
|
- 旧空间对象入口只作为柜体、导轨、安装板模型入口。
|