|
|
|
@ -0,0 +1,703 @@
|
|
|
|
|
|
|
|
# FreeCAD 二次开发笔记(中文)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
本文档记录基于当前 FreeCAD 1.1.1 Windows 开发环境开展二次开发时,一些适合先固定下来的设计约定。目标不是一次把系统做满,而是先把“哪些对象能被识别、哪些对象能参与后续能力”这件事做稳。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 文档范围
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
当前先记录一个很具体、也很关键的方向:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 在 FreeCAD 原生对象体系中,如何表示“端子/接线柱”
|
|
|
|
|
|
|
|
- 如何让系统先把端子识别出来
|
|
|
|
|
|
|
|
- 如何在后期再给端子绑定电气属性
|
|
|
|
|
|
|
|
- 如何约束“只有端子才能进行 3D 接线”
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这份文档偏架构和对象设计,不要求现在就改源码实现全部功能。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 结论先说
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果目标是后续做“带电气语义的 3D 接线”,第一版最推荐的约定是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 端子使用 `Datum CoordinateSystem`(LCS,本地坐标系)表示
|
|
|
|
|
|
|
|
- LCS 原点表示连接点位置
|
|
|
|
|
|
|
|
- LCS 某一根轴表示出线方向
|
|
|
|
|
|
|
|
- 只有被明确标记为端子的 LCS,才允许参与 3D 接线
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
也就是说,第一版可以直接把:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
> 端子 = 被标记过的 LCS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
作为系统约定。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 为什么优先选 LCS,而不是普通点或顶点
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FreeCAD 里可以拿很多东西表示“一个点”,但如果后面要做真正可识别、可约束、可扩展的端子,`Datum CoordinateSystem` 比普通几何点更合适。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
推荐 LCS 的原因:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 有明确的位置
|
|
|
|
|
|
|
|
- 有明确的方向
|
|
|
|
|
|
|
|
- 可以附着到面、边、孔位或其他基准对象
|
|
|
|
|
|
|
|
- 更适合承载后续业务语义
|
|
|
|
|
|
|
|
- 更适合做 3D 接线的起点/终点
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
不推荐直接使用几何顶点作为端子,主要原因是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 拓扑命名不稳定,模型变化后引用容易失效
|
|
|
|
|
|
|
|
- 顶点只有位置,没有天然方向
|
|
|
|
|
|
|
|
- 顶点不适合作为长期挂载业务属性的对象
|
|
|
|
|
|
|
|
- 后期做规则校验和交互约束会比较难
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果只是做纯几何辅助点,`Datum Point` 也能用;但只要目标里包含“出线方向”或“只有端子才能接线”,优先选 LCS。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 原生 FreeCAD 能做什么,不能直接做什么
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FreeCAD 原生能力足够支持下面这些事:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 创建可定位、可附着的基准对象
|
|
|
|
|
|
|
|
- 给对象增加属性
|
|
|
|
|
|
|
|
- 建立对象之间的引用关系
|
|
|
|
|
|
|
|
- 用 Python/C++ 扩展命令、对象和工作流
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
但 FreeCAD 原生并没有现成的 ECAD 级对象体系,例如:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 原生 `Terminal`
|
|
|
|
|
|
|
|
- 原生 `Pin`
|
|
|
|
|
|
|
|
- 原生 `Net`
|
|
|
|
|
|
|
|
- 原生“端子之间自动形成电气连接关系”的对象模型
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
所以比较现实的路线不是“找到现成电气端子对象”,而是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. 先选一个原生对象来承载几何定位
|
|
|
|
|
|
|
|
2. 再通过类型或属性,把它定义成“端子”
|
|
|
|
|
|
|
|
3. 最后在扩展层实现端子的电气语义和接线规则
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 端子的识别策略
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 5.1 推荐的过渡方案
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
第一阶段最实用的做法是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 底层对象类型:`Datum CoordinateSystem`
|
|
|
|
|
|
|
|
- 业务标记属性:`Role = "Terminal"`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这样后续任何工具在扫描文档时,都可以用统一规则识别端子:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. 对象必须是 LCS
|
|
|
|
|
|
|
|
2. 对象必须带有 `Role`
|
|
|
|
|
|
|
|
3. `Role` 的值必须是 `"Terminal"`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这个方案的好处是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 不需要一开始就引入新的底层对象类型
|
|
|
|
|
|
|
|
- 不需要修改 FreeCAD 原生数据结构
|
|
|
|
|
|
|
|
- 对后续升级成自定义对象也兼容
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 5.2 后续更干净的方案
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果后面需求稳定了,可以把过渡方案升级成真正的自定义对象类型,例如:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `MyElectrical::Terminal`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
到那时,工具就不必依赖字符串属性判断,而可以直接按对象类型判断。这个方案更干净,但适合在第一版规则已经验证稳定之后再做。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 推荐的最小属性集合
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果第一版就要为后续电气扩展留好口子,建议端子对象至少预留下面这些属性:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `Role`:固定写 `"Terminal"`
|
|
|
|
|
|
|
|
- `TerminalId`:端子唯一标识
|
|
|
|
|
|
|
|
- `TerminalName`:端子显示名
|
|
|
|
|
|
|
|
- `CanWire`:是否允许参与 3D 接线
|
|
|
|
|
|
|
|
- `DirectionAxis`:约定使用哪根局部轴作为默认出线方向
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果准备继续往电气语义扩展,可以继续补:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `NetName`
|
|
|
|
|
|
|
|
- `VoltageClass`
|
|
|
|
|
|
|
|
- `CurrentLimit`
|
|
|
|
|
|
|
|
- `SignalType`
|
|
|
|
|
|
|
|
- `ConnectorId`
|
|
|
|
|
|
|
|
- `GroupName`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
第一版不一定要全部做完,但建议命名先统一,不然后面会很难兼容旧数据。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 7. 推荐的对象分层
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
为了让系统后面好扩展,建议把端子拆成两层理解。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 7.1 几何层
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
由 FreeCAD 原生对象负责:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 位置
|
|
|
|
|
|
|
|
- 朝向
|
|
|
|
|
|
|
|
- 附着关系
|
|
|
|
|
|
|
|
- 在三维场景中的显示
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这里推荐继续使用 LCS。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 7.2 电气层
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
由二次开发逻辑负责:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 端子编号
|
|
|
|
|
|
|
|
- 网络名
|
|
|
|
|
|
|
|
- 电压等级
|
|
|
|
|
|
|
|
- 电流等级
|
|
|
|
|
|
|
|
- 信号类型
|
|
|
|
|
|
|
|
- 可连接规则
|
|
|
|
|
|
|
|
- 当前连接到了哪些对象
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这样做的好处是,几何层保持稳定,电气层可以渐进增强。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 8. “只有端子才能 3D 接线”的实现约定
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果要做 3D 接线,建议从第一版开始就把选择规则收紧,而不是允许任意点都参与接线。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
推荐规则:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 3D 接线命令的起点必须是端子
|
|
|
|
|
|
|
|
- 3D 接线命令的终点必须是端子
|
|
|
|
|
|
|
|
- 普通顶点、普通草图点、普通边端点不允许直接接线
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
也就是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
> 接线工具只接受“被识别为 Terminal 的 LCS 对象”
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这样做的收益很直接:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 交互更稳定
|
|
|
|
|
|
|
|
- 业务语义更清楚
|
|
|
|
|
|
|
|
- 后期规则校验更容易加
|
|
|
|
|
|
|
|
- 不会把“几何上的点”和“电气上的连接点”混在一起
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 9. 推荐的第一版判断规则
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
后续插件或命令在判断一个对象能不能参与 3D 接线时,可以采用下面这组规则:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. 对象类型是 `Datum CoordinateSystem`
|
|
|
|
|
|
|
|
2. 对象具有 `Role` 属性
|
|
|
|
|
|
|
|
3. `Role == "Terminal"`
|
|
|
|
|
|
|
|
4. `CanWire == true`(如果启用这个属性)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果以上条件不满足,就不允许作为接线端点。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这套规则比“靠对象名称前缀判断”稳得多。名称前缀可以保留为辅助约定,但不建议把它作为唯一依据。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 10. 是否需要专门的端子分组
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
可以有,但建议把它当辅助信息,不要当唯一判定条件。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
例如可以建立一个组:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `ElectricalTerminals`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
然后把所有端子对象放进去。这样做有两个好处:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 方便用户浏览和管理
|
|
|
|
|
|
|
|
- 方便批量检查端子
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
但真正的业务判断,仍建议以“对象类型 + 属性标记”为准。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 11. 一个适合落地的第一版约定
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果现在就要开始做,并且希望后期演进成本低,建议我们先统一以下约定:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 所有端子都使用 LCS 创建
|
|
|
|
|
|
|
|
- 所有端子都必须带 `Role = "Terminal"`
|
|
|
|
|
|
|
|
- 所有端子都应具有稳定的 `TerminalId`
|
|
|
|
|
|
|
|
- 如果对象没有被标记为端子,就不能参与 3D 接线
|
|
|
|
|
|
|
|
- 接线工具只能选择端子对象作为端点
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这一版先解决“识别”和“约束”的问题,后面再逐步加:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 电压/电流/信号属性
|
|
|
|
|
|
|
|
- 网络关系
|
|
|
|
|
|
|
|
- 自动路由
|
|
|
|
|
|
|
|
- 连接合法性检查
|
|
|
|
|
|
|
|
- 端子表和报表输出
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 12. 后续扩展建议
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
等第一版跑顺之后,可以继续往下面这些方向扩展:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 自定义对象类型:把属性式端子升级为真正的 `Terminal` 对象
|
|
|
|
|
|
|
|
- 自定义视图提供器:让端子在三维视图中更醒目
|
|
|
|
|
|
|
|
- 连接关系对象:显式记录“哪个端子连到哪个端子”
|
|
|
|
|
|
|
|
- 规则检查器:检查悬空端子、重复连接、等级不匹配
|
|
|
|
|
|
|
|
- 线束/线缆语义:把单根连接升级为可管理的线束对象
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 13. 当前推荐结论
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
在当前 FreeCAD 二次开发阶段,最适合作为“电气端子”的原生对象是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `Datum CoordinateSystem`(LCS)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
最适合作为第一版识别规则的是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `LCS + Role="Terminal"`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
最适合作为 3D 接线准入规则的是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 只有被标记为端子的 LCS 才能作为接线端点
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这个方案不要求现在就修改 FreeCAD 原生源码,但已经足够支撑后续做一个结构清晰、规则明确的电气端子与 3D 接线系统。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 14. 电气柜与设备装配
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
除了端子与接线,电气柜场景通常还会遇到另一个基础问题:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 是否可以把多个设备模型装配到一个柜体模型中
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
对于这一点,当前 FreeCAD 原生能力是支持的。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 14.1 原生是否支持多设备装配
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
支持。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
当前 FreeCAD 已经提供原生 `Assembly` 工作台,可以用于:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 创建装配
|
|
|
|
|
|
|
|
- 插入外部或已有零部件
|
|
|
|
|
|
|
|
- 建立装配关系
|
|
|
|
|
|
|
|
- 求解装配位置
|
|
|
|
|
|
|
|
- 管理装配层级
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
对于“电气柜 + 多个设备”的典型场景,原生 FreeCAD 可以承担:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 柜体作为总装配基准
|
|
|
|
|
|
|
|
- 断路器、继电器、电源、端子排等设备作为子部件
|
|
|
|
|
|
|
|
- 将多个设备模型放入同一个柜体模型
|
|
|
|
|
|
|
|
- 调整设备的位置和姿态
|
|
|
|
|
|
|
|
- 维护装配结构
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
也就是说,从几何装配角度看,FreeCAD 原生已经具备“把很多设备装进一个电气柜”的能力。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 14.2 原生能力更适合解决什么问题
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
在电气柜场景里,原生装配更适合负责下面这些内容:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 设备模型复用
|
|
|
|
|
|
|
|
- 设备插入与摆放
|
|
|
|
|
|
|
|
- 设备姿态与空间位置控制
|
|
|
|
|
|
|
|
- 装配层级组织
|
|
|
|
|
|
|
|
- 柜体与设备之间的几何关系
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
它比较像一个可靠的三维装配底座。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 14.3 原生不会直接替代的电气语义
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
虽然原生装配能做几何放置,但它并不会天然提供完整的电气柜业务语义,例如:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 自动识别“这是导轨设备”或“这是面板设备”
|
|
|
|
|
|
|
|
- 自动判断安装孔位、导轨、槽位是否符合某类电器安装规则
|
|
|
|
|
|
|
|
- 自动完成电气设备布置规则
|
|
|
|
|
|
|
|
- 自动识别设备的电气连接关系
|
|
|
|
|
|
|
|
- 自动限制哪些点能接线、哪些设备能互连
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
因此,比较现实的路线依然是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. 使用原生装配能力处理几何放置
|
|
|
|
|
|
|
|
2. 在二次开发层补充设备、电气、安装规则等业务语义
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 14.4 推荐的装配思路
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果目标是后续做“电气柜设备布置 + 端子识别 + 3D 接线”,建议按下面这条路线走:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. 柜体模型作为总装配对象
|
|
|
|
|
|
|
|
2. 各类设备模型作为子部件插入装配
|
|
|
|
|
|
|
|
3. 使用 `App::Link` 或装配中的链接对象复用设备模型
|
|
|
|
|
|
|
|
4. 使用 `Placement`、LCS 和装配约束管理设备位置
|
|
|
|
|
|
|
|
5. 在后续扩展层再给设备补安装语义和电气语义
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这样做的优点是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 几何装配先跑通
|
|
|
|
|
|
|
|
- 设备复用能力强
|
|
|
|
|
|
|
|
- 不会把电气逻辑硬塞进几何底层
|
|
|
|
|
|
|
|
- 后续接线与设备属性扩展更容易接上
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 14.5 为什么推荐继续使用 LCS 作为安装基准
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
在装配场景里,LCS 依然很重要。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
推荐做法是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 柜体上定义安装基准 LCS
|
|
|
|
|
|
|
|
- 设备上定义安装基准 LCS
|
|
|
|
|
|
|
|
- 装配时优先让“设备安装 LCS”对齐“柜体安装 LCS”
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这样做有几个明显好处:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 设备摆放规则更清楚
|
|
|
|
|
|
|
|
- 安装方向更明确
|
|
|
|
|
|
|
|
- 后续端子、接线点、设备朝向可以共用同一套基准体系
|
|
|
|
|
|
|
|
- 从“设备装配”过渡到“设备接线”会自然很多
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 14.6 当前推荐结论
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
对于“电气柜中放置多个设备模型”这个需求,当前推荐结论如下:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 原生 FreeCAD 可以做多设备装配
|
|
|
|
|
|
|
|
- 原生 `Assembly` 工作台足够承担柜体与设备的几何装配任务
|
|
|
|
|
|
|
|
- 原生装配适合作为电气柜二次开发的三维底座
|
|
|
|
|
|
|
|
- 电气设备类型、安装规则、接线规则仍建议放在二次开发层实现
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果后续要把这条路线继续收敛成统一约定,可以先把系统拆成下面两层:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 装配层:负责柜体、设备、位置、方向、层级
|
|
|
|
|
|
|
|
- 电气层:负责设备属性、端子属性、连线规则、网络关系
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这样从模型装配到电气语义的演进路径会比较清楚,也更适合逐步落地。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 15. 2D 与 3D 协同的总体思路
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
当前系统并不是“从零做一个既懂 2D 又懂 3D 的全新电气 CAD”,而是更适合拆成两个真相源:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 2D 软件(`D:\project\MingTuCAD\qelectrotech`)负责电气语义
|
|
|
|
|
|
|
|
- 3D 软件(`D:\project\LightWork3D\FreeCAD`)负责三维装配、空间位置与走线表现
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
推荐原则:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 2D 继续作为设备、符号、端子、网络、导线关系的主数据源
|
|
|
|
|
|
|
|
- 3D 不重复发明电气语义,而是读取并绑定 2D 已有语义
|
|
|
|
|
|
|
|
- 2D 与 3D 通过稳定标识进行绑定,而不是靠显示名称猜测
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
一句话概括:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
> 2D 是“电气真相源”,3D 是“空间真相源”。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 16. 为什么优先走数据库绑定,而不是重新解析 XML
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
从 2D 代码看,项目文件虽然是 XML 体系,但 2D/3D 协同所需的数据已经被整理到本地数据库和专用仓储层。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
已经存在的关键入口包括:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 项目运行库表结构
|
|
|
|
|
|
|
|
[projectlocaldatabase.cpp](D:/project/MingTuCAD/qelectrotech/sources/dataBase/projectlocaldatabase.cpp:364)
|
|
|
|
|
|
|
|
- 3D 绑定仓储
|
|
|
|
|
|
|
|
[ThreeDAssemblyRepository.cpp](D:/project/MingTuCAD/qelectrotech/sources/ThreeD/ThreeDAssemblyRepository.cpp:300)
|
|
|
|
|
|
|
|
- 3D 绑定同步服务
|
|
|
|
|
|
|
|
[ThreeDAssemblySyncService.cpp](D:/project/MingTuCAD/qelectrotech/sources/ThreeD/ThreeDAssemblySyncService.cpp:107)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
因此当前推荐:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 不把 XML 作为首选交换接口
|
|
|
|
|
|
|
|
- 优先复用 2D 现有 SQLite/运行库表和同步服务
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这样做的好处:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 标识字段已经存在
|
|
|
|
|
|
|
|
- 2D 端子与导线关系已经能稳定落库
|
|
|
|
|
|
|
|
- 3D 侧只需要读写明确的绑定表,不必重新推断图纸语义
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 17. 2D 侧已经具备的关键数据
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 17.1 设备级数据
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
设备元数据里已经存在与 3D 相关的字段:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `parts_3d`
|
|
|
|
|
|
|
|
- `layout_2d_diagram`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
对应代码:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- [DeviceMeta.h](D:/project/MingTuCAD/qelectrotech/sources/DeviceManager/DeviceMeta.h:32)
|
|
|
|
|
|
|
|
- [deviceeditor.cpp](D:/project/MingTuCAD/qelectrotech/sources/DeviceManager/deviceeditor.cpp:1484)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这意味着 2D 侧已经能表达:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 设备使用哪个 3D 资产
|
|
|
|
|
|
|
|
- 设备关联哪个 2D 布局图
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 17.2 设备端子数据
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
设备端子并不是简单文本,而是已经有结构化表:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `device_circuit_terminals`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
表中已存字段包括:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `tag`
|
|
|
|
|
|
|
|
- `direction`
|
|
|
|
|
|
|
|
- `type_id`
|
|
|
|
|
|
|
|
- `max_wire`
|
|
|
|
|
|
|
|
- `mnemonic`
|
|
|
|
|
|
|
|
- `usage`
|
|
|
|
|
|
|
|
- `max_sec`
|
|
|
|
|
|
|
|
- `min_sec`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
对应代码:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- [deviceterminaleditor.cpp](D:/project/MingTuCAD/qelectrotech/sources/InsertFunction/deviceterminaleditor.cpp:94)
|
|
|
|
|
|
|
|
- [deviceterminaleditor.cpp](D:/project/MingTuCAD/qelectrotech/sources/InsertFunction/deviceterminaleditor.cpp:214)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这说明 2D 侧已经有“端子属性”基础,不需要在 3D 里重新手填。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 17.3 2D/3D 绑定表
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
项目本地库已经定义了下面这些表:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `project_3d_scene_instance`
|
|
|
|
|
|
|
|
- `project_3d_space_object`
|
|
|
|
|
|
|
|
- `project_2d3d_link`
|
|
|
|
|
|
|
|
- `project_2d3d_symbol_binding`
|
|
|
|
|
|
|
|
- `project_2d3d_terminal_binding`
|
|
|
|
|
|
|
|
- `start_end_terminal_matches`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
对应代码:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- [projectlocaldatabase.cpp](D:/project/MingTuCAD/qelectrotech/sources/dataBase/projectlocaldatabase.cpp:364)
|
|
|
|
|
|
|
|
- [projectlocaldatabase.cpp](D:/project/MingTuCAD/qelectrotech/sources/dataBase/projectlocaldatabase.cpp:411)
|
|
|
|
|
|
|
|
- [projectlocaldatabase.cpp](D:/project/MingTuCAD/qelectrotech/sources/dataBase/projectlocaldatabase.cpp:425)
|
|
|
|
|
|
|
|
- [projectlocaldatabase.cpp](D:/project/MingTuCAD/qelectrotech/sources/dataBase/projectlocaldatabase.cpp:446)
|
|
|
|
|
|
|
|
- [projectlocaldatabase.cpp](D:/project/MingTuCAD/qelectrotech/sources/dataBase/projectlocaldatabase.cpp:469)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这些表已经非常接近最终所需接口。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 17.4 2D 已经在生成端子绑定
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`ThreeDAssemblySyncService` 已经会为单个 2D 元件生成端子绑定数据,核心字段包括:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `elementUuid`
|
|
|
|
|
|
|
|
- `terminalUuid`
|
|
|
|
|
|
|
|
- `symbolTerminal`
|
|
|
|
|
|
|
|
- `instanceId`
|
|
|
|
|
|
|
|
- `terminalKey`
|
|
|
|
|
|
|
|
- `connectionPointKey`
|
|
|
|
|
|
|
|
- `wireLabel`
|
|
|
|
|
|
|
|
- `netId`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
对应代码:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- [ThreeDAssemblySyncService.cpp](D:/project/MingTuCAD/qelectrotech/sources/ThreeD/ThreeDAssemblySyncService.cpp:125)
|
|
|
|
|
|
|
|
- [ThreeDAssemblySyncService.cpp](D:/project/MingTuCAD/qelectrotech/sources/ThreeD/ThreeDAssemblySyncService.cpp:159)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这意味着“2D 端子 -> 3D 端子”的映射字段体系,其实已经具备。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 18. 推荐的数据传递方案
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 18.1 设备级绑定
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
设备级建议用 `project_2d3d_symbol_binding` 表表达:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `project_uuid`
|
|
|
|
|
|
|
|
- `source_diagram_uuid`
|
|
|
|
|
|
|
|
- `scene_diagram_uuid`
|
|
|
|
|
|
|
|
- `element_uuid`
|
|
|
|
|
|
|
|
- `instance_id`
|
|
|
|
|
|
|
|
- `device_id`
|
|
|
|
|
|
|
|
- `display_tag`
|
|
|
|
|
|
|
|
- `asset_uri`
|
|
|
|
|
|
|
|
- `host_binding_mode`
|
|
|
|
|
|
|
|
- `host_object_id`
|
|
|
|
|
|
|
|
- `host_object_type`
|
|
|
|
|
|
|
|
- `extra_json`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这一层解决的问题是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 2D 中某个设备实例,对应 3D 中哪个设备实例
|
|
|
|
|
|
|
|
- 这个设备实例使用哪个 3D 资源
|
|
|
|
|
|
|
|
- 它被装配到哪个宿主对象上
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 18.2 端子级绑定
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
端子级建议用 `project_2d3d_terminal_binding` 表表达:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `project_uuid`
|
|
|
|
|
|
|
|
- `source_diagram_uuid`
|
|
|
|
|
|
|
|
- `scene_diagram_uuid`
|
|
|
|
|
|
|
|
- `element_uuid`
|
|
|
|
|
|
|
|
- `terminal_uuid`
|
|
|
|
|
|
|
|
- `binding_key`
|
|
|
|
|
|
|
|
- `symbol_terminal`
|
|
|
|
|
|
|
|
- `instance_id`
|
|
|
|
|
|
|
|
- `terminal_key`
|
|
|
|
|
|
|
|
- `connection_point_key`
|
|
|
|
|
|
|
|
- `wire_label`
|
|
|
|
|
|
|
|
- `net_id`
|
|
|
|
|
|
|
|
- `conductor_uuid`
|
|
|
|
|
|
|
|
- `extra_json`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这一层解决的问题是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 2D 里的哪个端子,对应 3D 里的哪个连接点
|
|
|
|
|
|
|
|
- 当前端子属于哪个设备实例
|
|
|
|
|
|
|
|
- 当前端子所在网络、线号、导线标识是什么
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 18.3 设备与端子的主键约定
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
建议后续统一按下面这组键思考:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 设备主键:`element_uuid + instance_id`
|
|
|
|
|
|
|
|
- 端子主键:`terminal_uuid` 或 `binding_key`
|
|
|
|
|
|
|
|
- 3D 连接点主键:`connection_point_key`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
不要依赖:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 显示名称
|
|
|
|
|
|
|
|
- 标签文字
|
|
|
|
|
|
|
|
- 树节点名称
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 19. 推荐的数据流
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 19.1 从 2D 到 3D
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
推荐主流程:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. 2D 编辑设备、端子、导线和网络
|
|
|
|
|
|
|
|
2. 2D 把设备级绑定写入 `project_2d3d_symbol_binding`
|
|
|
|
|
|
|
|
3. 2D 把端子级绑定写入 `project_2d3d_terminal_binding`
|
|
|
|
|
|
|
|
4. FreeCAD 插件读取这些表
|
|
|
|
|
|
|
|
5. FreeCAD 创建/更新 3D 设备实例、3D 端子对象和连接点绑定
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 19.2 从 3D 回写到 2D
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
推荐回写内容:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. 设备实例的三维位姿写入 `project_3d_scene_instance`
|
|
|
|
|
|
|
|
2. 宿主绑定信息写入 `project_2d3d_symbol_binding`
|
|
|
|
|
|
|
|
3. 端子实际落到哪个连接点,写入 `connection_point_key`
|
|
|
|
|
|
|
|
4. 后续若 3D 连线参与校验,可回写线束/路径附加信息到 `extra_json`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 20. FreeCAD 侧的扩展基础
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FreeCAD 这边不建议第一版就改 C++ 内核,先走 Python 工作台/插件路线更稳。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
当前可直接复用的基础有:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `FeaturePython`:可创建自定义对象
|
|
|
|
|
|
|
|
[FeaturePython.h](D:/project/LightWork3D/FreeCAD/src/App/FeaturePython.h:178)
|
|
|
|
|
|
|
|
- `App::LocalCoordinateSystem / Part::LocalCoordinateSystem`:适合作为连接点
|
|
|
|
|
|
|
|
[Datums.h](D:/project/LightWork3D/FreeCAD/src/App/Datums.h:46)
|
|
|
|
|
|
|
|
- 动态属性机制:可加 `PropertyString / PropertyBool / PropertyLink / PropertyLinkList`
|
|
|
|
|
|
|
|
参考 [ifctree.py](D:/project/LightWork3D/FreeCAD/src/Mod/BIM/utils/ifctree.py:100)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
另外,Assembly 对 LCS/Datum 本身也是认可的:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- [JointObject.py](D:/project/LightWork3D/FreeCAD/src/Mod/Assembly/JointObject.py:1449)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 21. 3D 端子的推荐定义
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
当前推荐把 3D 端子定义成:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
> 一个带 LCS 的语义对象,而不是普通点
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
建议最小结构:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 一个 `FeaturePython` 端子对象,作为语义容器
|
|
|
|
|
|
|
|
- 一个 `Part::LocalCoordinateSystem`,作为几何连接点
|
|
|
|
|
|
|
|
- 一组绑定属性,映射到 2D 端子语义
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 21.1 端子对象最小属性建议
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
建议至少包含:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `ProjectUuid`
|
|
|
|
|
|
|
|
- `SourceDiagramUuid`
|
|
|
|
|
|
|
|
- `ElementUuid`
|
|
|
|
|
|
|
|
- `TerminalUuid`
|
|
|
|
|
|
|
|
- `InstanceId`
|
|
|
|
|
|
|
|
- `TerminalKey`
|
|
|
|
|
|
|
|
- `ConnectionPointKey`
|
|
|
|
|
|
|
|
- `SymbolTerminal`
|
|
|
|
|
|
|
|
- `WireLabel`
|
|
|
|
|
|
|
|
- `NetId`
|
|
|
|
|
|
|
|
- `CanWire`
|
|
|
|
|
|
|
|
- `Status`
|
|
|
|
|
|
|
|
- `OwnerDevice`(`PropertyLink`)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这样它就不再是“一个点”,而是一个:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 有几何位置
|
|
|
|
|
|
|
|
- 有 2D 语义映射
|
|
|
|
|
|
|
|
- 能参与接线规则
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
的端子对象。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 21.2 LCS 的职责
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LCS 只负责:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 连接点位置
|
|
|
|
|
|
|
|
- 连接点姿态
|
|
|
|
|
|
|
|
- 后续装配/连线的几何基准
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LCS 不负责:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 保存全部电气语义
|
|
|
|
|
|
|
|
- 保存网络拓扑
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
电气语义仍建议放在端子对象本身的属性里。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 22. 3D 端子二开实施步骤
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 阶段 1:读绑定,不做自动路由
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
先完成:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. 在 FreeCAD 侧做一个独立工作台或插件
|
|
|
|
|
|
|
|
2. 读取 `project_2d3d_symbol_binding`
|
|
|
|
|
|
|
|
3. 读取 `project_2d3d_terminal_binding`
|
|
|
|
|
|
|
|
4. 为每个 2D 设备创建一个 3D 设备实例
|
|
|
|
|
|
|
|
5. 为每个 2D 端子创建一个 3D 端子对象 + LCS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这一阶段先验证:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 2D 设备能不能在 3D 找到对应设备
|
|
|
|
|
|
|
|
- 2D 端子能不能在 3D 找到对应连接点
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 阶段 2:让 3D 连线只认端子对象
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
下一步完成:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. 3D 连线命令只允许选择端子对象
|
|
|
|
|
|
|
|
2. 端子对象必须带 `CanWire == true`
|
|
|
|
|
|
|
|
3. 连线命令优先读取:
|
|
|
|
|
|
|
|
- `TerminalUuid`
|
|
|
|
|
|
|
|
- `TerminalKey`
|
|
|
|
|
|
|
|
- `ConnectionPointKey`
|
|
|
|
|
|
|
|
- `NetId`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这一阶段的目标是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 把“3D 接线点”升级成“可识别的电气端子”
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 阶段 3:回写绑定状态
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
再往后完成:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. 将设备位姿写回 `project_3d_scene_instance`
|
|
|
|
|
|
|
|
2. 将端子落点写回 `project_2d3d_terminal_binding.connection_point_key`
|
|
|
|
|
|
|
|
3. 将宿主对象关系写回 `project_2d3d_symbol_binding.host_object_id / host_object_type`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这一阶段的目标是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 让 2D 和 3D 之间形成真正稳定的双向绑定
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 阶段 4:再考虑自动路由
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
只有在前 3 个阶段稳定之后,才建议继续做:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 沿机柜/线槽的自动路径
|
|
|
|
|
|
|
|
- 端子与线槽的吸附规则
|
|
|
|
|
|
|
|
- 空间避障
|
|
|
|
|
|
|
|
- 线束与报表联动
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 23. 当前推荐结论
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
对于当前这两套代码,最推荐的路线不是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 在 FreeCAD 里重新造一套电气数据库
|
|
|
|
|
|
|
|
- 或在 3D 端重复维护设备和端子语义
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
而是:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. 继续让 QElectroTech 负责设备、端子、导线、网络等电气语义
|
|
|
|
|
|
|
|
2. 继续使用其现有 `project_2d3d_*` 表和 `ThreeDAssembly*` 服务作为绑定入口
|
|
|
|
|
|
|
|
3. 让 FreeCAD 读取绑定表,把端子做成“带 LCS 的语义对象”
|
|
|
|
|
|
|
|
4. 让 3D 接线、装配、空间走线全部围绕这些绑定对象展开
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
一句话总结:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
> 3D 端子不应只是几何点,而应是“有位置的 2D 电气语义映射节点”。
|