Check zone fills for being out-of-date during DRC.
This commit is contained in:
parent
9f5316e38f
commit
d54a252eaa
|
@ -2051,6 +2051,15 @@ void SHAPE_POLY_SET::triangulateSingle( const POLYGON& aPoly,
|
|||
}
|
||||
|
||||
|
||||
MD5_HASH SHAPE_POLY_SET::GetHash() const
|
||||
{
|
||||
if( !m_hash.IsValid() )
|
||||
return checksum();
|
||||
|
||||
return m_hash;
|
||||
}
|
||||
|
||||
|
||||
bool SHAPE_POLY_SET::IsTriangulationUpToDate() const
|
||||
{
|
||||
if( !m_triangulationValid )
|
||||
|
|
|
@ -1168,6 +1168,8 @@ class SHAPE_POLY_SET : public SHAPE
|
|||
void CacheTriangulation();
|
||||
bool IsTriangulationUpToDate() const;
|
||||
|
||||
MD5_HASH GetHash() const;
|
||||
|
||||
private:
|
||||
void triangulateSingle( const POLYGON& aPoly, SHAPE_POLY_SET::TRIANGULATED_POLYGON& aResult );
|
||||
|
||||
|
|
|
@ -404,14 +404,6 @@ void DRC::RunTests( wxTextCtrl* aMessages )
|
|||
|
||||
testTracks( aMessages ? aMessages->GetParent() : m_pcbEditorFrame, true );
|
||||
|
||||
// Before testing segments and unconnected, refill all zones:
|
||||
// this is a good caution, because filled areas can be outdated.
|
||||
if( aMessages )
|
||||
{
|
||||
aMessages->AppendText( _( "Fill zones...\n" ) );
|
||||
wxSafeYield();
|
||||
}
|
||||
|
||||
// caller (a wxTopLevelFrame) is the wxDialog or the Pcb Editor frame that call DRC:
|
||||
wxWindow* caller = aMessages ? aMessages->GetParent() : m_pcbEditorFrame;
|
||||
|
||||
|
@ -420,11 +412,16 @@ void DRC::RunTests( wxTextCtrl* aMessages )
|
|||
aMessages->AppendText( _( "Refilling all zones...\n" ) );
|
||||
m_pcbEditorFrame->Fill_All_Zones( caller );
|
||||
}
|
||||
else
|
||||
{
|
||||
aMessages->AppendText( _( "Checking zone fills...\n" ) );
|
||||
m_pcbEditorFrame->Check_All_Zones( caller );
|
||||
}
|
||||
|
||||
// test zone clearances to other zones
|
||||
if( aMessages )
|
||||
{
|
||||
aMessages->AppendText( _( "Test zones...\n" ) );
|
||||
aMessages->AppendText( _( "Zone to zone clearances...\n" ) );
|
||||
wxSafeYield();
|
||||
}
|
||||
|
||||
|
|
|
@ -1436,6 +1436,13 @@ public:
|
|||
*/
|
||||
int Fill_All_Zones( wxWindow * aActiveWindow );
|
||||
|
||||
/**
|
||||
* Function Check_All_Zones
|
||||
* Checks for out-of-date fills and fills them if requested by the user.
|
||||
* @param aActiveWindow
|
||||
*/
|
||||
void Check_All_Zones( wxWindow* aActiveWindow );
|
||||
|
||||
|
||||
/**
|
||||
* Function Add_Zone_Cutout
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <geometry/shape_file_io.h>
|
||||
#include <geometry/convex_hull.h>
|
||||
#include <geometry/geometry_utils.h>
|
||||
#include <confirm.h>
|
||||
|
||||
#include "zone_filler.h"
|
||||
|
||||
|
@ -75,12 +76,12 @@ ZONE_FILLER::~ZONE_FILLER()
|
|||
}
|
||||
|
||||
|
||||
void ZONE_FILLER::SetProgressReporter( PROGRESS_REPORTER* aReporter )
|
||||
void ZONE_FILLER::SetProgressReporter( WX_PROGRESS_REPORTER* aReporter )
|
||||
{
|
||||
m_progressReporter = aReporter;
|
||||
}
|
||||
|
||||
void ZONE_FILLER::Fill( std::vector<ZONE_CONTAINER*> aZones )
|
||||
void ZONE_FILLER::Fill( std::vector<ZONE_CONTAINER*> aZones, bool aCheck )
|
||||
{
|
||||
int parallelThreadCount = std::max( ( int )std::thread::hardware_concurrency(), 2 );
|
||||
|
||||
|
@ -90,9 +91,6 @@ void ZONE_FILLER::Fill( std::vector<ZONE_CONTAINER*> aZones )
|
|||
if( !connectivity->TryLock() )
|
||||
return;
|
||||
|
||||
// Remove segment zones
|
||||
m_board->m_Zone.DeleteAll();
|
||||
|
||||
for( auto zone : aZones )
|
||||
{
|
||||
// Keepout zones are not filled
|
||||
|
@ -114,28 +112,32 @@ void ZONE_FILLER::Fill( std::vector<ZONE_CONTAINER*> aZones )
|
|||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
m_progressReporter->Report( _( "Calculating zone fills..." ) );
|
||||
m_progressReporter->Report( _( "Checking zone fills..." ) );
|
||||
m_progressReporter->SetMaxProgress( toFill.size() );
|
||||
}
|
||||
|
||||
m_next = 0;
|
||||
m_out_of_date = false;
|
||||
m_count_done = 0;
|
||||
std::vector<std::thread> fillWorkers;
|
||||
|
||||
for( ssize_t ii = 0; ii < parallelThreadCount; ++ii )
|
||||
{
|
||||
fillWorkers.push_back( std::thread( [ this, toFill ]()
|
||||
fillWorkers.push_back( std::thread( [ this, aCheck, toFill ]()
|
||||
{
|
||||
size_t i = m_next.fetch_add( 1 );
|
||||
while( i < toFill.size() )
|
||||
{
|
||||
SHAPE_POLY_SET rawPolys, finalPolys;
|
||||
ZONE_SEGMENT_FILL segFill;
|
||||
fillSingleZone( toFill[i].m_zone, rawPolys, finalPolys );
|
||||
ZONE_CONTAINER* zone = toFill[i].m_zone;
|
||||
fillSingleZone( zone, rawPolys, finalPolys );
|
||||
|
||||
toFill[i].m_zone->SetRawPolysList( rawPolys );
|
||||
toFill[i].m_zone->SetFilledPolysList( finalPolys );
|
||||
toFill[i].m_zone->SetIsFilled( true );
|
||||
if( aCheck && zone->GetFilledPolysList().GetHash() != finalPolys.GetHash() )
|
||||
m_out_of_date.store( true );
|
||||
|
||||
zone->SetRawPolysList( rawPolys );
|
||||
zone->SetFilledPolysList( finalPolys );
|
||||
zone->SetIsFilled( true );
|
||||
|
||||
if( m_progressReporter )
|
||||
m_progressReporter->AdvanceProgress();
|
||||
|
@ -181,10 +183,36 @@ void ZONE_FILLER::Fill( std::vector<ZONE_CONTAINER*> aZones )
|
|||
zone.m_zone->SetFilledPolysList( poly );
|
||||
}
|
||||
|
||||
if( aCheck && m_out_of_date )
|
||||
{
|
||||
bool cancel = !IsOK( nullptr, _( "Zone fills may be out-of-date. Re-fill all zones?" ) );
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
// Sigh. Patch another case of "fall behind" dialogs on Mac.
|
||||
if( m_progressReporter->GetParent() )
|
||||
m_progressReporter->GetParent()->Raise();
|
||||
m_progressReporter->Raise();
|
||||
}
|
||||
|
||||
if( cancel )
|
||||
{
|
||||
if( m_commit )
|
||||
m_commit->Revert();
|
||||
|
||||
connectivity->SetProgressReporter( nullptr );
|
||||
connectivity->Unlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove segment zones
|
||||
m_board->m_Zone.DeleteAll();
|
||||
|
||||
if( m_progressReporter )
|
||||
{
|
||||
m_progressReporter->AdvancePhase();
|
||||
m_progressReporter->Report( _( "Caching polygon triangulations..." ) );
|
||||
m_progressReporter->Report( _( "Performing polygon fills..." ) );
|
||||
m_progressReporter->SetMaxProgress( toFill.size() );
|
||||
}
|
||||
|
||||
|
@ -236,7 +264,7 @@ void ZONE_FILLER::Fill( std::vector<ZONE_CONTAINER*> aZones )
|
|||
if( m_progressReporter )
|
||||
{
|
||||
m_progressReporter->AdvancePhase();
|
||||
m_progressReporter->Report( _( "Fill with segments..." ) );
|
||||
m_progressReporter->Report( _( "Performing segment fills..." ) );
|
||||
m_progressReporter->SetMaxProgress( zones_to_fill_count );
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include <vector>
|
||||
#include <class_zone.h>
|
||||
|
||||
class PROGRESS_REPORTER;
|
||||
class WX_PROGRESS_REPORTER;
|
||||
class BOARD;
|
||||
class COMMIT;
|
||||
class SHAPE_POLY_SET;
|
||||
|
@ -41,9 +41,8 @@ public:
|
|||
ZONE_FILLER( BOARD* aBoard, COMMIT* aCommit = nullptr );
|
||||
~ZONE_FILLER();
|
||||
|
||||
void SetProgressReporter( PROGRESS_REPORTER* aReporter );
|
||||
void Fill( std::vector<ZONE_CONTAINER*> aZones );
|
||||
void Unfill( std::vector<ZONE_CONTAINER*> aZones );
|
||||
void SetProgressReporter( WX_PROGRESS_REPORTER* aReporter );
|
||||
void Fill( std::vector<ZONE_CONTAINER*> aZones, bool aCheck = false );
|
||||
|
||||
private:
|
||||
|
||||
|
@ -118,11 +117,12 @@ private:
|
|||
|
||||
BOARD* m_board;
|
||||
COMMIT* m_commit;
|
||||
PROGRESS_REPORTER* m_progressReporter;
|
||||
WX_PROGRESS_REPORTER* m_progressReporter;
|
||||
|
||||
std::atomic_size_t m_next; // An index into the vector of zones to fill.
|
||||
// Used by the variuos parallel thread sets during
|
||||
// fill operations.
|
||||
std::atomic_bool m_out_of_date;
|
||||
std::atomic_size_t m_count_done;
|
||||
};
|
||||
|
||||
|
|
|
@ -101,3 +101,21 @@ int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow* aActiveWindow )
|
|||
toolMgr->RunAction( PCB_ACTIONS::zoneFillAll, true );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PCB_EDIT_FRAME::Check_All_Zones( wxWindow* aActiveWindow )
|
||||
{
|
||||
std::vector<ZONE_CONTAINER*> toFill;
|
||||
|
||||
for( auto zone : GetBoard()->Zones() )
|
||||
toFill.push_back(zone);
|
||||
|
||||
BOARD_COMMIT commit( this );
|
||||
|
||||
std::unique_ptr<WX_PROGRESS_REPORTER> progressReporter(
|
||||
new WX_PROGRESS_REPORTER( aActiveWindow, _( "Checking Zones" ), 3 ) );
|
||||
|
||||
ZONE_FILLER filler( GetBoard(), &commit );
|
||||
filler.SetProgressReporter( progressReporter.get() );
|
||||
filler.Fill( toFill, true );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue