Improved performance for Cleanup Tracks & Vias.
This commit is contained in:
parent
0070a4686e
commit
14378812be
|
@ -270,6 +270,7 @@ void TRACKS_CLEANER::deleteTracksInPads()
|
||||||
void TRACKS_CLEANER::cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegments,
|
void TRACKS_CLEANER::cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegments,
|
||||||
bool aDeleteDuplicateSegments, bool aMergeSegments )
|
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;
|
DRC_RTREE rtree;
|
||||||
|
|
||||||
for( PCB_TRACK* track : m_brd->Tracks() )
|
for( PCB_TRACK* track : m_brd->Tracks() )
|
||||||
|
@ -410,12 +411,17 @@ void TRACKS_CLEANER::cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegment
|
||||||
// merge collinear segments:
|
// merge collinear segments:
|
||||||
for( PCB_TRACK* segment : temp_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;
|
continue;
|
||||||
|
|
||||||
if( segment->HasFlag( IS_DELETED ) ) // already taken in account
|
if( segment->HasFlag( IS_DELETED ) ) // already taken into account
|
||||||
continue;
|
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() )
|
for( CN_ITEM* citem : connectivity->ItemEntry( segment ).GetItems() )
|
||||||
{
|
{
|
||||||
// Do not merge an end which has different width tracks attached -- it's a
|
// 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() )
|
if( !connected->Valid() )
|
||||||
continue;
|
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() )
|
if( candidateSegment->GetWidth() == segment->GetWidth() )
|
||||||
|
{
|
||||||
sameWidthCandidates.push_back( candidateSegment );
|
sameWidthCandidates.push_back( candidateSegment );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
differentWidthCandidates.push_back( candidateSegment );
|
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 = true;
|
||||||
merged |= mergeCollinearSegments( segment, candidate );
|
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() )
|
if( aSeg1->IsLocked() || aSeg2->IsLocked() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_brd->GetConnectivity();
|
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_brd->GetConnectivity();
|
||||||
|
|
||||||
std::vector<BOARD_CONNECTED_ITEM*> tracks = connectivity->GetConnectedItems( aSeg1, items );
|
std::vector<BOARD_CONNECTED_ITEM*> tracks = aSeg1Items;
|
||||||
std::vector<BOARD_CONNECTED_ITEM*> tracks2 = connectivity->GetConnectedItems( aSeg2, items );
|
std::vector<BOARD_CONNECTED_ITEM*> tracks2 = connectivity->GetConnectedItems( aSeg2, types );
|
||||||
|
|
||||||
std::move( tracks2.begin(), tracks2.end(), std::back_inserter( tracks ) );
|
std::move( tracks2.begin(), tracks2.end(), std::back_inserter( tracks ) );
|
||||||
std::sort( tracks.begin(), tracks.end() );
|
std::sort( tracks.begin(), tracks.end() );
|
||||||
tracks.erase( std::unique( tracks.begin(), tracks.end() ), tracks.end() );
|
tracks.erase( std::unique( tracks.begin(), tracks.end() ), tracks.end() );
|
||||||
|
|
||||||
tracks.erase(
|
tracks.erase( std::remove_if( tracks.begin(), tracks.end(),
|
||||||
std::remove_if( tracks.begin(), tracks.end(), [ aSeg1, aSeg2 ]( BOARD_CONNECTED_ITEM* aTest )
|
[ aSeg1, aSeg2 ]( BOARD_CONNECTED_ITEM* aTest )
|
||||||
{
|
{
|
||||||
return ( aTest == aSeg1 ) || ( aTest == aSeg2 );
|
return ( aTest == aSeg1 ) || ( aTest == aSeg2 );
|
||||||
} ), tracks.end() );
|
} ),
|
||||||
|
tracks.end() );
|
||||||
|
|
||||||
std::set<VECTOR2I> pts;
|
std::set<VECTOR2I> pts;
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,8 @@ private:
|
||||||
* @param aSeg1 is the reference
|
* @param aSeg1 is the reference
|
||||||
* @param aSeg2 is the candidate, and after merging, the removed segment
|
* @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
|
* @return true if a track end position is a node, i.e. a end connected
|
||||||
|
|
Loading…
Reference in New Issue