Skip to content

feat: add plated hole drill-to-drill clearance DRC check - #191

Open
zkasuran wants to merge 1 commit into
tscircuit:mainfrom
zkasuran:fix/plated-hole-drill-edge-clearance
Open

feat: add plated hole drill-to-drill clearance DRC check#191
zkasuran wants to merge 1 commit into
tscircuit:mainfrom
zkasuran:fix/plated-hole-drill-edge-clearance

Conversation

@zkasuran

@zkasuran zkasuran commented Aug 8, 2026

Copy link
Copy Markdown

What

Adds checkPlatedHoleDrillClearance, a DRC check that flags pairs of plated holes whose drilled holes sit closer than the minimum drill edge to drill edge clearance. This implements the "Pad Hole-to-Hole Spacing" item tracked in #15.

Why

min_plated_hole_drill_edge_to_drill_edge_clearance (0.15mm on JLCPCB) is defined in @tscircuit/jlcpcb-manufacturing-specs and can be set per board, but no check reads it today. Two plated holes drilled too close cannot be fabricated reliably: the web of material between the holes breaks down and the drill can wander or break out. The current checks miss this:

  • checkPadPadClearance measures the copper pad edges rather than the drill. It also skips same-net pairs, so two same-net through holes can sit with their drills almost touching and still pass.
  • checkSameNetViaSpacing and checkDifferentNetViaSpacing only look at pcb_via, not pcb_plated_hole.

So a board that should error returns []. Minimal repro: two same-net plated holes with 0.05mm annular rings (so the copper does not overlap) whose drills sit 0.12mm apart.

// hole_diameter 0.5, outer_diameter 0.6, centers 0.62mm apart, same net
{ "type": "pcb_plated_hole", "shape": "circle", "pcb_plated_hole_id": "PH1", "x": 0,    "y": 0, "hole_diameter": 0.5, "outer_diameter": 0.6, ... }
{ "type": "pcb_plated_hole", "shape": "circle", "pcb_plated_hole_id": "PH2", "x": 0.62, "y": 0, "hole_diameter": 0.5, "outer_diameter": 0.6, ... }

runAllChecks returns [] on this board before this change and a single pcb_pad_pad_clearance_error after it.

How

  • Each plated hole's drill (not its copper pad) is modeled as a capsule, a line segment plus a radius. A round hole is a degenerate capsule, an oval or pill hole is a segment as long as the elongation capped by a radius of half the short axis. The gap is segmentToSegmentMinDistance minus the two radii, so circle, oval, pill and the rect-pad hole variants are all handled, including hole_offset and rotation.
  • The check is net independent, because drill spacing is a constraint on the drill step rather than an electrical one. This mirrors checkSameNetViaSpacing, which enforces via hole spacing regardless of connectivity. Copper pad clearance stays in checkPadPadClearance.
  • Two holes at the same location are skipped as a placement duplicate, the same way the via spacing checks do.
  • Wired into runAllPlacementChecks next to checkPadPadClearance and exported from the index.

Tests

  • Too close returns one error, sufficiently spaced returns none, coincident duplicates return none, oval drills too close are flagged.
  • A same-net board where checkPadPadClearance returns [] while this check returns one error.
  • runAllChecks on that same board returns exactly the new error, which nothing caught before.
  • An error-drawn SVG snapshot of the two holes.

Verified locally, all green: bun test (148 pass), bunx tsc --noEmit, bun run format:check, bun run build, bunx @tscircuit/dependency-check.

AI assistance

I used AI assistance (Claude) while writing this change. I designed the approach, reviewed the code and verified the behavior myself. Verified locally before submitting: bun test (148 pass, including the new file), bunx tsc --noEmit, bun run format:check, bun run build and bunx @tscircuit/dependency-check all pass.

Flag pairs of plated holes whose drilled holes sit closer than the
minimum drill edge to drill edge clearance. Implements the Pad
Hole-to-Hole Spacing item from tscircuit#15. checkPadPadClearance measures
copper and skips same-net pairs, so same-net through holes with their
drills too close passed DRC. This check is net independent like
checkSameNetViaSpacing because drill spacing is a fabrication constraint.
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.

1 participant