diff --git a/docs/FreeCAD 3D自动布线设计方案.md b/docs/FreeCAD 3D自动布线设计方案.md index 541ac09..69fe0ef 100644 --- a/docs/FreeCAD 3D自动布线设计方案.md +++ b/docs/FreeCAD 3D自动布线设计方案.md @@ -87,6 +87,8 @@ terminal_uuid 相邻线槽端点允许存在小间隙。默认情况下,两个 `WireDuct` 端点距离不超过 5 mm 时会被视为相邻并自动桥接;自动布线选项 `adjoining_duct_tolerance` 可以按需要调大或调小,用于适配不同建模精度和线槽端部留缝。 +FreeCAD 的 `3D 布线连接` 面板提供“线槽桥接容差 mm”数值框,手动测试时可直接调整这个选项;生成布线路径网络、检查布线路径网络和生成布线连接都会读取当前面板值。 + ### 2.1 路由优先级 当前版本按下面优先级处理: @@ -432,6 +434,7 @@ tests/python/freecad_exchange_auto_routing_test.py 27. 批量布线报告会显示一条路径示例,列出首条可追踪导线经过的源对象标签。 28. 线槽源对象支持通过 `QetWireDuctEndMarginMm` 按对象调整中心路径端部缩进距离。 29. 自动布线支持通过 `adjoining_duct_tolerance` 调整相邻线槽端点自动桥接容差,并在网络结果中记录桥接段数量。 +30. `3D 布线连接` 面板提供“线槽桥接容差 mm”设置,面板生成/检查/布线流程会使用该值。 已完成 FreeCAD smoke: diff --git a/src/Mod/FreeCADExchange/AutoRoutingPanel.py b/src/Mod/FreeCADExchange/AutoRoutingPanel.py index e5e3906..5fd190d 100644 --- a/src/Mod/FreeCADExchange/AutoRoutingPanel.py +++ b/src/Mod/FreeCADExchange/AutoRoutingPanel.py @@ -71,8 +71,19 @@ def _selection_ex(): class AutoRoutingController: - def __init__(self): + def __init__(self, options=None): self.last_report = None + self.options = dict(options or {}) + + def routing_options(self): + return dict(self.options) + + def set_adjoining_duct_tolerance(self, value): + try: + tolerance = float(value) + except Exception: + tolerance = RoutingNetwork.DEFAULT_ADJOINING_DUCT_TOLERANCE + self.options["adjoining_duct_tolerance"] = max(tolerance, 0.0) def summary(self): doc = _active_document() @@ -109,6 +120,7 @@ class AutoRoutingController: self.last_report = AutoRouting.generate_eplan_routing_path_network( doc, project_uuid=project_uuid, + options=self.routing_options(), selection_ex=selection_ex, ) self.last_report["source_mode"] = source_mode @@ -120,6 +132,7 @@ class AutoRoutingController: self.last_report = AutoRouting.check_eplan_routing_path_network( doc, project_uuid=project_uuid, + options=self.routing_options(), ) return self.last_report @@ -141,6 +154,7 @@ class AutoRoutingController: report = AutoRouting.route_eplan_connections( doc, payload=payload if isinstance(payload, dict) and payload.get("wires") else None, + options=self.routing_options(), project_uuid=project_uuid, update_network=True, ) @@ -183,6 +197,22 @@ class AutoRoutingTaskPanel: layout = QtWidgets.QVBoxLayout(self.form) + options_layout = QtWidgets.QHBoxLayout() + options_layout.addWidget(QtWidgets.QLabel("线槽桥接容差 mm")) + self.adjoining_duct_tolerance_spin = QtWidgets.QDoubleSpinBox() + self.adjoining_duct_tolerance_spin.setRange(0.0, 1000.0) + self.adjoining_duct_tolerance_spin.setDecimals(1) + self.adjoining_duct_tolerance_spin.setSingleStep(1.0) + self.adjoining_duct_tolerance_spin.setValue( + float( + self.controller.routing_options().get( + "adjoining_duct_tolerance", + RoutingNetwork.DEFAULT_ADJOINING_DUCT_TOLERANCE, + ) + ) + ) + options_layout.addWidget(self.adjoining_duct_tolerance_spin) + self.generate_layout_button = QtWidgets.QPushButton("准备布线布局空间") self.generate_layout_button.setToolTip( "按 EPLAN 布局空间语义识别线槽、安装面、工程端子和障碍处理方式,不生成导线。" @@ -221,6 +251,7 @@ class AutoRoutingTaskPanel: ): layout.addWidget(widget) + layout.addLayout(options_layout) layout.addWidget(self.status_label) self.generate_paths_button.clicked.connect(self.generate_routing_paths) @@ -247,8 +278,12 @@ class AutoRoutingTaskPanel: self.status_label.setText(message) _console_error(message) + def _sync_options_from_widgets(self): + self.controller.set_adjoining_duct_tolerance(self.adjoining_duct_tolerance_spin.value()) + def generate_routing_paths(self): try: + self._sync_options_from_widgets() result = self.controller.generate_routing_paths() wire_ducts = result.get("wire_duct_carriers", 0) surfaces = result.get("surface_carriers", 0) @@ -274,6 +309,7 @@ class AutoRoutingTaskPanel: def check_routing_path_network(self): try: + self._sync_options_from_widgets() result = self.controller.check_routing_path_network() diagnostic = result.get("diagnostic", {}) if isinstance(result.get("diagnostic", {}), dict) else {} self._set_status( @@ -310,6 +346,7 @@ class AutoRoutingTaskPanel: def route_eplan_connections(self): try: + self._sync_options_from_widgets() report = self.controller.route_eplan_connections() self._set_status(AutoRouting.format_eplan_connection_route_report(report)) except Exception as exc: diff --git a/tests/python/freecad_exchange_auto_routing_test.py b/tests/python/freecad_exchange_auto_routing_test.py index bc9283e..8dc20be 100644 --- a/tests/python/freecad_exchange_auto_routing_test.py +++ b/tests/python/freecad_exchange_auto_routing_test.py @@ -1538,6 +1538,46 @@ class AutoRoutingTest(unittest.TestCase): self.assertEqual(1, diagnostic_payload["prepared_layout"]["wire_duct_carriers"]) self.assertEqual(2, diagnostic_payload["prepared_layout"]["terminal_access_carriers"]) + def test_auto_routing_controller_passes_adjoining_duct_tolerance_to_batch_route(self): + _install_fake_freecad() + terminal_objects, _wiring_objects, routing_network, _auto_routing = _reload_modules() + auto_routing_panel = importlib.import_module("AutoRoutingPanel") + app = sys.modules["FreeCAD"] + doc = FakeDocument() + app.ActiveDocument = doc + terminal_objects.ensure_root_group(doc, "project-1") + _terminal(doc, terminal_objects, "TerminalStart", "terminal-start", app.Vector(0, 0, 0)) + _terminal(doc, terminal_objects, "TerminalEnd", "terminal-end", app.Vector(100, 0, 0)) + routing_network.create_route_carrier( + doc, + [app.Vector(0, 0, 20), app.Vector(44, 0, 20)], + project_uuid="project-1", + kind="WireDuct", + ) + routing_network.create_route_carrier( + doc, + [app.Vector(56, 0, 20), app.Vector(100, 0, 20)], + project_uuid="project-1", + kind="WireDuct", + ) + app._qet_exchange_payload = { + "project_uuid": "project-1", + "wires": [ + { + "wire_id": "wire-1", + "start_terminal_uuid": "terminal-start", + "end_terminal_uuid": "terminal-end", + } + ], + } + + report = auto_routing_panel.AutoRoutingController( + options={"adjoining_duct_tolerance": 15.0} + ).route_eplan_connections() + + self.assertEqual(1, report["routed"]) + self.assertEqual(1, report["routes"][0]["network"]["bridged_segments"]) + def test_eplan_connection_route_rejects_far_network_entry_to_avoid_huge_render_bbox(self): _install_fake_freecad() terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()