Improve clean up tracks & vias algorithm for neck-downs.
Fixes https://gitlab.com/kicad/code/kicad/issues/10098
This commit is contained in:
parent
6e2460ad37
commit
d5a5928e5a
|
@ -287,7 +287,7 @@ public:
|
||||||
return std::abs( dist1 ) <= 1 && std::abs( dist2 ) <= 1;
|
return std::abs( dist1 ) <= 1 && std::abs( dist2 ) <= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ApproxParallel ( const SEG& aSeg, int aDistanceThreshold = 1 ) const
|
bool ApproxParallel( const SEG& aSeg, int aDistanceThreshold = 1 ) const
|
||||||
{
|
{
|
||||||
ecoord p, q, r;
|
ecoord p, q, r;
|
||||||
CanonicalCoefs( p, q, r );
|
CanonicalCoefs( p, q, r );
|
||||||
|
|
|
@ -401,6 +401,8 @@ void TRACKS_CLEANER::cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegment
|
||||||
merged = false;
|
merged = false;
|
||||||
m_brd->BuildConnectivity();
|
m_brd->BuildConnectivity();
|
||||||
|
|
||||||
|
auto connectivity = m_brd->GetConnectivity()->GetConnectivityAlgo();
|
||||||
|
|
||||||
// Keep a duplicate deque to all deleting in the primary
|
// Keep a duplicate deque to all deleting in the primary
|
||||||
std::deque<PCB_TRACK*> temp_segments( m_brd->Tracks() );
|
std::deque<PCB_TRACK*> temp_segments( m_brd->Tracks() );
|
||||||
|
|
||||||
|
@ -413,12 +415,13 @@ void TRACKS_CLEANER::cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegment
|
||||||
if( segment->HasFlag( IS_DELETED ) ) // already taken in account
|
if( segment->HasFlag( IS_DELETED ) ) // already taken in account
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto connectivity = m_brd->GetConnectivity();
|
for( CN_ITEM* citem : connectivity->ItemEntry( segment ).GetItems() )
|
||||||
|
|
||||||
auto& entry = connectivity->GetConnectivityAlgo()->ItemEntry( segment );
|
|
||||||
|
|
||||||
for( CN_ITEM* citem : entry.GetItems() )
|
|
||||||
{
|
{
|
||||||
|
// Do not merge an end which has different width tracks attached -- it's a
|
||||||
|
// common use-case for necking-down a track between pads.
|
||||||
|
std::vector<PCB_TRACK*> sameWidthCandidates;
|
||||||
|
std::vector<PCB_TRACK*> differentWidthCandidates;
|
||||||
|
|
||||||
for( CN_ITEM* connected : citem->ConnectedItems() )
|
for( CN_ITEM* connected : citem->ConnectedItems() )
|
||||||
{
|
{
|
||||||
if( !connected->Valid() )
|
if( !connected->Valid() )
|
||||||
|
@ -430,13 +433,19 @@ void TRACKS_CLEANER::cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegment
|
||||||
{
|
{
|
||||||
PCB_TRACK* candidateSegment = static_cast<PCB_TRACK*>( candidateItem );
|
PCB_TRACK* candidateSegment = static_cast<PCB_TRACK*>( candidateItem );
|
||||||
|
|
||||||
// Do not merge segments having different widths: it is a frequent case
|
if( candidateSegment->GetWidth() == segment->GetWidth() )
|
||||||
// to draw a track between 2 pads:
|
sameWidthCandidates.push_back( candidateSegment );
|
||||||
if( candidateSegment->GetWidth() != segment->GetWidth() )
|
else
|
||||||
continue;
|
differentWidthCandidates.push_back( candidateSegment );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( segment->ApproxCollinear( *candidateSegment ) )
|
if( differentWidthCandidates.size() == 0 )
|
||||||
merged |= mergeCollinearSegments( segment, candidateSegment );
|
{
|
||||||
|
for( PCB_TRACK* candidate : sameWidthCandidates )
|
||||||
|
{
|
||||||
|
if( segment->ApproxCollinear( *candidate ) )
|
||||||
|
merged |= mergeCollinearSegments( segment, candidate );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue