From aa4d7682ca77bf9cbc388e215c73873fbd334373 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 21 Jul 2019 16:36:08 -0600 Subject: [PATCH] Don't shove stitching vias. Whether or not it's a good idea, the current algorithm doesn't support it and leaves them on top of each other. Fixes: lp:1833214 * https://bugs.launchpad.net/kicad/+bug/1833214 --- pcbnew/router/pns_joint.h | 5 +++ pcbnew/router/pns_shove.cpp | 78 ++++++++++++++++--------------------- 2 files changed, 39 insertions(+), 44 deletions(-) diff --git a/pcbnew/router/pns_joint.h b/pcbnew/router/pns_joint.h index 2e68b43779..b394c13cd9 100644 --- a/pcbnew/router/pns_joint.h +++ b/pcbnew/router/pns_joint.h @@ -118,6 +118,11 @@ public: return ( m_linkedItems.Size() == 3 && vias == 1 && segs == 2 ); } + bool IsStitchingVia() const + { + return ( m_linkedItems.Size() == 1 && m_linkedItems.Count( VIA_T ) == 1 ); + } + bool IsTraceWidthChange() const { if( m_linkedItems.Size() != 2 ) diff --git a/pcbnew/router/pns_shove.cpp b/pcbnew/router/pns_shove.cpp index 7cc361d5f7..ecad37e94a 100644 --- a/pcbnew/router/pns_shove.cpp +++ b/pcbnew/router/pns_shove.cpp @@ -19,13 +19,9 @@ * with this program. If not, see . */ -#define PNS_DEBUG - #include #include -#include "range.h" - #include "pns_line.h" #include "pns_node.h" #include "pns_walkaround.h" @@ -35,14 +31,10 @@ #include "pns_via.h" #include "pns_utils.h" #include "pns_router.h" -#include "pns_shove.h" -#include "pns_utils.h" #include "pns_topology.h" #include "time_limit.h" -#include - namespace PNS { void SHOVE::replaceItems( ITEM* aOld, std::unique_ptr< ITEM > aNew ) @@ -128,12 +120,13 @@ bool SHOVE::checkBumpDirection( const LINE& aCurrent, const LINE& aShoved ) cons } -SHOVE::SHOVE_STATUS SHOVE::walkaroundLoneVia( LINE& aCurrent, LINE& aObstacle, - LINE& aShoved ) +SHOVE::SHOVE_STATUS SHOVE::walkaroundLoneVia( LINE& aCurrent, LINE& aObstacle, LINE& aShoved ) { int clearance = getClearance( &aCurrent, &aObstacle ); const SHAPE_LINE_CHAIN hull = aCurrent.Via().Hull( clearance, aObstacle.Width() ); - SHAPE_LINE_CHAIN path_cw, path_ccw; + SHAPE_LINE_CHAIN path_cw; + SHAPE_LINE_CHAIN path_ccw; + VECTOR2I dummy; if( ! aObstacle.Walkaround( hull, path_cw, true ) ) return SH_INCOMPLETE; @@ -261,8 +254,7 @@ SHOVE::SHOVE_STATUS SHOVE::processHullSet( LINE& aCurrent, LINE& aObstacle, } -SHOVE::SHOVE_STATUS SHOVE::ProcessSingleLine( LINE& aCurrent, LINE& aObstacle, - LINE& aShoved ) +SHOVE::SHOVE_STATUS SHOVE::ProcessSingleLine( LINE& aCurrent, LINE& aObstacle, LINE& aShoved ) { aShoved.ClearSegmentLinks(); @@ -610,6 +602,9 @@ SHOVE::SHOVE_STATUS SHOVE::pushVia( VIA* aVia, const VECTOR2I& aForce, int aCurr if( aVia->IsLocked() ) return SH_TRY_WALK; + if( jt->IsStitchingVia() ) + return SH_TRY_WALK; + if( jt->IsLocked() ) return SH_INCOMPLETE; @@ -723,9 +718,13 @@ SHOVE::SHOVE_STATUS SHOVE::onCollidingVia( ITEM* aCurrent, VIA* aObstacleVia ) { int clearance = getClearance( aCurrent, aObstacleVia ) ; LINE_PAIR_VEC draggedLines; - bool colLine = false, colVia = false; + bool lineCollision = false; + bool viaCollision = false; LINE* currentLine = NULL; - VECTOR2I mtvLine, mtvVia, mtv, mtvSolid; + VECTOR2I mtvLine; + VECTOR2I mtvVia; + VECTOR2I mtvSolid; + VECTOR2I mtv; int rank = -1; if( aCurrent->OfKind( ITEM::LINE_T ) ) @@ -736,20 +735,22 @@ SHOVE::SHOVE_STATUS SHOVE::onCollidingVia( ITEM* aCurrent, VIA* aObstacleVia ) #endif currentLine = (LINE*) aCurrent; - colLine = CollideShapes( aObstacleVia->Shape(), currentLine->Shape(), - clearance + currentLine->Width() / 2 + PNS_HULL_MARGIN, - true, mtvLine ); + lineCollision = CollideShapes( aObstacleVia->Shape(), currentLine->Shape(), + clearance + currentLine->Width() / 2 + PNS_HULL_MARGIN, + true, mtvLine ); if( currentLine->EndsWithVia() ) - colVia = CollideShapes( currentLine->Via().Shape(), aObstacleVia->Shape(), - clearance + PNS_HULL_MARGIN, true, mtvVia ); + { + viaCollision = CollideShapes( currentLine->Via().Shape(), aObstacleVia->Shape(), + clearance + PNS_HULL_MARGIN, true, mtvVia ); + } - if( !colLine && !colVia ) + if( !lineCollision && !viaCollision ) return SH_OK; - if( colLine && colVia ) + if( lineCollision && viaCollision ) mtv = mtvVia.EuclideanNorm() > mtvLine.EuclideanNorm() ? mtvVia : mtvLine; - else if( colLine ) + else if( lineCollision ) mtv = mtvLine; else mtv = mtvVia; @@ -1005,9 +1006,8 @@ SHOVE::SHOVE_STATUS SHOVE::shoveIteration( int aIter ) st = onCollidingSegment( currentLine, (SEGMENT*) ni ); if( st == SH_TRY_WALK ) - { st = onCollidingSolid( currentLine, ni ); - } + break; case ITEM::VIA_T: @@ -1015,9 +1015,8 @@ SHOVE::SHOVE_STATUS SHOVE::shoveIteration( int aIter ) st = onCollidingVia( ¤tLine, (VIA*) ni ); if( st == SH_TRY_WALK ) - { st = onCollidingSolid( currentLine, ni ); - } + break; case ITEM::SOLID_T: @@ -1077,7 +1076,8 @@ OPT_BOX2I SHOVE::totalAffectedArea() const { if( m_affectedAreaSum ) area->Merge( *m_affectedAreaSum ); - } else + } + else area = m_affectedAreaSum; return area; @@ -1268,8 +1268,7 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveMultiLines( const ITEM_SET& aHeadSet ) } -SHOVE::SHOVE_STATUS SHOVE::ShoveDraggingVia( VIA* aVia, const VECTOR2I& aWhere, - VIA** aNewVia ) +SHOVE::SHOVE_STATUS SHOVE::ShoveDraggingVia( VIA* aVia, const VECTOR2I& aWhere, VIA** aNewVia ) { SHOVE_STATUS st = SH_OK; @@ -1309,9 +1308,7 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveDraggingVia( VIA* aVia, const VECTOR2I& aWhere, else { if( aNewVia ) - { *aNewVia = nullptr; - } delete m_currentNode; m_currentNode = parent; @@ -1324,7 +1321,8 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveDraggingVia( VIA* aVia, const VECTOR2I& aWhere, void SHOVE::runOptimizer( NODE* aNode ) { OPTIMIZER optimizer( aNode ); - int optFlags = 0, n_passes = 0; + int optFlags = 0; + int n_passes = 0; PNS_OPTIMIZATION_EFFORT effort = Settings().OptimizerEffort(); @@ -1332,16 +1330,11 @@ void SHOVE::runOptimizer( NODE* aNode ) int maxWidth = 0; - for( std::vector::iterator i = m_optimizerQueue.begin(); - i != m_optimizerQueue.end(); ++i ) - { - maxWidth = std::max( i->Width(), maxWidth ); - } + for( LINE& line : m_optimizerQueue ) + maxWidth = std::max( line.Width(), maxWidth ); if( area ) - { area->Inflate( 10 * maxWidth ); - } switch( effort ) { @@ -1378,11 +1371,8 @@ void SHOVE::runOptimizer( NODE* aNode ) { std::reverse( m_optimizerQueue.begin(), m_optimizerQueue.end() ); - for( std::vector::iterator i = m_optimizerQueue.begin(); - i != m_optimizerQueue.end(); ++i ) + for( LINE& line : m_optimizerQueue) { - LINE& line = *i; - if( !( line.Marker() & MK_HEAD ) ) { LINE optimized;