Honour 90-degree router mode in a few more places.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/10421
This commit is contained in:
Jeff Young 2023-10-26 14:18:14 +01:00
parent 84b0848a1e
commit 8d3a3419f8
5 changed files with 63 additions and 13 deletions

View File

@ -807,10 +807,16 @@ bool LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, LINE& aNewHead, LINE& aNe
// the shove/walk mode that certain users find too intrusive. // the shove/walk mode that certain users find too intrusive.
if( obs ) if( obs )
{ {
int cl = m_currentNode->GetClearance( obs->m_item, &m_head, false ); int clearance = m_currentNode->GetClearance( obs->m_item, &m_head, false );
auto hull = obs->m_item->Hull( cl, m_head.Width() ); SHAPE_LINE_CHAIN hull = obs->m_item->Hull( clearance, m_head.Width() );
VECTOR2I nearest;
auto nearest = hull.NearestPoint( aP ); DIRECTION_45::CORNER_MODE cornerMode = Settings().GetCornerMode();
if( cornerMode == DIRECTION_45::MITERED_90 || cornerMode == DIRECTION_45::ROUNDED_90 )
nearest = hull.BBox().ClosestPointTo( aP );
else
nearest = hull.NearestPoint( aP );
if( ( nearest - aP ).EuclideanNorm() < m_head.Width() / 2 ) if( ( nearest - aP ).EuclideanNorm() < m_head.Width() / 2 )
buildInitialLine( nearest, m_head ); buildInitialLine( nearest, m_head );

View File

@ -283,9 +283,10 @@ int NODE::QueryColliding( const ITEM* aItem, NODE::OBSTACLES& aObstacles,
NODE::OPT_OBSTACLE NODE::NearestObstacle( const LINE* aLine, NODE::OPT_OBSTACLE NODE::NearestObstacle( const LINE* aLine,
const COLLISION_SEARCH_OPTIONS& aOpts ) const COLLISION_SEARCH_OPTIONS& aOpts )
{ {
const int clearanceEpsilon = GetRuleResolver()->ClearanceEpsilon(); DIRECTION_45::CORNER_MODE cornerMode = ROUTER::GetInstance()->Settings().GetCornerMode();
OBSTACLES obstacleList; const int clearanceEpsilon = GetRuleResolver()->ClearanceEpsilon();
std::vector<SEGMENT> tmpSegs; OBSTACLES obstacleList;
std::vector<SEGMENT> tmpSegs;
tmpSegs.reserve( aLine->CLine().SegmentCount() ); tmpSegs.reserve( aLine->CLine().SegmentCount() );
@ -335,10 +336,20 @@ NODE::OPT_OBSTACLE NODE::NearestObstacle( const LINE* aLine,
if( aOpts.m_restrictedSet && !aOpts.m_restrictedSet->empty() && aOpts.m_restrictedSet->count( obstacle.m_item ) == 0 ) if( aOpts.m_restrictedSet && !aOpts.m_restrictedSet->empty() && aOpts.m_restrictedSet->count( obstacle.m_item ) == 0 )
continue; continue;
int clearance = int clearance = GetClearance( obstacle.m_item, aLine, aOpts.m_useClearanceEpsilon )
GetClearance( obstacle.m_item, aLine, aOpts.m_useClearanceEpsilon ) + aLine->Width() / 2; + aLine->Width() / 2;
obstacleHull = obstacle.m_item->Hull( clearance, 0, layer ); obstacleHull = obstacle.m_item->Hull( clearance, 0, layer );
if( cornerMode == DIRECTION_45::MITERED_90 || cornerMode == DIRECTION_45::ROUNDED_90 )
{
BOX2I bbox = obstacleHull.BBox();
obstacleHull.Clear();
obstacleHull.Append( bbox.GetLeft(), bbox.GetTop() );
obstacleHull.Append( bbox.GetRight(), bbox.GetTop() );
obstacleHull.Append( bbox.GetRight(), bbox.GetBottom() );
obstacleHull.Append( bbox.GetLeft(), bbox.GetBottom() );
}
//debugDecorator->AddLine( obstacleHull, 2, 40000, "obstacle-hull-test" ); //debugDecorator->AddLine( obstacleHull, 2, 40000, "obstacle-hull-test" );
//debugDecorator->AddLine( aLine->CLine(), 5, 40000, "obstacle-test-line" ); //debugDecorator->AddLine( aLine->CLine(), 5, 40000, "obstacle-test-line" );
@ -359,6 +370,16 @@ NODE::OPT_OBSTACLE NODE::NearestObstacle( const LINE* aLine,
+ via.Diameter() / 2; + via.Diameter() / 2;
obstacleHull = obstacle.m_item->Hull( viaClearance, 0, layer ); obstacleHull = obstacle.m_item->Hull( viaClearance, 0, layer );
if( cornerMode == DIRECTION_45::MITERED_90 || cornerMode == DIRECTION_45::ROUNDED_90 )
{
BOX2I bbox = obstacleHull.BBox();
obstacleHull.Clear();
obstacleHull.Append( bbox.GetLeft(), bbox.GetTop() );
obstacleHull.Append( bbox.GetRight(), bbox.GetTop() );
obstacleHull.Append( bbox.GetRight(), bbox.GetBottom() );
obstacleHull.Append( bbox.GetLeft(), bbox.GetBottom() );
}
//debugDecorator->AddLine( obstacleHull, 3 ); //debugDecorator->AddLine( obstacleHull, 3 );
intersectingPts.clear(); intersectingPts.clear();

View File

@ -695,8 +695,11 @@ bool OPTIMIZER::mergeStep( LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath, int step
if( aLine->SegmentCount() < 2 ) if( aLine->SegmentCount() < 2 )
return false; return false;
DIRECTION_45 orig_start( aLine->CSegment( 0 ) ); DIRECTION_45::CORNER_MODE cornerMode = ROUTER::GetInstance()->Settings().GetCornerMode();
DIRECTION_45 orig_end( aLine->CSegment( -1 ) ); bool is90mode = cornerMode == DIRECTION_45::MITERED_90 || cornerMode == DIRECTION_45::ROUNDED_90;
DIRECTION_45 orig_start( aLine->CSegment( 0 ), is90mode );
DIRECTION_45 orig_end( aLine->CSegment( -1 ), is90mode );
for( int n = 0; n < n_segs - step; n++ ) for( int n = 0; n < n_segs - step; n++ )
@ -717,7 +720,7 @@ bool OPTIMIZER::mergeStep( LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath, int step
for( int i = 0; i < 2; i++ ) for( int i = 0; i < 2; i++ )
{ {
SHAPE_LINE_CHAIN bypass = DIRECTION_45().BuildInitialTrace( s1.A, s2.B, i ); SHAPE_LINE_CHAIN bypass = DIRECTION_45().BuildInitialTrace( s1.A, s2.B, i, cornerMode );
cost[i] = INT_MAX; cost[i] = INT_MAX;
bool ok = false; bool ok = false;
@ -1111,6 +1114,8 @@ bool OPTIMIZER::fanoutCleanup( LINE* aLine )
if( aLine->PointCount() < 3 ) if( aLine->PointCount() < 3 )
return false; return false;
DIRECTION_45::CORNER_MODE cornerMode = ROUTER::GetInstance()->Settings().GetCornerMode();
VECTOR2I p_start = aLine->CPoint( 0 ), p_end = aLine->CPoint( -1 ); VECTOR2I p_start = aLine->CPoint( 0 ), p_end = aLine->CPoint( -1 );
ITEM* startPad = findPadOrVia( aLine->Layer(), aLine->Net(), p_start ); ITEM* startPad = findPadOrVia( aLine->Layer(), aLine->Net(), p_start );
@ -1138,7 +1143,7 @@ bool OPTIMIZER::fanoutCleanup( LINE* aLine )
{ {
for( int i = 0; i < 2; i++ ) for( int i = 0; i < 2; i++ )
{ {
SHAPE_LINE_CHAIN l2 = DIRECTION_45().BuildInitialTrace( p_start, p_end, i ); SHAPE_LINE_CHAIN l2 = DIRECTION_45().BuildInitialTrace( p_start, p_end, i, cornerMode );
LINE repl; LINE repl;
repl = LINE( *aLine, l2 ); repl = LINE( *aLine, l2 );

View File

@ -1897,8 +1897,14 @@ void SHOVE::runOptimizer( NODE* aNode )
optimizer.SetRestrictArea( *area, false ); optimizer.SetRestrictArea( *area, false );
} }
if( Settings().SmartPads() ) DIRECTION_45::CORNER_MODE cornerMode = Settings().GetCornerMode();
// Smart Pads is incompatible with 90-degree mode for now
if( Settings().SmartPads()
&& ( cornerMode == DIRECTION_45::MITERED_45 || cornerMode == DIRECTION_45::ROUNDED_45 ) )
{
optFlags |= OPTIMIZER::SMART_PADS; optFlags |= OPTIMIZER::SMART_PADS;
}
optimizer.SetEffortLevel( optFlags & ~m_optFlagDisableMask ); optimizer.SetEffortLevel( optFlags & ~m_optFlagDisableMask );

View File

@ -102,6 +102,18 @@ WALKAROUND::WALKAROUND_STATUS WALKAROUND::singleStep( LINE& aPath, bool aWinding
SHAPE_LINE_CHAIN hull = current_obs->m_item->Hull( current_obs->m_clearance, aPath.Width() ); SHAPE_LINE_CHAIN hull = current_obs->m_item->Hull( current_obs->m_clearance, aPath.Width() );
DIRECTION_45::CORNER_MODE cornerMode = Settings().GetCornerMode();
if( cornerMode == DIRECTION_45::MITERED_90 || cornerMode == DIRECTION_45::ROUNDED_90 )
{
BOX2I bbox = hull.BBox();
hull.Clear();
hull.Append( bbox.GetLeft(), bbox.GetTop() );
hull.Append( bbox.GetRight(), bbox.GetTop() );
hull.Append( bbox.GetRight(), bbox.GetBottom() );
hull.Append( bbox.GetLeft(), bbox.GetBottom() );
}
bool s_cw = aPath.Walkaround( hull, path_walk, aWindingDirection ); bool s_cw = aPath.Walkaround( hull, path_walk, aWindingDirection );
PNS_DBG( Dbg(), BeginGroup, "hull/walk", 1 ); PNS_DBG( Dbg(), BeginGroup, "hull/walk", 1 );