Build nets by union-find over all wire points and component pins. Returns a mapping: rounded scene position → net name. Priority for net naming: 1. ground symbol → "0" 2. WireItem.net_name (explicit user label) 3. port symbol → port params["name"] if set 4. aut
(
components: list, # list[ComponentItem]
wires: list, # list[WireItem]
)
| 46 | |
| 47 | |
| 48 | def resolve_nets( |
| 49 | components: list, # list[ComponentItem] |
| 50 | wires: list, # list[WireItem] |
| 51 | ) -> dict[tuple[int, int], str]: |
| 52 | """ |
| 53 | Build nets by union-find over all wire points and component pins. |
| 54 | |
| 55 | Returns a mapping: rounded scene position → net name. |
| 56 | |
| 57 | Priority for net naming: |
| 58 | 1. ground symbol → "0" |
| 59 | 2. WireItem.net_name (explicit user label) |
| 60 | 3. port symbol → port params["name"] if set |
| 61 | 4. auto-generated "n1", "n2", ... |
| 62 | """ |
| 63 | from .component_item import PIN_POSITIONS |
| 64 | |
| 65 | uf = _UF() |
| 66 | |
| 67 | # ── union consecutive points along each wire ────────────────────────────── |
| 68 | for wire in wires: |
| 69 | pts = [_rpt(p) for p in wire.points] |
| 70 | for i in range(len(pts) - 1): |
| 71 | uf.union(pts[i], pts[i + 1]) |
| 72 | |
| 73 | # ── collect all candidate junction points ───────────────────────────────── |
| 74 | junctions: list[QPointF] = [] |
| 75 | for wire in wires: |
| 76 | junctions.extend(wire.points) |
| 77 | for comp in components: |
| 78 | for lx, ly in PIN_POSITIONS.get(comp.symbol_name, []): |
| 79 | junctions.append(comp.mapToScene(QPointF(lx, ly))) |
| 80 | |
| 81 | # ── ensure every junction key exists in the UF ──────────────────────────── |
| 82 | for q in junctions: |
| 83 | uf.find(_rpt(q)) |
| 84 | |
| 85 | # ── T-junction detection ────────────────────────────────────────────────── |
| 86 | # A junction point that falls on the interior of a wire segment joins that net. |
| 87 | for wire in wires: |
| 88 | for i in range(len(wire.points) - 1): |
| 89 | p1, p2 = wire.points[i], wire.points[i + 1] |
| 90 | seg_key = _rpt(p1) |
| 91 | for q in junctions: |
| 92 | if _on_segment(p1, p2, q): |
| 93 | uf.union(_rpt(q), seg_key) |
| 94 | |
| 95 | # ── same-name ports form one net regardless of physical connection ──────── |
| 96 | _port_roots: dict[str, tuple] = {} |
| 97 | for comp in components: |
| 98 | if comp.symbol_name == "port": |
| 99 | name = comp.params.get("name", "").strip() |
| 100 | if name: |
| 101 | root = uf.find(_rpt(comp.mapToScene(QPointF(0.0, 0.0)))) |
| 102 | if name in _port_roots: |
| 103 | uf.union(root, _port_roots[name]) |
| 104 | else: |
| 105 | _port_roots[name] = root |
no test coverage detected