router: correct walkaround corner case when both ends of the line lie on the hull edge

Fixes: lp:1810935
* https://bugs.launchpad.net/kicad/+bug/1810935
This commit is contained in:
Tomasz Włostowski 2019-02-03 11:21:48 +01:00
parent bb4d3faad7
commit 313ebb9dff
5 changed files with 50 additions and 7 deletions

View File

@ -377,30 +377,35 @@ bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aP ) const
inside = !inside;
}
}
return inside;
return inside && !PointOnEdge( aP );
}
bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aP ) const
{
return EdgeContainingPoint( aP ) >= 0;
}
int SHAPE_LINE_CHAIN::EdgeContainingPoint( const VECTOR2I& aP ) const
{
if( !PointCount() )
return false;
return -1;
else if( PointCount() == 1 )
return m_points[0] == aP;
return m_points[0] == aP ? 0 : -1;
for( int i = 0; i < SegmentCount(); i++ )
{
const SEG s = CSegment( i );
if( s.A == aP || s.B == aP )
return true;
return i;
if( s.Distance( aP ) <= 1 )
return true;
return i;
}
return false;
return -1;
}

View File

@ -564,6 +564,15 @@ public:
*/
bool PointOnEdge( const VECTOR2I& aP ) const;
/**
* Function EdgeContainingPoint()
*
* Checks if point aP lies on an edge or vertex of the line chain.
* @param aP point to check
* @return index of the first edge containing the point, otherwise negative
*/
int EdgeContainingPoint( const VECTOR2I& aP ) const;
/**
* Function CheckClearance()
*

View File

@ -163,13 +163,21 @@ bool LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
if( line.SegmentCount() < 1 )
return false;
const auto pFirst = line.CPoint(0);
const auto pLast = line.CPoint(-1);
if( aObstacle.PointInside( line.CPoint( 0 ) ) || aObstacle.PointInside( line.CPoint( -1 ) ) )
{
return false;
}
SHAPE_LINE_CHAIN::INTERSECTIONS ips;
line.Intersect( aObstacle, ips );
auto eFirst = aObstacle.EdgeContainingPoint( pFirst );
auto eLast = aObstacle.EdgeContainingPoint( pLast );
aWalk.Clear();
aPost.Clear();
@ -177,6 +185,23 @@ bool LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
int farthest_dist = 0;
SHAPE_LINE_CHAIN::INTERSECTION nearest, farthest;
SHAPE_LINE_CHAIN::INTERSECTION is;
if( eFirst >= 0 )
{
is.our = line.CSegment(0);
is.their = aObstacle.CSegment( eFirst );
is.p = pFirst;
ips.push_back(is);
}
if ( eLast >= 0 )
{
is.our = line.CSegment(-1);
is.their = aObstacle.CSegment( eLast );
is.p = pLast;
ips.push_back(is);
}
for( int i = 0; i < (int) ips.size(); i++ )
{

View File

@ -367,6 +367,7 @@ bool LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, LINE& aNewHead )
WALKAROUND walkaround( m_currentNode, Router() );
walkaround.SetSolidsOnly( false );
walkaround.SetDebugDecorator( Dbg() );
walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
WALKAROUND::WALKAROUND_STATUS wf = walkaround.Route( initTrack, walkFull, false );
@ -565,6 +566,7 @@ bool LINE_PLACER::rhShoveOnly( const VECTOR2I& aP, LINE& aNewHead )
walkaround.SetSolidsOnly( true );
walkaround.SetIterationLimit( 10 );
walkaround.SetDebugDecorator( Dbg() );
WALKAROUND::WALKAROUND_STATUS stat_solids = walkaround.Route( initTrack, walkSolids );
optimizer.SetEffortLevel( OPTIMIZER::MERGE_SEGMENTS );

View File

@ -801,6 +801,8 @@ void ROUTER_TOOL::performRouting()
// Don't crash if we missed an operation that cancelled routing.
wxCHECK2( m_router->RoutingInProgress(), break );
handleCommonEvents( *evt );
if( evt->IsMotion() )
{
m_router->SetOrthoMode( evt->Modifier( MD_CTRL ) );