diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp index bf429fc350..4240e3755d 100644 --- a/pcbnew/router/pns_kicad_iface.cpp +++ b/pcbnew/router/pns_kicad_iface.cpp @@ -268,6 +268,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 ) @@ -425,7 +453,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 ) ) { @@ -449,7 +477,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 ) ) {