diff --git a/src/Mod/FreeCADExchange/AutoRouting.py b/src/Mod/FreeCADExchange/AutoRouting.py index 144a272..e259a9a 100644 --- a/src/Mod/FreeCADExchange/AutoRouting.py +++ b/src/Mod/FreeCADExchange/AutoRouting.py @@ -1098,6 +1098,18 @@ def _wire_item_value(item, *names): return "" +def _route_lane_key(start_uuid, end_uuid): + endpoints = sorted( + value + for value in ( + str(start_uuid or "").strip(), + str(end_uuid or "").strip(), + ) + if value + ) + return tuple(endpoints) + + def bind_wire_task_terminals_from_payload(doc, payload): """Bind local template terminals to QET terminal UUIDs without creating wires.""" if doc is None: @@ -1175,8 +1187,9 @@ def route_eplan_connections_from_payload(doc, payload, options=None, prepared_la if isinstance(prepared_layout, dict): report["prepared_layout"] = prepared_layout missing_endpoint_uuids = set() + lane_indexes_by_pair = {} - for index, item in enumerate(wires): + for item in wires: if not isinstance(item, dict): report["skipped_invalid"] += 1 continue @@ -1206,12 +1219,14 @@ def route_eplan_connections_from_payload(doc, payload, options=None, prepared_la } ) continue + lane_key = _route_lane_key(start_uuid, end_uuid) + route_lane_index = lane_indexes_by_pair.get(lane_key, 0) try: result = route_eplan_connection_between_terminals( doc, start_terminal, end_terminal, - route_index=index, + route_index=route_lane_index, options=options, wire_uuid=_wire_item_value(item, "wire_id", "wire_uuid", "id"), wire_label=_wire_item_value(item, "wire_label", "wire_mark"), @@ -1224,6 +1239,7 @@ def route_eplan_connections_from_payload(doc, payload, options=None, prepared_la except Exception as exc: report["errors"].append(str(exc)) continue + lane_indexes_by_pair[lane_key] = route_lane_index + 1 if result["route_status"] == "CollisionWarning": report["collision_warnings"] += 1 route_collision_samples = [] diff --git a/tests/python/freecad_exchange_auto_routing_test.py b/tests/python/freecad_exchange_auto_routing_test.py index f57050c..7648c1f 100644 --- a/tests/python/freecad_exchange_auto_routing_test.py +++ b/tests/python/freecad_exchange_auto_routing_test.py @@ -1241,6 +1241,59 @@ class AutoRoutingTest(unittest.TestCase): self.assertEqual(1, route["network"]["carriers"]) self.assertEqual("WireDuct", route["route_track"]["segments"][0]["carrier"]["kind"]) + def test_route_eplan_connections_lane_index_is_per_terminal_pair(self): + _install_fake_freecad() + terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules() + app = sys.modules["FreeCAD"] + doc = FakeDocument() + 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, 100, 0)) + _terminal(doc, terminal_objects, "TerminalEndB", "terminal-end-b", app.Vector(100, 100, 0)) + routing_network.create_route_carrier( + doc, + [app.Vector(0, 0, 20), app.Vector(100, 0, 20)], + project_uuid="project-1", + kind="WireDuct", + ) + routing_network.create_route_carrier( + doc, + [app.Vector(0, 100, 20), app.Vector(100, 100, 20)], + project_uuid="project-1", + kind="WireDuct", + ) + 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", + }, + { + "wire_id": "wire-a-repeat", + "start_terminal_uuid": "terminal-start-a", + "end_terminal_uuid": "terminal-end-a", + }, + ], + } + + report = auto_routing.route_eplan_connections_from_payload( + doc, + payload, + options={"lane_spacing": 10.0, "lane_axis": "y"}, + ) + + self.assertEqual(0, report["routes"][0]["lane"]["index"]) + self.assertEqual(0, report["routes"][1]["lane"]["index"]) + self.assertEqual(1, report["routes"][2]["lane"]["index"]) + def test_route_eplan_connections_report_includes_collision_samples(self): _install_fake_freecad() terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()