From 6ab2f35f742b9ce98a9b8f82137154b309ec841a Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Sat, 24 Aug 2013 10:08:55 +0200 Subject: [PATCH] Pcbnew: read netlist enhancements: add option to remove single pads nets, add enforce tests to report non existing netnames in zones. Fix also some very minor errors in comments. --- include/wxPcbStruct.h | 3 + pcbnew/class_board.cpp | 77 ++++++++++++++++++++++- pcbnew/class_board.h | 5 +- pcbnew/class_netinfo.h | 2 +- pcbnew/class_netinfolist.cpp | 2 +- pcbnew/dialogs/dialog_netlist.cpp | 6 ++ pcbnew/dialogs/dialog_netlist_fbp.cpp | 6 ++ pcbnew/dialogs/dialog_netlist_fbp.fbp | 90 +++++++++++++++++++++++++++ pcbnew/dialogs/dialog_netlist_fbp.h | 1 + pcbnew/netlist.cpp | 3 +- 10 files changed, 189 insertions(+), 6 deletions(-) diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index a37d22e02d..5fb8256601 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -1451,6 +1451,8 @@ public: * @param aSelectByTimestamp if true, use timestamp instead of reference to identify * footprints from components (use after reannotation of the * schematic) + * @param aDeleteSinglePadNets if true, remove nets counting only one pad + * and set net code to 0 for these pads * @param aIsDryRun performs a dry run without making any changes if true. */ void ReadPcbNetlist( const wxString& aNetlistFileName, @@ -1460,6 +1462,7 @@ public: bool aDeleteBadTracks, bool aDeleteExtraFootprints, bool aSelectByTimestamp, + bool aDeleteSinglePadNets, bool aIsDryRun ); /** diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index c71c0f3f78..46ea086b93 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -2332,7 +2333,8 @@ bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, ZONE_CONTAI } -void BOARD::ReplaceNetlist( NETLIST& aNetlist, REPORTER* aReporter ) +void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, + REPORTER* aReporter ) { unsigned i; wxPoint bestPosition; @@ -2603,7 +2605,53 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, REPORTER* aReporter ) } } - // Last step: verify all pads found in netlist: + // If needed, remove the single pad nets: + if( aDeleteSinglePadNets && !aNetlist.IsDryRun() ) + { + BuildListOfNets(); + std::vector padlist = GetPads(); + // padlist is the list of pads, sorted by netname. + int count = 0; + wxString netname; + D_PAD * pad = NULL; + D_PAD * previouspad = NULL; + for( unsigned ii = 0; ii < padlist.size(); ii++ ) + { + pad = padlist[ii]; + + if( pad->GetNetname().IsEmpty() ) + continue; + + if( netname != pad->GetNetname() ) // End of net + { + if( previouspad && count == 1 ) + { + if( aReporter && aReporter->ReportAll() ) + { + msg.Printf( _( "Remove single pad net \"%s\" on \"%s\" pad <%s>\n" ), + GetChars( pad->GetNetname() ), + GetChars( pad->GetParent()->GetReference() ), + GetChars( previouspad->GetPadName() ) ); + aReporter->Report( msg ); + } + previouspad->SetNetname( wxEmptyString ); + } + netname = pad->GetNetname(); + count = 1; + } + else + count++; + + previouspad = pad; + } + + // Examine last pad + if( pad && count == 1 ) + pad->SetNetname( wxEmptyString ); + } + + // Last step: Some tests: + // verify all pads found in netlist: // They should exist in footprints, otherwise the footprint is wrong // note also references or time stamps are updated, so we use only // the reference to find a footprint @@ -2636,5 +2684,30 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, REPORTER* aReporter ) } } } + + // Verify zone net names validity: + // After schematic changes, a zone can have a non existing net name. + // It should be reported + if( aReporter && aReporter->ReportErrors() ) + { + //Loop through all copper zones + for( i = 0; i < m_ZoneDescriptorList.size(); i++ ) + { + ZONE_CONTAINER* zone = m_ZoneDescriptorList[i]; + + if( zone->GetNet() >= 0 || !zone->IsOnCopperLayer() ) + continue; + + // Net name not valid, report error + wxString coord; + coord << zone->GetPosition(); + msg.Printf( _( "** Error: Zone %s layer <%s>" + " has non-existent net name \"%s\" **\n" ), + GetChars( coord ), + GetChars( zone->GetLayerName() ), + GetChars( zone->GetNetName() ) ); + aReporter->Report( msg ); + } + } } diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index df63b410b4..5ba5c2174d 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -927,10 +927,13 @@ public: * any extra unlock footprints are removed from the #BOARD. * * @param aNetlist is the new netlist to revise the contents of the #BOARD with. + * @param aDeleteSinglePadNets if true, remove nets counting only one pad + * and set net code to 0 for these pads * @param aReporter is a #REPORTER object to report the changes \a aNetlist makes to * the #BOARD. If NULL, no change reporting occurs. */ - void ReplaceNetlist( NETLIST& aNetlist, REPORTER* aReporter = NULL ); + void ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, + REPORTER* aReporter = NULL ); /** * Function ReturnSortedNetnamesList diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index 926d5c1c56..427a7b5685 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -197,7 +197,7 @@ private: void clear(); /** - * Function BuildListOfNets + * Function buildListOfNets * builds or rebuilds the list of NETINFO_ITEMs * The list is sorted by names. */ diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index 955907ba9d..df5f8039de 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -72,7 +72,7 @@ static bool padlistSortByNetnames( const D_PAD* a, const D_PAD* b ) * Be aware NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) * when search a net by its net name does a binary search * and expects to have a nets list sorted by an alphabetic case sensitive sort - * So do not change Build_Pads_Full_List() taht build a sorted list of pads + * So do not change Build_Pads_Full_List() which build a sorted list of pads */ void NETINFO_LIST::buildListOfNets() { diff --git a/pcbnew/dialogs/dialog_netlist.cpp b/pcbnew/dialogs/dialog_netlist.cpp index 19d70b36b3..2137cf886c 100644 --- a/pcbnew/dialogs/dialog_netlist.cpp +++ b/pcbnew/dialogs/dialog_netlist.cpp @@ -47,6 +47,7 @@ #define NETLIST_SILENTMODE_KEY wxT("SilentMode") #define NETLIST_FULLMESSAGES_KEY wxT("NetlistReportAllMsg") +#define NETLIST_DELETESINGLEPADNETS_KEY wxT("NetlistDeleteSinglePadNets") void PCB_EDIT_FRAME::InstallNetlistFrame( wxDC* DC ) { @@ -97,6 +98,8 @@ DIALOG_NETLIST::DIALOG_NETLIST( PCB_EDIT_FRAME* aParent, wxDC * aDC, m_config = wxGetApp().GetSettings(); m_silentMode = m_config->Read( NETLIST_SILENTMODE_KEY, 0l ); m_reportAll = m_config->Read( NETLIST_FULLMESSAGES_KEY, 1l ); + bool tmp = m_config->Read( NETLIST_DELETESINGLEPADNETS_KEY, 0l ); + m_rbSingleNets->SetSelection( tmp == 0 ? 0 : 1); m_NetlistFilenameCtrl->SetValue( aNetlistFullFilename ); m_cmpNameSourceOpt->SetSelection( m_parent->GetUseCmpFileForFpNames() ? 1 : 0 ); m_checkBoxSilentMode->SetValue( m_silentMode ); @@ -109,6 +112,8 @@ DIALOG_NETLIST::~DIALOG_NETLIST() { m_config->Write( NETLIST_SILENTMODE_KEY, (long) m_silentMode ); m_config->Write( NETLIST_FULLMESSAGES_KEY, (long) m_reportAll ); + m_config->Write( NETLIST_DELETESINGLEPADNETS_KEY, + (long) m_rbSingleNets->GetSelection() ); } void DIALOG_NETLIST::OnOpenNetlistClick( wxCommandEvent& event ) @@ -187,6 +192,7 @@ void DIALOG_NETLIST::OnReadNetlistFileClick( wxCommandEvent& event ) m_DeleteBadTracks->GetSelection() == 1, m_RemoveExtraFootprintsCtrl->GetSelection() == 1, m_Select_By_Timestamp->GetSelection() == 1, + m_rbSingleNets->GetSelection() == 1, m_checkDryRun->GetValue() ); } diff --git a/pcbnew/dialogs/dialog_netlist_fbp.cpp b/pcbnew/dialogs/dialog_netlist_fbp.cpp index a4f709f8b4..243f306f69 100644 --- a/pcbnew/dialogs/dialog_netlist_fbp.cpp +++ b/pcbnew/dialogs/dialog_netlist_fbp.cpp @@ -74,6 +74,12 @@ DIALOG_NETLIST_FBP::DIALOG_NETLIST_FBP( wxWindow* parent, wxWindowID id, const w bTracksSizer->Add( m_RemoveExtraFootprintsCtrl, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + wxString m_rbSingleNetsChoices[] = { _("Keep"), _("Delete") }; + int m_rbSingleNetsNChoices = sizeof( m_rbSingleNetsChoices ) / sizeof( wxString ); + m_rbSingleNets = new wxRadioBox( this, wxID_ANY, _("Single Pad Nets"), wxDefaultPosition, wxDefaultSize, m_rbSingleNetsNChoices, m_rbSingleNetsChoices, 1, wxRA_SPECIFY_COLS ); + m_rbSingleNets->SetSelection( 0 ); + bTracksSizer->Add( m_rbSingleNets, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + bnetlistOptSizer->Add( bTracksSizer, 1, wxEXPAND, 5 ); diff --git a/pcbnew/dialogs/dialog_netlist_fbp.fbp b/pcbnew/dialogs/dialog_netlist_fbp.fbp index a4c4c8e3ff..35f547a11d 100644 --- a/pcbnew/dialogs/dialog_netlist_fbp.fbp +++ b/pcbnew/dialogs/dialog_netlist_fbp.fbp @@ -588,6 +588,96 @@ + + 5 + wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "Keep" "Delete" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Single Pad Nets + 1 + + 0 + + + 0 + + 1 + m_rbSingleNets + 1 + + + protected + 1 + + Resizable + 0 + 1 + + wxRA_SPECIFY_COLS + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcbnew/dialogs/dialog_netlist_fbp.h b/pcbnew/dialogs/dialog_netlist_fbp.h index e5befa18aa..6ecadf84da 100644 --- a/pcbnew/dialogs/dialog_netlist_fbp.h +++ b/pcbnew/dialogs/dialog_netlist_fbp.h @@ -51,6 +51,7 @@ class DIALOG_NETLIST_FBP : public DIALOG_SHIM wxRadioBox* m_ChangeExistingFootprintCtrl; wxRadioBox* m_DeleteBadTracks; wxRadioBox* m_RemoveExtraFootprintsCtrl; + wxRadioBox* m_rbSingleNets; wxButton* m_buttonRead; wxButton* m_buttonClose; wxButton* m_buttonFPTest; diff --git a/pcbnew/netlist.cpp b/pcbnew/netlist.cpp index d0478195b6..6df4c7e10e 100644 --- a/pcbnew/netlist.cpp +++ b/pcbnew/netlist.cpp @@ -50,6 +50,7 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName, bool aDeleteUnconnectedTracks, bool aDeleteExtraFootprints, bool aSelectByTimeStamp, + bool aDeleteSinglePadNets, bool aIsDryRun ) { wxString msg; @@ -90,7 +91,7 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName, GetScreen()->ClearUndoRedoList(); netlist.SortByReference(); - GetBoard()->ReplaceNetlist( netlist, aReporter ); + GetBoard()->ReplaceNetlist( netlist, aDeleteSinglePadNets, aReporter ); // If it was a dry run, nothing has changed so we're done. if( netlist.IsDryRun() )