VIEW: rebuild the R-trees from scratch if more than 30% of items require a geometry update.

(see comments in the code for detailed explanation)
This commit is contained in:
Tomasz Wlostowski 2021-11-21 17:33:13 +01:00
parent 90157db537
commit 9add03dd88
1 changed files with 51 additions and 7 deletions

View File

@ -1405,9 +1405,54 @@ void VIEW::RecacheAllItems()
void VIEW::UpdateItems() void VIEW::UpdateItems()
{ {
if( m_gal->IsVisible() ) if( !m_gal->IsVisible() )
{ return;
GAL_UPDATE_CONTEXT ctx( m_gal ); GAL_UPDATE_CONTEXT ctx( m_gal );
int cntTotal = 0, cntToUpdate = 0;
for( VIEW_ITEM* item : *m_allItems )
{
cntTotal++;
if( item->viewPrivData() && item->viewPrivData()->m_requiredUpdate & ( GEOMETRY | LAYERS ) )
{
cntToUpdate++;
}
}
double ratio = (double) cntToUpdate / (double) cntTotal;
// Optimization to improve view update time. If a lot of items (say, 30%) have their
// bboxes/geometry changed it's way faster (around 10 times) to rebuild the R-Trees
// from scratch rather than update the bbox of each changed item. Pcbnew does multiple
// full geometry updates during file load, this can save a solid 30 seconds on load time
// for larger designs...
if( ratio > 0.3 )
{
auto allItems = *m_allItems;
int layers[VIEW_MAX_LAYERS], layers_count;
// kill all Rtrees
for( VIEW_LAYER& layer : m_layers )
layer.items->RemoveAll();
// and re-insert items from scratch
for( VIEW_ITEM* item : allItems )
{
item->ViewGetLayers( layers, layers_count );
item->viewPrivData()->saveLayers( layers, layers_count );
for( int i = 0; i < layers_count; ++i )
{
VIEW_LAYER& l = m_layers[layers[i]];
l.items->Insert( item );
MarkTargetDirty( l.target );
}
item->viewPrivData()->m_requiredUpdate &= ~( LAYERS | GEOMETRY );
}
}
for( VIEW_ITEM* item : *m_allItems ) for( VIEW_ITEM* item : *m_allItems )
{ {
@ -1417,7 +1462,6 @@ void VIEW::UpdateItems()
item->viewPrivData()->m_requiredUpdate = NONE; item->viewPrivData()->m_requiredUpdate = NONE;
} }
} }
}
} }