diff --git a/pcbnew/router/pns_dp_meander_placer.cpp b/pcbnew/router/pns_dp_meander_placer.cpp index ac9bdd3ea3..954457fdc3 100644 --- a/pcbnew/router/pns_dp_meander_placer.cpp +++ b/pcbnew/router/pns_dp_meander_placer.cpp @@ -100,28 +100,25 @@ bool DP_MEANDER_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem ) if( !m_originPair.PLine().SegmentCount() || !m_originPair.NLine().SegmentCount() ) return false; - SOLID* padA = nullptr; - SOLID* padB = nullptr; - - m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &padA, &padB ); + m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &m_startPad_p, &m_endPad_p ); m_padToDieP = 0; - if( padA ) - m_padToDieP += padA->GetPadToDie(); + if( m_startPad_p ) + m_padToDieP += m_startPad_p->GetPadToDie(); - if( padB ) - m_padToDieP += padB->GetPadToDie(); + if( m_endPad_p ) + m_padToDieP += m_endPad_p->GetPadToDie(); - m_tunedPathN = topo.AssembleTuningPath( m_originPair.NLine().GetLink( 0 ), &padA, &padB ); + m_tunedPathN = topo.AssembleTuningPath( m_originPair.NLine().GetLink( 0 ), &m_startPad_n, &m_endPad_n ); m_padToDieN = 0; - if( padA ) - m_padToDieN += padA->GetPadToDie(); + if( m_startPad_n ) + m_padToDieN += m_startPad_n->GetPadToDie(); - if( padB ) - m_padToDieN += padB->GetPadToDie(); + if( m_endPad_n ) + m_padToDieN += m_endPad_n->GetPadToDie(); m_padToDieLength = std::max( m_padToDieP, m_padToDieN ); @@ -141,8 +138,8 @@ void DP_MEANDER_PLACER::release() long long int DP_MEANDER_PLACER::origPathLength() const { - long long int totalP = m_padToDieLength + lineLength( m_tunedPathP ); - long long int totalN = m_padToDieLength + lineLength( m_tunedPathN ); + long long int totalP = m_padToDieLength + lineLength( m_tunedPathP, m_startPad_p, m_endPad_p ); + long long int totalN = m_padToDieLength + lineLength( m_tunedPathN, m_startPad_n, m_endPad_n ); return std::max( totalP, totalN ); } diff --git a/pcbnew/router/pns_meander_placer.cpp b/pcbnew/router/pns_meander_placer.cpp index 17982952e5..3c3533f01c 100644 --- a/pcbnew/router/pns_meander_placer.cpp +++ b/pcbnew/router/pns_meander_placer.cpp @@ -72,19 +72,16 @@ bool MEANDER_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem ) m_world = Router()->GetWorld()->Branch(); m_originLine = m_world->AssembleLine( m_initialSegment ); - SOLID* padA = nullptr; - SOLID* padB = nullptr; - TOPOLOGY topo( m_world ); - m_tunedPath = topo.AssembleTuningPath( m_initialSegment, &padA, &padB ); + m_tunedPath = topo.AssembleTuningPath( m_initialSegment, &m_startPad_n, &m_endPad_n ); m_padToDieLength = 0; - if( padA ) - m_padToDieLength += padA->GetPadToDie(); + if( m_startPad_n ) + m_padToDieLength += m_startPad_n->GetPadToDie(); - if( padB ) - m_padToDieLength += padB->GetPadToDie(); + if( m_endPad_n ) + m_padToDieLength += m_endPad_n->GetPadToDie(); m_world->Remove( m_originLine ); @@ -97,7 +94,7 @@ bool MEANDER_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem ) long long int MEANDER_PLACER::origPathLength() const { - return m_padToDieLength + lineLength( m_tunedPath ); + return m_padToDieLength + lineLength( m_tunedPath, m_startPad_n, m_endPad_n ); } diff --git a/pcbnew/router/pns_meander_placer_base.cpp b/pcbnew/router/pns_meander_placer_base.cpp index 9dd7964f39..381c72fd2e 100644 --- a/pcbnew/router/pns_meander_placer_base.cpp +++ b/pcbnew/router/pns_meander_placer_base.cpp @@ -33,6 +33,10 @@ MEANDER_PLACER_BASE::MEANDER_PLACER_BASE( ROUTER* aRouter ) : m_world = nullptr; m_currentWidth = 0; m_padToDieLength = 0; + m_startPad_n = nullptr; + m_startPad_p = nullptr; + m_endPad_n = nullptr; + m_endPad_p = nullptr; } @@ -278,10 +282,36 @@ VECTOR2I MEANDER_PLACER_BASE::getSnappedStartPoint( LINKED_ITEM* aStartItem, VEC } -long long int MEANDER_PLACER_BASE::lineLength( const ITEM_SET& aLine ) const +long long int MEANDER_PLACER_BASE::lineLength( const ITEM_SET& aLine, const SOLID* aStartPad, const SOLID* aEndPad ) const { long long int total = 0; + if( aLine.Empty() ) + return 0; + + const ITEM* start_item = aLine[0]; + const ITEM* end_item = aLine[aLine.Size() - 1]; + bool start_via = false; + bool end_via = false; + int start_layer = -1; + int end_layer = -1; + + std::set layer_set; + + for( int idx = 0; idx < aLine.Size(); idx++ ) + { + const ITEM* item = aLine[idx]; + layer_set.insert( item->Layer() ); + } + + /** + * If there is a start pad but the pad's layers do not overlap the first track layer, then there must be a + * fanout via on the line. If there isn't, we still need to have the via back to the pad, so count the distance + * in the line tuning + */ + start_via = aStartPad && ( !aStartPad->LayersOverlap( start_item ) ); + end_via = aEndPad && ( !aEndPad->LayersOverlap( end_item ) ); + for( int idx = 0; idx < aLine.Size(); idx++ ) { const ITEM* item = aLine[idx]; @@ -300,6 +330,22 @@ long long int MEANDER_PLACER_BASE::lineLength( const ITEM_SET& aLine ) const } } + if( start_via ) + { + int layerPrev = aStartPad->Layer(); + int layerNext = start_item->Layer(); + + total += m_router->GetInterface()->StackupHeight( layerPrev, layerNext ); + } + + if( end_via ) + { + int layerPrev = end_item->Layer(); + int layerNext = aEndPad->Layer(); + + total += m_router->GetInterface()->StackupHeight( layerPrev, layerNext ); + } + return total; } diff --git a/pcbnew/router/pns_meander_placer_base.h b/pcbnew/router/pns_meander_placer_base.h index 9c0a999390..f52f706ac4 100644 --- a/pcbnew/router/pns_meander_placer_base.h +++ b/pcbnew/router/pns_meander_placer_base.h @@ -149,7 +149,7 @@ protected: * @param aLine * @return */ - long long int lineLength( const ITEM_SET& aLine ) const; + long long int lineLength( const ITEM_SET& aLine, const SOLID* aStartPad, const SOLID* aEndPad ) const; ///< Pointer to world to search colliding items. NODE* m_world; @@ -165,6 +165,11 @@ protected: ///< The current end point. VECTOR2I m_currentEnd; + + SOLID* m_startPad_p; + SOLID* m_endPad_p; + SOLID* m_startPad_n; + SOLID* m_endPad_n; }; } diff --git a/pcbnew/router/pns_meander_skew_placer.cpp b/pcbnew/router/pns_meander_skew_placer.cpp index 3a8d376154..00b6dad908 100644 --- a/pcbnew/router/pns_meander_skew_placer.cpp +++ b/pcbnew/router/pns_meander_skew_placer.cpp @@ -80,44 +80,41 @@ bool MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem ) !m_originPair.NLine().SegmentCount() ) return false; - SOLID* padA = nullptr; - SOLID* padB = nullptr; - - m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &padA, &padB ); + m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &m_startPad_p, &m_endPad_p ); m_padToDieP = 0; - if( padA ) - m_padToDieP += padA->GetPadToDie(); + if( m_startPad_p ) + m_padToDieP += m_startPad_p->GetPadToDie(); - if( padB ) - m_padToDieP += padB->GetPadToDie(); + if( m_endPad_p ) + m_padToDieP += m_endPad_p->GetPadToDie(); - m_tunedPathN = topo.AssembleTuningPath( m_originPair.NLine().GetLink( 0 ), &padA, &padB ); + m_tunedPathN = topo.AssembleTuningPath( m_originPair.NLine().GetLink( 0 ), &m_startPad_n, &m_endPad_n ); m_padToDieN = 0; - if( padA ) - m_padToDieN += padA->GetPadToDie(); + if( m_startPad_n ) + m_padToDieN += m_startPad_n->GetPadToDie(); - if( padB ) - m_padToDieN += padB->GetPadToDie(); + if( m_endPad_n ) + m_padToDieN += m_endPad_n->GetPadToDie(); m_world->Remove( m_originLine ); m_currentWidth = m_originLine.Width(); m_currentEnd = VECTOR2I( 0, 0 ); - if ( m_originPair.PLine().Net() == m_originLine.Net() ) + if ( m_originPair.NetP() == m_originLine.Net() ) { m_padToDieLength = m_padToDieP; - m_coupledLength = m_padToDieN + lineLength( m_tunedPathN ); + m_coupledLength = m_padToDieN + lineLength( m_tunedPathN, m_startPad_n, m_endPad_n ); m_tunedPath = m_tunedPathP; } else { m_padToDieLength = m_padToDieN; - m_coupledLength = m_padToDieP + lineLength( m_tunedPathP ); + m_coupledLength = m_padToDieP + lineLength( m_tunedPathP, m_startPad_p, m_endPad_p ); m_tunedPath = m_tunedPathN; } @@ -127,7 +124,11 @@ bool MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem ) long long int MEANDER_SKEW_PLACER::origPathLength() const { - return m_padToDieLength + lineLength( m_tunedPath ); + if ( m_originPair.NetP() == m_originLine.Net() ) + return m_padToDieLength + lineLength( m_tunedPath, m_startPad_p, m_endPad_p ); + + return m_padToDieLength + lineLength( m_tunedPath, m_startPad_n, m_endPad_n ); + }