From d0236ca7511b24ef106297482e7c58e65d63d186 Mon Sep 17 00:00:00 2001 From: Marek Roszko Date: Wed, 10 Jan 2024 19:55:18 -0500 Subject: [PATCH] Make DRC exclusions work in cli & python DRC The way exclusions work is actually silly, and you can end up with your project file losing them too. Fixes https://gitlab.com/kicad/code/kicad/-/issues/11562 --- pcbnew/board.cpp | 12 ++++++++++++ pcbnew/board.h | 5 +++++ pcbnew/dialogs/dialog_drc.cpp | 2 +- pcbnew/pcb_edit_frame.cpp | 13 ------------- pcbnew/pcb_edit_frame.h | 5 ----- pcbnew/pcbnew_config.cpp | 2 +- pcbnew/pcbnew_jobs_handler.cpp | 7 +++++++ .../python/scripting/pcbnew_scripting_helpers.cpp | 6 ++++++ 8 files changed, 32 insertions(+), 20 deletions(-) diff --git a/pcbnew/board.cpp b/pcbnew/board.cpp index bb7b788308..87898f4a79 100644 --- a/pcbnew/board.cpp +++ b/pcbnew/board.cpp @@ -2720,3 +2720,15 @@ bool BOARD::operator==( const BOARD_ITEM& aItem ) const return true; } + + +void BOARD::RecordDRCExclusions() +{ + m_designSettings->m_DrcExclusions.clear(); + + for( PCB_MARKER* marker : m_markers ) + { + if( marker->IsExcluded() ) + m_designSettings->m_DrcExclusions.insert( marker->Serialize() ); + } +} \ No newline at end of file diff --git a/pcbnew/board.h b/pcbnew/board.h index 898c4e6599..63b5a1e0b2 100644 --- a/pcbnew/board.h +++ b/pcbnew/board.h @@ -477,6 +477,11 @@ public: */ std::vector ResolveDRCExclusions( bool aCreateMarkers ); + /** + * Scan existing markers and record data from any that are Excluded. + */ + void RecordDRCExclusions(); + /** * Update the visibility flags on the current unconnected ratsnest lines. */ diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp index 7e68761a35..f76e83f41c 100644 --- a/pcbnew/dialogs/dialog_drc.cpp +++ b/pcbnew/dialogs/dialog_drc.cpp @@ -285,7 +285,7 @@ void DIALOG_DRC::OnRunDRCClick( wxCommandEvent& aEvent ) m_footprintTestsRun = false; m_cancelled = false; - m_frame->RecordDRCExclusions(); + m_frame->GetBoard()->RecordDRCExclusions(); deleteAllMarkers( true ); std::vector> violations = DRC_ITEM::GetItemsWithSeverities(); diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 564dc97914..9848f00628 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -994,19 +994,6 @@ void PCB_EDIT_FRAME::OnQuit( wxCommandEvent& event ) } -void PCB_EDIT_FRAME::RecordDRCExclusions() -{ - BOARD_DESIGN_SETTINGS& bds = GetBoard()->GetDesignSettings(); - bds.m_DrcExclusions.clear(); - - for( PCB_MARKER* marker : GetBoard()->Markers() ) - { - if( marker->IsExcluded() ) - bds.m_DrcExclusions.insert( marker->Serialize() ); - } -} - - void PCB_EDIT_FRAME::ResolveDRCExclusions( bool aCreateMarkers ) { BOARD_COMMIT commit( this ); diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index fb27486730..e3cbc6afe9 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -233,11 +233,6 @@ public: */ void SetLastPath( LAST_PATH_TYPE aType, const wxString& aLastPath ); - /** - * Scan existing markers and record data from any that are Excluded. - */ - void RecordDRCExclusions(); - /** * If aCreateMarkers then create DRC exclusion markers from the serialized data. If false, * then use the serialized data to set exclusion flags on existing markers. diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp index 30ccbbb29d..cf6341c604 100644 --- a/pcbnew/pcbnew_config.cpp +++ b/pcbnew/pcbnew_config.cpp @@ -149,7 +149,7 @@ void PCB_EDIT_FRAME::SaveProjectLocalSettings() project.m_LayerPresets = m_appearancePanel->GetUserLayerPresets(); project.m_Viewports = m_appearancePanel->GetUserViewports(); - RecordDRCExclusions(); + GetBoard()->RecordDRCExclusions(); // Save render settings that aren't stored in PCB_DISPLAY_OPTIONS diff --git a/pcbnew/pcbnew_jobs_handler.cpp b/pcbnew/pcbnew_jobs_handler.cpp index 941cc36bdd..687318e8f9 100644 --- a/pcbnew/pcbnew_jobs_handler.cpp +++ b/pcbnew/pcbnew_jobs_handler.cpp @@ -1004,10 +1004,17 @@ int PCBNEW_JOBS_HANDLER::JobExportDrc( JOB* aJob ) commit.Add( marker ); } ); + brd->RecordDRCExclusions(); + brd->DeleteMARKERs( true, true ); drcEngine->RunTests( units, drcJob->m_reportAllTrackErrors, false ); + drcEngine->ClearViolationHandler(); commit.Push( _( "DRC" ), SKIP_UNDO | SKIP_SET_DIRTY ); + // now "resolve" the drc exclusions again because its the only way to set exclusion status on a marker + for( PCB_MARKER* marker : brd->ResolveDRCExclusions( false ) ) + brd->Add( marker ); + std::shared_ptr markersProvider = std::make_shared( brd, MARKER_BASE::MARKER_DRC, MARKER_BASE::MARKER_DRAWING_SHEET ); diff --git a/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp b/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp index b2cb11e291..5ffb0ddc81 100644 --- a/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp +++ b/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp @@ -585,9 +585,15 @@ bool WriteDRCReport( BOARD* aBoard, const wxString& aFileName, EDA_UNITS aUnits, } } ); + aBoard->RecordDRCExclusions(); + aBoard->DeleteMARKERs( true, true ); engine->RunTests( aUnits, aReportAllTrackErrors, false ); engine->ClearViolationHandler(); + // now "resolve" the drc exclusions again because its the only way to set exclusion status on a marker + for( PCB_MARKER* marker : aBoard->ResolveDRCExclusions( false ) ) + aBoard->Add( marker ); + // TODO: Unify this with DIALOG_DRC::writeReport FILE* fp = wxFopen( aFileName, wxT( "w" ) );