feat: 面板支持并行线方向

dev
Zhaowenlong 3 weeks ago
parent 71e2fec765
commit 2302eea33f

@ -91,7 +91,7 @@ FreeCAD 的 `3D 布线连接` 面板提供“线槽桥接容差 mm”数值框
同一面板还提供“端子接入最大距离 mm”和“端子出线长度 mm”。前者用于控制端子距离最近路由网络超过多少毫米时不再生成 `TerminalAccess`,避免设备还没摆放好时生成超长悬空接入线;后者用于控制端子沿 LCS 出线方向先走出的短线长度,避免导线从设备壳体内部或端子原点直接折返。 同一面板还提供“端子接入最大距离 mm”和“端子出线长度 mm”。前者用于控制端子距离最近路由网络超过多少毫米时不再生成 `TerminalAccess`,避免设备还没摆放好时生成超长悬空接入线;后者用于控制端子沿 LCS 出线方向先走出的短线长度,避免导线从设备壳体内部或端子原点直接折返。
面板还提供“并行线间距 mm”用于控制多根导线共用同一路径时的可视 lane 偏移距离。它只影响 3D 显示上导线之间的错位间距,不代表真实线槽截面内的排布位置。 面板还提供“并行线间距 mm”和“并行线方向”,用于控制多根导线共用同一路径时的可视 lane 偏移。方向默认 `auto`,也可以手动指定 `x`、`y`、`z`。这些设置只影响 3D 显示上导线之间的错位方式,不代表真实线槽截面内的排布位置。
### 2.1 路由优先级 ### 2.1 路由优先级
@ -462,7 +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 偏移距离 37. `3D 布线连接` 面板提供“并行线间距 mm”和“并行线方向”设置,用于调整多线共路时的可视 lane 偏移。
已完成 FreeCAD smoke 已完成 FreeCAD smoke

@ -106,6 +106,12 @@ class AutoRoutingController:
lane_spacing = AutoRouting.DEFAULT_OPTIONS["lane_spacing"] lane_spacing = AutoRouting.DEFAULT_OPTIONS["lane_spacing"]
self.options["lane_spacing"] = max(lane_spacing, 0.0) self.options["lane_spacing"] = max(lane_spacing, 0.0)
def set_lane_axis(self, value):
lane_axis = str(value or "").strip().lower()
if lane_axis not in {"auto", "x", "y", "z"}:
lane_axis = AutoRouting.DEFAULT_OPTIONS["lane_axis"]
self.options["lane_axis"] = lane_axis
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))
@ -288,6 +294,19 @@ class AutoRoutingTaskPanel:
) )
) )
options_layout.addWidget(self.lane_spacing_spin) options_layout.addWidget(self.lane_spacing_spin)
options_layout.addWidget(QtWidgets.QLabel("并行线方向"))
self.lane_axis_combo = QtWidgets.QComboBox()
self.lane_axis_combo.addItems(["auto", "x", "y", "z"])
lane_axis = str(
self.controller.routing_options().get(
"lane_axis",
AutoRouting.DEFAULT_OPTIONS["lane_axis"],
)
or "auto"
).lower()
axis_index = self.lane_axis_combo.findText(lane_axis)
self.lane_axis_combo.setCurrentIndex(axis_index if axis_index >= 0 else 0)
options_layout.addWidget(self.lane_axis_combo)
self.generate_layout_button = QtWidgets.QPushButton("准备布线布局空间") self.generate_layout_button = QtWidgets.QPushButton("准备布线布局空间")
self.generate_layout_button.setToolTip( self.generate_layout_button.setToolTip(
@ -359,6 +378,7 @@ class AutoRoutingTaskPanel:
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()) self.controller.set_lane_spacing(self.lane_spacing_spin.value())
self.controller.set_lane_axis(self.lane_axis_combo.currentText())
def generate_routing_paths(self): def generate_routing_paths(self):
try: try:

@ -1771,6 +1771,49 @@ class AutoRoutingTest(unittest.TestCase):
self.assertEqual(14.0, report["routes"][1]["lane"]["spacing_mm"]) self.assertEqual(14.0, report["routes"][1]["lane"]["spacing_mm"])
self.assertEqual(14.0, report["routes"][1]["lane"]["offset_mm"]) self.assertEqual(14.0, report["routes"][1]["lane"]["offset_mm"])
def test_auto_routing_controller_exposes_lane_axis(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(0, 100, 0))
_terminal(doc, terminal_objects, "TerminalStartB", "terminal-start-b", app.Vector(0, 0, 0))
_terminal(doc, terminal_objects, "TerminalEndB", "terminal-end-b", app.Vector(0, 100, 0))
routing_network.create_route_carrier(
doc,
[app.Vector(0, 0, 20), app.Vector(0, 100, 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(8.0)
controller.set_lane_axis("z")
report = controller.route_eplan_connections()
self.assertEqual("z", controller.routing_options()["lane_axis"])
self.assertEqual("z", report["routes"][1]["lane"]["axis"])
self.assertEqual(8.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