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:
parent
bb4d3faad7
commit
313ebb9dff
|
@ -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
|
||||
{
|
||||
if( !PointCount() )
|
||||
return false;
|
||||
return EdgeContainingPoint( aP ) >= 0;
|
||||
}
|
||||
|
||||
int SHAPE_LINE_CHAIN::EdgeContainingPoint( const VECTOR2I& aP ) const
|
||||
{
|
||||
if( !PointCount() )
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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()
|
||||
*
|
||||
|
|
|
@ -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++ )
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 ) );
|
||||
|
|
Loading…
Reference in New Issue