From 39cc686dc4d1e9cd19339a7649092bfe178e371e Mon Sep 17 00:00:00 2001 From: Mike Williams Date: Mon, 1 May 2023 08:53:36 -0400 Subject: [PATCH] Back Annotation: add support for DNP and Exclude from BOM attributes Fixes: https://gitlab.com/kicad/code/kicad/-/issues/14584 --- eeschema/dialogs/dialog_update_from_pcb.cpp | 7 +- eeschema/dialogs/dialog_update_from_pcb.h | 1 + .../dialogs/dialog_update_from_pcb_base.cpp | 7 +- .../dialogs/dialog_update_from_pcb_base.fbp | 70 +++++++++++++++++- .../dialogs/dialog_update_from_pcb_base.h | 6 +- eeschema/tools/backannotate.cpp | 72 ++++++++++++++++++- eeschema/tools/backannotate.h | 10 ++- pcbnew/cross-probing.cpp | 11 +++ pcbnew/netlist_reader/pcb_netlist.cpp | 7 ++ 9 files changed, 181 insertions(+), 10 deletions(-) diff --git a/eeschema/dialogs/dialog_update_from_pcb.cpp b/eeschema/dialogs/dialog_update_from_pcb.cpp index caf350dd4c..c59885d271 100644 --- a/eeschema/dialogs/dialog_update_from_pcb.cpp +++ b/eeschema/dialogs/dialog_update_from_pcb.cpp @@ -31,7 +31,7 @@ // Saved dialog settings DIALOG_UPDATE_FROM_PCB::DIALOG_UPDATE_FROM_PCB_SAVED_STATE - DIALOG_UPDATE_FROM_PCB::s_savedDialogState{ false, true, true, true, false }; + DIALOG_UPDATE_FROM_PCB::s_savedDialogState{ false, true, true, true, false, true }; DIALOG_UPDATE_FROM_PCB::DIALOG_UPDATE_FROM_PCB( SCH_EDIT_FRAME* aParent ) @@ -61,6 +61,7 @@ DIALOG_UPDATE_FROM_PCB::DIALOG_UPDATE_FROM_PCB( SCH_EDIT_FRAME* aParent ) m_cbUpdateFootprints->SetValue( s_savedDialogState.UpdateFootprints ); m_cbUpdateValues->SetValue( s_savedDialogState.UpdateValues ); m_cbUpdateNetNames->SetValue( s_savedDialogState.UpdateNetNames ); + m_cbUpdateAttributes->SetValue( s_savedDialogState.UpdateAttributes ); SetupStandardButtons( { { wxID_OK, _( "Update Schematic" ) }, { wxID_CANCEL, _( "Close" ) } } ); @@ -80,6 +81,7 @@ void DIALOG_UPDATE_FROM_PCB::updateData() m_cbUpdateValues->GetValue(), m_cbUpdateReferences->GetValue(), m_cbUpdateNetNames->GetValue(), + m_cbUpdateAttributes->GetValue(), true ); std::string netlist; @@ -131,6 +133,8 @@ void DIALOG_UPDATE_FROM_PCB::OnOptionChanged( wxCommandEvent& event ) s_savedDialogState.UpdateValues = m_cbUpdateValues->GetValue(); else if( event.GetEventObject() == m_cbUpdateNetNames ) s_savedDialogState.UpdateNetNames = m_cbUpdateNetNames->GetValue(); + else if( event.GetEventObject() == m_cbUpdateAttributes ) + s_savedDialogState.UpdateAttributes = m_cbUpdateAttributes->GetValue(); } @@ -145,6 +149,7 @@ void DIALOG_UPDATE_FROM_PCB::OnUpdateClick( wxCommandEvent& event ) m_cbUpdateValues->GetValue(), m_cbUpdateReferences->GetValue(), m_cbUpdateNetNames->GetValue(), + m_cbUpdateAttributes->GetValue(), false ); if( backAnno.FetchNetlistFromPCB( netlist ) && backAnno.BackAnnotateSymbols( netlist ) ) diff --git a/eeschema/dialogs/dialog_update_from_pcb.h b/eeschema/dialogs/dialog_update_from_pcb.h index ef623403d4..887dd5545f 100644 --- a/eeschema/dialogs/dialog_update_from_pcb.h +++ b/eeschema/dialogs/dialog_update_from_pcb.h @@ -55,6 +55,7 @@ private: bool UpdateFootprints; bool UpdateValues; bool UpdateNetNames; + bool UpdateAttributes; }; static DIALOG_UPDATE_FROM_PCB_SAVED_STATE s_savedDialogState; diff --git a/eeschema/dialogs/dialog_update_from_pcb_base.cpp b/eeschema/dialogs/dialog_update_from_pcb_base.cpp index 36d697b857..0ec152401e 100644 --- a/eeschema/dialogs/dialog_update_from_pcb_base.cpp +++ b/eeschema/dialogs/dialog_update_from_pcb_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 26 2018) +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -69,6 +69,9 @@ DIALOG_UPDATE_FROM_PCB_BASE::DIALOG_UPDATE_FROM_PCB_BASE( wxWindow* parent, wxWi m_cbUpdateNetNames = new wxCheckBox( sbSizer2->GetStaticBox(), wxID_ANY, _("Net names"), wxDefaultPosition, wxDefaultSize, 0 ); fgSizer2->Add( m_cbUpdateNetNames, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + m_cbUpdateAttributes = new wxCheckBox( sbSizer2->GetStaticBox(), wxID_ANY, _("Attributes"), wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer2->Add( m_cbUpdateAttributes, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 ); + sbSizer2->Add( fgSizer2, 1, wxEXPAND, 5 ); @@ -108,6 +111,7 @@ DIALOG_UPDATE_FROM_PCB_BASE::DIALOG_UPDATE_FROM_PCB_BASE( wxWindow* parent, wxWi m_cbUpdateFootprints->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); m_cbUpdateValues->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); m_cbUpdateNetNames->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); + m_cbUpdateAttributes->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnUpdateClick ), NULL, this ); } @@ -119,6 +123,7 @@ DIALOG_UPDATE_FROM_PCB_BASE::~DIALOG_UPDATE_FROM_PCB_BASE() m_cbUpdateFootprints->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); m_cbUpdateValues->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); m_cbUpdateNetNames->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); + m_cbUpdateAttributes->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this ); m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnUpdateClick ), NULL, this ); } diff --git a/eeschema/dialogs/dialog_update_from_pcb_base.fbp b/eeschema/dialogs/dialog_update_from_pcb_base.fbp index 23b81b9116..90729b156d 100644 --- a/eeschema/dialogs/dialog_update_from_pcb_base.fbp +++ b/eeschema/dialogs/dialog_update_from_pcb_base.fbp @@ -1,6 +1,6 @@ - + C++ @@ -14,6 +14,7 @@ dialog_update_from_pcb_base 1000 none + 1 dialog_update_from_pcb_base @@ -25,6 +26,7 @@ 1 1 UI + 0 1 0 @@ -50,6 +52,7 @@ DIALOG_SHIM; dialog_shim.h Update Schematic from PCB + 0 @@ -452,6 +455,71 @@ OnOptionChanged + + 5 + wxBOTTOM|wxLEFT|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Attributes + + 0 + + + 0 + + 1 + m_cbUpdateAttributes + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnOptionChanged + + diff --git a/eeschema/dialogs/dialog_update_from_pcb_base.h b/eeschema/dialogs/dialog_update_from_pcb_base.h index b92ed4bd22..54b8b056cf 100644 --- a/eeschema/dialogs/dialog_update_from_pcb_base.h +++ b/eeschema/dialogs/dialog_update_from_pcb_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 26 2018) +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -40,12 +40,13 @@ class DIALOG_UPDATE_FROM_PCB_BASE : public DIALOG_SHIM wxCheckBox* m_cbUpdateFootprints; wxCheckBox* m_cbUpdateValues; wxCheckBox* m_cbUpdateNetNames; + wxCheckBox* m_cbUpdateAttributes; WX_HTML_REPORT_PANEL* m_messagePanel; wxStdDialogButtonSizer* m_sdbSizer; wxButton* m_sdbSizerOK; wxButton* m_sdbSizerCancel; - // Virtual event handlers, overide them in your derived class + // Virtual event handlers, override them in your derived class virtual void OnOptionChanged( wxCommandEvent& event ) { event.Skip(); } virtual void OnUpdateClick( wxCommandEvent& event ) { event.Skip(); } @@ -53,6 +54,7 @@ class DIALOG_UPDATE_FROM_PCB_BASE : public DIALOG_SHIM public: DIALOG_UPDATE_FROM_PCB_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Update Schematic from PCB"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~DIALOG_UPDATE_FROM_PCB_BASE(); }; diff --git a/eeschema/tools/backannotate.cpp b/eeschema/tools/backannotate.cpp index eeaa0adef7..dfe346be58 100644 --- a/eeschema/tools/backannotate.cpp +++ b/eeschema/tools/backannotate.cpp @@ -42,13 +42,15 @@ BACK_ANNOTATE::BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, bool aRelinkFootprints, bool aProcessFootprints, bool aProcessValues, - bool aProcessReferences, bool aProcessNetNames, bool aDryRun ) : + bool aProcessReferences, bool aProcessNetNames, + bool aProcessAttributes, bool aDryRun ) : m_reporter( aReporter ), m_matchByReference( aRelinkFootprints ), m_processFootprints( aProcessFootprints ), m_processValues( aProcessValues ), m_processReferences( aProcessReferences ), m_processNetNames( aProcessNetNames ), + m_processAttributes( aProcessAttributes ), m_dryRun( aDryRun ), m_frame( aFrame ), m_changesCount( 0 ), @@ -68,7 +70,7 @@ bool BACK_ANNOTATE::BackAnnotateSymbols( const std::string& aNetlist ) m_appendUndo = false; if( !m_matchByReference && !m_processValues && !m_processFootprints && !m_processReferences - && !m_processNetNames ) + && !m_processNetNames && !m_processAttributes ) { m_reporter.ReportTail( _( "Select at least one property to back annotate." ), RPT_SEVERITY_ERROR ); @@ -148,6 +150,7 @@ void BACK_ANNOTATE::getPcbModulesFromString( const std::string& aPayload ) for( const std::pair& item : tree ) { wxString path, value, footprint; + bool dnp = false, exBOM = false; std::map pinNetMap; wxASSERT( item.first == "ref" ); wxString ref = getStr( item.second ); @@ -169,6 +172,28 @@ void BACK_ANNOTATE::getPcbModulesFromString( const std::string& aPayload ) footprint = getStr( item.second.get_child( "fpid" ) ); value = getStr( item.second.get_child( "value" ) ); + // Get DNP and Exclude from BOM out of the properties if they exist + for( const auto& child : item.second ) + { + if( child.first != "property" ) + continue; + + auto property = child.second; + auto name = property.get_child_optional( "name" ); + + if( !name ) + continue; + + if( name.get().front().first == "dnp" ) + { + dnp = true; + } + else if( name.get().front().first == "exclude_from_bom" ) + { + exBOM = true; + } + } + boost::optional nets = item.second.get_child_optional( "nets" ); if( nets ) @@ -201,7 +226,8 @@ void BACK_ANNOTATE::getPcbModulesFromString( const std::string& aPayload ) else { // Add footprint to the map - auto data = std::make_shared( ref, footprint, value, pinNetMap ); + auto data = + std::make_shared( ref, footprint, value, dnp, exBOM, pinNetMap ); m_pcbFootprints.insert( nearestItem, std::make_pair( path, data ) ); } } @@ -321,8 +347,15 @@ void BACK_ANNOTATE::applyChangelist() SCH_SCREEN* screen = ref.GetSheetPath().LastScreen(); wxString oldFootprint = ref.GetFootprint(); wxString oldValue = ref.GetValue(); + bool oldDNP = ref.GetSymbol()->GetDNP(); + bool oldExBOM = !ref.GetSymbol()->GetIncludeInBom(); bool skip = ( ref.GetSymbol()->GetFlags() & SKIP_STRUCT ) > 0; + auto boolString = []( bool b ) -> wxString + { + return b ? _( "true" ) : _( "false" ); + }; + if( m_processReferences && ref.GetRef() != fpData.m_ref && !skip ) { ++m_changesCount; @@ -376,6 +409,39 @@ void BACK_ANNOTATE::applyChangelist() m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION ); } + if( m_processAttributes && oldDNP != fpData.m_DNP && !skip ) + { + ++m_changesCount; + msg.Printf( _( "Change %s 'Do not populate' from '%s' to '%s'." ), ref.GetRef(), + boolString( oldDNP ), boolString( fpData.m_DNP ) ); + + if( !m_dryRun ) + { + m_frame->SaveCopyInUndoList( screen, symbol, UNDO_REDO::CHANGED, m_appendUndo ); + m_appendUndo = true; + symbol->SetDNP( fpData.m_DNP ); + } + + m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION ); + } + + if( m_processAttributes && oldExBOM != fpData.m_excludeFromBOM && !skip ) + { + ++m_changesCount; + msg.Printf( _( "Change %s 'Exclude from bill of materials' from '%s' to '%s'." ), + ref.GetRef(), boolString( oldExBOM ), + boolString( fpData.m_excludeFromBOM ) ); + + if( !m_dryRun ) + { + m_frame->SaveCopyInUndoList( screen, symbol, UNDO_REDO::CHANGED, m_appendUndo ); + m_appendUndo = true; + symbol->SetIncludeInBom( !fpData.m_excludeFromBOM ); + } + + m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION ); + } + if( m_processNetNames ) { for( const std::pair& entry : fpData.m_pinMap ) diff --git a/eeschema/tools/backannotate.h b/eeschema/tools/backannotate.h index efaa6a4af4..5b827a9853 100644 --- a/eeschema/tools/backannotate.h +++ b/eeschema/tools/backannotate.h @@ -61,16 +61,21 @@ public: struct PCB_FP_DATA { PCB_FP_DATA( const wxString& aRef, const wxString& aFootprint, const wxString& aValue, + bool aDNP, bool aExcludeFromBOM, const std::map aPinMap ) : m_ref( aRef ), m_footprint( aFootprint ), m_value( aValue ), + m_DNP( aDNP ), + m_excludeFromBOM( aExcludeFromBOM ), m_pinMap( aPinMap ) - {}; + {} wxString m_ref; wxString m_footprint; wxString m_value; + bool m_DNP; + bool m_excludeFromBOM; std::map m_pinMap; }; @@ -81,7 +86,7 @@ public: BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, bool aRelinkFootprints, bool aProcessFootprints, bool aProcessValues, bool aProcessReferences, - bool aProcessNetNames, bool aDryRun ); + bool aProcessNetNames, bool aProcessAttributes, bool aDryRun ); ~BACK_ANNOTATE(); /** @@ -137,6 +142,7 @@ private: bool m_processValues; bool m_processReferences; bool m_processNetNames; + bool m_processAttributes; bool m_dryRun; PCB_FOOTPRINTS_MAP m_pcbFootprints; diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index 0b2b305454..af041da7b2 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -563,6 +563,17 @@ void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail ) } } + // Add DNP and Exclude from BOM properties + std::map properties; + + if( footprint->GetAttributes() & FP_DNP ) + properties.emplace( "dnp", "" ); + + if( footprint->GetAttributes() & FP_EXCLUDE_FROM_BOM ) + properties.emplace( "exclude_from_bom", "" ); + + component->SetProperties( properties ); + netlist.AddComponent( component ); } diff --git a/pcbnew/netlist_reader/pcb_netlist.cpp b/pcbnew/netlist_reader/pcb_netlist.cpp index e16947b279..e4402be80e 100644 --- a/pcbnew/netlist_reader/pcb_netlist.cpp +++ b/pcbnew/netlist_reader/pcb_netlist.cpp @@ -93,6 +93,13 @@ void COMPONENT::Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl ) path += '/' + m_kiids.front().AsString(); aOut->Print( nl+1, "(timestamp %s)\n", aOut->Quotew( path ).c_str() ); + + // Add DNP and Exclude from BOM properties if we have them + if( m_properties.count( "dnp" ) ) + aOut->Print( nl + 1, "(property (name \"dnp\"))\n" ); + + if( m_properties.count( "exclude_from_bom" ) ) + aOut->Print( nl + 1, "(property (name \"exclude_from_bom\"))\n" ); } if( !( aCtl & CTL_OMIT_FILTERS ) && m_footprintFilters.GetCount() )