mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-03-30 06:46:55 +00:00
Performance improvements for teardrop regeneration.
Avoid O(n^2) behaviour when deleting many zones from the board zones list.
This commit is contained in:
parent
5edae8250d
commit
281aa74f30
pcbnew
@ -1187,6 +1187,23 @@ void BOARD::FinalizeBulkRemove( std::vector<BOARD_ITEM*>& aRemovedItems )
|
||||
}
|
||||
|
||||
|
||||
void BOARD::BulkRemoveStaleTeardrops( BOARD_COMMIT& aCommit )
|
||||
{
|
||||
for( int ii = (int) m_zones.size() - 1; ii > 0; --ii )
|
||||
{
|
||||
ZONE* zone = m_zones[ii];
|
||||
|
||||
if( zone->IsTeardropArea() && zone->HasFlag( STRUCT_DELETED ) )
|
||||
{
|
||||
m_itemByIdCache.erase( zone->m_Uuid );
|
||||
m_zones.erase( m_zones.begin() + ii );
|
||||
m_connectivity->Remove( zone );
|
||||
aCommit.Removed( zone );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BOARD::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aRemoveMode )
|
||||
{
|
||||
// find these calls and fix them! Don't send me no stinking' nullptr.
|
||||
|
@ -424,6 +424,12 @@ public:
|
||||
PCB_GENERATOR_T, PCB_FOOTPRINT_T,
|
||||
PCB_TRACE_T, PCB_SHAPE_T } );
|
||||
|
||||
/**
|
||||
* Remove all teardrop zones with the STRUCT_DELETED flag set. This avoids O(n^2) traversal
|
||||
* over the zone list.
|
||||
*/
|
||||
void BulkRemoveStaleTeardrops( BOARD_COMMIT& aCommit );
|
||||
|
||||
/**
|
||||
* Must be used if Add() is used using a BULK_x ADD_MODE to generate a change event for
|
||||
* listeners.
|
||||
|
@ -101,7 +101,6 @@ void TEARDROP_MANAGER::RemoveTeardrops( BOARD_COMMIT& aCommit,
|
||||
const std::set<PCB_TRACK*>* dirtyTracks )
|
||||
{
|
||||
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity();
|
||||
std::vector<ZONE*> stale_teardrops;
|
||||
|
||||
auto isStale =
|
||||
[&]( ZONE* zone )
|
||||
@ -135,14 +134,10 @@ void TEARDROP_MANAGER::RemoveTeardrops( BOARD_COMMIT& aCommit,
|
||||
for( ZONE* zone : m_board->Zones() )
|
||||
{
|
||||
if( zone->IsTeardropArea() && isStale( zone ) )
|
||||
stale_teardrops.push_back( zone );
|
||||
zone->SetFlags( STRUCT_DELETED );
|
||||
}
|
||||
|
||||
for( ZONE* td : stale_teardrops )
|
||||
{
|
||||
m_board->Remove( td, REMOVE_MODE::BULK );
|
||||
aCommit.Removed( td );
|
||||
}
|
||||
m_board->BulkRemoveStaleTeardrops( aCommit );
|
||||
}
|
||||
|
||||
|
||||
@ -162,19 +157,13 @@ void TEARDROP_MANAGER::UpdateTeardrops( BOARD_COMMIT& aCommit,
|
||||
// Old teardrops must be removed, to ensure a clean teardrop rebuild
|
||||
if( aForceFullUpdate )
|
||||
{
|
||||
std::vector<ZONE*> teardrops;
|
||||
|
||||
for( ZONE* zone : m_board->Zones() )
|
||||
{
|
||||
if( zone->IsTeardropArea() )
|
||||
teardrops.push_back( zone );
|
||||
zone->SetFlags( STRUCT_DELETED );
|
||||
}
|
||||
|
||||
for( ZONE* td : teardrops )
|
||||
{
|
||||
m_board->Remove( td, REMOVE_MODE::BULK );
|
||||
aCommit.Removed( td );
|
||||
}
|
||||
m_board->BulkRemoveStaleTeardrops( aCommit );
|
||||
}
|
||||
|
||||
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity();
|
||||
@ -283,19 +272,13 @@ void TEARDROP_MANAGER::UpdateTeardrops( BOARD_COMMIT& aCommit,
|
||||
|
||||
void TEARDROP_MANAGER::DeleteTrackToTrackTeardrops( BOARD_COMMIT& aCommit )
|
||||
{
|
||||
std::vector<ZONE*> stale_teardrops;
|
||||
|
||||
for( ZONE* zone : m_board->Zones() )
|
||||
{
|
||||
if( zone->IsTeardropArea() && zone->GetTeardropAreaType() == TEARDROP_TYPE::TD_TRACKEND )
|
||||
stale_teardrops.push_back( zone );
|
||||
zone->SetFlags( STRUCT_DELETED );
|
||||
}
|
||||
|
||||
for( ZONE* td : stale_teardrops )
|
||||
{
|
||||
m_board->Remove( td, REMOVE_MODE::BULK );
|
||||
aCommit.Removed( td );
|
||||
}
|
||||
m_board->BulkRemoveStaleTeardrops( aCommit );
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user