From c05cc345f3326aa6f01c21fadc5466d2ae9494fe Mon Sep 17 00:00:00 2001 From: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> Date: Sun, 9 Mar 2025 21:59:29 +0100 Subject: [PATCH] multichannel: possible fix for ghosting footprints when using grouping --- pcbnew/tools/multichannel_tool.cpp | 56 ++++++++++++++++++------------ pcbnew/tools/multichannel_tool.h | 2 ++ 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/pcbnew/tools/multichannel_tool.cpp b/pcbnew/tools/multichannel_tool.cpp index 654a5e73d0..e8561e41dc 100644 --- a/pcbnew/tools/multichannel_tool.cpp +++ b/pcbnew/tools/multichannel_tool.cpp @@ -501,12 +501,10 @@ int MULTICHANNEL_TOOL::RepeatLayout( const TOOL_EVENT& aEvent, ZONE* aRefZone ) if( !targetArea.second.m_isOk ) continue; - std::unordered_set<BOARD_ITEM*> affectedItems; - std::unordered_set<BOARD_ITEM*> groupableItems; if( !copyRuleAreaContents( targetArea.second.m_matchingComponents, &commit, m_areas.m_refRA, - targetArea.first, m_areas.m_options, affectedItems, - groupableItems ) ) + targetArea.first, m_areas.m_options, targetArea.second.m_affectedItems, + targetArea.second.m_groupableItems ) ) { auto errMsg = wxString::Format( _( "Copy Rule Area contents failed between rule areas '%s' and '%s'." ), @@ -522,26 +520,34 @@ int MULTICHANNEL_TOOL::RepeatLayout( const TOOL_EVENT& aEvent, ZONE* aRefZone ) return -1; } - - if( m_areas.m_options.m_groupItems ) - { - pruneExistingGroups( commit, affectedItems ); - - PCB_GROUP* grp = new PCB_GROUP( board() ); - - commit.Add( grp ); - - for( BOARD_ITEM* item : groupableItems ) - { - commit.Stage( item, CHT_GROUP ); - } - } - totalCopied++; } + commit.Push( _( "Repeat layout" ) ); + if( m_areas.m_options.m_groupItems ) + { + BOARD_COMMIT grpCommit( GetManager(), true ); + + for( auto& targetArea : m_areas.m_compatMap ) + { + pruneExistingGroups( grpCommit, targetArea.second.m_affectedItems ); + + PCB_GROUP* grp = new PCB_GROUP( board() ); + + grpCommit.Add( grp ); + + for( BOARD_ITEM* item : targetArea.second.m_groupableItems ) + { + grpCommit.Stage( item, CHT_GROUP ); + } + } + + grpCommit.Push( _( "Group repeated items" ) ); + } + + if( Pgm().IsGUI() ) { frame()->ShowInfoBarMsg( wxString::Format( _( "Copied to %d Rule Areas." ), totalCopied ), @@ -998,14 +1004,21 @@ bool MULTICHANNEL_TOOL::resolveConnectionTopology( RULE_AREA* aRefArea, RULE_ARE bool MULTICHANNEL_TOOL::pruneExistingGroups( COMMIT& aCommit, const std::unordered_set<BOARD_ITEM*>& aItemsToRemove ) { - for( PCB_GROUP* grp : board()->Groups() ) + std::deque<PCB_GROUP*> pending ( board()->Groups() ); + while( !pending.empty() ) { + auto grp = pending.front(); + pending.pop_front(); + std::unordered_set<BOARD_ITEM*>& grpItems = grp->GetItems(); size_t n_erased = 0; for( BOARD_ITEM* refItem : grpItems ) { - //printf("check ref %p [%s]\n", refItem, refItem->GetTypeDesc().c_str().AsChar() ); + + if( refItem->Type() == PCB_GROUP_T ) + pending.push_back( static_cast<PCB_GROUP*>(refItem) ); + for( BOARD_ITEM* testItem : aItemsToRemove ) { if( refItem->m_Uuid == testItem->m_Uuid ) @@ -1021,7 +1034,6 @@ bool MULTICHANNEL_TOOL::pruneExistingGroups( COMMIT& aCommit, aCommit.Stage( grp, CHT_REMOVE ); } - //printf("Grp %p items %d pruned %d air %d\n", grp,grpItems.size(), (int) n_erased, (int) aItemsToRemove.size() ); } return false; diff --git a/pcbnew/tools/multichannel_tool.h b/pcbnew/tools/multichannel_tool.h index a0b4b77d7a..243ead0646 100644 --- a/pcbnew/tools/multichannel_tool.h +++ b/pcbnew/tools/multichannel_tool.h @@ -68,6 +68,8 @@ struct RULE_AREA_COMPAT_DATA bool m_doCopy = false; wxString m_errorMsg; TMATCH::COMPONENT_MATCHES m_matchingComponents; + std::unordered_set<BOARD_ITEM*> m_affectedItems; + std::unordered_set<BOARD_ITEM*> m_groupableItems; }; struct RULE_AREA