From 231fa952fb655a0520d848ae368ebd4882cdcd43 Mon Sep 17 00:00:00 2001 From: JamesJCode <13408010-JamesJCode@users.noreply.gitlab.com> Date: Sun, 3 Nov 2024 21:43:55 +0000 Subject: [PATCH] Add auto-generation of placement rules areas from component classes --- ...ialog_multichannel_generate_rule_areas.cpp | 136 +++++++++++++++--- .../dialog_multichannel_generate_rule_areas.h | 4 + ..._multichannel_generate_rule_areas_base.cpp | 30 +--- ..._multichannel_generate_rule_areas_base.fbp | 41 +----- ...og_multichannel_generate_rule_areas_base.h | 8 +- pcbnew/tools/multichannel_tool.cpp | 110 +++++++++++--- pcbnew/tools/multichannel_tool.h | 11 +- qa/tests/pcbnew/test_multichannel.cpp | 2 +- 8 files changed, 232 insertions(+), 110 deletions(-) diff --git a/pcbnew/dialogs/dialog_multichannel_generate_rule_areas.cpp b/pcbnew/dialogs/dialog_multichannel_generate_rule_areas.cpp index d07a8de2d2..72d07756aa 100644 --- a/pcbnew/dialogs/dialog_multichannel_generate_rule_areas.cpp +++ b/pcbnew/dialogs/dialog_multichannel_generate_rule_areas.cpp @@ -34,34 +34,119 @@ DIALOG_MULTICHANNEL_GENERATE_RULE_AREAS::DIALOG_MULTICHANNEL_GENERATE_RULE_AREAS DIALOG_MULTICHANNEL_GENERATE_RULE_AREAS_BASE( aFrame ), m_parentTool( aParentTool ) { - int i = 0; + // Generate the sheet source grid + m_sheetGrid = new WX_GRID( m_sourceNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_sheetGrid->CreateGrid( 0, 3 ); + m_sheetGrid->EnableEditing( false ); + m_sheetGrid->EnableGridLines( true ); + m_sheetGrid->EnableDragGridSize( false ); + m_sheetGrid->SetMargins( 0, 0 ); + m_sheetGrid->SetColSize( 0, 100 ); + m_sheetGrid->SetColSize( 1, 300 ); + m_sheetGrid->SetColSize( 2, 100 ); + m_sheetGrid->AutoSizeColumns(); + m_sheetGrid->EnableDragColMove( true ); + m_sheetGrid->EnableDragColSize( true ); + m_sheetGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); + m_sheetGrid->AutoSizeRows(); + m_sheetGrid->EnableDragRowSize( true ); + m_sheetGrid->SetRowLabelSize( wxGRID_AUTOSIZE ); + m_sheetGrid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); + m_sheetGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); + m_sheetGrid->EnableEditing( true ); + m_sheetGrid->HideRowLabels(); + m_sheetGrid->SetColLabelValue( 0, wxT( "Generate" ) ); + m_sheetGrid->SetColLabelValue( 1, wxT( "Sheet Path" ) ); + m_sheetGrid->SetColLabelValue( 2, wxT( "Sheet Name" ) ); + m_sheetGrid->AutoSizeColumn( 1 ); + m_sourceNotebook->AddPage( m_sheetGrid, _( "Sheets" ) ); + + // Generate the component class source grid + m_componentClassGrid = + new WX_GRID( m_sourceNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_componentClassGrid->CreateGrid( 0, 2 ); + m_componentClassGrid->EnableEditing( false ); + m_componentClassGrid->EnableGridLines( true ); + m_componentClassGrid->EnableDragGridSize( false ); + m_componentClassGrid->SetMargins( 0, 0 ); + m_componentClassGrid->SetColSize( 0, 100 ); + m_componentClassGrid->SetColSize( 1, 300 ); + m_componentClassGrid->AutoSizeColumns(); + m_componentClassGrid->EnableDragColMove( true ); + m_componentClassGrid->EnableDragColSize( true ); + m_componentClassGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); + m_componentClassGrid->AutoSizeRows(); + m_componentClassGrid->EnableDragRowSize( true ); + m_componentClassGrid->SetRowLabelSize( wxGRID_AUTOSIZE ); + m_componentClassGrid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); + m_componentClassGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); + m_componentClassGrid->EnableEditing( true ); + m_componentClassGrid->HideRowLabels(); + m_componentClassGrid->SetColLabelValue( 0, wxT( "Generate" ) ); + m_componentClassGrid->SetColLabelValue( 1, wxT( "Component Class" ) ); + m_componentClassGrid->AutoSizeColumn( 1 ); + m_sourceNotebook->AddPage( m_componentClassGrid, _( "Component Classes" ) ); RULE_AREAS_DATA* raData = m_parentTool->GetData(); - m_sheetsGrid->EnableEditing( true ); - m_sheetsGrid->HideRowLabels(); - m_sheetsGrid->SetColLabelValue( 0, wxT("Generate") ); - m_sheetsGrid->SetColLabelValue( 1, wxT("Sheet Path") ); - m_sheetsGrid->SetColLabelValue( 2, wxT("Sheet Name") ); - m_sheetsGrid->AppendRows( raData->m_areas.size() - 1 ); - m_sheetsGrid->AutoSizeColumn( 1 ); + int sheetRowIdx = 0; + int componentClassRowIdx = 0; - for( RULE_AREA& sheet : raData->m_areas ) + for( RULE_AREA& ruleArea : raData->m_areas ) { - m_sheetsGrid->SetCellValue( i, 1, sheet.m_sheetPath ); - m_sheetsGrid->SetCellValue( i, 2, sheet.m_sheetName ); - m_sheetsGrid->SetCellRenderer( i, 0, new wxGridCellBoolRenderer ); - m_sheetsGrid->SetCellEditor( i, 0, new wxGridCellBoolEditor ); - m_sheetsGrid->SetCellValue( i, 0, sheet.m_generateEnabled ? wxT("1") : wxT( "" ) ); - i++; + if( ruleArea.m_sourceType == RULE_AREA_PLACEMENT_SOURCE_TYPE::SHEETNAME ) + sheetRowIdx++; + else + componentClassRowIdx++; } - m_sheetsGrid->SetMaxSize( wxSize( -1, 800 ) ); - m_sheetsGrid->Fit(); + if( sheetRowIdx > 0 ) + m_sheetGrid->AppendRows( sheetRowIdx ); + + if( componentClassRowIdx > 0 ) + m_componentClassGrid->AppendRows( componentClassRowIdx ); + + sheetRowIdx = 0; + componentClassRowIdx = 0; + + for( RULE_AREA& ruleArea : raData->m_areas ) + { + if( ruleArea.m_sourceType == RULE_AREA_PLACEMENT_SOURCE_TYPE::SHEETNAME ) + { + m_sheetGrid->SetCellValue( sheetRowIdx, 1, ruleArea.m_sheetPath ); + m_sheetGrid->SetCellValue( sheetRowIdx, 2, ruleArea.m_sheetName ); + m_sheetGrid->SetCellRenderer( sheetRowIdx, 0, new wxGridCellBoolRenderer ); + m_sheetGrid->SetCellEditor( sheetRowIdx, 0, new wxGridCellBoolEditor ); + m_sheetGrid->SetCellValue( sheetRowIdx, 0, + ruleArea.m_generateEnabled ? wxT( "1" ) : wxT( "" ) ); + sheetRowIdx++; + } + else + { + m_componentClassGrid->SetCellValue( componentClassRowIdx, 1, + ruleArea.m_componentClass ); + m_componentClassGrid->SetCellRenderer( componentClassRowIdx, 0, + new wxGridCellBoolRenderer ); + m_componentClassGrid->SetCellEditor( componentClassRowIdx, 0, + new wxGridCellBoolEditor ); + m_componentClassGrid->SetCellValue( + componentClassRowIdx, 0, ruleArea.m_generateEnabled ? wxT( "1" ) : wxT( "" ) ); + componentClassRowIdx++; + } + } + + m_sheetGrid->SetMaxSize( wxSize( -1, 800 ) ); + m_sheetGrid->Fit(); + m_componentClassGrid->SetMaxSize( wxSize( -1, 800 ) ); + m_componentClassGrid->Fit(); m_cbGroupItems->SetValue( raData->m_options.m_groupItems ); m_cbReplaceExisting->SetValue( raData->m_replaceExisting ); Layout(); + + if( m_sheetGrid->GetNumberRows() == 1 && m_componentClassGrid->GetNumberRows() > 0 ) + m_sourceNotebook->SetSelection( 1 ); + SetupStandardButtons(); finishDialogSettings(); } @@ -71,9 +156,24 @@ bool DIALOG_MULTICHANNEL_GENERATE_RULE_AREAS::TransferDataFromWindow() { RULE_AREAS_DATA* raData = m_parentTool->GetData(); + int sheetRowIdx = 0; + int componentClassRowIdx = 0; + for( size_t i = 0; i < raData->m_areas.size(); i++ ) { - wxString enabled = m_sheetsGrid->GetCellValue( i, 0 ); + wxString enabled; + + if( raData->m_areas[i].m_sourceType == RULE_AREA_PLACEMENT_SOURCE_TYPE::SHEETNAME ) + { + enabled = m_sheetGrid->GetCellValue( sheetRowIdx, 0 ); + sheetRowIdx++; + } + else + { + enabled = m_componentClassGrid->GetCellValue( componentClassRowIdx, 0 ); + componentClassRowIdx++; + } + raData->m_areas[i].m_generateEnabled = ( !enabled.CompareTo( wxT( "1" ) ) ) ? true : false; } diff --git a/pcbnew/dialogs/dialog_multichannel_generate_rule_areas.h b/pcbnew/dialogs/dialog_multichannel_generate_rule_areas.h index 3c6ce9e785..9357e51272 100644 --- a/pcbnew/dialogs/dialog_multichannel_generate_rule_areas.h +++ b/pcbnew/dialogs/dialog_multichannel_generate_rule_areas.h @@ -26,6 +26,7 @@ #include #include +#include #include @@ -46,6 +47,9 @@ public: private: MULTICHANNEL_TOOL* m_parentTool; + + wxGrid* m_sheetGrid; + wxGrid* m_componentClassGrid; }; #endif diff --git a/pcbnew/dialogs/dialog_multichannel_generate_rule_areas_base.cpp b/pcbnew/dialogs/dialog_multichannel_generate_rule_areas_base.cpp index 9eb0bc1a09..70f6cd240f 100644 --- a/pcbnew/dialogs/dialog_multichannel_generate_rule_areas_base.cpp +++ b/pcbnew/dialogs/dialog_multichannel_generate_rule_areas_base.cpp @@ -22,35 +22,9 @@ DIALOG_MULTICHANNEL_GENERATE_RULE_AREAS_BASE::DIALOG_MULTICHANNEL_GENERATE_RULE_ fgSizer3->SetFlexibleDirection( wxBOTH ); fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - m_sheetsGrid = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_sourceNotebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); - // Grid - m_sheetsGrid->CreateGrid( 1, 3 ); - m_sheetsGrid->EnableEditing( false ); - m_sheetsGrid->EnableGridLines( true ); - m_sheetsGrid->EnableDragGridSize( false ); - m_sheetsGrid->SetMargins( 0, 0 ); - - // Columns - m_sheetsGrid->SetColSize( 0, 100 ); - m_sheetsGrid->SetColSize( 1, 300 ); - m_sheetsGrid->SetColSize( 2, 100 ); - m_sheetsGrid->AutoSizeColumns(); - m_sheetsGrid->EnableDragColMove( true ); - m_sheetsGrid->EnableDragColSize( true ); - m_sheetsGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); - - // Rows - m_sheetsGrid->AutoSizeRows(); - m_sheetsGrid->EnableDragRowSize( true ); - m_sheetsGrid->SetRowLabelSize( wxGRID_AUTOSIZE ); - m_sheetsGrid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); - - // Label Appearance - - // Cell Defaults - m_sheetsGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); - fgSizer3->Add( m_sheetsGrid, 1, wxALL|wxEXPAND, 5 ); + fgSizer3->Add( m_sourceNotebook, 1, wxEXPAND | wxALL, 5 ); wxBoxSizer* bSizer13; bSizer13 = new wxBoxSizer( wxVERTICAL ); diff --git a/pcbnew/dialogs/dialog_multichannel_generate_rule_areas_base.fbp b/pcbnew/dialogs/dialog_multichannel_generate_rule_areas_base.fbp index b48327d3ea..10c3977bc8 100644 --- a/pcbnew/dialogs/dialog_multichannel_generate_rule_areas_base.fbp +++ b/pcbnew/dialogs/dialog_multichannel_generate_rule_areas_base.fbp @@ -82,11 +82,11 @@ none 3 0 - + 5 - wxALL|wxEXPAND + wxEXPAND | wxALL 1 - + 1 1 1 @@ -95,25 +95,13 @@ 0 0 - 1 - 1 + 1 - - - wxALIGN_LEFT - - wxALIGN_TOP 0 1 - wxALIGN_CENTER - - - wxALIGN_CENTER - 3 - 100,300,100 1 0 @@ -121,25 +109,13 @@ 0 Left 0 - 1 - 1 - 0 - 1 - 0 1 1 - - 1 0 0 wxID_ANY - - - - 0 - 0 0 @@ -147,7 +123,7 @@ 0 1 - m_sheetsGrid + m_sourceNotebook 1 @@ -155,14 +131,9 @@ 1 Resizable - wxALIGN_CENTER - wxGRID_AUTOSIZE - - wxALIGN_CENTER - - 1 1 + ; ; forward_declare 0 diff --git a/pcbnew/dialogs/dialog_multichannel_generate_rule_areas_base.h b/pcbnew/dialogs/dialog_multichannel_generate_rule_areas_base.h index 826fa73149..0439699a3a 100644 --- a/pcbnew/dialogs/dialog_multichannel_generate_rule_areas_base.h +++ b/pcbnew/dialogs/dialog_multichannel_generate_rule_areas_base.h @@ -11,12 +11,12 @@ #include #include #include "dialog_shim.h" +#include +#include +#include #include #include #include -#include -#include -#include #include #include #include @@ -33,7 +33,7 @@ class DIALOG_MULTICHANNEL_GENERATE_RULE_AREAS_BASE : public DIALOG_SHIM wxBoxSizer* m_GeneralBoxSizer; protected: - wxGrid* m_sheetsGrid; + wxNotebook* m_sourceNotebook; wxCheckBox* m_cbReplaceExisting; wxCheckBox* m_cbGroupItems; wxStdDialogButtonSizer* m_sdbSizerStdButtons; diff --git a/pcbnew/tools/multichannel_tool.cpp b/pcbnew/tools/multichannel_tool.cpp index 0b56faa4eb..c5298335d5 100644 --- a/pcbnew/tools/multichannel_tool.cpp +++ b/pcbnew/tools/multichannel_tool.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -127,7 +128,7 @@ bool MULTICHANNEL_TOOL::identifyComponentsInRuleArea( ZONE* aRul } -std::set MULTICHANNEL_TOOL::queryComponentsInSheet( wxString aSheetName ) +std::set MULTICHANNEL_TOOL::queryComponentsInSheet( wxString aSheetName ) const { std::set rv; if( aSheetName.EndsWith( wxT( "/" ) ) ) @@ -149,6 +150,21 @@ std::set MULTICHANNEL_TOOL::queryComponentsInSheet( wxString aSheetN } +std::set +MULTICHANNEL_TOOL::queryComponentsInComponentClass( const wxString& aComponentClassName ) const +{ + std::set rv; + + for( auto& fp : board()->Footprints() ) + { + if( fp->GetComponentClass()->ContainsClassName( aComponentClassName ) ) + rv.insert( fp ); + } + + return rv; +} + + const SHAPE_LINE_CHAIN MULTICHANNEL_TOOL::buildRAOutline( std::set& aFootprints, int aMargin ) { @@ -192,31 +208,52 @@ const SHAPE_LINE_CHAIN MULTICHANNEL_TOOL::buildRAOutline( std::set& } -void MULTICHANNEL_TOOL::QuerySheets() +void MULTICHANNEL_TOOL::QuerySheetsAndComponentClasses() { using PathAndName = std::pair; std::set uniqueSheets; + std::set uniqueComponentClasses; m_areas.m_areas.clear(); - for( FOOTPRINT* fp : board()->Footprints() ) + for( const FOOTPRINT* fp : board()->Footprints() ) { uniqueSheets.insert( PathAndName( fp->GetSheetname(), fp->GetSheetfile() ) ); + + const COMPONENT_CLASS* compClass = fp->GetComponentClass(); + + for( const COMPONENT_CLASS* singleClass : compClass->GetConstituentClasses() ) + uniqueComponentClasses.insert( singleClass->GetName() ); } for( const PathAndName& sheet : uniqueSheets ) { RULE_AREA ent; + ent.m_sourceType = RULE_AREA_PLACEMENT_SOURCE_TYPE::SHEETNAME; ent.m_generateEnabled = false; ent.m_sheetPath = sheet.first; ent.m_sheetName = sheet.second; - ent.m_sheetComponents = queryComponentsInSheet( ent.m_sheetPath ); + ent.m_components = queryComponentsInSheet( ent.m_sheetPath ); m_areas.m_areas.push_back( ent ); wxLogTrace( traceMultichannelTool, wxT("found sheet '%s' @ '%s' s %d\n"), ent.m_sheetName, ent.m_sheetPath, (int)m_areas.m_areas.size() ); } + + for( const wxString& compClass : uniqueComponentClasses ) + { + RULE_AREA ent; + + ent.m_sourceType = RULE_AREA_PLACEMENT_SOURCE_TYPE::COMPONENT_CLASS; + ent.m_generateEnabled = false; + ent.m_componentClass = compClass; + ent.m_components = queryComponentsInComponentClass( ent.m_componentClass ); + m_areas.m_areas.push_back( ent ); + + wxLogTrace( traceMultichannelTool, wxT( "found component class '%s' s %d\n" ), + ent.m_componentClass, static_cast( m_areas.m_areas.size() ) ); + } } @@ -694,13 +731,14 @@ int MULTICHANNEL_TOOL::AutogenerateRuleAreas( const TOOL_EVENT& aEvent ) { if( Pgm().IsGUI() ) { - QuerySheets(); + QuerySheetsAndComponentClasses(); if( m_areas.m_areas.size() <= 1 ) { frame()->ShowInfoBarError( _( "Cannot auto-generate any placement areas because the " - "schematic has only one or no hierarchical sheet(s)." ), - true ); + "schematic has only one or no hierarchical sheet(s) or " + "component classes." ), + true ); return 0; } @@ -727,11 +765,23 @@ int MULTICHANNEL_TOOL::AutogenerateRuleAreas( const TOOL_EVENT& aEvent ) for( auto& ra : m_areas.m_areas ) { - if( components == ra.m_sheetComponents ) + if( components == ra.m_components ) { - wxLogTrace( traceMultichannelTool, - wxT( "Placement rule area for sheet '%s' already exists as '%s'\n" ), - ra.m_sheetPath, zone->GetZoneName() ); + if( zone->GetRuleAreaPlacementSourceType() + == RULE_AREA_PLACEMENT_SOURCE_TYPE::SHEETNAME ) + { + wxLogTrace( + traceMultichannelTool, + wxT( "Placement rule area for sheet '%s' already exists as '%s'\n" ), + ra.m_sheetPath, zone->GetZoneName() ); + } + else + { + wxLogTrace( traceMultichannelTool, + wxT( "Placement rule area for component class '%s' already exists " + "as '%s'\n" ), + ra.m_componentClass, zone->GetZoneName() ); + } ra.m_oldArea = zone; ra.m_existsAlready = true; @@ -751,16 +801,23 @@ int MULTICHANNEL_TOOL::AutogenerateRuleAreas( const TOOL_EVENT& aEvent ) if( ra.m_existsAlready && !m_areas.m_replaceExisting ) continue; - auto raOutline = buildRAOutline( ra.m_sheetComponents, 100000 ); + auto raOutline = buildRAOutline( ra.m_components, 100000 ); std::unique_ptr newZone( new ZONE( board() ) ); - newZone->SetZoneName( wxString::Format( wxT( "auto-placement-area-%s" ), ra.m_sheetPath ) ); + if( ra.m_sourceType == RULE_AREA_PLACEMENT_SOURCE_TYPE::SHEETNAME ) + { + newZone->SetZoneName( + wxString::Format( wxT( "auto-placement-area-%s" ), ra.m_sheetPath ) ); + } + else + { + newZone->SetZoneName( + wxString::Format( wxT( "auto-placement-area-%s" ), ra.m_componentClass ) ); + } - wxLogTrace( traceMultichannelTool, - wxT( "Generated rule area '%s' (%d components)\n" ), - newZone->GetZoneName(), - (int) ra.m_sheetComponents.size() ); + wxLogTrace( traceMultichannelTool, wxT( "Generated rule area '%s' (%d components)\n" ), + newZone->GetZoneName(), (int) ra.m_components.size() ); newZone->SetIsRuleArea( true ); newZone->SetLayerSet( LSET::AllCuMask() ); @@ -770,8 +827,19 @@ int MULTICHANNEL_TOOL::AutogenerateRuleAreas( const TOOL_EVENT& aEvent ) newZone->SetDoNotAllowTracks( false ); newZone->SetDoNotAllowPads( false ); newZone->SetDoNotAllowFootprints( false ); - newZone->SetRuleAreaPlacementSourceType( RULE_AREA_PLACEMENT_SOURCE_TYPE::SHEETNAME ); - newZone->SetRuleAreaPlacementSource( ra.m_sheetPath ); + + if( ra.m_sourceType == RULE_AREA_PLACEMENT_SOURCE_TYPE::SHEETNAME ) + { + newZone->SetRuleAreaPlacementSourceType( RULE_AREA_PLACEMENT_SOURCE_TYPE::SHEETNAME ); + newZone->SetRuleAreaPlacementSource( ra.m_sheetPath ); + } + else + { + newZone->SetRuleAreaPlacementSourceType( + RULE_AREA_PLACEMENT_SOURCE_TYPE::COMPONENT_CLASS ); + newZone->SetRuleAreaPlacementSource( ra.m_componentClass ); + } + newZone->AddPolygon( raOutline ); newZone->SetHatchStyle( ZONE_BORDER_DISPLAY_STYLE::NO_HATCH ); @@ -804,7 +872,7 @@ int MULTICHANNEL_TOOL::AutogenerateRuleAreas( const TOOL_EVENT& aEvent ) std::unordered_set toPrune; - std::copy( ra.m_sheetComponents.begin(), ra.m_sheetComponents.end(), + std::copy( ra.m_components.begin(), ra.m_components.end(), std::inserter( toPrune, toPrune.begin() ) ); if( ra.m_existsAlready ) @@ -817,7 +885,7 @@ int MULTICHANNEL_TOOL::AutogenerateRuleAreas( const TOOL_EVENT& aEvent ) grpCommit.Add( grp ); grpCommit.Stage( ra.m_area, CHT_GROUP ); - for( auto fp : ra.m_sheetComponents ) + for( auto fp : ra.m_components ) { grpCommit.Stage( fp, CHT_GROUP ); } diff --git a/pcbnew/tools/multichannel_tool.h b/pcbnew/tools/multichannel_tool.h index 7e41b4a820..171bea9e43 100644 --- a/pcbnew/tools/multichannel_tool.h +++ b/pcbnew/tools/multichannel_tool.h @@ -35,6 +35,7 @@ #include #include #include +#include enum class REPEAT_LAYOUT_EDGE_MODE { @@ -69,15 +70,17 @@ struct RULE_AREA_COMPAT_DATA struct RULE_AREA { + RULE_AREA_PLACEMENT_SOURCE_TYPE m_sourceType = RULE_AREA_PLACEMENT_SOURCE_TYPE::SHEETNAME; ZONE* m_oldArea = nullptr; ZONE* m_area = nullptr; std::set m_raFootprints; - std::set m_sheetComponents; + std::set m_components; bool m_existsAlready = false; bool m_generateEnabled = false; wxString m_sheetPath; wxString m_sheetName; wxString m_ruleName; + wxString m_componentClass; VECTOR2I m_center; }; @@ -110,7 +113,7 @@ public: RULE_AREAS_DATA* GetData() { return &m_areas; } int AutogenerateRuleAreas( const TOOL_EVENT& aEvent ); int RepeatLayout( const TOOL_EVENT& aEvent, ZONE* aRefZone ); - void QuerySheets(); + void QuerySheetsAndComponentClasses(); void FindExistingRuleAreas(); int CheckRACompatibility( ZONE *aRefZone ); @@ -121,7 +124,9 @@ private: wxString stripComponentIndex( wxString aRef ) const; bool identifyComponentsInRuleArea( ZONE* aRuleArea, std::set& aComponents ); const SHAPE_LINE_CHAIN buildRAOutline( std::set& aFootprints, int aMargin ); - std::set queryComponentsInSheet( wxString aSheetName ); + std::set queryComponentsInSheet( wxString aSheetName ) const; + std::set + queryComponentsInComponentClass( const wxString& aComponentClassName ) const; RULE_AREA* findRAByName( const wxString& aName ); bool resolveConnectionTopology( RULE_AREA* aRefArea, RULE_AREA* aTargetArea, RULE_AREA_COMPAT_DATA& aMatches ); diff --git a/qa/tests/pcbnew/test_multichannel.cpp b/qa/tests/pcbnew/test_multichannel.cpp index ea6644ab81..197406bf33 100644 --- a/qa/tests/pcbnew/test_multichannel.cpp +++ b/qa/tests/pcbnew/test_multichannel.cpp @@ -85,7 +85,7 @@ BOOST_FIXTURE_TEST_CASE( MultichannelToolRegressions, MULTICHANNEL_TEST_FIXTURE //RULE_AREAS_DATA* raData = m_parentTool->GetData(); - mtTool->QuerySheets(); + mtTool->QuerySheetsAndComponentClasses(); auto ruleData = mtTool->GetData();