Check zone fills for being out-of-date during DRC.

This commit is contained in:
Jeff Young 2018-04-06 11:24:23 +01:00
parent 9f5316e38f
commit d54a252eaa
7 changed files with 89 additions and 28 deletions

View File

@ -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 )

View File

@ -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 );

View File

@ -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();
}

View File

@ -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

View File

@ -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 );
}

View File

@ -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;
};

View File

@ -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 );
}