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 )
|
bool SHAPE::Parse( std::stringstream& aStream )
|
||||||
{
|
{
|
||||||
assert ( false );
|
assert( false );
|
||||||
return false;
|
return false;
|
||||||
};
|
}
|
||||||
|
|
||||||
const std::string SHAPE::Format( ) const
|
|
||||||
|
const std::string SHAPE::Format() const
|
||||||
{
|
{
|
||||||
assert ( false );
|
assert( false );
|
||||||
return std::string("");
|
return std::string( "" );
|
||||||
};
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* 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>
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* 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;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompareGeometry( const SHAPE_LINE_CHAIN & aOther ) const;
|
bool CompareGeometry( const SHAPE_LINE_CHAIN& aOther ) const;
|
||||||
|
|
||||||
void Move( const VECTOR2I& aVector ) override
|
void Move( const VECTOR2I& aVector ) override
|
||||||
{
|
{
|
||||||
|
@ -584,6 +584,8 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const VECTOR2I PointAlong( int aPathLength ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// array of vertices
|
/// array of vertices
|
||||||
std::vector<VECTOR2I> m_points;
|
std::vector<VECTOR2I> m_points;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
* 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.
|
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* 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 )
|
bool LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, LINE& aNewHead )
|
||||||
{
|
{
|
||||||
buildInitialLine( aP, m_head );
|
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;
|
aNewHead = m_head;
|
||||||
|
|
||||||
return static_cast<bool>( m_currentNode->CheckColliding( &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 )
|
bool LINE_PLACER::rhShoveOnly( const VECTOR2I& aP, LINE& aNewHead )
|
||||||
{
|
{
|
||||||
LINE initTrack( m_head );
|
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;
|
SHAPE_LINE_CHAIN l;
|
||||||
|
|
||||||
|
@ -1043,7 +1160,10 @@ bool LINE_PLACER::buildInitialLine( const VECTOR2I& aP, LINE& aHead )
|
||||||
}
|
}
|
||||||
else
|
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 )
|
if( l.SegmentCount() > 1 && m_orthoMode )
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* KiRouter - a push-and-(sometimes-)shove PCB router
|
* 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.
|
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
*
|
*
|
||||||
|
@ -335,6 +335,11 @@ private:
|
||||||
*/
|
*/
|
||||||
void routeStep( const VECTOR2I& aP );
|
void routeStep( const VECTOR2I& aP );
|
||||||
|
|
||||||
|
const LINE reduceToNearestObstacle( const LINE& aOriginalLine );
|
||||||
|
|
||||||
|
bool rhStopAtNearestObstacle( const VECTOR2I& aP, LINE& aNewHead );
|
||||||
|
|
||||||
|
|
||||||
///> route step, walkaround mode
|
///> route step, walkaround mode
|
||||||
bool rhWalkOnly( const VECTOR2I& aP, LINE& aNewHead);
|
bool rhWalkOnly( const VECTOR2I& aP, LINE& aNewHead);
|
||||||
|
|
||||||
|
@ -346,7 +351,7 @@ private:
|
||||||
|
|
||||||
const VIA makeVia( const VECTOR2I& aP );
|
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
|
///> current routing direction
|
||||||
DIRECTION_45 m_direction;
|
DIRECTION_45 m_direction;
|
||||||
|
|
Loading…
Reference in New Issue