Unify most special-case processing to the clearance if-then-else.

This also allows us to support hole-to-hole clearance when dragging
a via near another via on the same net.

Fixes https://gitlab.com/kicad/code/kicad/issues/12781

(cherry picked from commit 8a0c225efa)
This commit is contained in:
Jeff Young 2023-04-06 15:33:49 +01:00
parent 2b6d2fc117
commit 4c04233a20
2 changed files with 44 additions and 34 deletions

View File

@ -103,20 +103,6 @@ bool ITEM::collideSimple( const ITEM* aHead, const NODE* aNode,
if( aHead->m_kind == LINE_T ) if( aHead->m_kind == LINE_T )
lineWidthH = static_cast<const LINE*>( aHead )->Width() / 2; lineWidthH = static_cast<const LINE*>( aHead )->Width() / 2;
// same nets? no collision!
if( aCtx && aCtx->options.m_differentNetsOnly
&& m_net == aHead->m_net && m_net >= 0 && aHead->m_net >= 0 )
{
return false;
}
// a pad associated with a "free" pin (NIC) doesn't have a net until it has been used
if( aCtx && aCtx->options.m_differentNetsOnly
&& ( IsFreePad() || aHead->IsFreePad() ) )
{
return false;
}
// check if we are not on completely different layers first // check if we are not on completely different layers first
if( !m_layers.Overlaps( aHead->m_layers ) ) if( !m_layers.Overlaps( aHead->m_layers ) )
return false; return false;
@ -128,34 +114,56 @@ bool ITEM::collideSimple( const ITEM* aHead, const NODE* aNode,
collisionsFound |= holeI->collideSimple( aHead, aNode, aCtx ); collisionsFound |= holeI->collideSimple( aHead, aNode, aCtx );
if( holeH && holeI ) if( holeH && holeI )
collisionsFound |= holeI->collideSimple( holeH, aNode, aCtx );
int clearance;
if( aCtx && aCtx->options.m_overrideClearance >= 0 )
{ {
clearance = aCtx->options.m_overrideClearance; if( aCtx )
} {
else if( aNode->GetRuleResolver()->IsKeepout( this, aHead ) ) // Hole to hole collsions are never net-specific
{ COLLISION_SEARCH_OPTIONS holeToHoleOptions( aCtx->options );
clearance = 0; // keepouts are exact boundary; no clearance holeToHoleOptions.m_differentNetsOnly = false;
} COLLISION_SEARCH_CONTEXT holeToHoleCtx( aCtx->obstacles, holeToHoleOptions );
else collisionsFound |= holeI->collideSimple( holeH, aNode, &holeToHoleCtx );
{ }
clearance = aNode->GetClearance( this, aHead ); else
{
collisionsFound |= holeI->collideSimple( holeH, aNode, nullptr );
}
} }
// fixme: this f***ing singleton must go... // fixme: this f***ing singleton must go...
ROUTER* router = ROUTER::GetInstance(); ROUTER* router = ROUTER::GetInstance();
ROUTER_IFACE* iface = router ? router->GetInterface() : nullptr; ROUTER_IFACE* iface = router ? router->GetInterface() : nullptr;
bool differentNetsOnly = aCtx && aCtx->options.m_differentNetsOnly;
int clearance;
if( iface ) if( differentNetsOnly && m_net == aHead->m_net && m_net >= 0 && aHead->m_net >= 0 )
{ {
if( !iface->IsFlashedOnLayer( this, aHead->Layer() ) ) // same nets? no clearance!
return collisionsFound; clearance = -1;
}
if( !iface->IsFlashedOnLayer( aHead, Layer() ) ) else if( differentNetsOnly && ( IsFreePad() || aHead->IsFreePad() ) )
return collisionsFound; {
// a pad associated with a "free" pin (NIC) doesn't have a net until it has been used
clearance = -1;
}
else if( aNode->GetRuleResolver()->IsKeepout( this, aHead ) )
{
clearance = 0; // keepouts are exact boundary; no clearance
}
else if( iface && !iface->IsFlashedOnLayer( this, aHead->Layer() ) )
{
clearance = -1;
}
else if( iface && !iface->IsFlashedOnLayer( aHead, Layer() ) )
{
clearance = -1;
}
else if( aCtx && aCtx->options.m_overrideClearance >= 0 )
{
clearance = aCtx->options.m_overrideClearance;
}
else
{
clearance = aNode->GetClearance( this, aHead );
} }
if( clearance >= 0 ) if( clearance >= 0 )

View File

@ -340,6 +340,7 @@ bool PNS_PCBNEW_RULE_RESOLVER::QueryConstraint( PNS::CONSTRAINT_TYPE aType,
case PNS::ITEM::VIA_T: parentA = &m_dummyVias[0]; break; case PNS::ITEM::VIA_T: parentA = &m_dummyVias[0]; break;
case PNS::ITEM::SEGMENT_T: parentA = &m_dummyTracks[0]; break; case PNS::ITEM::SEGMENT_T: parentA = &m_dummyTracks[0]; break;
case PNS::ITEM::LINE_T: parentA = &m_dummyTracks[0]; break; case PNS::ITEM::LINE_T: parentA = &m_dummyTracks[0]; break;
case PNS::ITEM::HOLE_T: parentB = &m_dummyVias[0]; break;
default: break; default: break;
} }
@ -358,6 +359,7 @@ bool PNS_PCBNEW_RULE_RESOLVER::QueryConstraint( PNS::CONSTRAINT_TYPE aType,
case PNS::ITEM::VIA_T: parentB = &m_dummyVias[1]; break; case PNS::ITEM::VIA_T: parentB = &m_dummyVias[1]; break;
case PNS::ITEM::SEGMENT_T: parentB = &m_dummyTracks[1]; break; case PNS::ITEM::SEGMENT_T: parentB = &m_dummyTracks[1]; break;
case PNS::ITEM::LINE_T: parentB = &m_dummyTracks[1]; break; case PNS::ITEM::LINE_T: parentB = &m_dummyTracks[1]; break;
case PNS::ITEM::HOLE_T: parentB = &m_dummyVias[1]; break;
default: break; default: break;
} }