feat: 面板支持线槽桥接容差

dev
Zhaowenlong 3 weeks ago
parent 173580594c
commit d3b38dc70a

@ -87,6 +87,8 @@ terminal_uuid
相邻线槽端点允许存在小间隙。默认情况下,两个 `WireDuct` 端点距离不超过 5 mm 时会被视为相邻并自动桥接;自动布线选项 `adjoining_duct_tolerance` 可以按需要调大或调小,用于适配不同建模精度和线槽端部留缝。 相邻线槽端点允许存在小间隙。默认情况下,两个 `WireDuct` 端点距离不超过 5 mm 时会被视为相邻并自动桥接;自动布线选项 `adjoining_duct_tolerance` 可以按需要调大或调小,用于适配不同建模精度和线槽端部留缝。
FreeCAD 的 `3D 布线连接` 面板提供“线槽桥接容差 mm”数值框手动测试时可直接调整这个选项生成布线路径网络、检查布线路径网络和生成布线连接都会读取当前面板值。
### 2.1 路由优先级 ### 2.1 路由优先级
当前版本按下面优先级处理: 当前版本按下面优先级处理:
@ -432,6 +434,7 @@ tests/python/freecad_exchange_auto_routing_test.py
27. 批量布线报告会显示一条路径示例,列出首条可追踪导线经过的源对象标签。 27. 批量布线报告会显示一条路径示例,列出首条可追踪导线经过的源对象标签。
28. 线槽源对象支持通过 `QetWireDuctEndMarginMm` 按对象调整中心路径端部缩进距离。 28. 线槽源对象支持通过 `QetWireDuctEndMarginMm` 按对象调整中心路径端部缩进距离。
29. 自动布线支持通过 `adjoining_duct_tolerance` 调整相邻线槽端点自动桥接容差,并在网络结果中记录桥接段数量。 29. 自动布线支持通过 `adjoining_duct_tolerance` 调整相邻线槽端点自动桥接容差,并在网络结果中记录桥接段数量。
30. `3D 布线连接` 面板提供“线槽桥接容差 mm”设置面板生成/检查/布线流程会使用该值。
已完成 FreeCAD smoke 已完成 FreeCAD smoke

@ -71,8 +71,19 @@ def _selection_ex():
class AutoRoutingController: class AutoRoutingController:
def __init__(self): def __init__(self, options=None):
self.last_report = 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): def summary(self):
doc = _active_document() doc = _active_document()
@ -109,6 +120,7 @@ class AutoRoutingController:
self.last_report = AutoRouting.generate_eplan_routing_path_network( self.last_report = AutoRouting.generate_eplan_routing_path_network(
doc, doc,
project_uuid=project_uuid, project_uuid=project_uuid,
options=self.routing_options(),
selection_ex=selection_ex, selection_ex=selection_ex,
) )
self.last_report["source_mode"] = source_mode self.last_report["source_mode"] = source_mode
@ -120,6 +132,7 @@ class AutoRoutingController:
self.last_report = AutoRouting.check_eplan_routing_path_network( self.last_report = AutoRouting.check_eplan_routing_path_network(
doc, doc,
project_uuid=project_uuid, project_uuid=project_uuid,
options=self.routing_options(),
) )
return self.last_report return self.last_report
@ -141,6 +154,7 @@ class AutoRoutingController:
report = AutoRouting.route_eplan_connections( report = AutoRouting.route_eplan_connections(
doc, doc,
payload=payload if isinstance(payload, dict) and payload.get("wires") else None, payload=payload if isinstance(payload, dict) and payload.get("wires") else None,
options=self.routing_options(),
project_uuid=project_uuid, project_uuid=project_uuid,
update_network=True, update_network=True,
) )
@ -183,6 +197,22 @@ class AutoRoutingTaskPanel:
layout = QtWidgets.QVBoxLayout(self.form) 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 = QtWidgets.QPushButton("准备布线布局空间")
self.generate_layout_button.setToolTip( self.generate_layout_button.setToolTip(
"按 EPLAN 布局空间语义识别线槽、安装面、工程端子和障碍处理方式,不生成导线。" "按 EPLAN 布局空间语义识别线槽、安装面、工程端子和障碍处理方式,不生成导线。"
@ -221,6 +251,7 @@ class AutoRoutingTaskPanel:
): ):
layout.addWidget(widget) layout.addWidget(widget)
layout.addLayout(options_layout)
layout.addWidget(self.status_label) layout.addWidget(self.status_label)
self.generate_paths_button.clicked.connect(self.generate_routing_paths) self.generate_paths_button.clicked.connect(self.generate_routing_paths)
@ -247,8 +278,12 @@ class AutoRoutingTaskPanel:
self.status_label.setText(message) self.status_label.setText(message)
_console_error(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): def generate_routing_paths(self):
try: try:
self._sync_options_from_widgets()
result = self.controller.generate_routing_paths() result = self.controller.generate_routing_paths()
wire_ducts = result.get("wire_duct_carriers", 0) wire_ducts = result.get("wire_duct_carriers", 0)
surfaces = result.get("surface_carriers", 0) surfaces = result.get("surface_carriers", 0)
@ -274,6 +309,7 @@ class AutoRoutingTaskPanel:
def check_routing_path_network(self): def check_routing_path_network(self):
try: try:
self._sync_options_from_widgets()
result = self.controller.check_routing_path_network() result = self.controller.check_routing_path_network()
diagnostic = result.get("diagnostic", {}) if isinstance(result.get("diagnostic", {}), dict) else {} diagnostic = result.get("diagnostic", {}) if isinstance(result.get("diagnostic", {}), dict) else {}
self._set_status( self._set_status(
@ -310,6 +346,7 @@ class AutoRoutingTaskPanel:
def route_eplan_connections(self): def route_eplan_connections(self):
try: try:
self._sync_options_from_widgets()
report = self.controller.route_eplan_connections() report = self.controller.route_eplan_connections()
self._set_status(AutoRouting.format_eplan_connection_route_report(report)) self._set_status(AutoRouting.format_eplan_connection_route_report(report))
except Exception as exc: except Exception as exc:

@ -1538,6 +1538,46 @@ class AutoRoutingTest(unittest.TestCase):
self.assertEqual(1, diagnostic_payload["prepared_layout"]["wire_duct_carriers"]) self.assertEqual(1, diagnostic_payload["prepared_layout"]["wire_duct_carriers"])
self.assertEqual(2, diagnostic_payload["prepared_layout"]["terminal_access_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): def test_eplan_connection_route_rejects_far_network_entry_to_avoid_huge_render_bbox(self):
_install_fake_freecad() _install_fake_freecad()
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules() terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()

Loading…
Cancel
Save