feat: 自动布线避开已有导线占用路径

dev
Zhaowenlong 3 weeks ago
parent be007035be
commit 0fe5144257

@ -1337,6 +1337,10 @@ def _route_segment_key(segment):
def _route_segment_keys(result):
route_track = result.get("route_track", {}) if isinstance(result, dict) else {}
return _route_track_segment_keys(route_track)
def _route_track_segment_keys(route_track):
segments = route_track.get("segments", []) if isinstance(route_track, dict) else []
keys = []
for segment in segments or []:
@ -1346,6 +1350,35 @@ def _route_segment_keys(result):
return keys
def _incoming_wire_uuids(wires):
wire_uuids = set()
for item in wires or []:
if not isinstance(item, dict):
continue
wire_uuid = _wire_item_value(item, "wire_id", "wire_uuid", "id")
if wire_uuid:
wire_uuids.add(wire_uuid)
return wire_uuids
def _existing_routed_segment_usage(doc, excluded_wire_uuids=None):
excluded_wire_uuids = set(excluded_wire_uuids or [])
usage = {}
for wire in list(WiringObjects.iter_routed_wire_objects(doc)):
if (getattr(wire, "RouteType", "") or "").strip() != "RoutedConnection":
continue
wire_uuid = (getattr(wire, "QetWireUuid", "") or "").strip()
if wire_uuid and wire_uuid in excluded_wire_uuids:
continue
try:
route_track = json.loads((getattr(wire, "QetRouteTrackJson", "") or "").strip() or "{}")
except Exception:
route_track = {}
for segment_key in _route_track_segment_keys(route_track):
usage[segment_key] = usage.get(segment_key, 0) + 1
return usage
def bind_wire_task_terminals_from_payload(doc, payload):
"""Bind local template terminals to QET terminal UUIDs without creating wires."""
if doc is None:
@ -1427,7 +1460,10 @@ def route_eplan_connections_from_payload(doc, payload, options=None, prepared_la
missing_endpoint_uuids = set()
lane_indexes_by_pair = {}
lane_indexes_by_segment = {}
segment_usage_costs = {}
segment_usage_costs = _existing_routed_segment_usage(
doc,
excluded_wire_uuids=_incoming_wire_uuids(wires),
)
def add_status(status):
key = str(status or "").strip() or "Unknown"

@ -2035,6 +2035,68 @@ class AutoRoutingTest(unittest.TestCase):
self.assertIn("Alternate Duct", second_labels)
self.assertNotIn("Direct Duct", second_labels)
def test_route_eplan_connections_prefers_unused_segments_occupied_by_existing_wires(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")
start = _terminal(doc, terminal_objects, "TerminalStart", "terminal-start", app.Vector(0, 0, 0))
end = _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(100, 0, 20)],
label="Direct Duct",
project_uuid="project-1",
kind="WireDuct",
)
routing_network.create_route_carrier(
doc,
[app.Vector(0, 0, 20), app.Vector(0, 40, 20)],
label="Left Bridge",
project_uuid="project-1",
kind="WireDuct",
)
routing_network.create_route_carrier(
doc,
[app.Vector(0, 40, 20), app.Vector(100, 40, 20)],
label="Alternate Duct",
project_uuid="project-1",
kind="WireDuct",
)
routing_network.create_route_carrier(
doc,
[app.Vector(100, 40, 20), app.Vector(100, 0, 20)],
label="Right Bridge",
project_uuid="project-1",
kind="WireDuct",
)
auto_routing.route_eplan_connection_between_terminals(
doc,
start,
end,
wire_uuid="existing-wire",
)
payload = {
"project_uuid": "project-1",
"wires": [
{
"wire_id": "new-wire",
"start_terminal_uuid": "terminal-start",
"end_terminal_uuid": "terminal-end",
}
],
}
report = auto_routing.route_eplan_connections_from_payload(doc, payload)
route_labels = [
segment["carrier"]["label"]
for segment in report["routes"][0]["route_track"]["segments"]
]
self.assertIn("Alternate Duct", route_labels)
self.assertNotIn("Direct Duct", route_labels)
def test_route_eplan_connections_report_includes_collision_samples(self):
_install_fake_freecad()
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()

Loading…
Cancel
Save