From 35d522382567e9b4cc21585f09715141be45cfd7 Mon Sep 17 00:00:00 2001 From: Roberto Fernandez Bautista Date: Fri, 13 Aug 2021 19:08:45 +0100 Subject: [PATCH] Keep track of existing/excluded references when re-annotating the PCB Fixes https://gitlab.com/kicad/code/kicad/-/issues/8211 --- pcbnew/dialogs/dialog_board_reannotate.cpp | 94 ++++++++++++++++------ pcbnew/dialogs/dialog_board_reannotate.h | 10 ++- 2 files changed, 78 insertions(+), 26 deletions(-) diff --git a/pcbnew/dialogs/dialog_board_reannotate.cpp b/pcbnew/dialogs/dialog_board_reannotate.cpp index fd823201e5..10fd274559 100644 --- a/pcbnew/dialogs/dialog_board_reannotate.cpp +++ b/pcbnew/dialogs/dialog_board_reannotate.cpp @@ -23,6 +23,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include #include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -236,6 +238,32 @@ void DIALOG_BOARD_REANNOTATE::FilterPrefix( wxTextCtrl* aPrefix ) } +RefDesTypeStr* DIALOG_BOARD_REANNOTATE::GetOrBuildRefDesInfo( const wxString& aRefDesPrefix, + unsigned int aStartRefDes ) +{ + unsigned int requiredLastRef = ( aStartRefDes == 0 ? 1 : aStartRefDes ) - 1; + + for( size_t i = 0; i < m_refDesTypes.size(); i++ ) // See if it is in the types array + { + if( m_refDesTypes[i].RefDesType == aRefDesPrefix ) // Found it! + { + m_refDesTypes[i].LastUsedRefDes = std::max( m_refDesTypes[i].LastUsedRefDes, + requiredLastRef ); + + return &m_refDesTypes[i]; + } + } + + // Wasn't in the types array so add it + RefDesTypeStr newtype; + newtype.RefDesType = aRefDesPrefix; + newtype.LastUsedRefDes = requiredLastRef; + m_refDesTypes.push_back( newtype ); + + return &m_refDesTypes.back(); +} + + void DIALOG_BOARD_REANNOTATE::FilterFrontPrefix( wxCommandEvent& event ) { FilterPrefix( m_FrontPrefix ); @@ -739,7 +767,8 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector& aBadR m_refDesTypes.clear(); m_changeArray.clear(); - backstartrefdes = wxAtoi( m_BackRefDesStart->GetValue() ); + + BuildUnavailableRefsList(); if( !m_frontFootprints.empty() ) { @@ -749,8 +778,8 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector& aBadR if( !m_backFootprints.empty() ) { - BuildChangeArray( m_backFootprints, backstartrefdes, m_BackPrefix->GetValue(), - m_RemoveBackPrefix->GetValue(), aBadRefDes ); + BuildChangeArray( m_backFootprints, wxAtoi( m_BackRefDesStart->GetValue() ), + m_BackPrefix->GetValue(), m_RemoveBackPrefix->GetValue(), aBadRefDes ); } if( !m_changeArray.empty() ) @@ -788,17 +817,38 @@ bool DIALOG_BOARD_REANNOTATE::BuildFootprintList( std::vector& aBadR return ( 0 == errorcount ); } +void DIALOG_BOARD_REANNOTATE::BuildUnavailableRefsList() +{ + std::vector excludedFootprints; + + for( RefDesInfo fpData : m_frontFootprints ) + { + if( fpData.Action == Exclude ) + excludedFootprints.push_back( fpData ); + } + + for( RefDesInfo fpData : m_backFootprints ) + { + if( fpData.Action == Exclude ) + excludedFootprints.push_back( fpData ); + } + + for( RefDesInfo fpData : excludedFootprints ) + { + if( fpData.Action == Exclude ) + { + RefDesTypeStr* refDesInfo = GetOrBuildRefDesInfo( fpData.RefDesType ); + refDesInfo->UnavailableRefs.insert( UTIL::GetRefDesNumber( fpData.RefDesString ) ); + } + } +} + void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector& aFootprints, unsigned int aStartRefDes, const wxString& aPrefix, bool aRemovePrefix, std::vector& aBadRefDes ) { - size_t i; - RefDesChange change; - RefDesTypeStr newtype; - - wxString refdestype; size_t prefixsize = aPrefix.size(); bool haveprefix = ( 0 != prefixsize ); // Do I have a prefix? @@ -813,12 +863,15 @@ void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector& aFootpr if( 0 != aStartRefDes ) // Initialize the change array if present { - for( i = 0; i < m_refDesTypes.size(); i++ ) - m_refDesTypes[i].RefDesCount = aStartRefDes; + for( size_t i = 0; i < m_refDesTypes.size(); i++ ) + m_refDesTypes[i].LastUsedRefDes = aStartRefDes; } + for( RefDesInfo fpData : aFootprints ) { + RefDesChange change; + change.Uuid = fpData.Uuid; change.Action = fpData.Action; change.OldRefDesString = fpData.RefDesString; @@ -837,7 +890,6 @@ void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector& aFootpr if( change.Action == UpdateRefDes ) { - refdestype = fpData.RefDesType; prefixpresent = ( 0 == fpData.RefDesType.find( aPrefix ) ); if( addprefix && !prefixpresent ) @@ -846,22 +898,14 @@ void DIALOG_BOARD_REANNOTATE::BuildChangeArray( std::vector& aFootpr if( aRemovePrefix && prefixpresent ) // If there is a prefix remove it fpData.RefDesType.erase( 0, prefixsize ); - for( i = 0; i < m_refDesTypes.size(); i++ ) // See if it is in the types array - { - if( m_refDesTypes[i].RefDesType == fpData.RefDesType ) // Found it! - break; - } + RefDesTypeStr* refDesInfo = GetOrBuildRefDesInfo( fpData.RefDesType, aStartRefDes ); + unsigned int newRefDesNumber = refDesInfo->LastUsedRefDes + 1; - // Wasn't in the types array so add it - if( i == m_refDesTypes.size() ) - { - newtype.RefDesType = fpData.RefDesType; - newtype.RefDesCount = ( aStartRefDes == 0 ? 1 : aStartRefDes ); - m_refDesTypes.push_back( newtype ); - } + while( refDesInfo->UnavailableRefs.count( newRefDesNumber ) ) + newRefDesNumber++; - change.NewRefDes = m_refDesTypes[i].RefDesType - + std::to_string( m_refDesTypes[i].RefDesCount++ ); + change.NewRefDes = refDesInfo->RefDesType + std::to_string( newRefDesNumber ); + refDesInfo->LastUsedRefDes = newRefDesNumber; } m_changeArray.push_back( change ); diff --git a/pcbnew/dialogs/dialog_board_reannotate.h b/pcbnew/dialogs/dialog_board_reannotate.h index 89d89bdbc4..aa5a757b6c 100644 --- a/pcbnew/dialogs/dialog_board_reannotate.h +++ b/pcbnew/dialogs/dialog_board_reannotate.h @@ -92,7 +92,8 @@ struct RefDesInfo struct RefDesTypeStr { wxString RefDesType; - unsigned int RefDesCount; + unsigned int LastUsedRefDes; + std::set UnavailableRefs; }; @@ -159,6 +160,9 @@ private: /// @return true if success, false if errors bool BuildFootprintList( std::vector& aBadRefDes ); + /// Build list of unavailable references. E.g. unselected footprints or locked footprints. + void BuildUnavailableRefsList(); + /// Scan through the footprint arrays and create the from -> to array. void BuildChangeArray( std::vector& aFootprints, unsigned int aStartRefDes, const wxString& aPrefix, bool aRemovePrefix, @@ -180,6 +184,10 @@ private: /// Check to make sure the prefix (if there is one) is properly constructed. void FilterPrefix( wxTextCtrl* aPrefix ); + /// Get the structure representing the information currently held for aRefDesPrefix or create one + /// if it doesn't exist + RefDesTypeStr* GetOrBuildRefDesInfo( const wxString& aRefDesPrefix, unsigned int aStartRefDes = 0 ); + PCB_EDIT_FRAME* m_frame; FOOTPRINTS m_footprints; PCB_SELECTION m_selection;