@ -126,6 +126,45 @@ terminal_uuid
导线规格、颜色、线耳等导线数据由 QET 提供, FreeCAD 第一版只消费和保留,不在 3D 侧重新发明导线主数据。
#### 1.4.4 空机柜和未装配状态的处理
自动布线必须基于 FreeCAD 文档中的真实 3D 位姿。左侧树目录中存在设备、线槽或导轨,只表示对象已经导入,并不表示它们已经装配到机柜内,也不表示已经形成可走线的路径网络。
因此,下面状态不能用来判断自动布线最终效果:
1. 设备、端子排、小型断路器仍停留在导入位置,尚未摆到导轨或安装板上。
2. 线槽、导轨尚未贴到机柜背板或安装板。
3. 安装板、柜内空间或柜体没有作为柜内边界/布线区域参与识别。
4. 没有生成 `WireDuct` 、`RoutingRange`、`UserPath` 或 `TerminalAccess` carrier。
当前 FreeCAD 自动布线预检会把这些前置状态显式报告出来:
```text
路径网络: 0 段
布线源:未识别到线槽/布线面/用户路径
柜内边界:未标记
```
点击自动布线面板中的 `检查布线准备度` 后, FreeCAD 还会在树目录 `QETWiring_05_Diagnostics` 下写入一个 `RoutingPreflight` 诊断对象。该对象会保存 `QetProjectUuid` ; `QetDiagnosticOk` 表示本次诊断是否通过;`QetDiagnosticIssueCodes` 直接列出问题码;`QetDiagnosticIssueLabels` 直接列出中文问题标签;`QetDiagnosticMessage` 保存中文摘要;`QetDiagnosticJson` 保存压缩后的最新预检结果,包括导线任务数量、工程端子数量、路径网络段数、布线源摘要、柜内边界摘要、导线样式库状态、问题码 `issue_codes` 、缺失端点样例等。重复检查时旧的 `RoutingPreflight` 会被替换,只保留最新一次结果。
`RoutingPreflight` 还会附带 compact 路径网络诊断。若已标记 `CabinetInterior` ,但主路径 carrier 或工程端子越出柜内边界,预检报告会直接追加 `route_carriers_outside_boundary` 或 `terminals_outside_boundary` ,并在中文摘要中给出“越界路径”或“越界端子”样例。这样用户在生成导线前就能发现装配态问题。
预检的端点缺失示例会同时显示导线标签和端子对,例如 `导线 N4111, terminal-start -> terminal-missing` 。这用于第一时间判断问题来自哪条 QET 导线任务、哪个端子 UUID 没有绑定到 FreeCAD 工程端子。
看到这类提示时,应先完成最小装配闭环,再测试布线结果:
```text
安装板/背板
-> 导轨
-> 线槽或用户主路径
-> 真实 QET 设备实例
-> 工程端子
-> 布线路径网络
-> 自动布线连接
```
如果现场本来没有线槽, 也需要用草图、Draft 线或线段定义柜内主路径,并点击 `选中路径作为用户路径` ,让它生成 `UserPath` carrier。否则算法没有可走的主网络, 只能报告缺少路径网络。
### 1.5 设备脚号与 3D 脚点绑定方案
设备脚号与 3D 脚点绑定分成两层:模板槽位绑定和工程端子绑定。
@ -199,6 +238,37 @@ QET 侧还需要保证导线任务中继续提供:
其中导线规格、颜色、线耳等导线主数据以后由 `wire_style_id` 或等价字段回查 QET。
当前自动布线已经支持第一版导线样式渲染:`wires[].wire_style_id` 对应 QET 项目数据库 `wire_properties.id` 。FreeCAD 可通过自动布线 options 中的 `wire_style_database_path` 、`2d_to_3d.json` 顶层 `wire_style_database_path` ,或环境变量 `QET_WIRE_PROPERTIES_DB` ,打开项目 SQLite 数据库并查询 `wire_properties` 。查询时优先匹配当前 `project_uuid` ,读取到的样式会保存到已生成导线对象的 `QetWireStyleJson` 和 `QetRouteDiagnosticsJson.wire_style` 。
如果 `2d_to_3d.json` 没有显式提供数据库路径, FreeCAD 导入交换文件时会尝试扫描 JSON 同目录下的 `.sqlite / .sqlite3 / .db` 文件;只有确认数据库中存在 `wire_properties` 表时,才会自动写入 `wire_style_database_path` 。导入完成后,`_qet_exchange_summary.wire_style_database_path` 会记录最终使用的路径;自动布线面板摘要、批量布线 report、compact 诊断和中文报告都会显示“导线样式库:< 路径>”,便于检查 FreeCAD 是否识别到样式库。这是 FreeCAD 侧便利推断,不要求 QET 修改输出协议。
第一版使用字段如下:
```text
wire_properties.id -> wires[].wire_style_id
wire_properties.name -> 样式名称,写入诊断
wire_properties.line_color -> FreeCAD 导线显示颜色,支持 #RRGGBB / RRGGBB / 0xRRGGBB / #AARRGGBB / 0xAARRGGBB / 十进制颜色整数 / rgb(...) / 逗号 RGB / 常见英文色名; ARGB 的 alpha 暂不参与线颜色
wire_properties.line_type -> FreeCAD 导线线型,支持 Solid / DashLine / DotLine / DashDotLine 等常见写法
wire_properties.line_width -> FreeCAD 视图线宽,优先使用
wire_properties.diameter_mm -> line_width 缺失时作为显示线宽回退
wire_properties.area_or_spec -> 导线规格文本,写入诊断;当 line_width 和 diameter_mm 都缺失时,支持从 2.5mm2 / 2.5mm^2 / 2.5mm² 等文本估算显示线宽
```
查到样式后, FreeCAD 除了保存完整 `QetWireStyleJson` ,还会把常用字段展开到导线对象属性,方便在 FreeCAD 属性面板中直接查看:
```text
QetWireStyleName -> 样式名称
QetWireSpecText -> 导线规格文本
QetWireColorText -> 原始颜色文本
QetWireLineType -> 原始线型文本
QetWireType -> 导线类型
QetWireFormat -> 导线格式
QetWireDiameterMm -> 直径
QetWireLineWidth -> 显示线宽
```
如果查不到样式,导线仍按默认蓝色显示,并在导线对象 `QetWireStyleStatus` 与 `QetRouteDiagnosticsJson.wire_style_status` 中写入 `Missing` ;查到样式时写入 `Resolved` 。批量布线报告会汇总 `wire_style_status_counts` ,中文报告会提示“导线样式:缺失 N 条”,并带上第一条缺失样例,例如“示例导线 N2 样式 404”。已解析样式会进入批量 `routes[].wire_style` 和 compact `route_samples[].wire_style` , compact 诊断也会输出 `missing_wire_style_samples[]` , `route_samples[]` 会保留 `wire_style_id` 和 `wire_style_status` ,方便定位是哪条线缺少样式。这个状态由 FreeCAD 根据查询结果生成,不要求 QET 新增字段。如果导线存在碰撞告警,颜色仍会被红色告警覆盖,但线宽可以继续使用样式值。当前这是“视图线宽/颜色”的渲染,不是带真实半径的 3D 圆管导线。
### 1.6 区域与批量排布方案
#### 1.6.1 设备区域/柜内区域
@ -303,14 +373,14 @@ QetTerminalUuid = local:<instance_id>:<slot>
QetTerminalBindingMode = local
```
这类端子只有空间槽位,没有 2D 电气语义,不能直接用于批量导线任务。正式布线前需要执行“检查/绑定工程端子”。系统会根据导线任务中的 `start/end_terminal_uuid` 、`start/end_instance_id` 、`start/end_element_uuid` 和端子显示号,在对应 3D 设备下查找 local 端子或模板槽位;匹配成功后写入:
这类端子只有空间槽位,没有 2D 电气语义,不能直接用于批量导线任务。正式布线前需要执行“检查/绑定工程端子”。系统会优先 根据导线任务中的 `start/end_terminal_uuid` 、`start/end_element_uuid` 和端子显示号,在对应 3D 设备下查找 local 端子或模板槽位;如果任务或 `devices[]` 中已有 `instance_id` ,只作为 FreeCAD 侧辅助定位信息使用,不作为第一版 QET `wires[]` 的必填字段。 匹配成功后写入:
```text
QetTerminalUuid = < QET terminal_uuid >
QetTerminalBindingMode = qet
```
如果导线任务缺少实例定位信息 ,或 QET 端子显示号与模板槽位名称不一致,绑定会跳过并给出诊断。
如果导线任务缺少 `element_uuid` 、找不到对应 3D 设备 ,或 QET 端子显示号与模板槽位名称不一致,绑定会跳过并给出诊断。
### 3.2 路由路径 Carrier
@ -330,9 +400,11 @@ Points = [Vector, Vector, ...]
QetRouteSourceName = < FreeCAD source object name >
QetRouteSourceLabel = < FreeCAD source object label >
QetRouteSourceKind = "WireDuct" | "RoutingRange" | "WiringCutOut" | "UserPath" | "TerminalAccess"
QetRouteSourcePathIndex = "1" | "2" | ...
```
这些属性只用于 FreeCAD 文档内部刷新和清理,不写入数据库,也不要求 QET 提供。
其中 `QetRouteSourcePathIndex` 主要用于同一个草图拆成多条 `UserPath` 时区分第几条源路径,便于诊断和路径示例回溯。只有同一源对象生成多条 `UserPath` 时才保留该序号;草图刷新后只剩单条路径时会清空旧序号。最终导线的 `QetRouteTrackJson` segment carrier payload 和公开 `carrier_payload()` 都会同步输出 `source_path_index` ,便于导出诊断 JSON 后直接定位源草图路径。批量布线中文报告的“路径示例”在存在序号时会显示为 `源路径标签(路径1)` 、`源路径标签(路径2)` 这类格式;普通单路径不写该字段,因此不会显示 `(路径1)` 。
carrier 统一放在:
@ -543,19 +615,125 @@ QetWiringCutOutBridgeExtensionMm = 20.0
生成导线的 `QetRouteTrackJson` 会记录实际经过的 carrier。carrier 如果来自线槽、过线孔、支撑面或端子接入源对象, route track 中还会保留 `source_name` 、`source_label`、`source_kind`,用于手动测试时追踪“这段线实际走过哪个 3D 源对象”。route track 同时记录 carrier 的 `capacity` ,用于后续核对多根线共路、容量偏好和绕行行为。
生成导线对象的树目录 Label 会尽量包含导线标识、起终点端子和状态,例如 `N4111: terminal-start -> terminal-end (Routed)` 或 `N4111: terminal-start -> terminal-end (CollisionWarning)` 。这里的端点优先使用 FreeCAD 端子对象 Label; 在 QET 导入端子中通常就是 `terminal_uuid` 。这样手动测试截图时,可以直接从树目录定位是哪条 QET 导线、哪两个端子以及当前状态。
单根导线对象会写入 `QetRouteIssueCodes` 和 `QetRouteIssueLabels` ,用于汇总这根线自身的问题。当前会把长接入、碰撞/安全间隙、路径兜底、容量压力、柜内越界和候选入口碰撞风险映射成与批量诊断一致的问题码,例如 `long_terminal_access` 、`collision_warnings`、`route_quality_warnings`、`route_capacity_pressure`、`route_candidate_boundary_violations`。`QetRouteDiagnosticsJson.issue_codes` 和 `issue_labels` 会保存同一份数组,便于导出 JSON 后按单线筛选。
为了让手动测试不用每次展开 `QetRouteTrackJson` ,单根导线对象会同步写入 `QetRouteSourceLabels` 和 `QetRouteCarrierNames` 。`QetRouteSourceLabels` 优先显示源对象标签,例如线槽、黄色草图路径或用户路径标签;同一个源草图拆成多条 `UserPath` 时会显示为 `源路径标签(路径2)` 这类格式。`QetRouteCarrierNames` 保留实际经过的 carrier 对象名,便于在树目录中进一步定位。完整数组也会写入 `QetRouteDiagnosticsJson.route_source_labels` 和 `QetRouteDiagnosticsJson.route_carrier_names` 。
如果导线实际走过自动桥接边,`QetRouteTrackJson` 中对应段会记录 `is_bridge=true` ,并汇总 `bridged_segments` 。批量布线报告和诊断对象中的 route sample 会优先使用这个本路线实际桥接数量;旧诊断缺少该字段时,再回退到整张路径网络的桥接数量。自动桥接段是虚拟连通边,不代表真实线槽截面,因此不参与容量最小值计算,也不参与共路 lane 计数、路径复用惩罚、真实 carrier 类型汇总、诊断样例 carrier 列表和路径质量提示。
批量生成布线连接后,面板/控制台报告会从第一条可追踪路径中提取一条“路径示例”,显示导线经过的源对象标签,便于快速确认线路是否进入了预期线槽、过线孔和支撑面。路径示例会跳过 `is_bridge=true` 的虚拟桥接段,避免把自动补出来的连通边误显示成真实线槽或用户路径。
批量生成布线连接后,面板/控制台报告会从第一条可追踪路径中提取一条“路径示例”,显示导线经过的源对象标签,便于快速确认线路是否进入了预期线槽、过线孔和支撑面。如果某个 carrier 没有 `source_label` / `source_name` ,路径示例会回退显示 carrier 自身的 `label` / `name` ,避免手动创建或旧版本 carrier 完全无法定位。 路径示例会跳过 `is_bridge=true` 的虚拟桥接段,避免把自动补出来的连通边误显示成真实线槽或用户路径。
批量布线报告还会汇总本批次路线中使用到的路径网络特征:如果路线依赖相邻/投影主路径自动桥接,报告会显示自动桥接段数;如果主动避障时屏蔽了穿过障碍包围盒的网络边,报告会显示避障屏蔽段数。这里采用路线中的最大值展示,避免多条导线共用同一网络时重复累加。
一键执行“生成布线连接”时,系统会在更新路径网络后附带一份 `routing_path_network_diagnostic` 摘要到批量报告中。即使用户没有单独点击路径网络检查,报告也会显示“路径网络检查提示”,把空路径网络、路径对象几何无效、仅使用布线面兜底、端子局部路径无效、端子接入过长等问题带出来。
中文报告会区分 `布线布局空间` 和 `当前路径网络` 。前者表示本次操作中新生成或刷新的 carrier 数量,因此已有线槽路径复用时可能显示线槽路径 0 条;后者来自实际构建的路径网络 `route_network_carrier_kind_counts` ,会显示当前参与求路的 `WireDuct / WireDuctOpenEnd / UserPath / TerminalAccess / RoutingRange` 等总数。判断是否识别到线槽或用户路径时,以 `当前路径网络` 和 `路径采用` 为准。
`RoutingConnectionBatch.QetDiagnosticJson.route_samples[]` 会保留少量导线样例。每个 route sample 除了基础导线、端子、路径来源和 network 数据外,还会同步写入 `access` 、`collision_summary`、`quality`、`capacity`、`boundary` 等状态分组,字段口径与单根导线对象属性一致。这样手动测试后即使不逐根选中导线,也可以直接从诊断对象 JSON 看出样例线是否存在长接入、穿模/安全间隙、路径兜底、容量压力或柜内越界。
每个 route sample 还会保留 `wire_object_label` ,其值与 FreeCAD 左侧树目录中生成导线对象的 Label 一致,例如 `N4111: terminal-start -> terminal-end (CollisionWarning)` 。当用户把诊断 JSON 发回开发侧时,可以用这个字段直接对应到树目录里的导线对象,减少反复按 UUID 查找。
各类 warning sample 也会尽量保留 `wire_object_label` ,包括接入距离、路径质量、候选入口碰撞风险、柜内边界、路径约束、容量压力和碰撞样例。这样不论问题来自哪一类诊断,都可以用同一个字段回到 `QETWiring_04_Routed` 下定位导线。
中文报告会区分“定位类示例”和“统计类提示”:碰撞示例、缺失端点示例优先显示 `wire_object_label` ,方便在 FreeCAD 树目录中直接查找;导线样式缺失、路径示例、总量统计等仍使用短导线号,避免一行报告被完整对象 Label 拉得过长。
`route_samples[]` 不是简单截取前几条导线,而是优先保留带 `issue_codes` 的问题路线;问题数量相同或没有问题时,再按原生成顺序保留。这样当一次布线有很多正常线、少量异常线时,压缩诊断对象仍会优先给出异常样例,避免手动测试复制 JSON 后看不到真正需要处理的导线。
一键执行“生成布线连接”时,系统会在更新路径网络后附带一份 `routing_path_network_diagnostic` 摘要到批量报告中,并会按诊断建议先生成必要的 `UserPath` 桥接。脚本或调试场景直接调用 `route_eplan_connection_tasks()` 时,也会先执行同一类诊断桥接,保证任务入口和面板入口都优先尝试把孤立线槽接入端子主网络。直接从 QET payload 生成批量布线时,如果发现导线已经生成但没有使用线槽、`UserPath` 或过线孔主路径,也会自动补一次路径网络诊断,并把线槽未接入端子主网络、桥接建议等根因写回同一份批量报告。即使用户没有单独点击路径网络检查,报告也会显示“路径网络检查提示”,把空路径网络、路径对象几何无效、仅使用布线面兜底、端子局部路径无效、端子接入过长、端子越出柜内边界、路径越出柜内边界等问题带出来。如果路径源本身越出 `CabinetInterior` ,批量报告会额外显示“越界路径:< 路径标签> N 个越界点”,便于直接定位错误的线槽中心线或 `UserPath` 。如果工程端子越出边界,批量报告会显示“越界端子:< 端子对象/UUID> N 个越界点”,便于直接定位未装配到柜内的设备端子。
真实工程中路径 carrier 数量可能达到数百个,入口候选组合会直接影响批量布线耗时。第一版保留单根布线的 `network_entry_candidate_limit` ,同时在批量布线中增加 `batch_network_entry_candidate_limit` ,默认按更保守的候选数求路,避免 `入口候选 x 出口候选 x 导线数量` 过度放大。批量入口候选还增加了总量保护 `batch_network_entry_total_candidate_limit` ,当前默认值为 6; 它会限制单根导线最终参与组合评分的入口/出口候选总量,避免“距离候选 + 柜内候选 + 避障候选”叠加后把一次布线放大成几十次 Dijkstra 求路。缺路径重试仍可以按 `missing_route_retry_candidate_limit` 临时放宽候选数量,但正常批量路径优先受总上限保护。批量布线还会复用本次已构建的基础路径图,避免每根导线重复构建同一套网络;碰撞障碍物也会先收集成候选缓存,再按每根导线的端点设备和端点附近规则过滤,避免重复扫描数千个模型对象。当前批量默认采用性能优先的 `batch_avoid_obstacles=false` :不额外构建障碍过滤图,但仍会在生成后做碰撞诊断并输出 `collision_warnings` ;需要更激进避障时再开启批量障碍过滤。相关参数会写入 `RoutingConnectionBatch.QetDiagnosticJson.batch_network_entry_candidate_limit` 、`batch_network_entry_total_candidate_limit`、`batch_avoid_obstacles` 和 `batch_obstacle_candidates` ,便于手测时确认当前性能保护是否生效。
线槽接入主网络采用保守桥接策略。当前 `adjoining_duct_tolerance` 默认只允许 5mm 内的相邻端点或端点到主路径中段投影自动桥接,不会为了让线槽被使用而把远距离线槽强行接到布线面或端子接入网络。这样可以避免误把柜内无关路径连成一个错误网络。若诊断出现 `wire_ducts_without_terminal_access / 线槽未接入端子主网络` ,第一版推荐用户显式添加 UserPath、线槽开口或桥接路径; 诊断会在 `bridge_suggestion` 中给出建议连接的两段 carrier、最近点和距离。面板已提供 `按诊断建议生成桥接` ,用于先刷新诊断再按明确建议生成桥接;也提供 `选中两路径生成桥接` ,用于在用户选中的两个路径 carrier 最近点之间生成一段 `UserPath` 。这两个能力都属于半自动路径网络编辑,不会扫描全柜并自动连接所有远距离线槽。对于 UserPath 端点正好落在线槽中段的 0mm 接入,路径图会把被接入的线槽段在该点切开并并网,避免视觉上已经接触但路径组件仍被诊断为孤立。
孤立路径网络诊断只针对可行动的路径组件。线槽、UserPath、过线孔、辅助路径和端子接入如果分成多个组件, 会继续输出 `isolated_network_components` ;但纯 `RoutingRange` 布线面孤岛只作为兜底网格保留在 `components` 明细中,不再单独触发“存在孤立路径网络”问题码。这样可以避免真实工程中安装板/布线面网格被误当作主路径断网问题,手测时优先处理线槽、用户路径和端子局部接入。
端子接入过长属于质量告警,不等同于路径断开。`terminal_access_max_distance` 控制是否允许生成端子接入;`terminal_access_warning_distance` 只控制超过多长时提示 `long_terminal_accesses` 。当该值为 0 时继续沿用默认自动阈值;在较大机柜或端子到线槽本来就有较长局部出线的场景,可以把警告距离设置为 700mm 等工程可接受值,以减少误报,同时仍保留最大接入距离作为硬限制。
为了减少手动测试时反复展开属性查 JSON, `3D 布线连接` 面板提供 `汇总布线诊断` 。它读取 FreeCAD 文档中最新的 `RoutingPreflight` 、`RoutingPathNetwork`、`RoutingConnectionBatch` 三类诊断对象,按诊断类型合并状态、中文消息和 `issue_codes` ,输出一个总的“通过/未通过”摘要,并刷新 `RoutingDiagnosticSummary` 对象。所有这类诊断对象都会把问题码同步写到 `QetDiagnosticIssueCodes` ,把中文问题标签同步写到 `QetDiagnosticIssueLabels` ,方便在属性面板中直接查看;完整明细仍保留在 `QetDiagnosticJson` 。汇总诊断会从诊断 payload 中提取 `runtime_version` ,优先采用 `RoutingConnectionBatch` 的版本号,没有批量布线结果时再回退到预检或路径网络版本,便于确认当前工程是否加载了最新运行模块。该汇总不重新生成路径、不重新布线,也不访问 QET 或修改数据库;它只是把 FreeCAD 已保存的诊断状态集中显示并固化到诊断树中,便于把一次装配/布线测试的问题快速分成“准备不足、路径网络问题、批量布线问题”三类。
当最新 `RoutingConnectionBatch` 存在时,汇总诊断会把它视为最终诊断入口。若批量报告中已经内嵌 `routing_path_network_diagnostic` ,则不再要求额外存在独立 `RoutingPathNetwork` 诊断对象;同样,也不会因为用户没有单独执行 `检查布线准备度` 而把一次完整批量布线误判为失败。这样面板既支持完整流程,也支持现场更常用的简化流程:直接 `生成布线连接` 后点击 `汇总布线诊断` 。
如果汇总时发现旧版诊断对象存在但 `QetDiagnosticJson` 为空,会追加 `diagnostic_json_empty / 诊断 JSON 为空` 。这类对象不能证明当前布线状态有效,应重新运行对应诊断或重新生成布线连接,让新版本写入完整 `QetDiagnosticJson` 。
汇总诊断还会扫描 `QETWiring_04_Routed` 下的已生成导线。如果发现旧版 `RoutedConnection` 缺少单线 `QetRouteDiagnosticsJson` ,会追加 `routed_wire_diagnostics_missing / 导线诊断缺失` ,并给出一条导线 Label 示例。这能区分“模型里看得到线”和“这条线具备当前版本碰撞、柜内边界、路径质量等诊断数据”。
旧版批量诊断对象可能没有 `issue_codes` ,但会保留 `route_status_counts` 、`skipped_missing_terminal` 和 `missing_endpoint_samples` 。汇总诊断会从这些旧字段反推出 `routing_errors` 、`missing_terminals` 和 `missing_endpoints` ,并在中文摘要里显示“结果状态:错误 N 条,缺失端子 N 条”。这样用户重新打开旧工程时,不会因为旧诊断缺少新版字段而误以为没有布线错误。
如果单线 `QetRouteDiagnosticsJson` 存在但无法解析为合法 JSON, 会追加 `routed_wire_diagnostics_invalid / 导线诊断 JSON 无效` 。这类对象同样不能作为当前版本诊断依据,需要重新生成布线连接,让 FreeCAD 重新写入完整单线诊断。
当导线因为缺少布线路径网络被跳过时,批量报告会显示一条“缺路径网络示例”,包含导线号、起终点端子标签和已记录的失败原因。这里既包括整份文档没有有效路径段,也包括路径网络存在但该导线两端无法连通、端子接入距离阈值过小等情况。手动测试时可先按该示例定位设备两端附近是否缺线槽、`UserPath`、过线孔或布线面路径,或判断是否需要调整端子接入距离。
当最终导线虽然布通、但起点或终点到主路径入口距离超过警戒阈值时,批量报告会显示“接入距离提示”,列出触发导线数量、一条导线样例及起点/终点接入距离。这个提示不阻止生成导线,用于暴露设备附近缺少局部路径、主路径离端子过远或端子接入距离设置过大的情况。批量诊断 JSON 也会记录 `route_entry_distance_warning_count` 和 `route_entry_distance_warning_samples` ,便于导出后定位全部样例。
批量 `issue_codes` 会把缺端子原因从样例提升到顶层:`missing_device_binding_metadata / 端点缺少绑定信息`、`device_not_in_3d_scene / 3D场景缺少设备`、`no_3d_terminals_for_element / 设备缺少工程端子`、`no_3d_terminals_for_instance / 实例缺少工程端子`、`terminal_uuid_not_in_element / 端子UUID不匹配`。这样真实工程中只有少量缺端子时,也可以不展开 JSON 就判断下一步是补 QET 端点元数据、补 3D 设备装配/绑定,还是核对同设备端子 UUID。
批量布线原始 report 和 compact 批量诊断都会同步写入 `missing_terminal_summary` ,复用汇总诊断的缺端子分组口径。`reason_code_counts` 统计每类原因,`device_groups[]` 按缺失侧设备聚合 `element_uuid` 、`instance_id`、缺失端子、端子 UUID 和相关导线,便于把“缺 3D 设备”或“端子 UUID 不匹配”的问题直接交给装配/绑定流程处理。脚本或面板二次处理时应优先读取这个结构化字段,而不是解析中文报告里的 `需补端子设备` 文本。
当用户从已打开的 FCStd 任务对象直接执行布线,而任务对象自身没有携带完整 `devices[]` 时, FreeCAD 会尝试从当前 QET 交换上下文的 `2d_to_3d.json` 只读回补设备列表。该回补只合并 `devices[]` ,不会用磁盘 JSON 覆盖当前 FreeCAD 文档中的导线任务;项目 UUID 不一致时会拒绝回补。批量 report 会写入 `context_devices_loaded` 、`context_device_count` 和 `context_devices_json_path` ,用于确认本次是否加载了上下文设备列表。这样真实工程中 `UD:8 / UD:10 / UD:5` 这类缺设备分组可以继续带出 `instance_id` ,方便装配/绑定侧定位。
当批量布线已经生成导线,但 `route_path_usage.main_path_routes = 0` 且 `fallback_routes > 0` 时,诊断会追加 `main_path_not_used / 未使用线槽或用户主路径` 。这表示导线虽然能连通,但全部依赖 `RoutingRange` 或 `AuxiliaryPath` 兜底路径,没有真正进入线槽、过线孔或用户主路径网络。手动测试看到该提示时,应优先补线槽中心路径、柜内黄色 `UserPath` 、设备局部出线路径或主路径桥接,再重新生成布线连接。
批量诊断还会记录 `route_network_carrier_kind_counts` 和 `route_network_main_path_carriers` 。如果 `route_network_main_path_carriers > 0` 但仍触发 `main_path_not_used` ,说明 FreeCAD 已经识别到线槽/UserPath/过线孔主路径,但这些主路径没有接入端子局部网络,或距离/连通关系导致最终选路仍退回布线面。此时优先检查线槽端点、线槽到端子附近的桥接、`TerminalAccess` 最大距离、`UserPath` 是否贴近线槽中段,以及是否需要点击“按诊断建议生成桥接”。
当最终导线虽然布通、但起点或终点到主路径入口距离超过警戒阈值时,批量报告会显示“接入距离提示”,列出触发导线数量、一条导线样例、起点/终点接入距离和该样例实际经过的路径标签。这个提示不阻止生成导线,用于暴露设备附近缺少局部路径、主路径离端子过远或端子接入距离设置过大的情况。批量诊断 JSON 也会记录 `route_entry_distance_warning_count` 和 `route_entry_distance_warning_samples` ,其中 warning sample 会保留 `route_source_labels` ,便于导出后定位全部样例。
当单条路线使用 `RoutingRange` 或 `AuxiliaryPath` 时,批量报告会提示“路径质量提示”,说明该导线可能没有完全优先进入线槽。这个提示不阻止布线,只用于暴露“当前路径依赖布线面兜底”的情况,方便后续补线槽、补 `UserPath` 或调整设备位置。批量诊断 JSON 也会记录这类提示:`route_quality_warning_count` 表示依赖布线面/辅助路径的导线数量,`route_quality_warning_samples` 保留少量导线样例及其使用的 carrier 类型。
单根导线对象也会展开端子接入距离,避免手动测试时只能打开 JSON。`QetRouteEntryDistanceMm` / `QetRouteExitDistanceMm` 分别表示起点、终点端子出线点到主路径网络入口的距离;`QetRouteEntryPointMode` / `QetRouteExitPointMode` 表示接入点来自路径端点还是中段投影;`QetRouteEntryCandidateRank` / `QetRouteExitCandidateRank` 表示最终采用的入口候选排名;`QetRouteAccessWarningDistanceMm` 保存本次告警阈值。若 `QetRouteAccessStatus=LongAccessWarning` ,说明该线虽然已经布通,但起点或终点接入主路径过长,`QetRouteAccessWarningSides` 会标出 `entry` 、`exit` 或二者都触发。完整明细同步写入 `QetRouteDiagnosticsJson.access` 。手动测试看到该告警时,应优先补设备局部路径、把用户路径/线槽靠近设备端子,或重新检查设备是否已经装配到正确位置。
当候选路线评分发现最终候选仍有接入段或候选折线穿过障碍包围盒时,批量报告会显示“接入避障提示”,列出触发导线数量、一条样例和该样例实际经过的路径标签。这个提示通常表示当前附近缺少可绕开的线槽、`UserPath` 或设备局部路径;它不替代最终碰撞状态,但能帮助区分“已经布通但入口路径仍不理想”的情况。批量诊断 JSON 也会记录 `route_candidate_obstacle_warning_count` 和 `route_candidate_obstacle_warning_samples` ,其中 warning sample 会保留 `route_source_labels` ; `route_samples[].network` 中仍保留样例路线自身的候选入口 rank、候选评分和候选障碍命中数。
入口候选会按“投影点 + carrier”去重, 避免同一个近路径因为桥接边或重复边占满候选名额。有障碍物参与候选评分时, 系统除保留距离排序靠前的候选外, 还会额外保留一批接入折线不穿过障碍包围盒的候选, 再统一评分。这样可以减少“近入口需要穿设备、远一点入口更干净, 但远入口被候选上限截掉”的穿模问题。
最终导线碰撞诊断会区分两类碰撞:`HardIntersection` 表示导线段穿过原始障碍包围盒,中文报告显示为“硬碰撞”;`ClearanceWarning` 表示导线没有穿过原始障碍, 但进入了按安全间隙膨胀后的包围盒, 中文报告显示为“安全间隙”。批量报告会增加“碰撞分类”, compact 诊断 JSON 会记录 `collision_kind_counts` ,用于快速判断当前问题是明显穿模还是安全距离不足。单根导线对象的 `QetRouteDiagnosticsJson.collisions[]` 和批量碰撞样例都会尽量保留该导线实际经过的路径标签,例如 `路径 主线槽A` ,方便判断是线槽中心线、`UserPath` 还是兜底路径导致穿模。
批量 `issue_codes` 会在 `collision_warnings` 之外进一步追加碰撞处理分类:`structural_collision_candidates / 结构件碰撞候选` 表示存在可确认的柜体、门板、支架等结构件碰撞候选;`device_or_layout_collisions / 设备/布局碰撞` 表示存在真实设备或布局碰撞。这样汇总诊断和手动测试可以直接区分“可确认忽略的结构件”与“需要补路径或调整装配的设备碰撞”。
如果端子或设备模板明确提供了 `QetTerminalLocalRoutePointsJson` 局部出线路径,最终导线会保留这些局部路径点,并在 `QetRouteDiagnosticsJson.endpoint_access` 中写入起点/终点接入路径。碰撞诊断会把这些明确的端子局部接入段视为设备内部或设备附近的受控出线段,不把它们当成主路径穿模问题;但局部路径接入后的柜内主路径、中段线槽和 `UserPath` 仍会继续做碰撞诊断。这样可以减少设备壳体附近的误报,同时不会隐藏真正穿过柜体、设备或主路径障碍的导线。
批量 `collision_samples[]` 也会保留 `wire_object_label` ,其值与树目录导线对象 Label 一致。这样当报告显示某条线有硬碰撞或安全间隙告警时,可以直接用 `wire_object_label` 在 `QETWiring_04_Routed` 下找到对应导线,再检查 `QetRouteCollisionStatus` 、路径来源和碰撞包围盒。
单根导线对象会同步展开碰撞状态:`QetRouteCollisionCount` 表示总碰撞/间隙告警数量;`QetRouteHardIntersectionCount` 表示硬碰撞数量;`QetRouteClearanceWarningCount` 表示安全间隙告警数量;`QetRouteCollisionStatus` 会在 `NoCollision` 、`ClearanceWarning`、`HardIntersectionWarning` 之间切换。手动测试时,如果状态是 `HardIntersectionWarning` ,应优先检查导线是否穿过设备、线槽壁或柜体;如果只是 `ClearanceWarning` ,通常表示路线贴近障碍,需要调大线槽/用户路径距离、调整设备位置或降低安全间隙阈值后复测。
`3D 布线连接` 面板提供“障碍安全间隙 mm”设置, 对应 `obstacle_clearance` 。该值用于膨胀障碍包围盒:值越大,越容易把贴近设备或柜体的导线标记为 `ClearanceWarning` ,也会让候选入口评分更倾向避开贴近障碍的接入折线;值为 0 时只按原始障碍包围盒判断明显穿模。
柜内区域边界可以由 FreeCAD 文档中的对象提供,给对象设置 `QetRoutingBoundaryKind = "CabinetInterior"` 即可把该对象包围盒视为柜内可布线范围。边界对象不写数据库,也不会被当作障碍物;它先参与路径图过滤,再参与最终导线候选评分。当存在 `CabinetInterior` 时,系统会优先构建“柜内路径图”,只保留完全落在柜内边界内的路径段并先在这张图上求路;只有柜内路径图不可达时,才回退到原始路径图并保留柜内越界告警。这样即使柜外路径几何距离更近、柜内路径稍远,也会优先选择仍在柜内的线槽、`UserPath` 或支撑面路径。批量诊断 JSON 的 `route_samples[].network` 会记录 `boundary_aware` 、`boundary_filtered`、`boundary_filtered_segments` 和 `route_candidate_boundary_violations` ,用于确认本次布线是否启用了柜内边界约束、是否先使用了柜内过滤图,以及最终候选是否仍存在越界点。
如果柜内过滤图无法连通两端, 系统仍会回退到原始路径图并生成综合评分最高的路径, 但批量报告会显示“柜内边界提示”, 指出有多少条导线最终路径仍越出柜内区域, 并给出一条导线样例、越界点数量和该样例实际经过的路径标签。compact 诊断 JSON 同步记录 `route_candidate_boundary_warning_count` 和 `route_candidate_boundary_warning_samples` ,其中 warning sample 会保留 `route_source_labels` 。单根导线对象也会写入 `QetRouteBoundaryAware=true` 、`QetRouteBoundaryStatus=BoundaryWarning` 和 `QetRouteBoundaryViolationCount` ,便于选中某条导线后直接判断它是否跑出柜内区域。手动测试看到该提示时,应优先补柜内 `UserPath` 、线槽或设备局部路径;如果边界对象本身建模过窄,也可以调整 `CabinetInterior` 对象包围盒。
有柜内边界时,入口候选不会只按几何距离截断。系统会先保留距离排序靠前的候选,再额外保留一批投影点位于 `CabinetInterior` 内部的候选,最后统一按路径成本、接入距离、障碍命中和柜内越界点数评分。这样可以避免柜外近路径数量较多时,把稍远但正确的柜内 `UserPath` / 线槽在评分前就挤掉。
路径网络检查也会提前检查主路径 carrier 自身是否越出柜内边界。当文档中存在 `CabinetInterior` 时,`WireDuct`、`UserPath`、`WiringCutOut` 等非 `TerminalAccess` 路径点如果落在边界外,会记录 `route_carriers_outside_boundary / 路径越出柜内边界` ,并在中文报告中给出路径标签和越界点数量。这用于在生成导线前发现“用户路径或线槽中心线本身画到柜外”的问题,避免后续所有导线都沿错误主路径求路。
路径网络检查还会检查工程端子是否落在柜内边界内。当端子原点或端子出线末端位于 `CabinetInterior` 外时,会记录 `terminals_outside_boundary / 端子越出柜内边界` ,并高亮对应端子对象。这主要用于发现设备还停留在导入位置、端子 LCS 没有跟随装配实例移动、或柜内边界对象标得过窄等装配态问题。
`3D 布线连接` 面板摘要会显示当前文档内已识别的柜内边界数量,例如 `柜内边界: 1` 。执行“选中对象作为柜内边界”后,可先看摘要确认边界对象已经生效,再生成布线路径网络和布线连接。
被标记为 `CabinetInterior` 的对象只作为边界使用,不会再被自动识别成线槽、安装面、过线孔或 `UserPath` 源对象。这样可以避免辅助边界盒、柜体内腔对象或用户误选的柜体对象在生成布线路径网络时又变成导线可走 carrier。
路径约束已支持 SW/EPLAN 风格“禁止经过”和“必须经过”的第一版能力。调用自动布线时可以通过 options 传入 `forbidden_route_carrier_names` 、`forbidden_route_carrier_labels`、`forbidden_route_carrier_source_names`、`forbidden_route_carrier_source_labels` 或 `forbidden_route_carrier_kinds` , Dijkstra 搜索会直接跳过匹配 carrier 的边;也可以传入 `required_route_carrier_names` 、`required_route_carrier_labels`、`required_route_carrier_source_names`、`required_route_carrier_source_labels` 或 `required_route_carrier_kinds` , Dijkstra 状态会记录已经经过的必经 carrier 或源对象,只有所有必经条件满足时才允许结束。批量 `wires[]` 中的单条导线任务也可以携带这些同名字段,用于表达“某一根导线必须/禁止经过某些路径”。该能力当前先作为算法层和导线任务可选字段, 后续可接入面板、FreeCAD carrier 属性或 QET 导线规则;如果禁止/必经规则导致两端不再连通,导线会按“缺少布线路径网络/不连通”进入失败诊断。
当必经/禁经规则导致无可用路径时,单条布线会提示“没有满足路径约束的布线路径网络”;批量布线会把它归入 `MissingRouteNetwork` ,并在“缺路径网络示例”的 `error` 字段里保留路径约束原因。这样手动测试时可以区分“真的没有线槽/UserPath”和“路径存在但被规则禁止或必经规则无法满足”。
当路径约束成功生效并生成导线时,`QetRouteNetworkJson` 会保留 `route_constraints` ,记录本路线使用到的 required / forbidden carrier 名称、标签、源标签或类型。批量 compact 诊断的 `route_samples[].network.route_constraints` 也会保留这些字段,方便回看某条线为什么没有走最近路径。
批量生成布线连接的中文报告会汇总路径约束使用情况:当有导线应用必经/禁经规则时,报告显示“路径约束提示”,列出触发导线数量和一条样例导线,并按“必须经过/禁止经过”展示标签、名称、源标签或类型。compact 诊断 JSON 也会记录 `route_constraint_warning_count` 和 `route_constraint_warning_samples` ,便于导出后快速确认哪些导线受全局或单线规则影响。
为了便于 FreeCAD 手动测试,也可以直接在路径 carrier 对象上设置 `QetRouteConstraintMode` 。值为 `Forbidden` 时,该 carrier 会被所有自动布线跳过;值为 `Required` 时,所有自动布线都必须经过该 carrier, 否则进入路径约束失败诊断。这个对象属性适合验证工程规则或临时屏蔽某段线槽; 如果未来要做到“只对某一根导线生效”, 仍建议通过单条 `wires[]` 的 required/forbidden 字段表达。
`3D 布线连接` 面板提供“选中路径必须经过”“选中路径禁止经过”“清除选中路径约束”和“清除全部路径约束”四个入口。用户可以选中已经生成的 route carrier, 或选中草图、Draft 线等源路径对象,然后点击对应按钮写入或清空 `QetRouteConstraintMode` 。如果源路径对象还没有生成 carrier, 面板会按“源路径”计数; 后续生成 `UserPath` 时会继承该约束,避免用户必须严格按“先生成路径、再设置约束”的顺序操作。如果多次手动测试后不确定哪些路径仍保留 Required / Forbidden, 可使用“清除全部路径约束”, 它会同时清空当前文档内 route carrier 和源路径对象上的约束,避免重新生成路径网络后旧约束再次继承回来。该设置是 FreeCAD 文档内的全局路径规则,会影响后续所有自动布线。
手动编辑属性时,`QetRouteConstraintMode` 同时支持英文和中文别名:`Required`、`必须经过`、`必经` 都表示必经路径;`Forbidden`、`禁止经过`、`禁经`、`禁止` 都表示禁经路径。面板按钮仍写入标准英文值,便于程序稳定判断。
面板摘要会显示当前文档中 carrier 级路径约束数量,例如 `路径约束:必经 1, 禁经 1` 。如果约束写在尚未生成 carrier 的草图、Draft 线等源路径对象上,或写在线槽、过线孔、支撑面等已标记路由源对象上,摘要会单独显示 `源路径约束:必经 1, 禁经 0` 。前者代表已经参与当前路径网络求路的 carrier 规则,后者代表后续生成或刷新 `UserPath` / `WireDuct` / `WiringCutOut` 等 carrier 时会继承的源对象规则。标记或清除路径约束后,可先看摘要确认状态,再重新生成布线连接。
当用户选中源路径对象( 例如草图、Draft 线或线槽源对象)设置路径约束时,系统会同时把 `QetRouteConstraintMode` 写到源对象和它已经生成的 carrier 上。后续即使清除走线路径并重新生成 carrier, 新 carrier 也会继承源对象上的 Required / Forbidden 约束,避免工程规则在刷新路径网络后丢失。如果源路径对象的约束已经清空,刷新 `UserPath` 时也会同步清空旧 carrier 上残留的 Required / Forbidden, 避免多轮手动测试后旧规则继续影响自动布线。
同一个草图或 Draft 源对象可能包含多条不连通 `Wire` ,生成时会拆成多条 `UserPath` 。当约束来自源对象时,系统会按 `QetRouteSourceName` 聚合判断:`Required` 表示路线至少经过该源对象生成网络中的一条相关路径即可满足,不再强制同时经过所有生成子路径;`Forbidden` 表示该源对象生成的全部路径都不可走。这样更符合甲方“预先画黄色路径作为布线输入”的操作习惯,也避免多分支草图被误判为必经规则无法满足。
当单条路线使用 `RoutingRange` 或 `AuxiliaryPath` 时,批量报告会提示“路径质量提示”,说明该导线可能没有完全优先进入线槽。这个提示不阻止布线,只用于暴露“当前路径依赖布线面兜底”的情况,方便后续补线槽、补 `UserPath` 或调整设备位置。报告会尽量显示具体的布线面/辅助路径 carrier 标签,例如 `示例 N4111 使用布线面:安装板辅助路径` ;没有具体标签时仍回退显示 carrier 类型。批量诊断 JSON 也会记录这类提示:`route_quality_warning_count` 表示依赖布线面/辅助路径的导线数量,`route_quality_warning_samples` 保留少量导线样例、使用的 carrier 类型和 `route_carrier_labels` 。
单根导线对象也会展开路径质量状态:`QetRouteQualityStatus=NormalPath` 表示该线没有使用布线面/辅助路径兜底;`QetRouteQualityStatus=FallbackPathWarning` 表示实际路线经过了 `RoutingRange` 或 `AuxiliaryPath` 。`QetRouteFallbackCarrierKinds` 会列出兜底 carrier 类型,`QetRouteFallbackCarrierLabels` 会列出具体标签,例如安装板辅助路径。这个状态不代表布线失败,但说明第一版算法是在“能连通”的基础上用了低优先级路径;手动测试看到它时,应优先补线槽、黄色草图 `UserPath` 、过线孔或设备局部路径,让导线进入更明确的工程主路径。
当并行 lane 数超过实际经过路径的最小容量时, 批量报告会提示“容量提示”, 显示最大并行线数、路径最小容量, 并给出一条样例导线和真实经过的路径名称。这个提示不阻止布线; 它用于暴露线槽外共线拥挤、线槽容量设置过小或需要增加并行路径的场景。compact 诊断 JSON 同步记录 `route_capacity_pressure_warning_count` 和 `route_capacity_pressure_warning_samples` , 样例包含导线、并行线数、最小容量、lane index、carrier 名称和源路径标签。若容量压力来自同一个草图拆出的多条 `UserPath` ,中文报告和 compact 诊断会优先显示 `源路径标签(路径1)` 这类可回溯到黄色草图线的标签,而不是只显示自动生成的 carrier 名称。
`3D 布线连接` 面板提供“共路复用惩罚”设置,对应 `segment_reuse_penalty` 。当某段路径的已用导线数超过该 carrier 的 `QetRouteCarrierCapacity` 时, Dijkstra 会按该惩罚增加复用成本;调高后更倾向绕到备用线槽或 `UserPath` ,调低后更倾向继续走几何距离更短的公共路径。该参数只影响搜索成本,不代表真实线槽填充率校核。
路径网络检查还会识别“只有 `RoutingRange` 、没有 `WireDuct` / `UserPath` / `WiringCutOut` 主路径”的情况,并记录 `routing_range_only_network` 。这类网络可以作为无线槽或路径不完整时的临时兜底,但不是推荐的第一版主路径形态;手动测试看到该提示时,优先补线槽、补 `UserPath` 或补过线孔路径。
@ -569,6 +747,8 @@ QetWiringCutOutBridgeExtensionMm = 20.0
当单条路线的最大并行线数超过该路线 route track 中记录的路径最小容量时,批量报告会给出容量提示。这个提示只基于 `QetRouteCarrierCapacity` 和当前 lane 情况,用于暴露“可能容量不足”的调试线索,不等同于按线径、截面积和线槽填充率计算的工程容量校核。
单根导线对象会展开共路和容量状态,便于选中导线后直接检查。`QetRouteLaneIndex` 表示该线在共享路径中的 lane 序号,`QetRouteLaneAxis` / `QetRouteLaneOffsetMm` 表示显示错位方向和偏移量,`QetRouteParallelWireCount` 表示到该 lane 为止的并行线数量,`QetRouteMinCarrierCapacity` 表示该线实际经过路径的最小 carrier 容量。若 `QetRouteCapacityStatus=CapacityWarning` ,说明该线所在共享路径的并行线数已经超过当前路径容量,应补备用线槽、用户路径或调高真实 carrier 容量属性。
### 5.3 布线连接功能
已完成:
@ -586,6 +766,7 @@ QetWiringCutOutBridgeExtensionMm = 20.0
11. 自动导线可见显示并保存到 FreeCAD 文档。
12. 生成布线连接时保存 `QetRouteTrackJson` ,记录实际经过的 `WireDuct` / `RoutingRange` / `TerminalAccess` / `WiringCutOut` carrier。
13. 支持检查布线路径网络,诊断孤立网络、未接入端子和疑似线槽端点断点,并写入 `QETWiring_05_Diagnostics` 。
14. 支持柜内边界约束:当文档中存在 `QetRoutingBoundaryKind = "CabinetInterior"` 对象时,自动布线会先在柜内过滤后的路径图上求路,再回退原始路径图;路径网络检查也会提前提示主路径 carrier 或工程端子越出柜内边界。
### 5.4 FreeCAD 面板
@ -599,6 +780,11 @@ QET模板 -> 3D布线连接
```text
准备布线布局空间
选中对象作为柜内边界
选中路径必须经过
选中路径禁止经过
清除选中路径约束
清除全部路径约束
生成布线路径网络
检查布线路径网络
生成布线连接
@ -639,7 +825,7 @@ tests/python/freecad_exchange_auto_routing_test.py
20. “生成布线连接”会先更新同一套布线路径网络,再按全部 QET 导线任务批量求路。
21. 相邻主路径端点在容差内会被网络自动连通;支路端点靠近主路径中段时也会投影桥接;端子接入会连接到最近的网络线段点,而不是只连接到已有端点。
22. 线槽端部会生成 `WireDuctOpenEnd` 横向路径,穿线孔/过线孔会生成 `WiringCutOut` carrier。
23. 导线会保存 routing track; 网络检查会生成 `RoutingPathNetwork` 诊断对象。
23. 导线会保存 routing track; 网络检查会生成 `RoutingPathNetwork` 诊断对象,并在返回结果中同步给出 `issue_codes` 。诊断对象会保存 `QetProjectUuid` ; `QetDiagnosticOk` 表示是否通过;`QetDiagnosticIssueCodes` 直接列出问题码;`QetDiagnosticIssueLabels` 直接列出中文问题标签;`QetDiagnosticMessage` 保存中文摘要,`QetDiagnosticJson` 保存路径网络诊断明细和 `issue_codes` 。
24. 自动生成的线槽、过线孔和支撑面 carrier 会在源对象移动、缩放、删除或失效后刷新/清理。
25. `WiringCutOut` 会在穿孔方向外扩虚拟路径,用于桥接开孔两侧附近的线槽或支撑面网络,并支持通过 `QetWiringCutOutBridgeExtensionMm` 按对象调整外扩距离。
26. `QetRouteTrackJson` 会在 carrier 有源对象元数据时保存 `source_name` 、`source_label`、`source_kind`,方便核对导线实际走过的线槽、过线孔或支撑面。
@ -654,19 +840,99 @@ tests/python/freecad_exchange_auto_routing_test.py
35. `QetRouteTrackJson` 的 carrier payload 会记录 `capacity` ,方便后续分析线槽容量偏好和共路绕行。
36. 批量布线报告会在最大并行线数超过路径最小容量时显示容量提示,但当前仍不做真实填充率计算。
37. `3D 布线连接` 面板提供“并行线间距 mm”、“并行线最大偏移 mm”和“并行线方向”设置, 用于调整多线共路时的可视 lane 偏移。
38. 最终导线选路会在多个入口候选中避开接入段穿障碍的入口,并优先选择可避障的线槽 / `UserPath` 入口。
39. 同一入口下的端子接入正交折线会尝试不同轴向顺序,优先选择不穿过障碍包围盒的折线。
38. `3D 布线连接` 面板提供“障碍安全间隙 mm”设置, 用于调整安全间隙告警和接入候选避障评分。
39. `3D 布线连接` 面板提供“共路复用惩罚”设置,用于调整超过 carrier 容量后的复用成本和绕行倾向。
40. 最终导线选路会在多个入口候选中避开接入段穿障碍的入口,并优先选择可避障的线槽 / `UserPath` 入口。
41. 入口候选按投影点和 carrier 去重;存在障碍时会额外保留干净接入候选,避免重复近候选挤掉稍远的避障入口。
41. 同一入口下的端子接入正交折线会尝试不同轴向顺序,优先选择不穿过障碍包围盒的折线。
40. 并行导线可视 lane 偏移默认限制在固定上限内,防止密集共路时导线被显示到柜外。
41. 完整自动布线流程会使用支路端点到主路径中段的投影桥接,避免这类支路网络被误判为孤立。
42. `QetRouteTrackJson` 会标记实际走过的自动桥接段,并记录本路线实际使用的桥接段数量。
43. 批量布线报告的路径示例会跳过虚拟桥接段,只列出真实经过的源对象标签。
44. 共路 lane 计数和路径复用惩罚会跳过虚拟桥接段,避免仅共享自动桥接边的导线被误判为真实共路。
45. `3D 布线连接` 面板提供“选中对象作为柜内边界”,用于把选中对象的包围盒标记为 `CabinetInterior` ,让自动布线优先留在柜内区域。
46. 面板摘要会显示已识别的柜内边界数量,方便确认边界约束是否生效。
47. `CabinetInterior` 边界对象不会被自动识别成 `WireDuct` 、`RoutingRange`、`WiringCutOut` 或 `UserPath` 路径源。
48. 柜内边界存在时,入口候选会额外保留柜内候选参与评分,并且系统会先尝试柜内过滤路径图,避免大量柜外近路径或柜外捷径挤掉稍远但正确的柜内路径。
45. 路径质量提示会按非桥接段重新判断 carrier 类型,避免把虚拟桥接到 `RoutingRange` 误报为真实使用布线面兜底。
46. 缺少布线路径网络或路径网络两端不连通时,批量布线报告会显示一条导线、端点样例和失败原因,便于直接定位需要补路径的设备区域。
47. “端子接入最大距离”同时约束自动 `TerminalAccess` 和最终导线入口候选,防止最终求路绕过面板设置生成超长接入线。
48. 批量诊断 JSON 的 route sample 会跳过虚拟桥接段统计 carrier 类型和 carrier 名称,保持与中文报告一致。
49. 最终导线路由不会把 `TerminalAccess` 当作公共 transit carrier, 入口候选也会优先真实主路径, 避免端子局部接入线被误用来桥接主路径缺口或作为其它导线的起步路径。
50. 批量布线报告会提示最终导线起点/终点接入距离过长的样例,用于排查设备附近缺局部路径或主路径离端子太远。
51. 单根导线对象会展开 `QetRouteEntryDistanceMm` 、`QetRouteExitDistanceMm` 和 `QetRouteAccessStatus` ,用于选中某条线后直接判断是否存在长接入。
52. 单根导线对象会展开 `QetRouteSourceLabels` 和 `QetRouteCarrierNames` ,用于直接查看该线实际经过哪些线槽、黄色草图路径或用户路径。
53. 单根导线对象会展开 `QetRouteCollisionStatus` 、`QetRouteHardIntersectionCount` 和 `QetRouteClearanceWarningCount` ,用于直接区分穿模和安全间隙告警。
54. 单根导线对象会展开 `QetRouteQualityStatus` 、`QetRouteFallbackCarrierKinds` 和 `QetRouteFallbackCarrierLabels` ,用于判断该线是否依赖布线面/辅助路径兜底。
55. 批量诊断的 `route_samples[]` 会同步输出 `access` 、`collision_summary`、`quality`、`capacity`、`boundary` 状态分组,便于不逐根选中导线也能复盘样例路线。
56. 生成导线对象的树目录 Label 会包含导线标识、起终点端子和状态,便于在 FreeCAD 左侧树中定位问题导线。
57. 单根导线对象会展开 `QetRouteIssueCodes` 和 `QetRouteIssueLabels` ,用与批量诊断一致的问题码汇总该线自身的问题。
58. 批量诊断的 `route_samples[]` 会优先保留带问题码的路线样例,避免问题线排在后面时被 sample limit 截掉。
59. 批量诊断的 `route_samples[]` 会保留 `wire_object_label` ,用于从诊断 JSON 直接定位 FreeCAD 树目录中的导线对象。
60. 批量碰撞样例 `collision_samples[]` 会保留 `wire_object_label` ,便于从穿模/安全间隙告警直接定位问题导线。
61. 接入距离、路径质量、候选入口、柜内边界、路径约束和容量压力 warning samples 会保留 `wire_object_label` ,统一诊断定位方式。
62. 路径网络长接入样例会保留父设备、端子全局点、接入折点、主要超长方向和各轴长度。真实工程中如果 `terminal_access_dominant_axis=z` 且竖向长度占大头,可以直接判断为端子/设备高度或局部出线路径问题,而不是主路径网络断开。
63. 碰撞样例会保留障碍对象的父装配名称和标签,方便把 `NAUOxxx` 这类导入零件追溯到前门、柜体、安装板或具体设备,再决定是标记忽略碰撞还是补柜内路径。
64. 面板提供“选择越界路径/端子”,从最新 `RoutingPathNetwork` 诊断的 `route_carriers_outside_boundary` 和 `terminals_outside_boundary` 反向选择越出柜内边界的路径 carrier 与工程端子。该功能只定位对象,不自动调整边界、不移动设备、不写数据库。
64. 批量布线报告的 `top_collision_obstacles[]` 不再只记录对象标签和次数,还会记录对象名称、父装配、硬碰撞/安全间隙分类计数;中文摘要也会显示父装配,例如 `NAUO118(CABINET ASS'Y) 18 处` ,便于区分柜体/门板 AABB 误报和真实设备穿模。
65. 缺失端点样例会记录同 2D 设备、同 3D 实例下的 FreeCAD 工程端子数量,并输出原因码。真实工程里若原因是 `missing_device_binding_metadata` ,说明 QET 导线任务端点缺少 `element_uuid` , FreeCAD 无法判断缺失端子属于哪个 2D 设备;第一版不要求 QET 在 `wires[]` 端点提供 `start/end_instance_id` 。若原因是 `device_not_in_3d_scene` ,说明该 2D 设备当前没有对应 3D 设备实例,应回到设备导入、装配和 2D/3D 绑定流程排查;若原因是 `no_3d_terminals_for_element` ,说明设备实例在场景中但没有生成工程端子,应回到端子生成流程排查。这些都不是路径网络问题。
66. 高发碰撞对象会输出处理建议。疑似柜体、门板、支架、盖板等结构件时,建议用户确认后通过现有“选中对象忽略碰撞”标记为 `PassThrough` ;疑似设备或安装区域碰撞时,建议补主路径、局部出线路径或调整装配,而不是直接忽略。
67. 面板提供“选择高发碰撞对象”,从最新批量诊断 `top_collision_obstacles[]` 反向选择 FreeCAD 对象,方便现场确认后再手动标记忽略或调整路径。该功能只定位对象,不自动修改碰撞规则。
68. 面板提供“选择碰撞导线”,从最新批量诊断 `collision_samples[]` 和带 `collision_warnings` 的 `route_samples[]` 中反向选择 RoutedConnection 导线对象,便于和高发碰撞对象一起核对穿模位置。该功能只定位导线,不重新求路。
68. 面板提供“选择缺主路径导线”,从最新 `route_samples[]` 和导线对象自身的 `QetRouteIssueCodes` 中选择带 `main_path_detour_missing` 的 RoutedConnection 导线。该功能用于定位“选择性避障重算本可减少碰撞,但会退回到辅助路径/布线面兜底,因此被当前主路径优先策略拒绝”的导线;下一步应补 `UserPath` 、桥接主路径、调整线槽入口或完善设备局部出线路径,不自动接受 fallback 结果。
68. 自动布线会对明确的 `main_path_detour_missing` 做一次收敛处理:当选择性避障已经得到碰撞更少的 fallback 折线,但该折线因包含 `RoutingRange` 被拒绝时,系统会把这条折线固化为 `MainPathDetourPath` 类型的 `UserPath` ,再按 `兜底区域 -> 当前主路径` 生成 `MainPathDetourBridge` ,随后只重试受影响导线。这样保持主路径优先,不直接接受宽泛布线面兜底,同时避免整批导线二次全量重跑。
69. 面板提供“选择长接入端子”,从最新批量诊断 `routing_path_network_diagnostic.long_terminal_accesses[]` 中反向选择端子对象,便于检查端子高度、设备装配和局部出线路径。该功能只定位端子,不修改端子或路径数据。
70. 面板提供“选择缺端子设备”,从最新批量诊断 `missing_endpoint_samples[]` 的缺失侧读取 `*_instance_id` / `*_element_uuid` 并反向选择 3D 设备,便于补工程端子或检查 2D/3D 绑定。若缺失设备不在当前场景中,控制器仍会返回 `missing_terminal_device_instance_ids[]` 、`missing_terminal_device_element_uuids[]` 和可读标签,状态栏也会显示 instance_id, 便于把缺设备清单交给装配/绑定流程。该功能只定位设备,不自动创建端子、不修改 QET 数据。
71. 面板提供“选择缺端子另一端”,从缺端子样例中选择已找到的另一端工程端子,便于确认失败导线本来要连接到哪里,再对照缺失侧设备和端子脚号。该功能只定位端子,不自动补端子、不写数据库。
72. 面板提供“选择缺端子候选端子”,从 `*_instance_terminal_samples` / `*_element_terminal_samples` 中反向选择同设备或同实例已有工程端子,便于排查 `terminal_uuid_not_in_element` 这类“同设备已有端子但 UUID 不匹配”的问题。该功能只定位候选端子,不自动改绑定、不写数据库。
73. 碰撞障碍语义按 FreeCAD 父装配链递归识别。用户把柜体、门板、支架、盖板等父装配标记为 `PassThrough` 后,深层导入子零件也会被排除在导线障碍之外;碰撞样例的 `parent_refs` 也会尽量输出完整父链,避免只看到中间 `Compound/NAUO` 。
73. 第一版会自动过滤一类未绑定导入结构件碰撞:障碍物没有 QET `element_uuid` ,并且位于 `QET Exchange Devices / QETCabinet / LinkGroup / Compound / NAUO` 等导入装配上下文,同时名称或父链命中柜体、门板、支架、盖板等结构关键词时,不再计入导线碰撞。该规则不作用于带 `element_uuid` 的 3D 设备,因此不会吞掉真实设备/端子/断路器碰撞。
74. 面板提供“选择碰撞父装配”,从最新 `top_collision_obstacles[]` 的 `parent_names / parent_labels` 反向选择父装配,适合先确认前门、柜体、支架等总成是否可穿越,再统一标记 `PassThrough` 。该功能只定位父装配,不自动忽略碰撞。
75. 面板提供“确认结构件忽略碰撞”,按最新诊断只把疑似柜体、门板、支架、盖板等结构件碰撞的最近结构父装配标记为 `PassThrough` 。该动作不会沿父链继续标记 `QET Exchange Devices` 这类工程根组,不会标记 `review_device_or_layout_collision` ,也不写数据库;重新生成布线连接后,下级导入结构子件会因对应父装配 `PassThrough` 被排除出障碍候选,真实设备碰撞仍会继续保留诊断。
76. 面板提供“选择设备碰撞对象”,只从最新 `top_collision_obstacles[]` 中选择 `review_device_or_layout_collision` 候选。该功能用于处理结构件忽略后仍剩余的真实设备/布局碰撞,只定位对象,不自动忽略碰撞;后续应补设备局部出线路径、调整 UserPath/线槽入口或检查设备装配。
77. 面板提供“选择长接入设备”,从 `long_terminal_accesses[]` 的 `parent_device_name / parent_device_label` 反向选择设备对象,便于从设备整体高度、端子 LCS 跟随和局部出线路径三个角度排查长接入。
78. 面板提供“选择异常导线”,从最新 `route_samples[]` 中选择所有带 `issue_codes` 的 RoutedConnection 导线,并补充扫描导线对象自身的 `QetRouteIssueCodes` ,避免 compact 样例数量有限时漏选问题线。该功能是长接入、越界、容量、路径质量和碰撞问题的统一入口,只定位导线,不重新求路。
79. 面板提供“选择异常导线路径”,从异常 `route_samples[]` 的 `carrier_names` 和 `route_track.segments[].carrier` 反向选择导线实际经过的路径 carrier, 并尽量选择 carrier 的源草图/线槽对象。该功能只定位路径,不自动改 Required/Forbidden、容量或几何。
80. 面板提供“选择选中导线路径”,从当前选中的 RoutedConnection 导线对象读取 `QetRouteTrackJson` ,反向选择该线实际经过的路径 carrier 和源草图/线槽。该功能用于 compact `route_samples[]` 为空或样例不足时的单线排查,只读取 FreeCAD 文档中的导线元数据,不写数据库、不要求 QET 提供 3D 路径。
80. 面板提供“选择拒绝兜底路径”,从当前选中的 RoutedConnection 导线对象读取 `QetRouteDiagnosticsJson.selective_collision_reroute.rejected_fallback_labels` ,反向选择被局部避障重算发现但因使用 `RoutingRange` / `AuxiliaryPath` 而被拒绝的路径来源。该功能只用于判断应在哪里补 `UserPath` 、桥接主路径或设备局部出线路径,不会自动接受 fallback 路线,也不写数据库。
81. `汇总布线诊断` 会统计实际 RoutedConnection 导线对象上的 `QetRouteIssueCodes` ,输出异常导线总数和各问题码数量。该统计来自 FreeCAD 文档中的导线对象,不依赖 compact `route_samples[]` 的样例上限。
82. `汇总布线诊断` 会统计批量缺端子数量和缺失端点原因,例如 `missing_device_binding_metadata / 导线端点缺少 2D/3D 设备绑定信息` 、`device_not_in_3d_scene / 该 2D 设备未在 FreeCAD 场景中找到`、`no_3d_terminals_for_element / 该 2D 设备在 FreeCAD 中没有工程端子`,用于区分 QET 端点绑定元数据缺失、设备未导入/未绑定、端子未生成和路径网络问题。
83. `汇总布线诊断` 会根据当前问题生成手测建议动作,例如选择缺端子设备、选择异常导线、选择长接入端子/设备、选择碰撞父装配等。建议只引导 FreeCAD 面板操作,不自动修改路径或数据库。
84. 缺端子建议会按原因码分流:`missing_device_binding_metadata` 提示检查 QET 导线端点是否提供 `element_uuid` 和 `terminal_uuid` ,并明确第一版不要求 `start/end_instance_id` ; `device_not_in_3d_scene` 优先提示检查设备是否已导入、装配并完成 2D/3D 绑定;`no_3d_terminals_for_element` / `no_3d_terminals_for_instance` 才提示选择缺端子设备;`terminal_uuid_not_in_element` 提示选择缺端子候选端子核对 UUID 与脚号绑定。
85. `选择缺端子设备` 本身也会按原因码分流状态提示:如果缺失设备不在当前 FreeCAD 场景中,提示先补设备导入、装配和绑定;如果缺少 QET 端点 `element_uuid` ,提示先补齐 QET 端点绑定信息,避免用户在 3D 场景中反复寻找不存在的对象。
86. `生成布线连接` 的中文报告会根据缺端子原因追加关键提示:若包含 `missing_device_binding_metadata` ,直接提示 `QET 导线端点缺少 element_uuid` ,并注明第一版不要求 `start/end_instance_id` ;若包含 `device_not_in_3d_scene` ,直接提示部分导线引用的设备未在当前 FreeCAD 场景中找到。这个提示不依赖 `routed=0` ,即使多数导线已经成功、只有少量导线缺端子,也会在报告中显示。
87. 对旧版批量诊断中缺端子样例没有原因码的情况,汇总诊断会尝试用当前 FreeCAD 文档回填原因码:样例里有 `terminal_uuid` 但没有 `element_uuid` 或可回查的设备标识时回填为 `missing_device_binding_metadata` ;样例里有设备标识但当前场景找不到设备时回填为 `device_not_in_3d_scene` ;设备存在但无工程端子时回填为 `no_3d_terminals_for_element` 。只有基础字段不足以判断时才显示 `缺端点原因未记录` 并建议重新生成布线连接。
62. 对于 `missing_route_network_samples[]` 、`error_samples[]`、`missing_endpoint_samples[]` 这类失败样例,`wire_object_label` 保存的是任务侧最接近对象标题的显示名,不一定已经对应到真实 3D 导线对象。
51. 自动布线 options 支持按 carrier 名称、标签、源对象名称、源标签或类型设置禁止经过路径, Dijkstra 会跳过这些路径边。
52. 自动布线 options 支持按 carrier 名称、标签、源对象名称、源标签或类型设置必须经过路径, Dijkstra 状态会记录必经条件并只返回满足条件的路径。
53. 批量 `wires[]` 的单条导线任务可选携带 `required_route_carrier_*` / `forbidden_route_carrier_*` 字段,实现不同导线使用不同路径约束。
54. 成功布线的 `QetRouteNetworkJson` 和 compact route sample 会记录 `route_constraints` ,用于追踪某条线实际应用的必经/禁经规则。
55. 批量布线中文报告和 compact 诊断会汇总路径约束使用情况,显示受 Required/Forbidden 规则影响的导线数量和样例。
55. 批量布线后会在返回 report 和 `QETWiring_05_Diagnostics` 下的 `RoutingConnectionBatch` 诊断对象中写入同一套 `issue_codes` ;诊断对象会保存 `QetProjectUuid` ; `QetDiagnosticOk` 表示本次批量布线是否无问题码;`QetDiagnosticIssueCodes` 直接列出问题码;`QetDiagnosticIssueLabels` 直接列出中文问题标签;`QetDiagnosticMessage` 保存中文摘要,`QetDiagnosticJson` 保存 compact 批量诊断明细,并包含当前 `runtime_version` ,方便手测时确认 FreeCAD 已加载最新自动布线代码。即使当前没有导线任务,也会保留该诊断对象并提示“没有导线任务”。问题码示例包括 `no_wire_tasks` 、`no_routed_connections`、`missing_terminals`、`missing_route_network`、`collision_warnings`、`route_capacity_pressure` 等,便于脚本或人工快速筛选问题。
56. 当批量布线 `total_wires > 0` 但最终 `routed = 0` 时,中文报告会明确提示“未生成有效导线:本次只有路径承载/诊断对象,未生成 RoutedConnection 导线”。这类场景常见于端子缺失、路径网络不连通、模块版本不一致或普通布线错误,不能把树目录中的 `WireDuct` 、`RoutingRange`、`TerminalAccess` carrier 当成成功布线结果。
57. `检查布线准备度` 会记录 `runtime_capabilities` 。如果当前 FreeCAD 会话加载的 `RoutingNetwork` 模块缺少路径约束收集函数,会写入 `runtime_route_constraint_collector_missing` 并提示同步运行目录、重启 FreeCAD, 避免模块版本不一致导致批量布线整批失败。
58. 外层“生成布线连接”在补齐路径网络检查、`hidden_route_carriers` 和 `routing_path_network_updated` 等最终字段后,会重写一次 `RoutingConnectionBatch` 诊断对象,保证“汇总布线诊断”读取到的是最终 report, 而不是内层批量求路刚结束时的半成品诊断。
59. compact 批量诊断会记录容量压力样例,便于定位哪条导线在哪些路径上触发“并行线数超过路径容量”。
60. 批量布线中文报告和 compact 诊断会按 `HardIntersection` / `ClearanceWarning` 汇总碰撞分类,便于区分穿模和安全间隙不足。
57. FreeCAD 路径 carrier 支持 `QetRouteConstraintMode = Forbidden / Required` ,用于手动测试全局禁经/必经路径约束。
58. `3D 布线连接` 面板提供“选中路径必须经过”和“选中路径禁止经过”,可直接给选中 route carrier 写入 `QetRouteConstraintMode` 。
59. `3D 布线连接` 面板提供“清除选中路径约束”,可把选中 route carrier 的 `QetRouteConstraintMode` 清空。
60. `3D 布线连接` 面板提供“清除全部路径约束”,可一次清空当前文档中 route carrier 和源路径对象上的 Required/Forbidden 规则。
61. 面板摘要会显示 carrier 级路径约束数量,便于确认当前 Required/Forbidden 规则是否仍在生效。
62. 源路径对象上的 `QetRouteConstraintMode` 会在清除/重生成 carrier 后继承到新 carrier, 避免路径约束刷新后丢失。
63. 选中的草图、Draft 线和纯线状对象如果包含弧线、样条边或整条 `Wire` 拓扑,会先离散为 polyline 再生成 `UserPath` ,避免曲线路径在自动布线网络中被拉直。
64. `UserPath` 从草图、Draft 线、边或 `Wire` 提取点时会按源对象的 `Placement` / `getGlobalPlacement()` 转成文档坐标,避免装配移动后的路径仍按本地坐标生成。
65. 同一个草图或 Draft 对象中存在多条不连通 `Wire` 时,会分别生成多条 `UserPath` ,不会把第一条路径末端和第二条路径起点硬连成一条假路径。
66. 面板和报告中的 `user_path_carriers` 表示本次生成或刷新成功的 `UserPath` 数量;重复选择同一路径对象重生成时会刷新原 carrier, 并仍计入数量, 便于确认操作生效。
67. 同一个源草图生成多条 `UserPath` 时,对源草图设置 Required/Forbidden 路径约束会同步标记全部生成 carrier, 避免多路径草图只约束第一条路径。
68. 多 `Wire` 源草图刷新时,如果草图中的路径数量减少,系统会删除多余旧 `UserPath` carrier; 如果路径数量增加, 系统会新增对应 carrier, 避免布线网络和当前黄色路径不一致。
69. 同一个源草图生成多条 `UserPath` 时,每条 carrier 会记录 `QetRouteSourcePathIndex` ,用于区分同一源对象下第几条路径,方便诊断和路径示例回溯。
70. 通用 route carrier 创建入口也使用同样的多 `Wire` 分段规则,脚本或旧入口创建 `RoutingPath` 时不会把不连通路径硬拼成一条。
71. 多 `Wire` 源草图设置 `QetRouteCarrierCapacity` / `QetWireCapacity` 时,生成的每条 `UserPath` 都会继承该容量,用于共路容量提示和复用成本。
72. 创建 `UserPath` 时如果同时选中支撑面 Face 和悬空草图/Draft 线,系统会把路径点投影到该支撑面并保留默认偏移,减少 Draft 工作平面不正确导致的悬空路径。
73. 同一个源草图生成多条 `UserPath` 时,通过面板清除选中路径约束会同时清空源草图和全部生成 carrier 的 Required/Forbidden 约束。
74. 多 `Wire` 源草图设置 Required 时,自动布线按源对象聚合判断,经过该源对象生成的任一相关 `UserPath` 即可满足必经条件;设置 Forbidden 时,该源对象生成的全部 `UserPath` 都会被跳过。
63. `QetRouteConstraintMode` 支持中文别名:`必须经过` / `必经` / `禁止经过` / `禁经` / `禁止` 。
已完成 FreeCAD smoke:
@ -687,20 +953,22 @@ tests/manual/freecad_auto_routing_smoke.py
4. 清除走线路径
5. 点击“准备布线布局空间”
6. 按当前机柜情况调整主路径桥接容差、端子接入最大距离、端子出线长度
7. 可选:选中无法自动识别的线槽实体
8. 点击“生成布线路径网络”;如果不选择,则使用整份文档自动识别
9. 点击“生成布线连接”
7. 可选:选中柜内空间、柜体内腔或辅助实体,点击“选中对象作为柜内边界”
8. 可选:选中无法自动识别的线槽实体
9. 点击“生成布线路径网络”;如果不选择,则使用整份文档自动识别
10. 点击“生成布线连接”
```
三个按钮的职责:
```text
准备布线布局空间:识别并标记 layout space 里的线槽、支撑面、工程端子和障碍处理方式
选中对象作为柜内边界:把选中对象包围盒标记为 CabinetInterior, 只参与 3D 自动布线边界评分
生成布线路径网络:按 EPLAN routing path network 逻辑生成 WireDuct、UserPath、RoutingRange 和 TerminalAccess carrier
生成布线连接:先更新布线路径网络,再检查/绑定工程端子,按 QET 导线任务批量求路并生成 AutoSuggested 导线
```
如果模型名称/标签足够规范, 可以不手动选择, 直接执行三步; 也可以只点击“生成布线连接”, 系统会准备当前可识别的布线路径网络。若线槽无法自动识别, 则先选中线槽实体执行“生成布线路径网络”作为补充。若甲方现场没有线槽, 或需要绕开线槽自由定义柜内主路径, 可以选中草图、Draft 线、线段或纯线状对象,再执行“生成布线路径网络”,系统会生成 `UserPath` 。
如果模型名称/标签足够规范, 可以不手动选择, 直接执行三步; 也可以只点击“生成布线连接”, 系统会准备当前可识别的布线路径网络。若线槽无法自动识别, 则先选中线槽实体执行“生成布线路径网络”作为补充。若甲方现场没有线槽, 或需要绕开线槽自由定义柜内主路径, 可以选中草图、Draft 线、线段或纯线状对象,再执行“生成布线路径网络”,系统会生成 `UserPath` 。若手动测试发现导线容易跑到柜外,可先选中柜内空间或辅助包围盒执行“选中对象作为柜内边界”。
### 6.2 批量生成布线连接前提
@ -708,16 +976,20 @@ tests/manual/freecad_auto_routing_smoke.py
2. 每条导线包含:
```text
start_instance_id 或 start_element_uuid
start_element_uuid
start_terminal_uuid
start_terminal_display
end_instance_id 或 end_element_uuid
end_element_uuid
end_terminal_uuid
end_terminal_display
```
3. FreeCAD 文档中存在对应 `QetTerminalUuid` 的工程端子,或存在可按设备和端子显示号匹配的 `local:*` 模板端子。
4. 布线连接只按导线任务生成,不会把场景里所有端子任意两两相连。
`start_instance_id / end_instance_id` 不作为第一版 `wires[]` 的必填字段; FreeCAD 会通过端点 `element_uuid` 、`terminal_uuid`、`devices[]` 和当前 3D 文档中的绑定属性回查 3D 实例。
3. 可选:单条导线可以携带 `required_route_carrier_*` / `forbidden_route_carrier_*` 路径约束字段,按 carrier 名称、标签、源标签或类型控制必须/禁止经过。
4. 可选: QET 启动 FreeCAD 时提供 `QET_WIRE_PROPERTIES_DB=<项目数据库路径>` ,或在 `2d_to_3d.json` 顶层提供 `wire_style_database_path` ,或调用自动布线时传入同名 options 字段,用于按 `wire_style_id` 查询 `wire_properties` 并渲染导线颜色/线宽。
5. FreeCAD 文档中存在对应 `QetTerminalUuid` 的工程端子,或存在可按设备和端子显示号匹配的 `local:*` 模板端子。
6. 布线连接只按导线任务生成,不会把场景里所有端子任意两两相连。
注意:批量生成布线连接的依据是导线任务,不是“所有端子自动互连”。如果文档中只有端子而没有 `wires[]` 或 `QETWiring_01_Tasks` ,系统不能判断哪些端子应该连接。
@ -733,6 +1005,14 @@ end_terminal_display
6. 线槽是导线主路径。导线应优先从设备端子经 `TerminalAccess` 进入线槽,再沿 `WireDuct` 网络到达另一端。
7. 过线孔/穿线孔用于连接不同安装面、线槽或柜体开孔处的网络,应建模为 `WiringCutOut` ,不是普通障碍。
从甲方提供的 KYN28-12 3D 布线教程和新增截图看,成熟软件里的流程并不是“导入设备后完全自动推导所有路径”。实际操作会先完成 3D 装配和电气设备关联, 再由工程人员预先绘制黄色草图路径, 最后自动布线沿这些路径生成导线。也就是说, 预置草图路径是正式布线输入, 不是临时调试线; FreeCAD 第一版应优先保证“导入/选择已有草图路径后稳定生成 `UserPath` 并参与求路”。
视频里还显示门板、仪表、端子排和柜内主区域之间存在跨部件路径。例如门板上的局部梳状路径会接入一条跨门板到柜内的长主路径,端子排区域也会先形成局部短路径,再接入主路径。这说明自动布线需要支持“设备局部路径 -> 柜内主路径”的分层网络,而不是只按端子到最近线槽的一跳距离判断。
装配阶段和布线阶段应分开理解:端子排、仪表、按钮、导轨等对象先通过装配/配合确定最终 3D 位置; 自动布线只读取最终几何位姿、工程端子、草图路径和导线任务。FreeCAD 不应让自动布线反向修改装配关系,也不应把 3D 草图路径写入第一版数据库绑定表。
视频中的 SW Electrical 还要求把 3D 设备和电气树中的设备/端子进行关联。对应到本项目, QET 的 `wires[]` 、`terminal_uuid` 和 2D/3D 绑定仍是电气真相源; FreeCAD 侧需要在自动布线前校验工程端子是否已由这些 UUID 绑定到正确的 3D 端子对象。
因此,自动布线的推荐空间语义是:
```text
@ -748,9 +1028,17 @@ end_terminal_display
1. 选中草图、Draft 线、线段或纯线状对象。
2. 点击 3D 布线连接面板中的“选中路径作为用户路径”,或直接点击“生成布线路径网络”。
3. 系统把选中路径转换为 `UserPath` carrier, 并参与后续自动布线最短路搜索。“选中路径作为用户路径”只创建用户路径; “生成布线路径网络”会同时更新线槽、布线面、端子接入等完整网络。
4. 再次选择同一个路径对象生成网络时,系统会刷新原 carrier, 不会重复生成。
4. 再次选择同一个路径对象生成网络时,系统会刷新原 carrier, 不会重复生成;面板报告中的 `user_path_carriers` 会把刷新成功的 carrier 也计入数量。如果多 `Wire` 草图里的路径数量减少,刷新时会删除多余旧 carrier 。
5. 如果删除了原草图/线段源对象,再点击“选中路径作为用户路径”或重新生成网络,系统会清理对应的失效 `UserPath` carrier。
6. 如果源对象设置了 `QetRouteCarrierCapacity` 或 `QetWireCapacity` ,生成/刷新出的 `UserPath` 会继承该容量,用于多根线共路和容量提示。
6. 如果源对象设置了 `QetRouteCarrierCapacity` 或 `QetWireCapacity` ,生成/刷新出的 `UserPath` 会继承该容量;同一个源草图拆成多条 `UserPath` 时,每条生成路径都会继承,用于多根线共路和容量提示。
甲方视频里的黄色路径有两类:一类是柜内/门板区域的主路径或过渡路径,适合生成 `UserPath` ;另一类是每个设备、端子排、按钮附近的短梳状局部出线路径,更适合沉淀为端子级 `TerminalAccess` 或 `QetTerminalLocalRoutePointsJson` 。两者都可以来自草图,但语义不同:主路径可被多根线共享,局部路径只服务对应端子或设备附近接入。
SW 教程中路径可以由“创建草图”或“转换草图”得到, 并且路径可能包含弧线、样条或多段折线。FreeCAD 侧处理草图路径时不能只依赖直线 `Points` ;当前已支持把草图边、整条 `Wire` 、Draft 线和曲线按离散精度转换为稳定 polyline, 再按源对象的最终 `Placement` 转到文档坐标生成 route carrier, 并保留 `QetRouteSourceName` / `QetRouteSourceLabel` ,方便路径刷新和诊断回溯。这样甲方视频里的黄色曲线路径不会被简单拉直成首尾两点,也不容易因为导入对象只暴露 `Shape.Wires` 或装配移动后仍使用本地坐标而漏建、错位用户路径。若同一个草图里有多条不连通 `Wire` ,系统会分别生成多条 `UserPath` ,避免在两条路径之间产生并不存在的直连段。
已有草图路径随工程导入一起存在时,手动测试推荐流程是:先打开工程并确认黄色/草图路径在树中可见,再执行“生成布线路径网络”或“选中路径作为用户路径”,最后生成布线连接。这样比在 FreeCAD 里临时画 Draft 线更接近甲方实际流程,也能减少因工作平面选错导致的悬空路径问题。
如果临时画的 Draft 线或草图线明显悬空,可同时选中安装板/柜板上的支撑面 Face 和该路径对象,再执行“选中路径作为用户路径”或“生成布线路径网络”。系统会把路径点投影到支撑面附近,而不是直接使用 Draft 当前工作平面坐标。
`UserPath` 与线槽的关系:
@ -773,6 +1061,18 @@ QetTerminalLocalRoutePointsJson
[[0, 0, 0], [10, 0, 0], [10, 30, 0]]
```
也可以写成对象包装格式,便于后续模板工具附加其它元数据;当前会识别 `points` 、`route_points` 或 `local_points` 三个数组键:
```json
{
"points": [
{"x": 0, "y": 0, "z": 0},
{"x": 10, "y": 0, "z": 0},
{"x": 10, "y": 30, "z": 0}
]
}
```
自动生成 `TerminalAccess` 时,系统会先把这些局部点按端子和父设备的 `Placement` 转成全局点,再从局部路径末端连接到最近的柜内主路径、线槽、用户路径或布线面。没有该字段时,仍使用原来的端子 LCS `+Z` 方向短出线。
路径网络检查也使用同一口径:如果端子有有效局部路径,端子到主路径网络的接入距离按局部路径末端计算,而不是按默认 LCS 出线点计算。这样可以避免局部路径已经接入线槽、但诊断仍误报“端子未接入”的情况。
@ -794,7 +1094,7 @@ QetTerminalLocalRoutePointsJson
导入/更新工程端子时, FreeCAD 会把 `local_route_points` 写入该端子的 `QetTerminalLocalRoutePointsJson` 。后续自动生成 `TerminalAccess` 和最终导线几何时都会使用这段局部路径。
路径网络检查会校验端子局部路径元数据。`QetTerminalLocalRoutePointsJson` / `QetLocalRoutePointsJson` 必须是 JSON 数组,并且至少能解析出两个不同的有效点;如果 JSON 格式错误、不是 数组或有效点不足,诊断对象会记录 `invalid_terminal_local_routes` ,中文报告会提示“端子局部路径无效”。这类问题不会让 FreeCAD 依赖 QET 提供 3D 路径,只是提示模板端子或工程端子的 3D 局部出线元数据需要修正。
路径网络检查会校验端子局部路径元数据。`QetTerminalLocalRoutePointsJson` / `QetLocalRoutePointsJson` 必须是 JSON 数组,或包含 `points` / `route_points` / `local_points` 数组的 JSON 对象, 并且至少能解析出两个不同的有效点;如果 JSON 格式错误、没有可识别的点 数组或有效点不足,诊断对象会记录 `invalid_terminal_local_routes` ,中文报告会提示“端子局部路径无效”。这类问题不会让 FreeCAD 依赖 QET 提供 3D 路径,只是提示模板端子或工程端子的 3D 局部出线元数据需要修正。
如果直接在 FCStd 模板端子 LCS 上维护,也可以给模板端子写入同名属性 `QetTerminalLocalRoutePointsJson` 。当前模板作者工具提供了内部函数:
@ -813,6 +1113,18 @@ TemplateAuthoring.set_template_terminal_local_route_points(terminal, points)
4. 系统把所选路径的文档坐标转换为该端子的本地坐标,并写入 QetTerminalLocalRoutePointsJson。
```
如果已经在工程机柜里完成装配,也可以直接给工程端子补现场局部出线路径:
```text
1. 在 3D 布线连接面板中,先选中一个可布线工程端子。
2. 再选中一条表示该端子局部出线的草图、Draft 线、边或连续 Wire。
3. 点击“选中端子设置局部出线”。
4. 系统把所选路径从 FreeCAD 文档坐标转换为该端子的本地坐标,并写入工程端子的 QetTerminalLocalRoutePointsJson。
5. 重新点击“生成布线路径网络”或“生成布线连接”,新的 TerminalAccess 会优先沿这段局部路径接入柜内主路径。
```
这个工程端子现场设置入口只修改当前 FreeCAD 文档,不写数据库,也不要求 QET 输出 3D 路径。它适合手动测试中发现某个设备端子接入过长、从设备内部穿模、或默认 LCS 出线方向不符合实物时使用。若同一类设备会在多个项目复用,应优先把局部路径沉淀到 FCStd 设备模板里;若只是当前机柜现场微调,可以直接在工程端子上设置。
第一版不要求 QET 提供这个字段。它属于 FreeCAD 设备模板/工程端子的 3D 几何元数据,由 FreeCAD 模板作者维护; QET 仍只提供导线任务、设备实例、端子实例和 2D/3D 绑定所需 UUID。
## 7. 当前限制
@ -840,14 +1152,14 @@ TemplateAuthoring.set_template_terminal_local_route_points(terminal, points)
2. 路径网络规模较大,但检查提示存在孤立路径网络和端子接入过长,说明部分设备局部路径没有可靠接入柜内主路径。
3. 部分导线穿过设备模型。当前碰撞检测只给出告警,不会强制阻止生成,因此在可用绕行路径不足时仍可能生成穿模导线。
4. 多根导线在公共路径上共线或高度拥挤。在线槽内共路可以接受,但在线槽外和设备端子附近需要更好的并行错位、束线显示和容量策略。
5. 部分导线跑到机柜外侧。该问题需要后续增加柜内有效区域/柜体边界诊断,但当前优先级低于提升布通率 。
5. 部分导线跑到机柜外侧。当前已支持把柜内空间、柜体或辅助实体标记为 `CabinetInterior` 边界,并在批量报告中提示仍越出柜内区域的导线;但该能力依赖用户先标记边界,且仍需要补充柜内 `UserPath` 、线槽或局部路径来提供可选的柜内路线 。
6. Draft 线段可能悬空。原因通常是 Draft 当前工作平面没有锁定到安装板或线槽面;作为自由空间 `UserPath` 这是允许的,但作为贴面主路径时需要投影、吸附或明确提示。
当前开发优先级调整为:
1. 先保证更多导线能稳定布通,优先处理孤立路径网络和端子接入过长。
2. 其次降低明显穿模和线槽外共线拥挤。
3. 柜内越界诊断放到后续阶段,不阻塞当前布通率改进 。
3. 柜内越界诊断已进入第一版收尾能力:有边界对象时会参与候选评分,并在最终路径仍越界时输出“柜内边界提示”;后续重点是让边界更容易自动识别和让用户路径更容易贴合到柜内结构 。
已完成的对应改进:
@ -860,6 +1172,7 @@ TemplateAuthoring.set_template_terminal_local_route_points(terminal, points)
7. 接入候选评分会检查端子出口到路径网络入口之间的小段是否穿过障碍包围盒;当近入口接入段穿模、稍远入口可避开障碍时,会优先选择不穿模的入口。最终碰撞诊断仍保留端点附近设备外壳的宽容规则,避免把端子自身外壳误报成碰撞。
8. 同一个路径入口已经确定后,端子出口到入口、主路径出口到端子入口的正交折线会尝试不同轴向顺序;当“先走 X”会穿设备、“先走 Y/Z”可绕开时, 优先使用不穿模的折线顺序。
9. 并行导线 lane 偏移增加默认上限,避免大量导线共路时可视错位距离随 lane 序号无限增大, 把导线推到线槽或柜体外。lane 序号仍保留,用于容量提示和并行数量报告。
10. 柜内边界对象会先参与路径图过滤, 再参与路径候选评分。若柜内过滤图不可达且最终路径仍存在柜内越界点, 中文报告会显示“柜内边界提示”, compact 诊断会写入 `route_candidate_boundary_warning_count` 和 `route_candidate_boundary_warning_samples` 。
### 8.1 近期优先级
@ -953,6 +1266,8 @@ PE 线优先路径
11. 两条相交或重叠的线槽中心路径能在交点/重叠端点处连通并自动拐弯。
12. 自动识别出的安装板/柜面能生成低优先级 `RoutingRange` ,并可被布线连接使用。
13. 保存 FreeCAD 文档后,自动导线和路由网络仍保留。
14. 如果 `wires[].wire_style_id` 能在 `wire_properties` 中解析,生成导线会使用对应的显示颜色、线宽和线型;解析失败时诊断显示 `Missing` ,但仍按默认蓝色样式生成导线。
15. “生成布线连接”后的 `RoutingConnectionBatch` 诊断对象保存最终 report, 包括 `hidden_route_carriers` 、`routing_path_network_updated`、路径网络检查结果和 `no_routed_connections` 等问题码。
## 10. 开发验证命令