diff --git a/include/drc_item.h b/include/drc_item.h index bcf7755f9f..67eb129900 100644 --- a/include/drc_item.h +++ b/include/drc_item.h @@ -78,6 +78,11 @@ public: SetData( aUnits, aErrorCode, aMainItem, aMainPos, bAuxiliaryItem, bAuxiliaryPos ); } + DRC_ITEM( EDA_UNITS_T aUnits, int aErrorCode, EDA_ITEM* aMainItem, const wxPoint& aMainPos ) + { + SetData( aUnits, aErrorCode, aMainItem, aMainPos ); + } + DRC_ITEM( int aErrorCode, const wxString& aMainText ) { diff --git a/pcbnew/dialogs/dialog_cleanup_tracks_and_vias.cpp b/pcbnew/dialogs/dialog_cleanup_tracks_and_vias.cpp index 9a04fa2681..54e93dc75e 100644 --- a/pcbnew/dialogs/dialog_cleanup_tracks_and_vias.cpp +++ b/pcbnew/dialogs/dialog_cleanup_tracks_and_vias.cpp @@ -26,32 +26,48 @@ */ #include -#include -#include +#include "dialog_drclistbox.h" #include -#include +#include +#include +#include #include -#include #include #include -#include -#include "dialog_drclistbox.h" +#include +#include +#include -// Static members of DIALOG_CLEANUP_TRACKS_AND_VIAS -bool DIALOG_CLEANUP_TRACKS_AND_VIAS::m_cleanVias = true; -bool DIALOG_CLEANUP_TRACKS_AND_VIAS::m_mergeSegments = true; -bool DIALOG_CLEANUP_TRACKS_AND_VIAS::m_deleteUnconnectedSegm = true; -bool DIALOG_CLEANUP_TRACKS_AND_VIAS::m_deleteShortCircuits = true; +// Keywords for read and write config +#define CleanupViaKey wxT( "DialogCleanupVias" ) +#define MergeKey wxT( "DialogCleanupMergeSegments" ) +#define UnconnectedKey wxT( "DialogCleanupUnconnected" ) +#define ShortCircuitKey wxT( "DialogCleanupShortCircuit" ) +#define TracksInPadKey wxT( "DialogCleanupTracksInPads" ) DIALOG_CLEANUP_TRACKS_AND_VIAS::DIALOG_CLEANUP_TRACKS_AND_VIAS( PCB_EDIT_FRAME* aParentFrame ): DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE( aParentFrame ), m_parentFrame( aParentFrame ) { - m_cleanViasOpt->SetValue( m_cleanVias ); - m_mergeSegmOpt->SetValue( m_mergeSegments ); - m_deleteUnconnectedOpt->SetValue( m_deleteUnconnectedSegm ); - m_cleanShortCircuitOpt->SetValue( m_deleteShortCircuits ); + m_config = Kiface().KifaceSettings(); + m_config->SetPath( "/dialogs/cleanup_tracks/" ); + + bool value; + m_config->Read( CleanupViaKey, &value, true ); + m_cleanViasOpt->SetValue( value ); + + m_config->Read( MergeKey, &value, true ); + m_mergeSegmOpt->SetValue( value ); + + m_config->Read( UnconnectedKey, &value, true ); + m_deleteUnconnectedOpt->SetValue( value ); + + m_config->Read( ShortCircuitKey, &value, true ); + m_cleanShortCircuitOpt->SetValue( value ); + + m_config->Read( TracksInPadKey, &value, true ); + m_deleteTracksInPadsOpt->SetValue( value ); // We use a sdbSizer to get platform-dependent ordering of the action buttons, but // that requires us to correct the button labels here. @@ -65,10 +81,11 @@ DIALOG_CLEANUP_TRACKS_AND_VIAS::DIALOG_CLEANUP_TRACKS_AND_VIAS( PCB_EDIT_FRAME* DIALOG_CLEANUP_TRACKS_AND_VIAS::~DIALOG_CLEANUP_TRACKS_AND_VIAS() { - m_cleanVias = m_cleanViasOpt->GetValue(); - m_mergeSegments = m_mergeSegmOpt->GetValue(); - m_deleteUnconnectedSegm = m_deleteUnconnectedOpt->GetValue(); - m_deleteShortCircuits = m_cleanShortCircuitOpt->GetValue(); + m_config->Write( CleanupViaKey, m_cleanViasOpt->GetValue() ); + m_config->Write( MergeKey, m_mergeSegmOpt->GetValue() ); + m_config->Write( UnconnectedKey, m_deleteUnconnectedOpt->GetValue() ); + m_config->Write( ShortCircuitKey, m_cleanShortCircuitOpt->GetValue() ); + m_config->Write( TracksInPadKey, m_deleteTracksInPadsOpt->GetValue() ); for( DRC_ITEM* item : m_items ) delete item; @@ -117,11 +134,9 @@ void DIALOG_CLEANUP_TRACKS_AND_VIAS::doCleanup( bool aDryRun ) // Old model has to be refreshed, GAL normally does not keep updating it m_parentFrame->Compile_Ratsnest( false ); - bool modified = cleaner.CleanupBoard( aDryRun, &m_items, - m_cleanShortCircuitOpt->GetValue(), - m_cleanViasOpt->GetValue(), - m_mergeSegmOpt->GetValue(), - m_deleteUnconnectedOpt->GetValue() ); + bool modified = cleaner.CleanupBoard( aDryRun, &m_items, m_cleanShortCircuitOpt->GetValue(), + m_cleanViasOpt->GetValue(), m_mergeSegmOpt->GetValue(), + m_deleteUnconnectedOpt->GetValue(), m_deleteTracksInPadsOpt->GetValue() ); if( aDryRun ) { diff --git a/pcbnew/dialogs/dialog_cleanup_tracks_and_vias.h b/pcbnew/dialogs/dialog_cleanup_tracks_and_vias.h index 80437477eb..a776c38220 100644 --- a/pcbnew/dialogs/dialog_cleanup_tracks_and_vias.h +++ b/pcbnew/dialogs/dialog_cleanup_tracks_and_vias.h @@ -28,6 +28,7 @@ #include #include +#include class PCB_EDIT_FRAME; @@ -37,11 +38,7 @@ class DIALOG_CLEANUP_TRACKS_AND_VIAS: public DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE { PCB_EDIT_FRAME* m_parentFrame; DRC_LIST m_items; - - static bool m_cleanVias; - static bool m_mergeSegments; - static bool m_deleteUnconnectedSegm; - static bool m_deleteShortCircuits; + wxConfigBase* m_config; void doCleanup( bool aDryRun ); diff --git a/pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.cpp b/pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.cpp index ecb5717eab..dccfa77b7f 100644 --- a/pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.cpp +++ b/pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Dec 30 2017) +// C++ code generated with wxFormBuilder (version Apr 23 2019) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -14,71 +14,77 @@ DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) { this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - + wxBoxSizer* bSizerMain; bSizerMain = new wxBoxSizer( wxVERTICAL ); - + wxBoxSizer* bSizerUpper; bSizerUpper = new wxBoxSizer( wxVERTICAL ); - + m_cleanShortCircuitOpt = new wxCheckBox( this, wxID_ANY, _("Delete &tracks connecting different nets"), wxDefaultPosition, wxDefaultSize, 0 ); m_cleanShortCircuitOpt->SetToolTip( _("remove track segments connecting nodes belonging to different nets (short circuit)") ); - + bSizerUpper->Add( m_cleanShortCircuitOpt, 0, wxALL, 5 ); - + m_cleanViasOpt = new wxCheckBox( this, wxID_ANY, _("&Delete redundant vias"), wxDefaultPosition, wxDefaultSize, 0 ); m_cleanViasOpt->SetToolTip( _("remove vias on through hole pads and superimposed vias") ); - + bSizerUpper->Add( m_cleanViasOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 ); - + m_mergeSegmOpt = new wxCheckBox( this, wxID_ANY, _("&Merge co-linear tracks"), wxDefaultPosition, wxDefaultSize, 0 ); m_mergeSegmOpt->SetToolTip( _("merge aligned track segments, and remove null segments") ); - + bSizerUpper->Add( m_mergeSegmOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 ); - + m_deleteUnconnectedOpt = new wxCheckBox( this, wxID_ANY, _("Delete &dangling tracks"), wxDefaultPosition, wxDefaultSize, 0 ); m_deleteUnconnectedOpt->SetToolTip( _("delete tracks having at least one dangling end") ); - + bSizerUpper->Add( m_deleteUnconnectedOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 ); - - + + m_deleteTracksInPadsOpt = new wxCheckBox( this, wxID_ANY, _("Delete Tracks in Pads"), wxDefaultPosition, wxDefaultSize, 0 ); + m_deleteTracksInPadsOpt->SetToolTip( _("Delete tracks that have both start and end positions inside of a pad") ); + + bSizerUpper->Add( m_deleteTracksInPadsOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 ); + + bSizerMain->Add( bSizerUpper, 0, wxEXPAND|wxALL, 5 ); - + wxBoxSizer* bLowerSizer; bLowerSizer = new wxBoxSizer( wxVERTICAL ); - - bLowerSizer->SetMinSize( wxSize( 660,250 ) ); + + bLowerSizer->SetMinSize( wxSize( 660,250 ) ); staticChangesLabel = new wxStaticText( this, wxID_ANY, _("Changes To Be Applied:"), wxDefaultPosition, wxDefaultSize, 0 ); staticChangesLabel->Wrap( -1 ); bLowerSizer->Add( staticChangesLabel, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_ItemsListBox = new DRCLISTBOX( this, ID_CLEANUP_ITEMS_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); + + m_ItemsListBox = new DRCLISTBOX( this, ID_CLEANUP_ITEMS_LIST, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); bLowerSizer->Add( m_ItemsListBox, 1, wxEXPAND | wxALL, 5 ); - - + + bSizerMain->Add( bLowerSizer, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - + m_sdbSizer = new wxStdDialogButtonSizer(); m_sdbSizerOK = new wxButton( this, wxID_OK ); m_sdbSizer->AddButton( m_sdbSizerOK ); m_sdbSizerCancel = new wxButton( this, wxID_CANCEL ); m_sdbSizer->AddButton( m_sdbSizerCancel ); m_sdbSizer->Realize(); - + bSizerMain->Add( m_sdbSizer, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 ); - - + + this->SetSizer( bSizerMain ); this->Layout(); bSizerMain->Fit( this ); - + this->Centre( wxBOTH ); - + // Connect Events m_cleanShortCircuitOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); m_cleanViasOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); m_mergeSegmOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); m_deleteUnconnectedOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); + m_deleteTracksInPadsOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); m_ItemsListBox->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnLeftDClickItem ), NULL, this ); m_ItemsListBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnSelectItem ), NULL, this ); m_ItemsListBox->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnRightUpItem ), NULL, this ); @@ -91,8 +97,9 @@ DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::~DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE() m_cleanViasOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); m_mergeSegmOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); m_deleteUnconnectedOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); + m_deleteTracksInPadsOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnCheckBox ), NULL, this ); m_ItemsListBox->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnLeftDClickItem ), NULL, this ); m_ItemsListBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnSelectItem ), NULL, this ); m_ItemsListBox->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE::OnRightUpItem ), NULL, this ); - + } diff --git a/pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.fbp b/pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.fbp index fd24beda18..e13f14df6d 100644 --- a/pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.fbp +++ b/pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.fbp @@ -1,6 +1,6 @@ - + C++ @@ -14,6 +14,8 @@ dialog_cleanup_tracks_and_vias_base 1000 none + + 1 dialog_cleanup_tracks_and_vias @@ -24,6 +26,7 @@ 1 1 UI + 0 0 0 @@ -52,61 +55,25 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + bSizerMain wxVERTICAL none - + 5 wxEXPAND|wxALL 0 - + bSizerUpper wxVERTICAL none - + 5 wxALL 0 - + 1 1 1 @@ -164,37 +131,14 @@ - OnCheckBox - - - - - - - - - - - - - - - - - - - - - - - + 5 wxBOTTOM|wxLEFT|wxRIGHT 0 - + 1 1 1 @@ -252,37 +196,14 @@ - OnCheckBox - - - - - - - - - - - - - - - - - - - - - - - + 5 wxBOTTOM|wxLEFT|wxRIGHT 0 - + 1 1 1 @@ -340,37 +261,14 @@ - OnCheckBox - - - - - - - - - - - - - - - - - - - - - - - + 5 wxBOTTOM|wxLEFT|wxRIGHT 0 - + 1 1 1 @@ -428,48 +326,90 @@ - OnCheckBox - - - - - - - - - - - - - - - - - - - - - - + + + + 5 + wxBOTTOM|wxLEFT|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Delete Tracks in Pads + + 0 + + + 0 + + 1 + m_deleteTracksInPadsOpt + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + Delete tracks that have both start and end positions inside of a pad + + wxFILTER_NONE + wxDefaultValidator + + + + + OnCheckBox - + 5 wxEXPAND|wxRIGHT|wxLEFT 1 - + 660,250 bLowerSizer wxVERTICAL none - + 5 wxTOP|wxRIGHT|wxLEFT 0 - + 1 1 1 @@ -498,6 +438,7 @@ 0 wxID_ANY Changes To Be Applied: + 0 0 @@ -523,36 +464,13 @@ -1 - - - - - - - - - - - - - - - - - - - - - - - - + 5 wxEXPAND | wxALL 1 - + 1 1 1 @@ -609,40 +527,18 @@ - - - - - - - OnLeftDClickItem - - OnSelectItem - - - - - - - - - - OnRightUpItem - - - - + 5 wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT 0 - + 0 1 0 @@ -654,14 +550,6 @@ m_sdbSizer protected - - - - - - - - diff --git a/pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.h b/pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.h index 19dc21d1b9..84f6222dd4 100644 --- a/pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.h +++ b/pcbnew/dialogs/dialog_cleanup_tracks_and_vias_base.h @@ -1,12 +1,11 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Dec 30 2017) +// C++ code generated with wxFormBuilder (version Apr 23 2019) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// -#ifndef __DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE_H__ -#define __DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE_H__ +#pragma once #include #include @@ -36,30 +35,30 @@ class DRCLISTBOX; class DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE : public DIALOG_SHIM { private: - + protected: wxCheckBox* m_cleanShortCircuitOpt; wxCheckBox* m_cleanViasOpt; wxCheckBox* m_mergeSegmOpt; wxCheckBox* m_deleteUnconnectedOpt; + wxCheckBox* m_deleteTracksInPadsOpt; wxStaticText* staticChangesLabel; wxStdDialogButtonSizer* m_sdbSizer; wxButton* m_sdbSizerOK; wxButton* m_sdbSizerCancel; - + // Virtual event handlers, overide them in your derived class virtual void OnCheckBox( wxCommandEvent& event ) { event.Skip(); } virtual void OnLeftDClickItem( wxMouseEvent& event ) { event.Skip(); } virtual void OnSelectItem( wxCommandEvent& event ) { event.Skip(); } virtual void OnRightUpItem( wxMouseEvent& event ) { event.Skip(); } - - + + public: DRCLISTBOX* m_ItemsListBox; - - DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Cleanup Tracks and Vias"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + + DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Cleanup Tracks and Vias"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE(); - + }; -#endif //__DIALOG_CLEANUP_TRACKS_AND_VIAS_BASE_H__ diff --git a/pcbnew/drc.h b/pcbnew/drc.h index 7798269b78..3f7a999c42 100644 --- a/pcbnew/drc.h +++ b/pcbnew/drc.h @@ -112,6 +112,7 @@ #define DRCE_DANGLING_TRACK 62 #define DRCE_DANGLING_VIA 63 #define DRCE_ZERO_LENGTH_TRACK 64 +#define DRCE_TRACK_IN_PAD 65 class PCB_EDIT_FRAME; diff --git a/pcbnew/drc_item.cpp b/pcbnew/drc_item.cpp index 6467adb3ac..d25017cf34 100644 --- a/pcbnew/drc_item.cpp +++ b/pcbnew/drc_item.cpp @@ -164,6 +164,8 @@ wxString DRC_ITEM::GetErrorText() const return wxString( _( "Remove dangling via" ) ); case DRCE_ZERO_LENGTH_TRACK: return wxString( _( "Remove zero-length track" ) ); + case DRCE_TRACK_IN_PAD: + return wxString( _( "Remove track inside pad" ) ); default: return wxString::Format( _( "Unknown DRC error code %d" ), m_ErrorCode ); diff --git a/pcbnew/netinfo.h b/pcbnew/netinfo.h index 9729a252e7..25b5250491 100644 --- a/pcbnew/netinfo.h +++ b/pcbnew/netinfo.h @@ -568,13 +568,4 @@ private: int m_newNetCode; ///< possible value for new net code assignment }; - -/***********************************************************/ -/* Description of a trace point for monitoring connections */ -/***********************************************************/ -#define START_ON_PAD 0x10 -#define END_ON_PAD 0x20 -#define START_ON_TRACK 0x40 -#define END_ON_TRACK 0x80 - #endif // CLASS_NETINFO_ diff --git a/pcbnew/tracks_cleaner.cpp b/pcbnew/tracks_cleaner.cpp index d6e5488140..5018f4ae86 100644 --- a/pcbnew/tracks_cleaner.cpp +++ b/pcbnew/tracks_cleaner.cpp @@ -66,44 +66,14 @@ TRACKS_CLEANER::TRACKS_CLEANER( EDA_UNITS_T aUnits, BOARD* aPcb, BOARD_COMMIT& a } -void TRACKS_CLEANER::buildTrackConnectionInfo() -{ - auto connectivity = m_brd->GetConnectivity(); - - connectivity->Build(m_brd); - - // clear flags and variables used in cleanup - for( auto track : m_brd->Tracks() ) - { - track->SetState( START_ON_PAD | END_ON_PAD | BUSY, false ); - } - - for( auto track : m_brd->Tracks() ) - { - // Mark track if connected to pads - for( auto pad : connectivity->GetConnectedPads( track ) ) - { - if( pad->HitTest( track->GetStart() ) ) - track->SetState( START_ON_PAD, true ); - - if( pad->HitTest( track->GetEnd() ) ) - track->SetState( END_ON_PAD, true ); - } - } -} - - /* Main cleaning function. * Delete * - Redundant points on tracks (merge aligned segments) * - vias on pad * - null length segments */ -bool TRACKS_CLEANER::CleanupBoard( bool aDryRun, DRC_LIST* aItemsList, - bool aRemoveMisConnected, - bool aCleanVias, - bool aMergeSegments, - bool aDeleteUnconnected ) +bool TRACKS_CLEANER::CleanupBoard( bool aDryRun, DRC_LIST* aItemsList, bool aRemoveMisConnected, + bool aCleanVias, bool aMergeSegments, bool aDeleteUnconnected, bool aDeleteTracksinPad ) { m_dryRun = aDryRun; m_itemsList = aItemsList; @@ -120,11 +90,12 @@ bool TRACKS_CLEANER::CleanupBoard( bool aDryRun, DRC_LIST* aItemsList, else if( aRemoveMisConnected ) modified |= deleteNullSegments( m_brd->Tracks() ); - buildTrackConnectionInfo(); - if( aRemoveMisConnected ) modified |= removeBadTrackSegments(); + if( aDeleteTracksinPad ) + modified |= deleteTracksInPads(); + // Delete dangling tracks if( aDeleteUnconnected ) { @@ -160,9 +131,8 @@ bool TRACKS_CLEANER::removeBadTrackSegments() { if( m_itemsList ) { - m_itemsList->emplace_back( new DRC_ITEM( m_units, DRCE_SHORT, - segment, segment->GetPosition(), - nullptr, wxPoint() ) ); + m_itemsList->emplace_back( + new DRC_ITEM( m_units, DRCE_SHORT, segment, segment->GetPosition() ) ); } toRemove.insert( segment ); @@ -259,6 +229,21 @@ bool TRACKS_CLEANER::cleanupVias() } +bool TRACKS_CLEANER::testTrackHasPad( const TRACK* aTrack ) const +{ + auto connectivity = m_brd->GetConnectivity(); + + // Mark track if connected to pads + for( auto pad : connectivity->GetConnectedPads( aTrack ) ) + { + if( pad->HitTest( aTrack->GetStart() ) || pad->HitTest( aTrack->GetEnd() ) ) + return true; + } + + return false; +} + + bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK* aTrack ) { auto connectivity = m_brd->GetConnectivity(); @@ -288,10 +273,6 @@ bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK* aTrack ) } -/* Delete dangling tracks - * Vias: - * If a via is only connected to a dangling track, it also will be removed - */ bool TRACKS_CLEANER::deleteDanglingTracks() { bool item_erased = false; @@ -299,7 +280,6 @@ bool TRACKS_CLEANER::deleteDanglingTracks() do // Iterate when at least one track is deleted { - buildTrackConnectionInfo(); item_erased = false; for( auto track_it = m_brd->Tracks().begin(); track_it != m_brd->Tracks().end(); @@ -308,15 +288,14 @@ bool TRACKS_CLEANER::deleteDanglingTracks() auto track = *track_it; bool flag_erase = false; // Start without a good reason to erase it + if( track->Type() != PCB_TRACE_T ) + continue; + /* if a track endpoint is not connected to a pad, test if * the endpoint is connected to another track or to a zone. - * For via test, an enhancement could be to test if - * connected to 2 items on different layers. Currently - * a via must be connected to 2 items, that can be on the - * same layer */ + */ - // Check if there is nothing attached on the start - if( !( track->GetState( START_ON_PAD | END_ON_PAD ) ) ) + if( !testTrackHasPad( track ) ) flag_erase |= testTrackEndpointDangling( track ); if( flag_erase ) @@ -324,9 +303,8 @@ bool TRACKS_CLEANER::deleteDanglingTracks() if( m_itemsList ) { int code = track->IsTrack() ? DRCE_DANGLING_TRACK : DRCE_DANGLING_VIA; - m_itemsList->emplace_back( new DRC_ITEM( m_units, code, - track, track->GetPosition(), - nullptr, wxPoint() ) ); + m_itemsList->emplace_back( + new DRC_ITEM( m_units, code, track, track->GetPosition() ) ); } if( !m_dryRun ) @@ -359,9 +337,8 @@ bool TRACKS_CLEANER::deleteNullSegments( TRACKS& aTracks ) { if( m_itemsList ) { - m_itemsList->emplace_back( new DRC_ITEM( m_units, DRCE_ZERO_LENGTH_TRACK, - segment, segment->GetPosition(), - nullptr, wxPoint() ) ); + m_itemsList->emplace_back( new DRC_ITEM( + m_units, DRCE_ZERO_LENGTH_TRACK, segment, segment->GetPosition() ) ); } toRemove.insert( segment ); @@ -372,6 +349,35 @@ bool TRACKS_CLEANER::deleteNullSegments( TRACKS& aTracks ) } +bool TRACKS_CLEANER::deleteTracksInPads() +{ + std::set toRemove; + + // Delete tracks that start and end on the same pad + auto connectivity = m_brd->GetConnectivity(); + + for( auto track : m_brd->Tracks() ) + { + // Mark track if connected to pads + for( auto pad : connectivity->GetConnectedPads( track ) ) + { + if( pad->HitTest( track->GetStart() ) && pad->HitTest( track->GetEnd() ) ) + { + if( m_itemsList ) + { + m_itemsList->emplace_back( new DRC_ITEM( + m_units, DRCE_TRACK_IN_PAD, track, track->GetPosition() ) ); + } + + toRemove.insert( track ); + } + } + } + + return removeItems( toRemove ); +} + + // Delete null length segments, and intermediate points .. bool TRACKS_CLEANER::cleanupSegments() { @@ -380,8 +386,6 @@ bool TRACKS_CLEANER::cleanupSegments() // Easy things first modified |= deleteNullSegments( m_brd->Tracks() ); - buildTrackConnectionInfo(); - std::set toRemove; for( auto it = m_brd->Tracks().begin(); it != m_brd->Tracks().end(); it++ ) @@ -423,9 +427,8 @@ bool TRACKS_CLEANER::cleanupSegments() { auto segment = *track_it; auto connectivity = m_brd->GetConnectivity(); - auto clusters = connectivity->GetConnectivityAlgo()->GetClusters(); - auto& entry = m_brd->GetConnectivity()->GetConnectivityAlgo()->ItemEntry( segment ); + auto& entry = connectivity->GetConnectivityAlgo()->ItemEntry( segment ); for( auto citem : entry.GetItems() ) { @@ -488,6 +491,13 @@ bool TRACKS_CLEANER::mergeCollinearSegments( TRACK* aSeg1, TRACK* aSeg2 ) } connectivity->Update( aSeg1 ); + + // Clear the status flags here after update. + for( auto pad : connectivity->GetConnectedPads( aSeg1 ) ) + { + aSeg1->SetState( BEGIN_ONPAD, pad->HitTest( aSeg1->GetStart() ) ); + aSeg1->SetState( END_ONPAD, pad->HitTest( aSeg1->GetEnd() ) ); + } } diff --git a/pcbnew/tracks_cleaner.h b/pcbnew/tracks_cleaner.h index 6baa3678e5..8f7909c9be 100644 --- a/pcbnew/tracks_cleaner.h +++ b/pcbnew/tracks_cleaner.h @@ -43,11 +43,12 @@ public: * @param aRemoveMisConnected = true to remove segments connecting 2 different nets * @param aMergeSegments = true to merge collinear segmenst and remove 0 len segm * @param aDeleteUnconnected = true to remove dangling tracks + * @param aDeleteTracksinPad = true to remove tracks fully inside pads * (short circuits) */ - bool CleanupBoard( bool aDryRun, DRC_LIST* aItemsList, - bool aCleanVias, bool aRemoveMisConnected, - bool aMergeSegments, bool aDeleteUnconnected ); + bool CleanupBoard( bool aDryRun, DRC_LIST* aItemsList, bool aCleanVias, + bool aRemoveMisConnected, bool aMergeSegments, bool aDeleteUnconnected, + bool aDeleteTracksinPad ); private: /* finds and remove all track segments which are connected to more than one net. @@ -55,6 +56,13 @@ private: */ bool removeBadTrackSegments(); + /** + * Checks whether the track is connected to a pad + * @param aTrack pointer to the track + * @return true if the track has a pad + */ + bool testTrackHasPad( const TRACK* aTrack ) const; + /** * Removes redundant vias like vias at same location * or on pad through @@ -66,6 +74,11 @@ private: */ bool deleteDanglingTracks(); + /** + * Removes tracks that are fully inside pads + */ + bool deleteTracksInPads(); + /// Delete null length track segments bool deleteNullSegments( TRACKS& aTracks );