Pcbnew, update footprint: fix loss of net info in some cases.

When pads having a similar name but some were not on a copper layer
(aperture pads) the net info update from old footprint to the new footprint
was incorrectly transferred. Now, only pads on copper layers are considered.
Fixes #8979
https://gitlab.com/kicad/code/kicad/issues/8979
This commit is contained in:
jean-pierre charras 2021-08-16 20:52:49 +02:00
parent e1bbb717f6
commit ca42f31bb5
3 changed files with 43 additions and 10 deletions

View File

@ -481,7 +481,7 @@ FP_TEXT* getMatchingTextItem( FP_TEXT* aRefItem, FOOTPRINT* aFootprint )
return candidates[0];
}
#include <wx/log.h>
void PCB_EDIT_FRAME::ExchangeFootprint( FOOTPRINT* aExisting, FOOTPRINT* aNew,
BOARD_COMMIT& aCommit, bool deleteExtraTexts,
bool resetTextLayers, bool resetTextEffects,
@ -511,18 +511,42 @@ void PCB_EDIT_FRAME::ExchangeFootprint( FOOTPRINT* aExisting, FOOTPRINT* aNew,
aNew->SetLocked( aExisting->IsLocked() );
// Now transfer the net info from "old" pads to the new footprint
for( PAD* pad : aNew->Pads() )
{
PAD* oldPad = aExisting->FindPadByName( pad->GetName() );
PAD* pad_model = nullptr;
if( oldPad )
// Skip pad not on a copper layer, because we only want to transfer the net info
if( !pad->IsOnCopperLayer() )
continue;
// Pads with no name are never connected to a net
if( pad->GetName().IsEmpty() )
continue;
// Search for a similar pad on a copper layer, to reuse net info
PAD* last_pad = nullptr;
while( true )
{
pad->SetLocalRatsnestVisible( oldPad->GetLocalRatsnestVisible() );
pad->SetPinFunction( oldPad->GetPinFunction() );
pad->SetLocked( oldPad->IsLocked() );
pad_model = aExisting->FindPadByName( pad->GetName(), last_pad );
if( !pad_model )
break;
if( pad_model->IsOnCopperLayer() ) // a candidate is found
break;
last_pad = pad_model;
}
pad->SetNetCode( oldPad ? oldPad->GetNetCode() : NETINFO_LIST::UNCONNECTED );
if( pad_model )
{
pad->SetLocalRatsnestVisible( pad_model->GetLocalRatsnestVisible() );
pad->SetPinFunction( pad_model->GetPinFunction() );
}
pad->SetNetCode( pad_model ? pad_model->GetNetCode() : NETINFO_LIST::UNCONNECTED );
}
// Copy reference

View File

@ -1009,11 +1009,19 @@ bool FOOTPRINT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy )
}
PAD* FOOTPRINT::FindPadByName( const wxString& aPadName ) const
PAD* FOOTPRINT::FindPadByName( const wxString& aPadName, PAD* aSearchAfterMe ) const
{
bool can_select = aSearchAfterMe ? false : true;
for( PAD* pad : m_pads )
{
if( pad->GetName() == aPadName )
if( !can_select && pad == aSearchAfterMe )
{
can_select = true;
continue;
}
if( can_select && pad->GetName() == aPadName )
return pad;
}

View File

@ -485,9 +485,10 @@ public:
* @note Names may not be unique depending on how the footprint was created.
*
* @param aPadName the pad name to find.
* @param aSearchAfterMe = not nullptr to find a pad living after aAfterMe
* @return the first matching named #PAD is returned or NULL if not found.
*/
PAD* FindPadByName( const wxString& aPadName ) const;
PAD* FindPadByName( const wxString& aPadName, PAD* aSearchAfterMe = nullptr ) const;
/**
* Get a pad at \a aPosition on \a aLayerMask in the footprint.