diff --git a/pcbnew/router/pns_item.cpp b/pcbnew/router/pns_item.cpp index fdc19c356c..2208c763e3 100644 --- a/pcbnew/router/pns_item.cpp +++ b/pcbnew/router/pns_item.cpp @@ -201,8 +201,10 @@ bool ITEM::collideSimple( const ITEM* aHead, const NODE* aNode, // Note: we can't do castellation or net-tie processing in GetClearance() because they // depend on *where* the collision is. - bool checkCastellation = ( m_parent && m_parent->GetLayer() == Edge_Cuts ); - bool checkNetTie = ( m_parent && aNode->GetRuleResolver()->IsInNetTie( this ) ); + bool checkCastellation = ( m_parent && m_parent->GetLayer() == Edge_Cuts ) + || aNode->GetRuleResolver()->IsNonPlatedSlot( this ); + + bool checkNetTie = aNode->GetRuleResolver()->IsInNetTie( this ); if( checkCastellation || checkNetTie ) { diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp index 1997cc8209..39c26e1930 100644 --- a/pcbnew/router/pns_kicad_iface.cpp +++ b/pcbnew/router/pns_kicad_iface.cpp @@ -120,6 +120,9 @@ public: bool IsNetTieExclusion( const PNS::ITEM* aItem, const VECTOR2I& aCollisionPos, const PNS::ITEM* aCollidingItem ) override; + bool IsDrilledHole( const PNS::ITEM* aItem ) override; + bool IsNonPlatedSlot( const PNS::ITEM* aItem ) override; + /** * @return true if \a aObstacle is a keepout. Set \a aEnforce if said keepout's rules * exclude \a aItem. @@ -281,7 +284,18 @@ static bool isHole( const PNS::ITEM* aItem ) } -static bool isDrilledHole( const PNS::ITEM* aItem ) +static bool isEdge( const PNS::ITEM* aItem ) +{ + if ( !aItem ) + return false; + + const PCB_SHAPE *parent = dynamic_cast( aItem->BoardItem() ); + + return parent && ( parent->IsOnLayer( Edge_Cuts ) || parent->IsOnLayer( Margin ) ); +} + + +bool PNS_PCBNEW_RULE_RESOLVER::IsDrilledHole( const PNS::ITEM* aItem ) { if( !isHole( aItem ) ) return false; @@ -295,31 +309,33 @@ static bool isDrilledHole( const PNS::ITEM* aItem ) } -static bool isNonPlatedSlot( const PNS::ITEM* aItem ) +bool PNS_PCBNEW_RULE_RESOLVER::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(); + BOARD_ITEM* parent = aItem->Parent(); - // Via holes are (currently) always round + if( !parent && aItem->ParentPadVia() ) + parent = aItem->ParentPadVia()->Parent(); + + if( parent ) + { + if( parent->Type() == PCB_PAD_T ) + { + PAD* pad = static_cast( parent ); + + return pad->GetAttribute() == PAD_ATTRIB::NPTH + && pad->GetDrillSizeX() != pad->GetDrillSizeY(); + } + + // Via holes are (currently) always round, and always plated + } return false; } -static bool isEdge( const PNS::ITEM* aItem ) -{ - if ( !aItem ) - return false; - - const PCB_SHAPE *parent = dynamic_cast( aItem->BoardItem() ); - - return parent && ( parent->IsOnLayer( Edge_Cuts ) || parent->IsOnLayer( Margin ) ); -} - - BOARD_ITEM* PNS_PCBNEW_RULE_RESOLVER::getBoardItem( const PNS::ITEM* aItem, int aLayer, int aIdx ) { switch( aItem->Kind() ) @@ -503,7 +519,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( isDrilledHole( aA ) && isDrilledHole( aB) ) + if( IsDrilledHole( aA ) && IsDrilledHole( aB ) ) { if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_HOLE_TO_HOLE, aA, aB, layer, &constraint ) ) { @@ -529,7 +545,7 @@ int PNS_PCBNEW_RULE_RESOLVER::Clearance( const PNS::ITEM* aA, const PNS::ITEM* a } // No 'else'; non-plated milled holes get both HOLE_CLEARANCE and EDGE_CLEARANCE - if( isEdge( aA ) || isNonPlatedSlot( aA ) || isEdge( aB ) || isNonPlatedSlot( aB ) ) + if( isEdge( aA ) || IsNonPlatedSlot( aA ) || isEdge( aB ) || IsNonPlatedSlot( aB ) ) { if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_EDGE_CLEARANCE, aA, aB, layer, &constraint ) ) { diff --git a/pcbnew/router/pns_node.h b/pcbnew/router/pns_node.h index ae30ffd130..8b5b898b58 100644 --- a/pcbnew/router/pns_node.h +++ b/pcbnew/router/pns_node.h @@ -151,7 +151,10 @@ public: virtual bool IsInNetTie( const ITEM* aA ) = 0; virtual bool IsNetTieExclusion( const ITEM* aItem, const VECTOR2I& aCollisionPos, - const ITEM* aCollidingItem )= 0; + const ITEM* aCollidingItem ) = 0; + + virtual bool IsDrilledHole( const PNS::ITEM* aItem ) = 0; + virtual bool IsNonPlatedSlot( const PNS::ITEM* aItem ) = 0; /** * @return true if \a aObstacle is a keepout. Set \a aEnforce if said keepout's rules diff --git a/qa/tests/pcbnew/test_pns_basics.cpp b/qa/tests/pcbnew/test_pns_basics.cpp index 802ecb20f0..2d4e64dc84 100644 --- a/qa/tests/pcbnew/test_pns_basics.cpp +++ b/qa/tests/pcbnew/test_pns_basics.cpp @@ -249,6 +249,10 @@ public: return false; } + bool IsDrilledHole( const PNS::ITEM* aItem ) override { return false; } + + bool IsNonPlatedSlot( const PNS::ITEM* aItem ) override { return false; } + bool IsKeepout( const PNS::ITEM* aObstacle, const PNS::ITEM* aItem, bool* aEnforce ) override { return false;