From 4e67de5c15f12b1ba778de8bdbc4c3b470c19280 Mon Sep 17 00:00:00 2001 From: Tomasz Wlostowski Date: Fri, 14 Nov 2014 19:17:01 +0100 Subject: [PATCH] P&S router bugfixes - fixed walkaround bug causing unwanted overlap/clearance violation when the first segment of trace being laid intersects the obstacle's hull at the same point twice (ie. goes in, turns around and goes out). - fixed placer bug not splitting the start segment after toggling via placement or changing trace width --- common/geometry/shape_line_chain.cpp | 13 ++++++++----- pcbnew/router/pns_line.cpp | 3 +++ pcbnew/router/pns_line_placer.cpp | 11 +++++++---- pcbnew/router/pns_line_placer.h | 1 + pcbnew/router/pns_walkaround.cpp | 12 +++++++++--- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/common/geometry/shape_line_chain.cpp b/common/geometry/shape_line_chain.cpp index e442fcd503..d5b974bb1e 100644 --- a/common/geometry/shape_line_chain.cpp +++ b/common/geometry/shape_line_chain.cpp @@ -150,10 +150,7 @@ int SHAPE_LINE_CHAIN::Split( const VECTOR2I& aP ) int ii = -1; int min_dist = 2; - ii = Find( aP ); - - if( ii >= 0 ) - return ii; + int found_index = Find( aP ); for( int s = 0; s < SegmentCount(); s++ ) { @@ -165,10 +162,16 @@ int SHAPE_LINE_CHAIN::Split( const VECTOR2I& aP ) if( dist < min_dist && seg.A != aP && seg.B != aP ) { min_dist = dist; - ii = s; + if(found_index < 0) + ii = s; + else if(s < found_index) + ii = s; } } + if( ii < 0 ) + ii = found_index; + if( ii >= 0 ) { m_points.insert( m_points.begin() + ii + 1, aP ); diff --git a/pcbnew/router/pns_line.cpp b/pcbnew/router/pns_line.cpp index cbf3a3e68e..d5494dc047 100644 --- a/pcbnew/router/pns_line.cpp +++ b/pcbnew/router/pns_line.cpp @@ -190,6 +190,9 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre, line.Intersect( aObstacle, ips ); + aWalk.Clear(); + aPost.Clear(); + int nearest_dist = INT_MAX; int farthest_dist = 0; diff --git a/pcbnew/router/pns_line_placer.cpp b/pcbnew/router/pns_line_placer.cpp index f56b66c793..0a57cea3b7 100644 --- a/pcbnew/router/pns_line_placer.cpp +++ b/pcbnew/router/pns_line_placer.cpp @@ -735,7 +735,8 @@ bool PNS_LINE_PLACER::SetLayer( int aLayer ) return false; } else if (!m_startItem || (m_startItem->OfKind(PNS_ITEM::VIA) && m_startItem->Layers().Overlaps( aLayer ))) { m_currentLayer = aLayer; - initPlacement ( ); + m_splitSeg = false; + initPlacement ( m_splitSeg ); Move ( m_currentEnd, NULL ); return true; } @@ -766,10 +767,11 @@ void PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ) m_startItem = aStartItem; m_placingVia = false; m_chainedPlacement = false; + m_splitSeg = splitSeg; setInitialDirection( Settings().InitialDirection() ); - initPlacement( splitSeg ); + initPlacement( m_splitSeg ); } void PNS_LINE_PLACER::initPlacement( bool aSplitSeg ) @@ -918,7 +920,8 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) m_startItem = NULL; m_placingVia = false; m_chainedPlacement = !pl.EndsWithVia(); - initPlacement(); + m_splitSeg = false; + initPlacement( ); } else { m_idle = true; } @@ -1000,7 +1003,7 @@ void PNS_LINE_PLACER::UpdateSizes( const PNS_SIZES_SETTINGS& aSizes ) m_sizes = aSizes; if( !m_idle ) { - initPlacement ( ); + initPlacement ( m_splitSeg ); Move ( m_currentEnd, NULL ); } } diff --git a/pcbnew/router/pns_line_placer.h b/pcbnew/router/pns_line_placer.h index 487dd1c99c..2c8aa010af 100644 --- a/pcbnew/router/pns_line_placer.h +++ b/pcbnew/router/pns_line_placer.h @@ -402,6 +402,7 @@ private: bool m_idle; bool m_chainedPlacement; + bool m_splitSeg; }; #endif // __PNS_LINE_PLACER_H diff --git a/pcbnew/router/pns_walkaround.cpp b/pcbnew/router/pns_walkaround.cpp index 071f762a32..d472d1ae95 100644 --- a/pcbnew/router/pns_walkaround.cpp +++ b/pcbnew/router/pns_walkaround.cpp @@ -57,7 +57,7 @@ PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::singleStep( PNS_LINE& aPath, VECTOR2I last = aPath.CPoint( -1 ); - if( ( current_obs->m_hull ).PointInside( last ) ) + if( ( current_obs->m_hull ).PointInside( last ) || ( current_obs->m_hull ).PointOnEdge( last ) ) { m_recursiveBlockageCount++; @@ -99,7 +99,10 @@ PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::singleStep( PNS_LINE& aPath, pnew.Append( path_walk[1] ); pnew.Append( path_post[1] ); - current_obs = nearestObstacle( PNS_LINE( aPath, path_post[1] ) ); + if(!path_post[1].PointCount() || !path_walk[1].PointCount()) + current_obs = nearestObstacle( PNS_LINE( aPath, path_pre[1] ) ); + else + current_obs = nearestObstacle( PNS_LINE( aPath, path_post[1] ) ); prev_recursive = false; } else @@ -108,7 +111,10 @@ PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::singleStep( PNS_LINE& aPath, pnew.Append( path_walk[0] ); pnew.Append( path_post[0] ); - current_obs = nearestObstacle( PNS_LINE( aPath, path_walk[0] ) ); + if(!path_post[0].PointCount() || !path_walk[0].PointCount()) + current_obs = nearestObstacle( PNS_LINE( aPath, path_pre[0] ) ); + else + current_obs = nearestObstacle( PNS_LINE( aPath, path_walk[0] ) ); if( !current_obs ) {