PNS: Fix propagateDpHeadForces obstacle calculation
Using a synthetic via here doesn't quite let us use VIA::PushoutForce because it will use the wrong clearance, and also doesn't quite have the logic we want. I am not familiar enough with PushoutForce to know if its logic is a bug in other cases, so instead I just brought in the parts of its algorithm that are needed here. Additionally, we prevent pushing more than once from a given obstacle, which causes walkaround to be more successful when routing diff pairs against a large collider such as a keepout area. Fixes https://gitlab.com/kicad/code/kicad/-/issues/8232
This commit is contained in:
parent
5974446523
commit
6425ad4118
|
@ -128,8 +128,6 @@ bool DIFF_PAIR_PLACER::propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I& aNe
|
|||
virtHead.SetDiameter( m_sizes.DiffPairGap() + 2 * m_sizes.DiffPairWidth() );
|
||||
}
|
||||
|
||||
VECTOR2I lead( 0, 0 );// = aP - m_currentStart ;
|
||||
VECTOR2I force;
|
||||
bool solidsOnly = true;
|
||||
|
||||
if( m_currentMode == RM_MarkObstacles )
|
||||
|
@ -143,7 +141,42 @@ bool DIFF_PAIR_PLACER::propagateDpHeadForces ( const VECTOR2I& aP, VECTOR2I& aNe
|
|||
}
|
||||
|
||||
// fixme: I'm too lazy to do it well. Circular approximaton will do for the moment.
|
||||
if( virtHead.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
|
||||
|
||||
// Note: this code is lifted from VIA::PushoutForce and then optimized for this use case and to
|
||||
// check proper clearances to the diff pair line. It can be removed if some specialized
|
||||
// pushout for traces / diff pairs is implemented. Just calling VIA::PushoutForce does not work
|
||||
// as the via may have different resolved clearance to items than the diff pair should.
|
||||
int maxIter = 40;
|
||||
int iter = 0;
|
||||
bool collided = false;
|
||||
VECTOR2I force, totalForce;
|
||||
std::set<ITEM*> handled;
|
||||
|
||||
while( iter < maxIter )
|
||||
{
|
||||
NODE::OPT_OBSTACLE obs = m_currentNode->CheckColliding( &virtHead, solidsOnly ?
|
||||
ITEM::SOLID_T :
|
||||
ITEM::ANY_T );
|
||||
if( !obs || handled.count( obs->m_item ) )
|
||||
break;
|
||||
|
||||
int clearance = m_currentNode->GetClearance( obs->m_item, &m_currentTrace.PLine() );
|
||||
|
||||
if( obs->m_item->Shape()->Collide( virtHead.Shape(), clearance, &force ) )
|
||||
{
|
||||
collided = true;
|
||||
totalForce += force;
|
||||
virtHead.SetPos( virtHead.Pos() + force );
|
||||
}
|
||||
|
||||
handled.insert( obs->m_item );
|
||||
|
||||
iter++;
|
||||
}
|
||||
|
||||
bool succeeded = ( !collided || iter != maxIter );
|
||||
|
||||
if( succeeded )
|
||||
{
|
||||
aNewP = aP + force;
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue