Lock net names on wires that belong to a net containing a port symbol. Uses a union-find over the wire/pin graph (same logic as connectivity.py) to find which nets contain port symbols. Wires on those nets have their net_name overridden with the port name; the original user
(self)
| 1402 | c.set_unconnected_pins(unconnected) |
| 1403 | |
| 1404 | def _sync_port_net_names(self) -> None: |
| 1405 | """Lock net names on wires that belong to a net containing a port symbol. |
| 1406 | |
| 1407 | Uses a union-find over the wire/pin graph (same logic as connectivity.py) |
| 1408 | to find which nets contain port symbols. Wires on those nets have their |
| 1409 | net_name overridden with the port name; the original user-set name is |
| 1410 | preserved in _user_net_name so it can be restored if the port is removed. |
| 1411 | """ |
| 1412 | from .connectivity import _UF, _rpt, _on_segment |
| 1413 | from .component_item import PIN_POSITIONS |
| 1414 | |
| 1415 | comps = [i for i in self.items() if isinstance(i, ComponentItem)] |
| 1416 | wires = [i for i in self.items() if isinstance(i, WireItem)] |
| 1417 | |
| 1418 | uf = _UF() |
| 1419 | |
| 1420 | # Union consecutive points on each wire |
| 1421 | for wire in wires: |
| 1422 | pts = [_rpt(p) for p in wire.points] |
| 1423 | for i in range(len(pts) - 1): |
| 1424 | uf.union(pts[i], pts[i + 1]) |
| 1425 | |
| 1426 | # Collect all candidate points and ensure they exist in the UF |
| 1427 | all_pts: list[tuple] = [] |
| 1428 | for wire in wires: |
| 1429 | all_pts.extend(_rpt(p) for p in wire.points) |
| 1430 | for comp in comps: |
| 1431 | for lx, ly in PIN_POSITIONS.get(comp.symbol_name, []): |
| 1432 | all_pts.append(_rpt(comp.mapToScene(QPointF(lx, ly)))) |
| 1433 | for pt in all_pts: |
| 1434 | uf.find(pt) |
| 1435 | |
| 1436 | # T-junction detection: wire endpoint on segment interior → same net |
| 1437 | for wire in wires: |
| 1438 | for i in range(len(wire.points) - 1): |
| 1439 | p1, p2 = wire.points[i], wire.points[i + 1] |
| 1440 | seg_key = _rpt(p1) |
| 1441 | for pt in all_pts: |
| 1442 | if _on_segment(p1, p2, QPointF(pt[0], pt[1])): |
| 1443 | uf.union(pt, seg_key) |
| 1444 | |
| 1445 | # Pin-to-pin contacts: two components with pins at the same position |
| 1446 | seen: dict[tuple, tuple] = {} |
| 1447 | for comp in comps: |
| 1448 | for lx, ly in PIN_POSITIONS.get(comp.symbol_name, []): |
| 1449 | pk = _rpt(comp.mapToScene(QPointF(lx, ly))) |
| 1450 | if pk in seen: |
| 1451 | uf.union(pk, seen[pk]) |
| 1452 | else: |
| 1453 | seen[pk] = pk |
| 1454 | |
| 1455 | # Same-named ports are on the same net regardless of physical position |
| 1456 | port_first: dict[str, tuple] = {} |
| 1457 | for comp in comps: |
| 1458 | if comp.symbol_name == "port": |
| 1459 | name = comp.params.get("name", "").strip() |
| 1460 | if name: |
| 1461 | root = uf.find(_rpt(comp.mapToScene(QPointF(0.0, 0.0)))) |
no test coverage detected