|
|
|
@ -189,8 +189,24 @@ bool LINE_PLACER::handlePullback() |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
DIRECTION_45 first_head( head.CSegment( 0 ) ); |
|
|
|
DIRECTION_45 last_tail( tail.CSegment( -1 ) ); |
|
|
|
DIRECTION_45 first_head, last_tail; |
|
|
|
|
|
|
|
const std::vector<ssize_t>& headShapes = head.CShapes(); |
|
|
|
const std::vector<ssize_t>& tailShapes = tail.CShapes(); |
|
|
|
|
|
|
|
wxASSERT( tail.PointCount() >= 2 ); |
|
|
|
if( headShapes[0] == -1 ) |
|
|
|
first_head = DIRECTION_45( head.CSegment( 0 ) ); |
|
|
|
else |
|
|
|
first_head = DIRECTION_45( head.CArcs()[ headShapes[0] ] ); |
|
|
|
|
|
|
|
int lastSegIdx = tail.PointCount() - 2; |
|
|
|
|
|
|
|
if( tailShapes[lastSegIdx] == -1 ) |
|
|
|
last_tail = DIRECTION_45( tail.CSegment( lastSegIdx ) ); |
|
|
|
else |
|
|
|
last_tail = DIRECTION_45( tail.CArcs()[tailShapes[lastSegIdx]] ); |
|
|
|
|
|
|
|
DIRECTION_45::AngleType angle = first_head.Angle( last_tail ); |
|
|
|
|
|
|
|
// case 1: we have a defined routing direction, and the currently computed
|
|
|
|
@ -204,9 +220,20 @@ bool LINE_PLACER::handlePullback() |
|
|
|
|
|
|
|
if( pullback_1 || pullback_2 ) |
|
|
|
{ |
|
|
|
const SEG last = tail.CSegment( -1 ); |
|
|
|
m_direction = DIRECTION_45( last ); |
|
|
|
m_p_start = last.A; |
|
|
|
lastSegIdx = tail.PrevShape( -1 ); |
|
|
|
|
|
|
|
if( tailShapes[lastSegIdx] == -1 ) |
|
|
|
{ |
|
|
|
const SEG& seg = tail.CSegment( lastSegIdx ); |
|
|
|
m_direction = DIRECTION_45( seg ); |
|
|
|
m_p_start = seg.A; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
const SHAPE_ARC& arc = tail.CArcs()[tailShapes[lastSegIdx]]; |
|
|
|
m_direction = DIRECTION_45( arc ); |
|
|
|
m_p_start = arc.GetP0(); |
|
|
|
} |
|
|
|
|
|
|
|
wxLogTrace( "PNS", "Placer: pullback triggered [%d] [%s %s]", |
|
|
|
n, last_tail.Format().c_str(), first_head.Format().c_str() ); |
|
|
|
@ -217,7 +244,7 @@ bool LINE_PLACER::handlePullback() |
|
|
|
if( n < 2 ) |
|
|
|
tail.Clear(); // don't leave a single-point tail
|
|
|
|
else |
|
|
|
tail.Remove( -1, -1 ); |
|
|
|
tail.RemoveShape( -1 ); |
|
|
|
|
|
|
|
if( !tail.SegmentCount() ) |
|
|
|
m_direction = m_initial_direction; |
|
|
|
@ -294,15 +321,6 @@ bool LINE_PLACER::reduceTail( const VECTOR2I& aEnd ) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool LINE_PLACER::checkObtusity( const SEG& aA, const SEG& aB ) const |
|
|
|
{ |
|
|
|
const DIRECTION_45 dir_a( aA ); |
|
|
|
const DIRECTION_45 dir_b( aB ); |
|
|
|
|
|
|
|
return dir_a.IsObtuse( dir_b ) || dir_a == dir_b; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool LINE_PLACER::mergeHead() |
|
|
|
{ |
|
|
|
SHAPE_LINE_CHAIN& head = m_head.Line(); |
|
|
|
@ -315,8 +333,8 @@ bool LINE_PLACER::mergeHead() |
|
|
|
head.Simplify(); |
|
|
|
tail.Simplify(); |
|
|
|
|
|
|
|
int n_head = head.SegmentCount(); |
|
|
|
int n_tail = tail.SegmentCount(); |
|
|
|
int n_head = head.ShapeCount(); |
|
|
|
int n_tail = tail.ShapeCount(); |
|
|
|
|
|
|
|
if( n_head < 3 ) |
|
|
|
{ |
|
|
|
@ -335,25 +353,41 @@ bool LINE_PLACER::mergeHead() |
|
|
|
|
|
|
|
DIRECTION_45 dir_tail, dir_head; |
|
|
|
|
|
|
|
dir_head = DIRECTION_45( head.CSegment( 0 ) ); |
|
|
|
const std::vector<ssize_t>& headShapes = head.CShapes(); |
|
|
|
const std::vector<ssize_t>& tailShapes = tail.CShapes(); |
|
|
|
|
|
|
|
if( headShapes[0] == -1 ) |
|
|
|
dir_head = DIRECTION_45( head.CSegment( 0 ) ); |
|
|
|
else |
|
|
|
dir_head = DIRECTION_45( head.CArcs()[ headShapes[0] ] ); |
|
|
|
|
|
|
|
if( n_tail ) |
|
|
|
{ |
|
|
|
dir_tail = DIRECTION_45( tail.CSegment( -1 ) ); |
|
|
|
wxASSERT( tail.PointCount() >= 2 ); |
|
|
|
int lastSegIdx = tail.PointCount() - 2; |
|
|
|
|
|
|
|
if( tailShapes[lastSegIdx] == -1 ) |
|
|
|
dir_tail = DIRECTION_45( tail.CSegment( -1 ) ); |
|
|
|
else |
|
|
|
dir_tail = DIRECTION_45( tail.CArcs()[ tailShapes[lastSegIdx] ] ); |
|
|
|
|
|
|
|
if( dir_head.Angle( dir_tail ) & ForbiddenAngles ) |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
tail.Append( head ); |
|
|
|
tail.Remove( -1 ); |
|
|
|
|
|
|
|
tail.Simplify(); |
|
|
|
|
|
|
|
SEG last = tail.CSegment( -1 ); |
|
|
|
|
|
|
|
SEG last = tail.CSegment( -1 ); |
|
|
|
m_p_start = last.B; |
|
|
|
m_direction = DIRECTION_45( last ).Right(); |
|
|
|
|
|
|
|
int lastSegIdx = tail.PointCount() - 2; |
|
|
|
|
|
|
|
if( tailShapes[lastSegIdx] == -1 ) |
|
|
|
m_direction = DIRECTION_45( tail.CSegment( -1 ) ); |
|
|
|
else |
|
|
|
m_direction = DIRECTION_45( tail.CArcs()[ tailShapes[lastSegIdx] ] ); |
|
|
|
|
|
|
|
head.Remove( 0, -1 ); |
|
|
|
|
|
|
|
@ -646,7 +680,7 @@ bool LINE_PLACER::optimizeTailHeadTransition() |
|
|
|
|
|
|
|
int threshold = std::min( tail.PointCount(), tailLookbackSegments + 1 ); |
|
|
|
|
|
|
|
if( tail.SegmentCount() < 3 ) |
|
|
|
if( tail.ShapeCount() < 3 ) |
|
|
|
return false; |
|
|
|
|
|
|
|
// assemble TailLookbackSegments tail segments with the current head
|
|
|
|
@ -691,10 +725,10 @@ void LINE_PLACER::routeStep( const VECTOR2I& aP ) |
|
|
|
|
|
|
|
LINE new_head; |
|
|
|
|
|
|
|
wxLogTrace( "PNS", "INIT-DIR: %s head: %d, tail: %d segs", |
|
|
|
m_initial_direction.Format().c_str(), |
|
|
|
m_head.SegmentCount(), |
|
|
|
m_tail.SegmentCount() ); |
|
|
|
wxLogTrace( "PNS", "routeStep: direction: %s head: %d, tail: %d shapes", |
|
|
|
m_direction.Format().c_str(), |
|
|
|
m_head.ShapeCount(), |
|
|
|
m_tail.ShapeCount() ); |
|
|
|
|
|
|
|
for( i = 0; i < n_iter; i++ ) |
|
|
|
{ |
|
|
|
@ -1064,6 +1098,7 @@ bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinis |
|
|
|
if( !fixAll && l.ArcCount() ) |
|
|
|
fixAll = true; |
|
|
|
|
|
|
|
// TODO: lastDirSeg will be calculated incorrectly if we end on an arc
|
|
|
|
SEG lastDirSeg = ( !fixAll && l.SegmentCount() > 1 ) ? l.CSegment( -2 ) : l.CSegment( -1 ); |
|
|
|
lastDirSeg.A.y = -lastDirSeg.A.y; |
|
|
|
lastDirSeg.B.y = -lastDirSeg.B.y; |
|
|
|
@ -1118,9 +1153,7 @@ bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem, bool aForceFinis |
|
|
|
setInitialDirection( d_last ); |
|
|
|
m_currentStart = ( m_placingVia || fixAll ) ? p_last : p_pre_last; |
|
|
|
|
|
|
|
NODE* commit = fixAll ? m_lastNode : m_currentNode; |
|
|
|
|
|
|
|
m_fixedTail.AddStage( m_p_start, m_currentLayer, m_placingVia, m_direction, commit ); |
|
|
|
m_fixedTail.AddStage( m_p_start, m_currentLayer, m_placingVia, m_direction, m_currentNode ); |
|
|
|
|
|
|
|
m_startItem = NULL; |
|
|
|
m_placingVia = false; |
|
|
|
@ -1323,6 +1356,9 @@ bool LINE_PLACER::buildInitialLine( const VECTOR2I& aP, LINE& aHead ) |
|
|
|
SHAPE_LINE_CHAIN l; |
|
|
|
DIRECTION_45 guessedDir = m_postureSolver.GetPosture( aP ); |
|
|
|
|
|
|
|
wxLogTrace( "PNS", "buildInitialLine: m_direction %s, guessedDir %s, tail points %d", |
|
|
|
m_direction.Format(), guessedDir.Format(), m_tail.PointCount() ); |
|
|
|
|
|
|
|
// Rounded corners don't make sense when routing orthogonally (single track at a time)
|
|
|
|
bool fillet = !m_orthoMode && Settings().GetCornerMode() == CORNER_MODE::ROUNDED_45; |
|
|
|
|
|
|
|
|