Skip to content

Island repair reports a pad joined by a track chain as an island - #368

Merged
SammyOina merged 6 commits into
absmach:mainfrom
JeffMboya:SYN-island-through-tracks
Nov 2, 2026
Merged

SammyOina merged 6 commits into
absmach:mainfrom
JeffMboya:SYN-island-through-tracks

Conversation

@JeffMboya

@JeffMboya JeffMboya commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

What type of PR is this?

This is a bug fix.

What does this do?

island_vias now walks track, pad and via chains through join_through_copper, so a pad-holding sliver is not an island.

Which issue(s) does this PR fix/relate to?

Fixes #367.

Have you included tests for your changes?

Yes. A track through the gap, a 0.01 mm gap staying apart, and overlapping pads joining.

Did you document any new/modified features?

No, an internal repair; no user-facing change.

Notes

Copper joins only where it touches (1 nm tolerance, was 20 um); overlapping same-net pads join. fmt, clippy clean.

@SammyOina SammyOina left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested

[P1] Detect track copper intersecting a pour, not only track endpoints

pieces_of() associates a track with a pour only when one of its endpoints is inside the pour region:

let mut regions = hits(&segment.layer, a);
regions.extend(hits(&segment.layer, b));

A track that passes through a sliver or pour with both endpoints outside it is still electrically connected in KiCad, but this implementation will not associate it with that region and may incorrectly add a redundant island via.

The new chain logic also treats tracks as zero-width and uses only centerline/end-point proximity. It can miss valid connections where the track copper overlaps a pad, via, or another track by its width.

Please use segment/polygon intersection and copper width when determining connectivity. Add regression coverage for:

  • a track crossing a pour with both endpoints outside the pour;
  • a track ending at the edge of a pad/via using its actual width;
  • a via chain connecting the sliver to the main pour.

The current test only covers two centerline-aligned tracks whose endpoints meet, so it does not exercise these physical-copper cases. CI is green, but the connectivity model is still narrower than KiCad’s.

@JeffMboya

Copy link
Copy Markdown
Contributor Author

@SammyOina Fixed in 8b9050b: segment/pour intersection and width-aware track, via and pad joins; four regression tests added.

@SammyOina SammyOina left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested\n\n### [P1] Detect pad and via copper overlapping a pour edge\n\nIn crates/synth-router/src/island_vias.rs, pieces_of associates pads and vias with pours only when their centers are inside the region. A large pad or via whose copper overlaps a pour edge while its center is outside will therefore remain disconnected in the model, and the repair can still add a redundant island via.\n\nUse the actual pad and via copper geometry against the region, not center-point containment, and add regression fixtures for a pad-edge overlap and a via-edge overlap.\n\n### [P2] Avoid sampled track-to-pad connectivity\n\ncopper_gap samples track-to-pad distance every 0.05 mm. A short overlap between samples can be missed, particularly for narrow pads or angled tracks. Replace the sampling with exact segment-to-pad geometry, or use a conservative bound that cannot miss an overlap, and add a fixture where the overlap is shorter than the sampling interval.\n\n### [P2] Bound the connectivity pass for large nets\n\njoin_through_copper compares every pair of same-net pads, vias, and tracks. Large ground nets can make this quadratic, and track-to-pad sampling adds further work. Add a realistic large-board performance test and use spatial bucketing or another spatial index if the pass is not bounded sufficiently.\n\nThe earlier track-through-pour and width-aware track/via-chain concerns are addressed, but the pad/via-to-pour center test leaves the physical-copper connectivity model incomplete.

@JeffMboya
JeffMboya force-pushed the SYN-island-through-tracks branch from 8b9050b to 5af8d04 Compare October 29, 2026 09:04
@JeffMboya

Copy link
Copy Markdown
Contributor Author

@SammyOina 5af8d04: pads and vias join pours by their copper, track-to-pad distance is exact, the pass is grid-bounded; edge, corner and 12,000-piece fixtures added.

@SammyOina SammyOina left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested

[P1] Do not treat a 20 µm real gap as electrical connectivity. join_through_copper currently unions pieces when copper_gap <= 0.02. This means two same-net tracks, pads, or vias separated by a genuine 0.01 mm gap can be classified as connected, suppressing the island via that is needed to restore connectivity. Use exact geometry or a much smaller numerical epsilon, and add a regression proving that a small but nonzero gap remains disconnected while true copper overlap remains connected.

[P2] Handle overlapping same-net pads. copper_gap returns f64::MAX for Pad–Pad pairs, so overlapping pads are never joined through direct copper. KiCad can use overlapping same-net pads for stacked, thermal, or exposed-pad footprints. Add direct pad-overlap handling and a regression if those footprint types are supported by the exporter.

The previous track-crossing, copper-width, pad/via edge-overlap, exact track-to-pad, and large-net performance concerns are addressed, and CI is green. Please resolve these remaining connectivity cases before approval.

@JeffMboya
JeffMboya force-pushed the SYN-island-through-tracks branch from 5af8d04 to 3a65744 Compare October 30, 2026 00:25
@JeffMboya

Copy link
Copy Markdown
Contributor Author

@SammyOina 3a65744: copper joins only on touch (was 20 um), overlapping same-net pads join; regressions for both.

@SammyOina SammyOina left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested

[P1] Preserve the actual outline of non-rectangular pads in connectivity

PadBox::new() reduces every pad to a sharp rectangle before pieces_of() and join_through_copper() decide whether copper is connected. That is wider than the actual copper at the corners for KiCad circle, oval, and roundrect pads. A track, via, or pour that falls only in one of those rectangular corner areas can therefore be classified as connected even though there is a real clearance gap. The island-repair pass would then suppress the tie via that restores the physical connection.

The PCB reader already retains Pad.shape and corner_ratio, and its signed-distance implementation distinguishes these outlines. Please carry shape-aware geometry into this connectivity path (or use the shared geometry), rather than treating every pad as a rectangle. Add regressions for circle, oval, and roundrect corner-clearance cases that stay disconnected, alongside a touching case that joins.

The previous track-through-pour, physical-width, edge-overlap, small-gap, pad-overlap, and large-net cases are addressed by the current head; this is the remaining blocker for approval.

@JeffMboya
JeffMboya force-pushed the SYN-island-through-tracks branch from d1acd2c to b36ccef Compare October 31, 2026 19:53
@JeffMboya

Copy link
Copy Markdown
Contributor Author

@SammyOina b36ccef: pads join by real outline (circle, oval, roundrect radius); corner-clearance regressions stay apart, touching joins.

JeffMboya and others added 6 commits November 2, 2026 13:39
join_copper only linked pours, so a sliver holding a pad that a track, pad or via chain ties to the rest of the net was reported as an island although KiCad counts it connected. Walk track, pad and via chains outside the pours before declaring an island.
A track is in a pour when its body reaches it, not only when an end is
inside, and pieces of a net join when their copper by real width touches:
track to track, via, pad, and via to via. Tests: a track crossing the
island with both ends outside, tracks that overlap by width, a track
ending at a pad edge, and a via chain.
…ly, and in bounded time

A pad or via joins a pour when its copper overlaps the pour's edge, not only when
its centre is inside, so a large pad whose centre is outside is no longer left
unattached and given a redundant via. The track-to-pad gap is measured exactly
(the segment against the pad's box in the pad's own axes) instead of sampling
every 0.05 mm. The same-net connectivity pass looks only at pieces whose boxes
share a cell of a grid, so a large ground net is not compared pair by pair.
Regression fixtures cover a pad edge, a via edge, a corner clip shorter than the
old sampling step, and twelve thousand pieces.
…ounding rectangle

PadBox reduced every pad to a sharp rectangle, so a via, track or pour in the empty
corner of a circle, oval or rounded rectangle counted as touching it and suppressed
the tie via. A pad is now its inner rectangle grown by the corner radius the PCB
reader's signed distance uses, and the distances, overlap test and bounds follow
that outline. Regressions: a via and a track in the corner stay apart, a via on the
copper joins, and two round pads cross only when their rims do.
@rodneyosodo
rodneyosodo force-pushed the SYN-island-through-tracks branch from b36ccef to 431f4ed Compare November 2, 2026 11:03
@SammyOina
SammyOina merged commit c2d3f06 into absmach:main Nov 2, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Island repair reports a pad joined by a track chain as an island

3 participants