Improved performance for Cleanup Tracks & Vias.

This commit is contained in:
Jeff Young 2022-03-13 15:53:34 +00:00
parent 0070a4686e
commit 14378812be
2 changed files with 37 additions and 19 deletions

View File

@ -270,6 +270,7 @@ void TRACKS_CLEANER::deleteTracksInPads()
void TRACKS_CLEANER::cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegments,
bool aDeleteDuplicateSegments, bool aMergeSegments )
{
KICAD_T types[] = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T, PCB_ZONE_T };
DRC_RTREE rtree;
for( PCB_TRACK* track : m_brd->Tracks() )
@ -410,12 +411,17 @@ void TRACKS_CLEANER::cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegment
// merge collinear segments:
for( PCB_TRACK* segment : temp_segments )
{
if( segment->Type() != PCB_TRACE_T ) // one can merge only track collinear segments, not vias.
// one can merge only collinear segments, not vias or arcs.
if( segment->Type() != PCB_TRACE_T )
continue;
if( segment->HasFlag( IS_DELETED ) ) // already taken in account
if( segment->HasFlag( IS_DELETED ) ) // already taken into account
continue;
std::vector<BOARD_CONNECTED_ITEM*> connectedItems =
m_brd->GetConnectivity()->GetConnectedItems( segment, types );
// for each end of the segment:
for( CN_ITEM* citem : connectivity->ItemEntry( segment ).GetItems() )
{
// Do not merge an end which has different width tracks attached -- it's a
@ -428,25 +434,34 @@ void TRACKS_CLEANER::cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegment
if( !connected->Valid() )
continue;
BOARD_CONNECTED_ITEM* candidateItem = connected->Parent();
BOARD_CONNECTED_ITEM* candidate = connected->Parent();
if( candidateItem->Type() == PCB_TRACE_T && !candidateItem->HasFlag( IS_DELETED ) )
if( candidate->Type() == PCB_TRACE_T && !candidate->HasFlag( IS_DELETED ) )
{
PCB_TRACK* candidateSegment = static_cast<PCB_TRACK*>( candidateItem );
PCB_TRACK* candidateSegment = static_cast<PCB_TRACK*>( candidate );
if( candidateSegment->GetWidth() == segment->GetWidth() )
{
sameWidthCandidates.push_back( candidateSegment );
}
else
{
differentWidthCandidates.push_back( candidateSegment );
break;
}
}
}
if( differentWidthCandidates.size() == 0 )
if( !differentWidthCandidates.empty() )
continue;
for( PCB_TRACK* candidate : sameWidthCandidates )
{
for( PCB_TRACK* candidate : sameWidthCandidates )
if( segment->ApproxCollinear( *candidate )
&& mergeCollinearSegments( segment, candidate, connectedItems ) )
{
if( segment->ApproxCollinear( *candidate ) )
merged |= mergeCollinearSegments( segment, candidate );
merged = true;
break;
}
}
}
@ -459,27 +474,29 @@ void TRACKS_CLEANER::cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegment
}
bool TRACKS_CLEANER::mergeCollinearSegments( PCB_TRACK* aSeg1, PCB_TRACK* aSeg2 )
bool TRACKS_CLEANER::mergeCollinearSegments( PCB_TRACK* aSeg1, PCB_TRACK* aSeg2,
const std::vector<BOARD_CONNECTED_ITEM*>& aSeg1Items )
{
KICAD_T items[] = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T, PCB_ZONE_T };
static KICAD_T types[] = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T, PCB_ZONE_T };
if( aSeg1->IsLocked() || aSeg2->IsLocked() )
return false;
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_brd->GetConnectivity();
std::vector<BOARD_CONNECTED_ITEM*> tracks = connectivity->GetConnectedItems( aSeg1, items );
std::vector<BOARD_CONNECTED_ITEM*> tracks2 = connectivity->GetConnectedItems( aSeg2, items );
std::vector<BOARD_CONNECTED_ITEM*> tracks = aSeg1Items;
std::vector<BOARD_CONNECTED_ITEM*> tracks2 = connectivity->GetConnectedItems( aSeg2, types );
std::move( tracks2.begin(), tracks2.end(), std::back_inserter( tracks ) );
std::sort( tracks.begin(), tracks.end() );
tracks.erase( std::unique( tracks.begin(), tracks.end() ), tracks.end() );
tracks.erase(
std::remove_if( tracks.begin(), tracks.end(), [ aSeg1, aSeg2 ]( BOARD_CONNECTED_ITEM* aTest )
{
return ( aTest == aSeg1 ) || ( aTest == aSeg2 );
} ), tracks.end() );
tracks.erase( std::remove_if( tracks.begin(), tracks.end(),
[ aSeg1, aSeg2 ]( BOARD_CONNECTED_ITEM* aTest )
{
return ( aTest == aSeg1 ) || ( aTest == aSeg2 );
} ),
tracks.end() );
std::set<VECTOR2I> pts;

View File

@ -81,7 +81,8 @@ private:
* @param aSeg1 is the reference
* @param aSeg2 is the candidate, and after merging, the removed segment
*/
bool mergeCollinearSegments( PCB_TRACK* aSeg1, PCB_TRACK* aSeg2 );
bool mergeCollinearSegments( PCB_TRACK* aSeg1, PCB_TRACK* aSeg2,
const std::vector<BOARD_CONNECTED_ITEM*>& aSeg1Items );
/**
* @return true if a track end position is a node, i.e. a end connected