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:
parent
2b6d2fc117
commit
4c04233a20
|
@ -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 )
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue