From ad9109cad48944d73d0f88b157c3b13987e7aee2 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 21 May 2023 19:57:47 +0100 Subject: [PATCH] Reconcile PNS router with DRC. Hole-to-hole is only for drilled holes. NPTH slots also get EDGE_CLEARANCE applied. Fixes https://gitlab.com/kicad/code/kicad/-/issues/14771 (cherry picked from commit df763eaf88161a0e723fd9bf5c25b6ca838b3392) --- pcbnew/router/pns_kicad_iface.cpp | 34 +++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp index 07bfd8cd49..b8cbebc199 100644 --- a/pcbnew/router/pns_kicad_iface.cpp +++ b/pcbnew/router/pns_kicad_iface.cpp @@ -275,6 +275,34 @@ static bool isHole( const PNS::ITEM* aItem ) } +static bool isDrilledHole( const PNS::ITEM* aItem ) +{ + if( !isHole( aItem ) ) + return false; + + if( PAD* pad = dynamic_cast( aItem->Parent() ) ) + return pad->GetDrillSizeX() && pad->GetDrillSizeX() == pad->GetDrillSizeY(); + + // Via holes are (currently) always round + + return true; +} + + +static bool isNonPlatedSlot( const PNS::ITEM* aItem ) +{ + if( !isHole( aItem ) ) + return false; + + if( PAD* pad = dynamic_cast( aItem->Parent() ) ) + return pad->GetAttribute() == PAD_ATTRIB::NPTH && pad->GetDrillSizeX() != pad->GetDrillSizeY(); + + // Via holes are (currently) always round + + return false; +} + + static bool isEdge( const PNS::ITEM* aItem ) { if ( !aItem ) @@ -432,7 +460,7 @@ int PNS_PCBNEW_RULE_RESOLVER::Clearance( const PNS::ITEM* aA, const PNS::ITEM* a for( int layer = layers.Start(); layer <= layers.End(); ++layer ) { - if( isHole( aA ) && isHole( aB) ) + if( isDrilledHole( aA ) && isDrilledHole( aB) ) { if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_HOLE_TO_HOLE, aA, aB, layer, &constraint ) ) { @@ -456,7 +484,9 @@ int PNS_PCBNEW_RULE_RESOLVER::Clearance( const PNS::ITEM* aA, const PNS::ITEM* a rv = constraint.m_Value.Min(); } } - else if( isEdge( aA ) || ( aB && isEdge( aB ) ) ) + + // No 'else'; non-plated milled holes get both HOLE_CLEARANCE and EDGE_CLEARANCE + if( isEdge( aA ) || isNonPlatedSlot( aA ) || isEdge( aB ) || isNonPlatedSlot( aB ) ) { if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_EDGE_CLEARANCE, aA, aB, layer, &constraint ) ) {