7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-04 23:35:31 +00:00

Ensure PNS length tuning calculation uses correct layer ID context

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20372
This commit is contained in:
JamesJCode 2025-03-18 12:37:16 +00:00
parent 4ef0d3554e
commit 24a8c2a684
5 changed files with 36 additions and 31 deletions

View File

@ -104,7 +104,8 @@ bool DP_MEANDER_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
if( !m_originPair.PLine().SegmentCount() || !m_originPair.NLine().SegmentCount() )
return false;
m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &m_startPad_p, &m_endPad_p );
m_tunedPathP = topo.AssembleTuningPath( Router()->GetInterface(), m_originPair.PLine().GetLink( 0 ), &m_startPad_p,
&m_endPad_p );
m_padToDieP = 0;
@ -114,7 +115,8 @@ bool DP_MEANDER_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
if( m_endPad_p )
m_padToDieP += m_endPad_p->GetPadToDie();
m_tunedPathN = topo.AssembleTuningPath( m_originPair.NLine().GetLink( 0 ), &m_startPad_n, &m_endPad_n );
m_tunedPathN = topo.AssembleTuningPath( Router()->GetInterface(), m_originPair.NLine().GetLink( 0 ), &m_startPad_n,
&m_endPad_n );
m_padToDieN = 0;

View File

@ -72,7 +72,7 @@ bool MEANDER_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
m_originLine = m_world->AssembleLine( m_initialSegment );
TOPOLOGY topo( m_world );
m_tunedPath = topo.AssembleTuningPath( m_initialSegment, &m_startPad_n, &m_endPad_n );
m_tunedPath = topo.AssembleTuningPath( Router()->GetInterface(), m_initialSegment, &m_startPad_n, &m_endPad_n );
m_padToDieLength = 0;

View File

@ -78,7 +78,8 @@ bool MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
!m_originPair.NLine().SegmentCount() )
return false;
m_tunedPathP = topo.AssembleTuningPath( m_originPair.PLine().GetLink( 0 ), &m_startPad_p, &m_endPad_p );
m_tunedPathP = topo.AssembleTuningPath( Router()->GetInterface(), m_originPair.PLine().GetLink( 0 ), &m_startPad_p,
&m_endPad_p );
m_padToDieP = 0;
@ -88,7 +89,8 @@ bool MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, ITEM* aStartItem )
if( m_endPad_p )
m_padToDieP += m_endPad_p->GetPadToDie();
m_tunedPathN = topo.AssembleTuningPath( m_originPair.NLine().GetLink( 0 ), &m_startPad_n, &m_endPad_n );
m_tunedPathN = topo.AssembleTuningPath( Router()->GetInterface(), m_originPair.NLine().GetLink( 0 ), &m_startPad_n,
&m_endPad_n );
m_padToDieN = 0;

View File

@ -331,7 +331,8 @@ const ITEM_SET TOPOLOGY::AssembleTrivialPath( ITEM* aStart,
}
const ITEM_SET TOPOLOGY::AssembleTuningPath( ITEM* aStart, SOLID** aStartPad, SOLID** aEndPad )
const ITEM_SET TOPOLOGY::AssembleTuningPath( ROUTER_IFACE* aRouterIface, ITEM* aStart, SOLID** aStartPad,
SOLID** aEndPad )
{
std::pair<const JOINT*, const JOINT*> joints;
ITEM_SET initialPath = AssembleTrivialPath( aStart, &joints, true );
@ -416,41 +417,40 @@ const ITEM_SET TOPOLOGY::AssembleTuningPath( ITEM* aStart, SOLID** aStartPad, SO
aLine.Insert( aForward ? 0 : aLine.PointCount(), aPad->GetPosition() );
};
auto processPad =
[&]( const JOINT* aJoint, PAD* aPad, PCB_LAYER_ID aLayer )
{
const auto& shape = aPad->GetEffectivePolygon( aLayer, ERROR_INSIDE );
auto processPad = [&]( const JOINT* aJoint, PAD* aPad, int aLayer )
{
for( int idx = 0; idx < initialPath.Size(); idx++ )
{
if( initialPath[idx]->Kind() != ITEM::LINE_T )
continue;
for( int idx = 0; idx < initialPath.Size(); idx++ )
{
if( initialPath[idx]->Kind() != ITEM::LINE_T )
continue;
LINE* line = static_cast<LINE*>( initialPath[idx] );
PCB_LAYER_ID pcbLayer = aRouterIface->GetBoardLayerFromPNSLayer( line->Layer() );
LINE* line = static_cast<LINE*>( initialPath[idx] );
if( !aPad->FlashLayer( pcbLayer ) )
continue;
if( !aPad->FlashLayer( line->Layer() ) )
continue;
const std::vector<VECTOR2I>& points = line->CLine().CPoints();
const std::vector<VECTOR2I>& points = line->CLine().CPoints();
if( points.front() != aJoint->Pos() && points.back() != aJoint->Pos() )
continue;
if( points.front() != aJoint->Pos() && points.back() != aJoint->Pos() )
continue;
const auto& shape = aPad->GetEffectivePolygon( pcbLayer, ERROR_INSIDE );
SHAPE_LINE_CHAIN& slc = line->Line();
const PCB_LAYER_ID& layer = static_cast<PCB_LAYER_ID>( line->Layer() );
SHAPE_LINE_CHAIN& slc = line->Line();
if( shape->Contains( slc.CPoint( 0 ) ) )
clipLineToPad( slc, aPad, layer, true );
else if( shape->Contains( slc.CPoint( -1 ) ) )
clipLineToPad( slc, aPad, layer, false );
}
};
if( shape->Contains( slc.CPoint( 0 ) ) )
clipLineToPad( slc, aPad, pcbLayer, true );
else if( shape->Contains( slc.CPoint( -1 ) ) )
clipLineToPad( slc, aPad, pcbLayer, false );
}
};
if( padA )
processPad( joints.first, padA, static_cast<PCB_LAYER_ID>( joints.first->Layer() ) );
processPad( joints.first, padA, joints.first->Layer() );
if( padB )
processPad( joints.second, padB, static_cast<PCB_LAYER_ID>( joints.second->Layer() ) );
processPad( joints.second, padB, joints.second->Layer() );
return initialPath;
}

View File

@ -35,6 +35,7 @@ class JOINT;
class ITEM;
class SOLID;
class DIFF_PAIR;
class ROUTER_IFACE;
class TOPOLOGY
{
@ -90,7 +91,7 @@ public:
* @param aEndPad will be filled with the ending pad of the path, if found.
* @return an item set containing all the items in the path.
*/
const ITEM_SET AssembleTuningPath( ITEM* aStart, SOLID** aStartPad = nullptr,
const ITEM_SET AssembleTuningPath( ROUTER_IFACE* aRouterIface, ITEM* aStart, SOLID** aStartPad = nullptr,
SOLID** aEndPad = nullptr );
const DIFF_PAIR AssembleDiffPair( SEGMENT* aStart );