feat: 面板支持并行线间距

dev
Zhaowenlong 3 weeks ago
parent 02bae59017
commit 71e2fec765

@ -91,6 +91,8 @@ FreeCAD 的 `3D 布线连接` 面板提供“线槽桥接容差 mm”数值框
同一面板还提供“端子接入最大距离 mm”和“端子出线长度 mm”。前者用于控制端子距离最近路由网络超过多少毫米时不再生成 `TerminalAccess`,避免设备还没摆放好时生成超长悬空接入线;后者用于控制端子沿 LCS 出线方向先走出的短线长度,避免导线从设备壳体内部或端子原点直接折返。 同一面板还提供“端子接入最大距离 mm”和“端子出线长度 mm”。前者用于控制端子距离最近路由网络超过多少毫米时不再生成 `TerminalAccess`,避免设备还没摆放好时生成超长悬空接入线;后者用于控制端子沿 LCS 出线方向先走出的短线长度,避免导线从设备壳体内部或端子原点直接折返。
面板还提供“并行线间距 mm”用于控制多根导线共用同一路径时的可视 lane 偏移距离。它只影响 3D 显示上导线之间的错位间距,不代表真实线槽截面内的排布位置。
### 2.1 路由优先级 ### 2.1 路由优先级
当前版本按下面优先级处理: 当前版本按下面优先级处理:
@ -460,6 +462,7 @@ tests/python/freecad_exchange_auto_routing_test.py
34. 批量布线报告会显示最大 lane 编号和 lane 间距,方便确认多根线共路时是否发生了可视错位。 34. 批量布线报告会显示最大 lane 编号和 lane 间距,方便确认多根线共路时是否发生了可视错位。
35. `QetRouteTrackJson` 的 carrier payload 会记录 `capacity`,方便后续分析线槽容量偏好和共路绕行。 35. `QetRouteTrackJson` 的 carrier payload 会记录 `capacity`,方便后续分析线槽容量偏好和共路绕行。
36. 批量布线报告会在最大并行线数超过路径最小容量时显示容量提示,但当前仍不做真实填充率计算。 36. 批量布线报告会在最大并行线数超过路径最小容量时显示容量提示,但当前仍不做真实填充率计算。
37. `3D 布线连接` 面板提供“并行线间距 mm”设置用于调整多线共路时的可视 lane 偏移距离。
已完成 FreeCAD smoke 已完成 FreeCAD smoke

@ -99,6 +99,13 @@ class AutoRoutingController:
exit_length = AutoRouting.DEFAULT_OPTIONS["terminal_exit_length"] exit_length = AutoRouting.DEFAULT_OPTIONS["terminal_exit_length"]
self.options["terminal_exit_length"] = max(exit_length, 0.0) self.options["terminal_exit_length"] = max(exit_length, 0.0)
def set_lane_spacing(self, value):
try:
lane_spacing = float(value)
except Exception:
lane_spacing = AutoRouting.DEFAULT_OPTIONS["lane_spacing"]
self.options["lane_spacing"] = max(lane_spacing, 0.0)
def summary(self): def summary(self):
doc = _active_document() doc = _active_document()
terminal_count = len(AutoRouting.index_terminals(doc)) terminal_count = len(AutoRouting.index_terminals(doc))
@ -267,6 +274,20 @@ class AutoRoutingTaskPanel:
) )
) )
options_layout.addWidget(self.terminal_exit_length_spin) options_layout.addWidget(self.terminal_exit_length_spin)
options_layout.addWidget(QtWidgets.QLabel("并行线间距 mm"))
self.lane_spacing_spin = QtWidgets.QDoubleSpinBox()
self.lane_spacing_spin.setRange(0.0, 1000.0)
self.lane_spacing_spin.setDecimals(1)
self.lane_spacing_spin.setSingleStep(1.0)
self.lane_spacing_spin.setValue(
float(
self.controller.routing_options().get(
"lane_spacing",
AutoRouting.DEFAULT_OPTIONS["lane_spacing"],
)
)
)
options_layout.addWidget(self.lane_spacing_spin)
self.generate_layout_button = QtWidgets.QPushButton("准备布线布局空间") self.generate_layout_button = QtWidgets.QPushButton("准备布线布局空间")
self.generate_layout_button.setToolTip( self.generate_layout_button.setToolTip(
@ -337,6 +358,7 @@ class AutoRoutingTaskPanel:
self.controller.set_adjoining_duct_tolerance(self.adjoining_duct_tolerance_spin.value()) self.controller.set_adjoining_duct_tolerance(self.adjoining_duct_tolerance_spin.value())
self.controller.set_terminal_access_max_distance(self.terminal_access_max_distance_spin.value()) self.controller.set_terminal_access_max_distance(self.terminal_access_max_distance_spin.value())
self.controller.set_terminal_exit_length(self.terminal_exit_length_spin.value()) self.controller.set_terminal_exit_length(self.terminal_exit_length_spin.value())
self.controller.set_lane_spacing(self.lane_spacing_spin.value())
def generate_routing_paths(self): def generate_routing_paths(self):
try: try:

@ -1729,6 +1729,48 @@ class AutoRoutingTest(unittest.TestCase):
self.assertIn("桥接1", summary) self.assertIn("桥接1", summary)
def test_auto_routing_controller_exposes_lane_spacing(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, "TerminalStartA", "terminal-start-a", app.Vector(0, 0, 0))
_terminal(doc, terminal_objects, "TerminalEndA", "terminal-end-a", app.Vector(100, 0, 0))
_terminal(doc, terminal_objects, "TerminalStartB", "terminal-start-b", app.Vector(0, 0, 0))
_terminal(doc, terminal_objects, "TerminalEndB", "terminal-end-b", app.Vector(100, 0, 0))
routing_network.create_route_carrier(
doc,
[app.Vector(0, 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-a",
"start_terminal_uuid": "terminal-start-a",
"end_terminal_uuid": "terminal-end-a",
},
{
"wire_id": "wire-b",
"start_terminal_uuid": "terminal-start-b",
"end_terminal_uuid": "terminal-end-b",
},
],
}
controller = auto_routing_panel.AutoRoutingController()
controller.set_lane_spacing(14.0)
report = controller.route_eplan_connections()
self.assertEqual(14.0, controller.routing_options()["lane_spacing"])
self.assertEqual(14.0, report["routes"][1]["lane"]["spacing_mm"])
self.assertEqual(14.0, report["routes"][1]["lane"]["offset_mm"])
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