Performance improvements for zone filler.
This commit is contained in:
parent
8e26946567
commit
d8c4f2cb09
|
@ -2204,20 +2204,17 @@ SHAPE_POLY_SET &SHAPE_POLY_SET::operator=( const SHAPE_POLY_SET& aOther )
|
|||
{
|
||||
static_cast<SHAPE&>(*this) = aOther;
|
||||
m_polys = aOther.m_polys;
|
||||
m_triangulatedPolys.clear();
|
||||
m_triangulationValid = false;
|
||||
|
||||
if( aOther.IsTriangulationUpToDate() )
|
||||
{
|
||||
m_triangulatedPolys.clear();
|
||||
|
||||
for( unsigned i = 0; i < aOther.TriangulatedPolyCount(); i++ )
|
||||
{
|
||||
const TRIANGULATED_POLYGON* poly = aOther.TriangulatedPolygon( i );
|
||||
m_triangulatedPolys.push_back( std::make_unique<TRIANGULATED_POLYGON>( *poly ) );
|
||||
}
|
||||
|
||||
m_hash = aOther.GetHash();
|
||||
m_triangulationValid = true;
|
||||
}
|
||||
m_hash = aOther.m_hash;
|
||||
m_triangulationValid = aOther.m_triangulationValid;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -621,39 +621,51 @@ void BOARD::SetZoneSettings( const ZONE_SETTINGS& aSettings )
|
|||
}
|
||||
|
||||
|
||||
void BOARD::CacheTriangulation( PROGRESS_REPORTER* aReporter )
|
||||
void BOARD::CacheTriangulation( PROGRESS_REPORTER* aReporter, const std::vector<ZONE*>& aZones )
|
||||
{
|
||||
std::vector<ZONE*> zones = aZones;
|
||||
|
||||
if( zones.empty() )
|
||||
zones = m_zones;
|
||||
|
||||
if( zones.empty() )
|
||||
return;
|
||||
|
||||
if( aReporter )
|
||||
aReporter->Report( _( "Tessellating copper zones..." ) );
|
||||
|
||||
std::atomic<size_t> next( 0 );
|
||||
std::atomic<size_t> count_done( 0 );
|
||||
std::atomic<size_t> zones_done( 0 );
|
||||
std::atomic<size_t> threads_done( 0 );
|
||||
size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
|
||||
|
||||
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
|
||||
{
|
||||
std::thread t = std::thread(
|
||||
[ this, &count_done, &next ]( )
|
||||
[ &zones, &zones_done, &threads_done, &next ]( )
|
||||
{
|
||||
for( size_t i = next.fetch_add( 1 ); i < m_zones.size(); i = next.fetch_add( 1 ) )
|
||||
m_zones[i]->CacheTriangulation();
|
||||
for( size_t i = next.fetch_add( 1 ); i < zones.size(); i = next.fetch_add( 1 ) )
|
||||
{
|
||||
zones[i]->CacheTriangulation();
|
||||
zones_done.fetch_add( 1 );
|
||||
}
|
||||
|
||||
count_done++;
|
||||
threads_done.fetch_add( 1 );
|
||||
} );
|
||||
|
||||
t.detach();
|
||||
}
|
||||
|
||||
// Finalize the triangulation threads
|
||||
while( count_done < parallelThreadCount )
|
||||
while( threads_done < parallelThreadCount )
|
||||
{
|
||||
if( aReporter && m_zones.size() )
|
||||
if( aReporter )
|
||||
{
|
||||
aReporter->SetCurrentProgress( (double) count_done / (double) m_zones.size() );
|
||||
aReporter->SetCurrentProgress( (double) zones_done / (double) zones.size() );
|
||||
aReporter->KeepRefreshing();
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for( std::chrono::milliseconds( 30 ) );
|
||||
std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -308,7 +308,8 @@ public:
|
|||
*/
|
||||
void FinalizeBulkRemove( std::vector<BOARD_ITEM*>& aRemovedItems );
|
||||
|
||||
void CacheTriangulation( PROGRESS_REPORTER* aReporter = nullptr );
|
||||
void CacheTriangulation( PROGRESS_REPORTER* aReporter = nullptr,
|
||||
const std::vector<ZONE*>& aZones = {} );
|
||||
|
||||
/**
|
||||
* Get the first footprint on the board or nullptr.
|
||||
|
|
|
@ -619,10 +619,23 @@ void CN_CONNECTIVITY_ALGO::FindIsolatedCopperIslands( ZONE* aZone, PCB_LAYER_ID
|
|||
|
||||
void CN_CONNECTIVITY_ALGO::FindIsolatedCopperIslands( std::vector<CN_ZONE_ISOLATED_ISLAND_LIST>& aZones )
|
||||
{
|
||||
int delta = 10; // Number of additions between 2 calls to the progress bar
|
||||
int ii = 0;
|
||||
|
||||
for( CN_ZONE_ISOLATED_ISLAND_LIST& z : aZones )
|
||||
{
|
||||
Remove( z.m_zone );
|
||||
Add( z.m_zone );
|
||||
ii++;
|
||||
|
||||
if( m_progressReporter && ( ii % delta ) == 0 )
|
||||
{
|
||||
m_progressReporter->SetCurrentProgress( (double) ii / (double) aZones.size() );
|
||||
m_progressReporter->KeepRefreshing( false );
|
||||
}
|
||||
|
||||
if( m_progressReporter && m_progressReporter->IsCancelled() )
|
||||
return;
|
||||
}
|
||||
|
||||
m_connClusters = SearchClusters( CSM_CONNECTIVITY_CHECK );
|
||||
|
|
|
@ -292,9 +292,6 @@ public:
|
|||
{
|
||||
const SHAPE_POLY_SET& fill = aParent->GetFilledPolysList( aLayer );
|
||||
|
||||
if( !fill.IsTriangulationUpToDate() )
|
||||
const_cast<SHAPE_POLY_SET&>( fill ).CacheTriangulation();
|
||||
|
||||
m_triangulatedPoly = fill;
|
||||
|
||||
for( unsigned int ii = 0; ii < m_triangulatedPoly.TriangulatedPolyCount(); ++ii )
|
||||
|
|
|
@ -79,6 +79,7 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
|
|||
std::lock_guard<KISPINLOCK> lock( m_board->GetConnectivity()->GetLock() );
|
||||
|
||||
std::vector<std::pair<ZONE*, PCB_LAYER_ID>> toFill;
|
||||
std::map<std::pair<ZONE*, PCB_LAYER_ID>, MD5_HASH> oldFillHashes;
|
||||
std::vector<CN_ZONE_ISOLATED_ISLAND_LIST> islandsList;
|
||||
|
||||
std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity();
|
||||
|
@ -155,6 +156,7 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
|
|||
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
|
||||
{
|
||||
zone->BuildHashValue( layer );
|
||||
oldFillHashes[ { zone, layer } ] = zone->GetHashValue( layer );
|
||||
|
||||
// Add the zone to the list of zones to test or refill
|
||||
toFill.emplace_back( std::make_pair( zone, layer ) );
|
||||
|
@ -291,6 +293,8 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
|
|||
break;
|
||||
}
|
||||
|
||||
m_board->CacheTriangulation( m_progressReporter, aZones );
|
||||
|
||||
// Now update the connectivity to check for copper islands
|
||||
if( m_progressReporter )
|
||||
{
|
||||
|
@ -387,6 +391,9 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
|
|||
}
|
||||
}
|
||||
|
||||
// Re-cache triangulation after removing islands
|
||||
m_board->CacheTriangulation( m_progressReporter, aZones );
|
||||
|
||||
if( aCheck )
|
||||
{
|
||||
bool outOfDate = false;
|
||||
|
@ -399,12 +406,9 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
|
|||
|
||||
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
|
||||
{
|
||||
MD5_HASH was = zone->GetHashValue( layer );
|
||||
zone->CacheTriangulation( layer );
|
||||
zone->BuildHashValue( layer );
|
||||
MD5_HASH is = zone->GetHashValue( layer );
|
||||
|
||||
if( is != was )
|
||||
if( oldFillHashes[ { zone, layer } ] != zone->GetHashValue( layer ) )
|
||||
outOfDate = true;
|
||||
}
|
||||
}
|
||||
|
@ -427,66 +431,6 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
|
|||
}
|
||||
}
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
m_progressReporter->AdvancePhase();
|
||||
m_progressReporter->Report( _( "Performing polygon fills..." ) );
|
||||
m_progressReporter->SetMaxProgress( islandsList.size() );
|
||||
}
|
||||
|
||||
nextItem = 0;
|
||||
|
||||
auto tri_lambda =
|
||||
[&]( PROGRESS_REPORTER* aReporter ) -> size_t
|
||||
{
|
||||
size_t num = 0;
|
||||
|
||||
for( size_t i = nextItem++; i < islandsList.size(); i = nextItem++ )
|
||||
{
|
||||
islandsList[i].m_zone->CacheTriangulation();
|
||||
num++;
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
m_progressReporter->AdvanceProgress();
|
||||
|
||||
if( m_progressReporter->IsCancelled() )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return num;
|
||||
};
|
||||
|
||||
size_t parallelThreadCount = std::min( cores, islandsList.size() );
|
||||
std::vector<std::future<size_t>> returns( parallelThreadCount );
|
||||
|
||||
if( parallelThreadCount <= 1 )
|
||||
tri_lambda( m_progressReporter );
|
||||
else
|
||||
{
|
||||
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
|
||||
returns[ii] = std::async( std::launch::async, tri_lambda, m_progressReporter );
|
||||
|
||||
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
|
||||
{
|
||||
// Here we balance returns with a 100ms timeout to allow UI updating
|
||||
std::future_status status;
|
||||
do
|
||||
{
|
||||
if( m_progressReporter )
|
||||
{
|
||||
m_progressReporter->KeepRefreshing();
|
||||
|
||||
if( m_progressReporter->IsCancelled() )
|
||||
break;
|
||||
}
|
||||
|
||||
status = returns[ii].wait_for( std::chrono::milliseconds( 100 ) );
|
||||
} while( status != std::future_status::ready );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
if( m_progressReporter->IsCancelled() )
|
||||
|
|
Loading…
Reference in New Issue