Add cli option for zone refill before drc

Note: Does not save yet
This commit is contained in:
Mark Roszko 2025-07-24 20:40:33 -04:00
parent d538f8d848
commit dc6e0223c7
11 changed files with 137 additions and 22 deletions

View File

@ -81,6 +81,12 @@ DIALOG_RC_JOB_BASE::DIALOG_RC_JOB_BASE( wxWindow* parent, wxWindowID id, const w
bSizerBottom->Add( m_cbSchParity, 0, wxBOTTOM|wxLEFT, 5 );
bSizerBottom->Add( 0, 3, 0, wxEXPAND, 5 );
m_cbRefillZones = new wxCheckBox( this, wxID_ANY, _("Refill all zones before performing DRC"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerBottom->Add( m_cbRefillZones, 0, wxBOTTOM|wxLEFT, 5 );
bSizerMain->Add( bSizerBottom, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
m_sdbSizer1 = new wxStdDialogButtonSizer();
@ -95,7 +101,6 @@ DIALOG_RC_JOB_BASE::DIALOG_RC_JOB_BASE( wxWindow* parent, wxWindowID id, const w
this->SetSizer( bSizerMain );
this->Layout();
bSizerMain->Fit( this );
this->Centre( wxBOTH );

View File

@ -50,7 +50,7 @@
<property name="minimum_size"></property>
<property name="name">DIALOG_RC_JOB_BASE</property>
<property name="pos"></property>
<property name="size">443,239</property>
<property name="size">443,255</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h; forward_declare</property>
<property name="title"></property>
@ -774,6 +774,81 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="spacer" expanded="true">
<property name="height">3</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Refill all zones before performing DRC</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_cbRefillZones</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="false">

View File

@ -46,6 +46,7 @@ class KICOMMON_API DIALOG_RC_JOB_BASE : public DIALOG_SHIM
wxCheckBox* m_cbHaltOutput;
wxCheckBox* m_cbAllTrackViolations;
wxCheckBox* m_cbSchParity;
wxCheckBox* m_cbRefillZones;
wxStdDialogButtonSizer* m_sdbSizer1;
wxButton* m_sdbSizer1OK;
wxButton* m_sdbSizer1Cancel;
@ -56,7 +57,7 @@ class KICOMMON_API DIALOG_RC_JOB_BASE : public DIALOG_SHIM
public:
DIALOG_RC_JOB_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 443,239 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_RC_JOB_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 443,255 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_RC_JOB_BASE();

View File

@ -25,10 +25,13 @@
JOB_PCB_DRC::JOB_PCB_DRC() :
JOB_RC( "drc" ),
m_reportAllTrackErrors( false ),
m_parity( true )
m_parity( true ),
m_refillZones( false )
{
m_params.emplace_back( new JOB_PARAM<bool>( "parity", &m_parity, m_parity ) );
m_params.emplace_back( new JOB_PARAM<bool>( "report_all_track_errors", &m_reportAllTrackErrors, m_reportAllTrackErrors ) );
m_params.emplace_back(
new JOB_PARAM<bool>( "report_all_track_errors", &m_reportAllTrackErrors, m_reportAllTrackErrors ) );
m_params.emplace_back( new JOB_PARAM<bool>( "refill_zones", &m_refillZones, m_refillZones ) );
}

View File

@ -31,4 +31,6 @@ public:
bool m_reportAllTrackErrors;
bool m_parity;
bool m_refillZones;
};

View File

@ -27,6 +27,7 @@ DIALOG_ERC_JOB_CONFIG::DIALOG_ERC_JOB_CONFIG( wxWindow* parent, JOB_SCH_ERC* aJo
m_cbAllTrackViolations->Hide();
m_cbSchParity->Hide();
m_cbRefillZones->Hide();
Fit();
Layout();

View File

@ -38,6 +38,7 @@
#define ARG_SEVERITY_EXCLUSIONS "--severity-exclusions"
#define ARG_EXIT_CODE_VIOLATIONS "--exit-code-violations"
#define ARG_PARITY "--schematic-parity"
#define ARG_ZONE_FILL "--refill-zones"
CLI::PCB_DRC_COMMAND::PCB_DRC_COMMAND() : COMMAND( "drc" )
{
@ -88,6 +89,10 @@ CLI::PCB_DRC_COMMAND::PCB_DRC_COMMAND() : COMMAND( "drc" )
m_argParser.add_argument( ARG_EXIT_CODE_VIOLATIONS )
.help( UTF8STDSTR( _( "Return a nonzero exit code if DRC violations exist" ) ) )
.flag();
m_argParser.add_argument( ARG_ZONE_FILL )
.help( UTF8STDSTR( _( "Refill zones before running DRC" ) ) )
.flag();
}
@ -163,6 +168,7 @@ int CLI::PCB_DRC_COMMAND::doPerform( KIWAY& aKiway )
}
drcJob->m_parity = m_argParser.get<bool>( ARG_PARITY );
drcJob->m_refillZones = m_argParser.get<bool>( ARG_ZONE_FILL );
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, drcJob.get() );

View File

@ -36,6 +36,7 @@ bool DIALOG_DRC_JOB_CONFIG::TransferDataToWindow()
m_cbAllTrackViolations->SetValue( m_drcJob->m_reportAllTrackErrors );
m_cbSchParity->SetValue( m_drcJob->m_parity );
m_cbRefillZones->SetValue( m_drcJob->m_refillZones );
return true;
}
@ -47,5 +48,6 @@ bool DIALOG_DRC_JOB_CONFIG::TransferDataFromWindow()
m_drcJob->m_reportAllTrackErrors = m_cbAllTrackViolations->GetValue();
m_drcJob->m_parity = m_cbSchParity->GetValue();
m_drcJob->m_refillZones = m_cbRefillZones->GetValue();
return true;
}

View File

@ -93,6 +93,7 @@
#include <dialogs/dialog_render_job.h>
#include <dialogs/dialog_gencad_export_options.h>
#include <paths.h>
#include <tools/zone_filler_tool.h>
#include "pcbnew_scripting_helpers.h"
#include <locale_io.h>
@ -2134,6 +2135,14 @@ int PCBNEW_JOBS_HANDLER::JobExportDrc( JOB* aJob )
drcEngine->SetSchematicNetlist( netlist.get() );
}
if( drcJob->m_refillZones )
{
toolManager->RegisterTool( new ZONE_FILLER_TOOL );
ZONE_FILLER_TOOL* zoneFiller = toolManager->GetTool<ZONE_FILLER_TOOL>();
zoneFiller->FillAllZones( nullptr, m_progressReporter, true );
}
drcEngine->SetProgressReporter( m_progressReporter );
drcEngine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer,

View File

@ -115,14 +115,17 @@ void ZONE_FILLER_TOOL::singleShotRefocus( wxIdleEvent& )
}
void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aReporter )
void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aReporter, bool aHeadless )
{
if( m_fillInProgress )
return;
m_fillInProgress = true;
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
PCB_EDIT_FRAME* frame = nullptr;
if( !aHeadless )
frame = getEditFrame<PCB_EDIT_FRAME>();
BOARD_COMMIT commit( this );
std::unique_ptr<WX_PROGRESS_REPORTER> reporter;
TEARDROP_MANAGER teardropMgr( board(), m_toolMgr );
@ -137,7 +140,7 @@ void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aRepo
m_filler = std::make_unique<ZONE_FILLER>( board(), &commit );
if( !board()->GetDesignSettings().m_DRCEngine->RulesValid() )
if( !aHeadless && !board()->GetDesignSettings().m_DRCEngine->RulesValid() )
{
WX_INFOBAR* infobar = frame->GetInfoBar();
wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, _( "Show DRC rules" ), wxEmptyString );
@ -160,7 +163,7 @@ void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aRepo
{
m_filler->SetProgressReporter( aReporter );
}
else
else if( !aHeadless )
{
reporter = std::make_unique<WX_PROGRESS_REPORTER>( aCaller, _( "Fill All Zones" ), 5, PR_CAN_ABORT );
m_filler->SetProgressReporter( reporter.get() );
@ -168,9 +171,11 @@ void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aRepo
if( m_filler->Fill( toFill ) )
{
if( m_filler->GetProgressReporter() )
m_filler->GetProgressReporter()->AdvancePhase();
commit.Push( _( "Fill Zone(s)" ), SKIP_CONNECTIVITY | ZONE_FILL_OP );
if( !aHeadless )
frame->m_ZoneFillsDirty = false;
}
else
@ -178,15 +183,20 @@ void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aRepo
commit.Revert();
}
rebuildConnectivity();
rebuildConnectivity( aHeadless );
if( !aHeadless )
{
refresh();
if( m_filler->IsDebug() )
frame->UpdateUserInterface();
}
m_fillInProgress = false;
m_filler.reset( nullptr );
if( !aHeadless )
// wxWidgets has keyboard focus issues after the progress reporter. Re-setting the focus
// here doesn't work, so we delay it to an idle event.
canvas()->Bind( wxEVT_IDLE, &ZONE_FILLER_TOOL::singleShotRefocus, this );
@ -440,10 +450,11 @@ PROGRESS_REPORTER* ZONE_FILLER_TOOL::GetProgressReporter()
}
void ZONE_FILLER_TOOL::rebuildConnectivity()
void ZONE_FILLER_TOOL::rebuildConnectivity( bool aHeadless )
{
board()->BuildConnectivity();
m_toolMgr->PostEvent( EVENTS::ConnectivityChangedEvent );
if( !aHeadless )
canvas()->RedrawRatsnest();
}

View File

@ -50,7 +50,7 @@ public:
void Reset( RESET_REASON aReason ) override;
void CheckAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aReporter = nullptr );
void FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aReporter = nullptr );
void FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aReporter = nullptr, bool aHeadless = false );
int ZoneFill( const TOOL_EVENT& aEvent );
int ZoneFillAll( const TOOL_EVENT& aEvent );
@ -73,7 +73,7 @@ private:
///< Refocus on an idle event (used after the Progress Reporter messes up the focus).
void singleShotRefocus( wxIdleEvent& );
void rebuildConnectivity();
void rebuildConnectivity( bool aHeadless = false );
void refresh();
///< Set up handlers for various events.