From a2ac1cd0874919dac6f6680446fd005ee012627b Mon Sep 17 00:00:00 2001 From: Tomasz Wlostowski Date: Mon, 15 Aug 2016 17:16:49 +0200 Subject: [PATCH] P&S: cleaner placement of DP segments/vias. Speed improvements too. --- pcbnew/router/pns_diff_pair.cpp | 109 +++++++++++++++---------- pcbnew/router/pns_diff_pair.h | 12 ++- pcbnew/router/pns_diff_pair_placer.cpp | 34 ++++---- 3 files changed, 98 insertions(+), 57 deletions(-) diff --git a/pcbnew/router/pns_diff_pair.cpp b/pcbnew/router/pns_diff_pair.cpp index a6cedda2ff..802f939b0a 100644 --- a/pcbnew/router/pns_diff_pair.cpp +++ b/pcbnew/router/pns_diff_pair.cpp @@ -34,7 +34,7 @@ #include "pns_router.h" #include "pns_solid.h" #include "pns_utils.h" - +#include "pns_debug_decorator.h" class PNS_LINE; @@ -121,6 +121,42 @@ DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::anchorDirection( PNS_ITEM* aItem, const VECT return DIRECTION_45( s->Seg().B - s->Seg().A ); } +void PNS_DP_PRIMITIVE_PAIR::CursorOrientation( const VECTOR2I& aCursorPos, VECTOR2I& aMidpoint, VECTOR2I& aDirection ) const +{ + assert (m_primP && m_primN); + + VECTOR2I aP, aN, dir, midpoint; + + if ( m_primP->OfKind(PNS_ITEM::SEGMENT) && m_primN->OfKind(PNS_ITEM::SEGMENT) ) + { + aP = m_primP->Anchor( 1 ); + aN = m_primN->Anchor( 1 ); + midpoint = ( aP + aN ) / 2; + SEG s = static_cast (m_primP)->Seg(); + if ( s.B != s.A ) + { + dir = s.B - s.A; + } + else + { + dir = VECTOR2I(0, 1); + } + + dir = dir.Resize( (aP - aN).EuclideanNorm() ); + + } else { + aP = m_primP->Anchor( 0 ); + aN = m_primN->Anchor( 0 ); + midpoint = ( aP + aN ) / 2; + dir = ( aP - aN ).Perpendicular(); + + if ( dir.Dot( aCursorPos - midpoint ) < 0 ) + dir = -dir; + } + + aMidpoint = midpoint; + aDirection = dir; +} DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirP() const { @@ -134,19 +170,6 @@ DIRECTION_45 PNS_DP_PRIMITIVE_PAIR::DirN() const } -static void drawGw( VECTOR2I p, int color ) -{ - SHAPE_LINE_CHAIN l; - - l.Append( p - VECTOR2I( -50000, -50000 ) ); - l.Append( p + VECTOR2I( -50000, -50000 ) ); - - l.Clear(); - l.Append( p - VECTOR2I( 50000, -50000 ) ); - l.Append( p + VECTOR2I( 50000, -50000 ) ); -} - - static DIRECTION_45::AngleType angle( const VECTOR2I &a, const VECTOR2I &b ) { DIRECTION_45 dir_a( a ); @@ -182,7 +205,7 @@ void PNS_DP_GATEWAY::Reverse() } -bool PNS_DIFF_PAIR::BuildInitial( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY &aTarget, bool aPrefDiagonal ) +bool PNS_DIFF_PAIR::BuildInitial( const PNS_DP_GATEWAY& aEntry, const PNS_DP_GATEWAY &aTarget, bool aPrefDiagonal ) { SHAPE_LINE_CHAIN p = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorP(), aTarget.AnchorP(), aPrefDiagonal ); SHAPE_LINE_CHAIN n = DIRECTION_45().BuildInitialTrace ( aEntry.AnchorN(), aTarget.AnchorN(), aPrefDiagonal ); @@ -314,45 +337,41 @@ void PNS_DP_GATEWAYS::BuildOrthoProjections( PNS_DP_GATEWAYS& aEntries, bool PNS_DP_GATEWAYS::FitGateways( PNS_DP_GATEWAYS& aEntry, PNS_DP_GATEWAYS& aTarget, bool aPrefDiagonal, PNS_DIFF_PAIR& aDp ) { - std::vector candidates; + DP_CANDIDATE best; - for( PNS_DP_GATEWAY g_entry : aEntry.Gateways() ) + int n = 0; + int bestScore = -1000; + bool found = false; + + for( const PNS_DP_GATEWAY& g_entry : aEntry.Gateways() ) { - for( PNS_DP_GATEWAY g_target : aTarget.Gateways() ) + for( const PNS_DP_GATEWAY& g_target : aTarget.Gateways() ) { + + n++; + for( int attempt = 0; attempt < 2; attempt++ ) { + int score = ( attempt == 1 ? -3 : 0 ); + score += g_entry.Priority(); + score += g_target.Priority(); + + if( score < bestScore ) + continue; + PNS_DIFF_PAIR l( m_gap ); if( l.BuildInitial( g_entry, g_target, aPrefDiagonal ^ ( attempt ? true : false ) ) ) { - int score = ( attempt == 1 ? -3 : 0 ); - score +=g_entry.Priority(); - score +=g_target.Priority(); - - DP_CANDIDATE c; - c.score = score; - c.p = l.CP(); - c.n = l.CN(); - candidates.push_back( c ); + best.p = l.CP(); + best.n = l.CN(); + bestScore = score; + found = true; } } } } - int bestScore = -1000; - DP_CANDIDATE best; - bool found = false; - - for( DP_CANDIDATE c : candidates ) - { - if( c.score > bestScore ) - { - bestScore = c.score; - best = c; - found = true; - } - } if( found ) { @@ -373,6 +392,14 @@ bool PNS_DP_GATEWAYS::checkDiagonalAlignment( const VECTOR2I& a, const VECTOR2I& } +void PNS_DP_GATEWAYS::FilterByOrientation ( int aAngleMask, DIRECTION_45 aRefOrientation ) +{ + std::remove_if( m_gateways.begin(), m_gateways.end(), [aAngleMask, aRefOrientation] ( const PNS_DP_GATEWAY& dp) { + DIRECTION_45 orient ( dp.AnchorP() - dp.AnchorN() ); + return ! (orient.Angle ( aRefOrientation ) & aAngleMask ); + } ); +} + void PNS_DP_GATEWAYS::BuildFromPrimitivePair( PNS_DP_PRIMITIVE_PAIR aPair, bool aPreferDiagonal ) { VECTOR2I majorDirection; @@ -519,8 +546,6 @@ void PNS_DP_GATEWAYS::BuildForCursor( const VECTOR2I& aCursorPos ) m_gateways.push_back( PNS_DP_GATEWAY( aCursorPos + dir, aCursorPos - dir, attempt ? true : false ) ); - drawGw ( aCursorPos + dir, 2 ); - drawGw ( aCursorPos - dir, 3 ); } } } diff --git a/pcbnew/router/pns_diff_pair.h b/pcbnew/router/pns_diff_pair.h index e2e150097f..7e03a2e4bd 100644 --- a/pcbnew/router/pns_diff_pair.h +++ b/pcbnew/router/pns_diff_pair.h @@ -157,6 +157,9 @@ public: DIRECTION_45 DirP() const; DIRECTION_45 DirN() const; + + void CursorOrientation( const VECTOR2I& aCursorPos, VECTOR2I& aMidpoint, VECTOR2I& aDirection ) const; + void dump() { printf("-- Prim-P %p anchor [%d, %d]\n", m_primP, m_anchorP.x, m_anchorP.y); @@ -223,6 +226,13 @@ class PNS_DP_GATEWAYS return m_gateways; } + const std::vector& CGateways() const + { + return m_gateways; + } + + void FilterByOrientation ( int aAngleMask, DIRECTION_45 aRefOrientation ); + private: struct DP_CANDIDATE @@ -460,7 +470,7 @@ public: const SHAPE_LINE_CHAIN& CP() const { return m_p; } const SHAPE_LINE_CHAIN& CN() const { return m_n; } - bool BuildInitial ( PNS_DP_GATEWAY& aEntry, PNS_DP_GATEWAY& aTarget, bool aPrefDiagonal ); + bool BuildInitial ( const PNS_DP_GATEWAY& aEntry, const PNS_DP_GATEWAY& aTarget, bool aPrefDiagonal ); bool CheckConnectionAngle ( const PNS_DIFF_PAIR &aOther, int allowedAngles ) const; int CoupledLength ( const SEG& aP, const SEG& aN ) const; diff --git a/pcbnew/router/pns_diff_pair_placer.cpp b/pcbnew/router/pns_diff_pair_placer.cpp index 1109165cb3..2aa92057d5 100644 --- a/pcbnew/router/pns_diff_pair_placer.cpp +++ b/pcbnew/router/pns_diff_pair_placer.cpp @@ -18,9 +18,6 @@ * with this program. If not, see . */ -#include - -#include #include #include #include @@ -37,8 +34,6 @@ #include "pns_topology.h" #include "pns_debug_decorator.h" -using boost::optional; - PNS_DIFF_PAIR_PLACER::PNS_DIFF_PAIR_PLACER( PNS_ROUTER* aRouter ) : PNS_PLACEMENT_ALGO( aRouter ) { @@ -486,7 +481,7 @@ bool PNS_DIFF_PAIR_PLACER::findDpPrimitivePair( const VECTOR2I& aP, PNS_ITEM* aI if(!result) return false; - + int refNet = aItem->Net(); int coupledNet = (refNet == netP) ? netN : netP; @@ -664,10 +659,6 @@ bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP ) gwsEntry.BuildFromPrimitivePair( *m_prevPair, m_startDiagonal ); -// m_prevPair->dump(); - -// printf("Entry %d\n", gwsEntry.Gateways().size()); - PNS_DP_PRIMITIVE_PAIR target; if( findDpPrimitivePair ( aP, m_currentEndItem, target ) ) @@ -680,10 +671,23 @@ bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP ) if( !propagateDpHeadForces( aP, fp ) ) return false; + + VECTOR2I midp, dirV; + m_prevPair->CursorOrientation(fp, midp, dirV); + + VECTOR2I fpProj = SEG( midp, midp+dirV ).LineProject ( fp ); + int lead_dist = (fpProj - fp).EuclideanNorm(); + gwsTarget.SetFitVias( m_placingVia, m_sizes.ViaDiameter(), viaGap() ); - gwsTarget.BuildForCursor( fp ); - gwsTarget.BuildOrthoProjections( gwsEntry, fp, m_orthoMode ? 200 : -200 ); -// printf("Target %d\n", gwsTarget.Gateways().size()); + + if (lead_dist > m_sizes.DiffPairGap() + m_sizes.DiffPairWidth() ) + { + gwsTarget.BuildForCursor( fp ); + } else { + gwsTarget.BuildForCursor( fpProj ); + gwsTarget.FilterByOrientation ( DIRECTION_45::ANG_STRAIGHT | DIRECTION_45::ANG_HALF_FULL, DIRECTION_45 ( dirV ) ); + } + m_snapOnTarget = false; } @@ -691,7 +695,9 @@ bool PNS_DIFF_PAIR_PLACER::routeHead( const VECTOR2I& aP ) m_currentTrace.SetGap( gap() ); m_currentTrace.SetLayer( m_currentLayer ); - if ( gwsEntry.FitGateways( gwsEntry, gwsTarget, m_startDiagonal, m_currentTrace ) ) + bool result = gwsEntry.FitGateways( gwsEntry, gwsTarget, m_startDiagonal, m_currentTrace ); + + if ( result ) { m_currentTrace.SetNets( m_netP, m_netN ); m_currentTrace.SetWidth( m_sizes.DiffPairWidth() );