# FreeCAD 3D 自动布线设计方案 本文档描述 QET / LightWork3D 与 FreeCAD 协同中的 3D 自动布线设计。 当前版本目标不是完整复刻 EPLAN Pro Panel 或 SOLIDWORKS Electrical,而是先完成一个可用的最小闭环: ```text 工程端子 -> 路由路径网络 -> 自动求路 -> 生成 3D 折线导线 -> 可保存到 FreeCAD 文档 ``` ## 1. 设计边界 ### 1.1 当前版本目标 当前版本只要求完成“能够自动布线”: 1. 能识别 FreeCAD 文档中的工程端子。 2. 能从用户指定的线槽、草图、面域创建路由网络。 3. 能在两个端子之间自动生成 3D 折线导线。 4. 能批量处理 QET 导入的导线任务。 5. 能绕开或至少发现明显障碍碰撞。 6. 默认禁止长距离悬空线。 ### 1.2 当前版本不做 当前版本不做以下工程级能力: 1. 不修改 FreeCAD C++ 源码。 2. 不写入或依赖旧 3D 场景数据库表。 3. 不把 3D 位姿、3D 路径点写入数据库。 4. 不做完整线槽容量计算。 5. 不做线径、弯曲半径、线束层叠排列。 6. 不做强弱电隔离、EMC、屏蔽线等电气规则。 7. 不保证达到 EPLAN / SOLIDWORKS Electrical 的完整工程级自动布线效果。 ### 1.3 数据库约束 第一版严格遵守 `docs/数据库设计.md`: 1. 设备绑定只依赖: ```text project_2d3d_symbol_binding: project_uuid element_uuid instance_id ``` 2. 端子绑定只依赖: ```text project_2d3d_terminal_binding: project_uuid terminal_uuid instance_id ``` 3. 3D 端子绑定唯一依据是: ```text terminal_uuid ``` 4. 3D 位姿、装配关系、布线几何以 FreeCAD 文档为准。 ## 2. 总体方案 自动布线不直接在任意 3D 空间里找线,也不会把所有端子任意两两连接。它参考 EPLAN / SOLIDWORKS 的思路,先建立“可走路径网络”,再按 QET 导线任务中的起点端子和终点端子逐条求路。 ```text 端子出线段 -> 进入最近路由节点 -> 在线槽/路由路径网络中求最短路 -> 从路由网络出来 -> 进入目标端子 ``` 路由网络由 `carrier` 组成。一个 carrier 表示一段可走线中心线或辅助路由区域中的一条网格线。 ### 2.1 路由优先级 当前版本按下面优先级处理: 1. `WireDuct`:线槽中心路径,最高优先级。 2. `RoutingPath`:用户画的草图线、Draft Wire、明确选中的路由边。 3. `AuxiliaryPath`:辅助路径,后续扩展使用。 4. `RoutingRange`:选中面生成的辅助路由区域,成本较高,只用于过渡或没有线槽时兜底。 普通机柜、设备外壳、实体边默认不是路由路径。 ## 3. FreeCAD 对象语义 ### 3.1 工程端子 工程端子是可布线起点和终点,必须满足: ```text Role = "Terminal" CanWire = true QetTerminalUuid = <2D terminal_uuid> QetInstanceId = <3D instance_id> QetProjectUuid = ``` 端子空间位置来自 FreeCAD 文档。自动布线使用端子的全局坐标和方向。 ### 3.2 路由路径 Carrier 路由路径对象使用以下语义属性: ```text QetRoutingRole = "RoutingCarrier" QetRouteCarrierKind = "WireDuct" | "RoutingPath" | "AuxiliaryPath" | "RoutingRange" CanRouteWire = true QetProjectUuid = Points = [Vector, Vector, ...] ``` carrier 统一放在: ```text QETWiring 02_Carriers ``` ### 3.3 自动导线 自动生成的导线放在: ```text QETWiring 04_Routed ``` 自动导线语义: ```text RouteType = "AutoSuggested" RouteMode = "Auto" RouteStatus = "Routed" | "CollisionWarning" QetStartTerminalUuid QetEndTerminalUuid QetAutoRouteAlgorithm QetAutoRouteDiagnosticsJson ``` ### 3.4 线槽实体 当用户选择线槽实体并执行“从线槽实体生成中心路径”后: 1. 系统按包围盒长轴生成 `WireDuct` 中心路径。 2. 原线槽实体标记为可穿线路由源。 3. 碰撞检测跳过该线槽实体本身,避免“线在槽内却撞到线槽外壳”的误报。 线槽实体属性: ```text QetRoutingSourceKind = "WireDuct" QetRoutingObstacleMode = "PassThrough" QetRouteCarrierName = ``` ## 4. 算法设计 ### 4.1 路由网络构建 模块: ```text src/Mod/FreeCADExchange/RoutingNetwork.py ``` 构建步骤: 1. 收集所有 `QetRoutingRole = RoutingCarrier` 的对象。 2. 读取 carrier 的 `Points`。 3. 将相同或接近坐标的点合并为图节点。 4. 将相邻点之间的线段建立为图边。 5. 每条边记录所属 carrier,用于计算路径成本。 ### 4.2 最短路算法 当前使用: ```text Dijkstra + bend_penalty ``` 路径成本: ```text edge_cost = segment_length * carrier_kind_factor + bend_penalty ``` 其中: ```text WireDuct = 1.0 RoutingPath = 1.0 AuxiliaryPath = 2.0 RoutingRange = 8.0 ``` 这使算法优先走线槽和明确路由路径,尽量少走辅助面域。 ### 4.3 端子接入 模块: ```text src/Mod/FreeCADExchange/AutoRouting.py ``` 流程: 1. 读取起点端子和终点端子的全局坐标。 2. 按端子方向生成短出线段。 3. 找到距离起点出线点最近的路由节点。 4. 找到距离终点出线点最近的路由节点。 5. 在路由网络中执行 Dijkstra。 6. 将端子出线段、网络路径、终点入线段拼成最终折线。 当前算法名: ```text network-dijkstra-v1 ``` ### 4.4 悬空线策略 当前版本默认: ```text allow_floating_fallback = false ``` 也就是说,如果没有可用路由网络,系统不会生成长距离悬空线,而是提示用户先创建线槽路径、草图路径或辅助路由区域。 调试时可以显式启用 fallback,但正式使用不建议开启。 ### 4.5 障碍物处理 当前版本使用 AABB 包围盒做碰撞诊断: 1. 收集 FreeCAD 文档中的几何对象。 2. 排除端子、carrier、已布线导线、原点辅助对象。 3. 排除标记为 `QetRoutingObstacleMode = PassThrough` 的线槽实体。 4. 检查导线线段是否与障碍包围盒相交。 5. 如果有碰撞,导线状态设为: ```text RouteStatus = "CollisionWarning" ``` 当前版本是“碰撞诊断”,不是完整自由空间避障。 ## 5. 当前已完成 ### 5.1 Python 模块 已实现: ```text src/Mod/FreeCADExchange/RoutingNetwork.py src/Mod/FreeCADExchange/AutoRouting.py src/Mod/FreeCADExchange/AutoRoutingPanel.py ``` 并已加入: ```text src/Mod/FreeCADExchange/CMakeLists.txt src/Mod/FreeCADExchange/InitGui.py ``` ### 5.2 路由网络功能 已完成: 1. 从选中草图线、Draft Wire、明确选中的边创建 `RoutingPath`。 2. 从选中线槽实体生成 `WireDuct` 中心路径。 3. 从选中面生成 `RoutingRange` 辅助路由区域。 4. 清除已生成路由路径。 5. 扫描并统计路由网络。 ### 5.3 自动布线功能 已完成: 1. 两个选中端子之间自动布线。 2. 根据导线任务批量自动布线。 3. 使用 Dijkstra 求路。 4. 支持转弯惩罚。 5. 支持 carrier 类型成本。 6. 默认禁止长距离悬空线。 7. 碰撞检测和 `CollisionWarning` 状态。 8. 自动导线可见显示并保存到 FreeCAD 文档。 ### 5.4 FreeCAD 面板 面板入口: ```text QET模板 -> 3D自动布线 ``` 当前按钮: ```text 扫描端子/网络 从线槽实体生成中心路径 从线槽/草图创建路由路径 从选中面创建辅助路由区域 测试布线选中两个端子 按导线任务自动布线全部 清除自动布线 清除走线路径 保存 ``` ### 5.5 测试 已完成单元测试: ```text tests/python/freecad_exchange_auto_routing_test.py ``` 覆盖: 1. 无路由网络时默认拒绝悬空线。 2. 显式调试 fallback 时生成正交路径。 3. 优先使用用户路由网络。 4. 优先使用 `WireDuct`,降低 `RoutingRange` 优先级。 5. 从选中面生成辅助路由区域。 6. 选中整个实体不会把所有外壳边转成路径。 7. 从线槽实体生成中心路径。 8. 线槽实体不作为自身路径碰撞障碍。 9. 碰撞状态标记。 10. 批量导线任务缺端子时跳过。 11. 清除路由路径不删除已布线导线。 已完成 FreeCAD smoke: ```text tests/manual/freecad_auto_routing_smoke.py ``` ## 6. 当前使用流程 ### 6.1 单条导线自动布线 ```text 1. 打开 FreeCAD 工程 scene.FCStd 2. 进入 QET模板 -> 3D自动布线 3. 清除走线路径 4. 选中线槽实体 5. 点击“从线槽实体生成中心路径” 6. 必要时选草图线或 Draft Wire,点击“从线槽/草图创建路由路径” 7. 必要时选背板/门板面,点击“从选中面创建辅助路由区域” 8. 选中两个工程端子 9. 点击“测试布线选中两个端子” ``` ### 6.2 批量导线自动布线 前提: 1. QET 导出的 `2d_to_3d.json` 中包含 `wires[]`。 2. 每条导线包含: ```text start_terminal_uuid end_terminal_uuid ``` 3. FreeCAD 文档中存在对应 `QetTerminalUuid` 的工程端子。 操作: ```text 1. 创建线槽/路由网络 2. 点击“按导线任务自动布线全部” ``` 注意:批量自动布线的依据是导线任务,不是“所有端子自动互连”。如果文档中只有端子而没有 `wires[]` 或 `QETWiring_01_Tasks`,系统不能判断哪些端子应该连接。 ## 7. 当前限制 当前版本可完成自动布线原型,但仍有以下限制: 1. 线槽实体中心线生成基于包围盒长轴,不理解真实线槽开口、盖板和内部空间。 2. 多根线会沿同一路径生成,暂未做并行错位排列。 3. 未计算线槽填充率和容量。 4. 未考虑线径、最小弯曲半径。 5. 未做强弱电分槽、线缆类型隔离。 6. 障碍检测基于 AABB,存在误报和漏报。 7. 辅助路由区域是网格近似,不等于专业软件的完整布线区域建模。 8. 端子出线方向依赖端子 LCS 方向;如果模板端子方向不准,自动布线会受影响。 9. 导线几何当前保存在 FreeCAD 文档,不作为第一版数据库字段回写。 ## 8. 后续需要完成 ### 8.1 近期优先级 1. 线槽语义库 ```text WireDuct: centerline width height inlet/outlet usable_area cover_state ``` 2. 多根线错位排列 ```text 同一路径上的多根导线按 lane_offset 排列 避免完全重叠 ``` 3. 线槽容量和填充率 ```text 按线径估算截面积 计算 duct fill ratio 超过阈值给出警告 ``` 4. 端子出线规则 ```text 根据端子 LCS 方向、设备安装面、接线孔方向生成更合理的短出线段 ``` ### 8.2 中期能力 1. 真实几何碰撞检测 从 AABB 升级到更精确的 Shape / BRep 碰撞检测,降低误报。 2. 弯曲半径约束 根据线缆类型和线径控制转弯半径。 3. 线束对象 把多根同路导线抽象成 bundle,并支持展开显示。 4. 规则约束 支持: ```text 强电 / 弱电隔离 PE 线优先路径 屏蔽线规则 不同电压等级分槽 禁布区域 ``` 5. 更智能的线槽识别 根据对象名称、尺寸比例、设备库语义自动识别线槽,而不完全依赖用户选择。 ### 8.3 长期能力 1. 接近 EPLAN / SOLIDWORKS 的工程级路由器。 2. 完整导线长度统计。 3. 自动生成线束报表。 4. 2D / 3D 导线一致性校验。 5. 自动推荐线槽路径和线槽容量。 6. 多柜体、多门板、多安装板之间的跨区域路由。 7. 可视化布线诊断面板。 ## 9. 验收标准 当前版本验收只看“能否自动布线”: 1. 文档中有至少两个工程端子。 2. 文档中有至少一条 `WireDuct` 或 `RoutingPath` carrier。 3. 选择两个端子后执行单线测试布线,能生成 `AutoSuggested` 导线。 4. 存在导线任务时执行“按导线任务自动布线全部”,能批量生成 `AutoSuggested` 导线。 5. 生成导线在 `QETWiring_04_Routed` 下可见。 6. 没有路由网络时不生成长距离悬空线。 7. 没有导线任务时,批量布线明确提示缺少连接关系。 8. 明显碰撞时状态为 `CollisionWarning`。 9. 保存 FreeCAD 文档后,自动导线和路由网络仍保留。 ## 10. 开发验证命令 单元测试: ```powershell D:\FreeCAD-1.1.1\bin\python.exe -m unittest discover -s tests\python -p "freecad_exchange*_test.py" ``` 真实 FreeCAD smoke: ```powershell D:\FreeCAD-1.1.1\bin\python.exe tests\manual\freecad_auto_routing_smoke.py ``` 语法检查: ```powershell D:\FreeCAD-1.1.1\bin\python.exe -m py_compile src\Mod\FreeCADExchange\AutoRouting.py src\Mod\FreeCADExchange\RoutingNetwork.py src\Mod\FreeCADExchange\AutoRoutingPanel.py ```