router: snap to clearance boundaries in Highlight Collisions mode
Fixes: lp:1655819 * https://bugs.launchpad.net/kicad/+bug/1655819
This commit is contained in:
parent
2eb840b2ed
commit
ba9576b014
|
@ -27,12 +27,13 @@
|
|||
|
||||
bool SHAPE::Parse( std::stringstream& aStream )
|
||||
{
|
||||
assert ( false );
|
||||
assert( false );
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
const std::string SHAPE::Format( ) const
|
||||
|
||||
const std::string SHAPE::Format() const
|
||||
{
|
||||
assert ( false );
|
||||
return std::string("");
|
||||
};
|
||||
assert( false );
|
||||
return std::string( "" );
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* Copyright (C) 2013-2017 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -587,3 +587,28 @@ bool SHAPE_LINE_CHAIN::Parse( std::stringstream& aStream )
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const VECTOR2I SHAPE_LINE_CHAIN::PointAlong( int aPathLength ) const
|
||||
{
|
||||
int total = 0;
|
||||
|
||||
if( aPathLength == 0 )
|
||||
return CPoint( 0 );
|
||||
|
||||
for( int i = 0; i < SegmentCount(); i++ )
|
||||
{
|
||||
const SEG& s = CSegment( i );
|
||||
int l = s.Length();
|
||||
|
||||
if( total + l >= aPathLength )
|
||||
{
|
||||
VECTOR2I d( s.B - s.A );
|
||||
return s.A + d.Resize( aPathLength - total );
|
||||
}
|
||||
|
||||
total += l;
|
||||
}
|
||||
|
||||
return CPoint( -1 );
|
||||
}
|
||||
|
|
|
@ -571,7 +571,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CompareGeometry( const SHAPE_LINE_CHAIN & aOther ) const;
|
||||
bool CompareGeometry( const SHAPE_LINE_CHAIN& aOther ) const;
|
||||
|
||||
void Move( const VECTOR2I& aVector ) override
|
||||
{
|
||||
|
@ -584,6 +584,8 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
const VECTOR2I PointAlong( int aPathLength ) const;
|
||||
|
||||
private:
|
||||
/// array of vertices
|
||||
std::vector<VECTOR2I> m_points;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||
*
|
||||
* Copyright (C) 2013-2014 CERN
|
||||
* Copyright (C) 2013-2017 CERN
|
||||
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
|
@ -413,11 +413,128 @@ bool LINE_PLACER::rhWalkOnly( const VECTOR2I& aP, LINE& aNewHead )
|
|||
bool LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, LINE& aNewHead )
|
||||
{
|
||||
buildInitialLine( aP, m_head );
|
||||
|
||||
auto obs = m_currentNode->NearestObstacle( &m_head );
|
||||
|
||||
if( obs )
|
||||
{
|
||||
int cl = m_currentNode->GetClearance( obs->m_item, &m_head );
|
||||
auto hull = obs->m_item->Hull( cl, m_head.Width() );
|
||||
|
||||
auto nearest = hull.NearestPoint( aP );
|
||||
Dbg()->AddLine( hull, 2, 10000 );
|
||||
|
||||
if( ( nearest - aP ).EuclideanNorm() < m_head.Width() )
|
||||
{
|
||||
buildInitialLine( nearest, m_head );
|
||||
}
|
||||
}
|
||||
|
||||
aNewHead = m_head;
|
||||
|
||||
return static_cast<bool>( m_currentNode->CheckColliding( &m_head ) );
|
||||
}
|
||||
|
||||
|
||||
const LINE LINE_PLACER::reduceToNearestObstacle( const LINE& aOriginalLine )
|
||||
{
|
||||
auto l0 = aOriginalLine.CLine();
|
||||
|
||||
if ( !l0.PointCount() )
|
||||
return aOriginalLine;
|
||||
|
||||
int l = l0.Length();
|
||||
int step = l / 2;
|
||||
VECTOR2I target;
|
||||
|
||||
LINE l_test( aOriginalLine );
|
||||
|
||||
while( step > 0 )
|
||||
{
|
||||
target = l0.PointAlong( l );
|
||||
SHAPE_LINE_CHAIN l_cur( l0 );
|
||||
|
||||
int index = l_cur.Split( target );
|
||||
|
||||
l_test.SetShape( l_cur.Slice( 0, index ) );
|
||||
|
||||
if ( m_currentNode->CheckColliding( &l_test ) )
|
||||
l -= step;
|
||||
else
|
||||
l += step;
|
||||
|
||||
step /= 2;
|
||||
}
|
||||
|
||||
l = l_test.CLine().Length();
|
||||
|
||||
while( m_currentNode->CheckColliding( &l_test ) && l > 0 )
|
||||
{
|
||||
l--;
|
||||
target = l0.PointAlong( l );
|
||||
SHAPE_LINE_CHAIN l_cur( l0 );
|
||||
|
||||
int index = l_cur.Split( target );
|
||||
|
||||
l_test.SetShape( l_cur.Slice( 0, index ) );
|
||||
}
|
||||
|
||||
return l_test;
|
||||
}
|
||||
|
||||
|
||||
bool LINE_PLACER::rhStopAtNearestObstacle( const VECTOR2I& aP, LINE& aNewHead )
|
||||
{
|
||||
LINE l0;
|
||||
l0 = m_head;
|
||||
|
||||
buildInitialLine( aP, l0 );
|
||||
|
||||
LINE l_cur = reduceToNearestObstacle( l0 );
|
||||
|
||||
const auto l_shape = l_cur.CLine();
|
||||
|
||||
if( l_shape.SegmentCount() == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( l_shape.SegmentCount() == 1 )
|
||||
{
|
||||
auto s = l_shape.CSegment( 0 );
|
||||
|
||||
VECTOR2I dL( DIRECTION_45( s ).Left().ToVector() );
|
||||
VECTOR2I dR( DIRECTION_45( s ).Right().ToVector() );
|
||||
|
||||
SEG leadL( s.B, s.B + dL );
|
||||
SEG leadR( s.B, s.B + dR );
|
||||
|
||||
SEG segL( s.B, leadL.LineProject( aP ) );
|
||||
SEG segR( s.B, leadR.LineProject( aP ) );
|
||||
|
||||
LINE finishL( l0, SHAPE_LINE_CHAIN( segL.A, segL.B ) );
|
||||
LINE finishR( l0, SHAPE_LINE_CHAIN( segR.A, segR.B ) );
|
||||
|
||||
LINE reducedL = reduceToNearestObstacle( finishL );
|
||||
LINE reducedR = reduceToNearestObstacle( finishR );
|
||||
|
||||
int lL = reducedL.CLine().Length();
|
||||
int lR = reducedR.CLine().Length();
|
||||
|
||||
if( lL > lR )
|
||||
l_cur.Line().Append( reducedL.CLine() );
|
||||
else
|
||||
l_cur.Line().Append( reducedR.CLine() );
|
||||
|
||||
l_cur.Line().Simplify();
|
||||
}
|
||||
|
||||
m_head = l_cur;
|
||||
aNewHead = m_head;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool LINE_PLACER::rhShoveOnly( const VECTOR2I& aP, LINE& aNewHead )
|
||||
{
|
||||
LINE initTrack( m_head );
|
||||
|
@ -1027,7 +1144,7 @@ void LINE_PLACER::SetOrthoMode( bool aOrthoMode )
|
|||
}
|
||||
|
||||
|
||||
bool LINE_PLACER::buildInitialLine( const VECTOR2I& aP, LINE& aHead )
|
||||
bool LINE_PLACER::buildInitialLine( const VECTOR2I& aP, LINE& aHead, bool aInvertPosture )
|
||||
{
|
||||
SHAPE_LINE_CHAIN l;
|
||||
|
||||
|
@ -1043,7 +1160,10 @@ bool LINE_PLACER::buildInitialLine( const VECTOR2I& aP, LINE& aHead )
|
|||
}
|
||||
else
|
||||
{
|
||||
l = m_direction.BuildInitialTrace( m_p_start, aP );
|
||||
if ( aInvertPosture )
|
||||
l = m_direction.Right().BuildInitialTrace( m_p_start, aP );
|
||||
else
|
||||
l = m_direction.BuildInitialTrace( m_p_start, aP );
|
||||
}
|
||||
|
||||
if( l.SegmentCount() > 1 && m_orthoMode )
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||
*
|
||||
* Copyright (C) 2013-2014 CERN
|
||||
* Copyright (C) 2013-2017 CERN
|
||||
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
|
@ -335,6 +335,11 @@ private:
|
|||
*/
|
||||
void routeStep( const VECTOR2I& aP );
|
||||
|
||||
const LINE reduceToNearestObstacle( const LINE& aOriginalLine );
|
||||
|
||||
bool rhStopAtNearestObstacle( const VECTOR2I& aP, LINE& aNewHead );
|
||||
|
||||
|
||||
///> route step, walkaround mode
|
||||
bool rhWalkOnly( const VECTOR2I& aP, LINE& aNewHead);
|
||||
|
||||
|
@ -346,7 +351,7 @@ private:
|
|||
|
||||
const VIA makeVia( const VECTOR2I& aP );
|
||||
|
||||
bool buildInitialLine( const VECTOR2I& aP, LINE& aHead );
|
||||
bool buildInitialLine( const VECTOR2I& aP, LINE& aHead, bool aInvertPosture = false );
|
||||
|
||||
///> current routing direction
|
||||
DIRECTION_45 m_direction;
|
||||
|
|
Loading…
Reference in New Issue