From 888cbf8e7ab64b460bfca650272ac9f743cd7723 Mon Sep 17 00:00:00 2001 From: Jeff Young <jeff@rokeby.ie> Date: Wed, 26 Feb 2025 10:55:19 +0000 Subject: [PATCH] Don't use connectivity system for Track & Via Properties dialog. It will propagate through zones, and since we haven't yet done a refill it will pick up a bunch of false stuff any time the track was widened more than the clearance. Fixes https://gitlab.com/kicad/code/kicad/-/issues/20084 --- .../dialogs/dialog_track_via_properties.cpp | 138 +++++++++++------- pcbnew/dialogs/dialog_track_via_properties.h | 1 + 2 files changed, 83 insertions(+), 56 deletions(-) diff --git a/pcbnew/dialogs/dialog_track_via_properties.cpp b/pcbnew/dialogs/dialog_track_via_properties.cpp index bc5a5a2d20..b662ba90b4 100644 --- a/pcbnew/dialogs/dialog_track_via_properties.cpp +++ b/pcbnew/dialogs/dialog_track_via_properties.cpp @@ -537,6 +537,30 @@ void DIALOG_TRACK_VIA_PROPERTIES::onUnitsChanged( wxCommandEvent& aEvent ) } +bool DIALOG_TRACK_VIA_PROPERTIES::confirmShortingNets( int aNet, const std::set<int>& shortingNets ) +{ + wxString msg; + + if( shortingNets.size() == 1 ) + { + msg.Printf( _( "Applying these changes will short net %s with %s." ), + m_netSelector->GetValue(), + m_frame->GetBoard()->FindNet( *shortingNets.begin() )->GetNetname() ); + } + else + { + msg.Printf( _( "Applying these changes will short net %s with other nets." ), + m_netSelector->GetValue() ); + } + + KIDIALOG dlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING ); + dlg.SetOKCancelLabels( _( "Apply Anyway" ), _( "Cancel Changes" ) ); + dlg.DoNotShowCheckbox( __FILE__, __LINE__ ); + + return dlg.ShowModal() == wxID_OK; +} + + bool DIALOG_TRACK_VIA_PROPERTIES::confirmPadChange( const std::set<PAD*>& changingPads ) { wxString msg; @@ -577,12 +601,12 @@ bool DIALOG_TRACK_VIA_PROPERTIES::confirmPadChange( const std::set<PAD*>& changi bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow() { - std::vector<PCB_TRACK*> tracks; + std::vector<PCB_TRACK*> selected_tracks; for( EDA_ITEM* item : m_items ) { if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item ) ) - tracks.push_back( track ); + selected_tracks.push_back( track ); } // Check for malformed data ONLY; design rules and constraints are the business of DRC. @@ -636,7 +660,7 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow() bool changeLock = m_lockedCbox->Get3StateValue() != wxCHK_UNDETERMINED; bool setLock = m_lockedCbox->Get3StateValue() == wxCHK_CHECKED; - for( PCB_TRACK* track : tracks ) + for( PCB_TRACK* track : selected_tracks ) { commit.Modify( track ); @@ -809,74 +833,76 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow() } } - commit.Push( _( "Edit Track/Via Properties" ) ); - - // Pushing the commit will have updated the connectivity so we can now test to see if we - // need to update any pad nets. - - auto connectivity = m_frame->GetBoard()->GetConnectivity(); + std::set<int> shortingNets; int newNetCode = m_netSelector->GetSelectedNetcode(); - bool updateNets = false; std::set<PAD*> changingPads; - if ( !m_netSelector->IsIndeterminate() ) - { - updateNets = true; - - for( PCB_TRACK* track : tracks ) - { - BOARD_CONNECTED_ITEM* boardItem = static_cast<BOARD_CONNECTED_ITEM*>( track ); - auto connectedItems = connectivity->GetConnectedItems( boardItem, - { PCB_TRACE_T, PCB_ARC_T, PCB_PAD_T, PCB_VIA_T, PCB_FOOTPRINT_T }, true ); - - for ( BOARD_CONNECTED_ITEM* citem : connectedItems ) + // Do NOT use the connectivity code here. It will propagate through zones, and we haven't + // refilled those yet so it's going to pick up a whole bunch of other nets any time the track + // width was increased. + auto collide = + [&]( BOARD_CONNECTED_ITEM* a, BOARD_CONNECTED_ITEM* b ) { - if( citem->Type() == PCB_PAD_T ) + for( PCB_LAYER_ID layer : LSET( a->GetLayerSet() & b->GetLayerSet() ).Seq() ) { - PAD* pad = static_cast<PAD*>( citem ); + if( a->GetEffectiveShape( layer )->Collide( b->GetEffectiveShape( layer ).get() ) ) + return true; + } - if( pad->GetNetCode() != newNetCode ) + return false; + }; + + for( PCB_TRACK* track : selected_tracks ) + { + for( PCB_TRACK* other : m_frame->GetBoard()->Tracks() ) + { + if( other->GetNetCode() == track->GetNetCode() || other->GetNetCode() == newNetCode ) + continue; + + if( collide( track, other ) ) + shortingNets.insert( other->GetNetCode() ); + } + + for( FOOTPRINT* footprint : m_frame->GetBoard()->Footprints() ) + { + for( PAD* pad : footprint->Pads() ) + { + if( pad->GetNetCode() == newNetCode ) + continue; + + if( collide( track, pad ) ) + { + if( pad->GetNetCode() == track->GetNetCode() ) changingPads.insert( pad ); + else + shortingNets.insert( pad->GetNetCode() ); } } } } - if( changingPads.size() && !confirmPadChange( changingPads ) ) - updateNets = false; - - if( updateNets ) + if( shortingNets.size() && !confirmShortingNets( newNetCode, shortingNets ) ) { - for( EDA_ITEM* item : m_items ) - { - commit.Modify( item ); - - switch( item->Type() ) - { - case PCB_TRACE_T: - case PCB_ARC_T: - static_cast<PCB_TRACK*>( item )->SetNetCode( newNetCode ); - break; - - case PCB_VIA_T: - static_cast<PCB_VIA*>( item )->SetNetCode( newNetCode ); - break; - - default: - wxASSERT( false ); - break; - } - } - - for( PAD* pad : changingPads ) - { - commit.Modify( pad ); - pad->SetNetCode( newNetCode ); - } - - commit.Push( _( "Update Nets" ) ); + commit.Revert(); + return true; } + if( !m_netSelector->IsIndeterminate() ) + { + if( changingPads.empty() || confirmPadChange( changingPads ) ) + { + for( PCB_TRACK* track : selected_tracks ) + track->SetNetCode( newNetCode ); + + for( PAD* pad : changingPads ) + { + commit.Modify( pad ); + pad->SetNetCode( newNetCode ); + } + } + } + + commit.Push( _( "Edit Track/Via Properties" ) ); return true; } diff --git a/pcbnew/dialogs/dialog_track_via_properties.h b/pcbnew/dialogs/dialog_track_via_properties.h index 7f186b199c..9d1b69590e 100644 --- a/pcbnew/dialogs/dialog_track_via_properties.h +++ b/pcbnew/dialogs/dialog_track_via_properties.h @@ -58,6 +58,7 @@ private: void onUnitsChanged( wxCommandEvent& aEvent ); void onTeardropsUpdateUi( wxUpdateUIEvent& event ) override; + bool confirmShortingNets( int aNet, const std::set<int>& shortingNets ); bool confirmPadChange( const std::set<PAD*>& connectedPads ); int getLayerDepth();