Performance: don't alloc std::vector in critical areas.

For some history, see also aa2ad3b44c
This commit is contained in:
Jeff Young 2024-06-21 19:07:42 +01:00
parent b494166b10
commit c549a214c9
24 changed files with 279 additions and 207 deletions

View File

@ -92,6 +92,7 @@ bool SELECTION::Contains( EDA_ITEM* aItem ) const
/// Returns the center point of the selection area bounding box.
VECTOR2I SELECTION::GetCenter() const
{
static const std::vector<KICAD_T> textTypes = { SCH_TEXT_T, SCH_LABEL_LOCATE_ANY_T };
bool hasOnlyText = true;
// If the selection contains only texts calculate the center as the mean of all positions
@ -100,7 +101,7 @@ VECTOR2I SELECTION::GetCenter() const
for( EDA_ITEM* item : m_items )
{
if( !item->IsType( { SCH_TEXT_T, SCH_LABEL_LOCATE_ANY_T } ) )
if( !item->IsType( textTypes ) )
{
hasOnlyText = false;
break;

View File

@ -376,7 +376,7 @@ void SCH_EDIT_FRAME::DeleteJunction( SCH_COMMIT* aCommit, SCH_ITEM* aJunction )
{
SCH_LINE* line = static_cast<SCH_LINE*>( item );
if( line->IsType( { SCH_ITEM_LOCATE_WIRE_T, SCH_ITEM_LOCATE_BUS_T } )
if( ( line->IsWire() || line->IsBus() )
&& line->IsEndPoint( aJunction->GetPosition() )
&& !( line->GetEditFlags() & STRUCT_DELETED ) )
{

View File

@ -419,6 +419,9 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( SCH_COMMIT* aCommit,
}
}
static const std::vector<KICAD_T> wireLabelTypes = { SCH_LABEL_LOCATE_WIRE_T };
static const std::vector<KICAD_T> busLabelTypes = { SCH_LABEL_LOCATE_BUS_T };
switch( aItem->Type() )
{
case SCH_SYMBOL_T:
@ -508,10 +511,10 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( SCH_COMMIT* aCommit,
case SCH_GLOBAL_LABEL_T:
case SCH_HIER_LABEL_T:
case SCH_DIRECTIVE_LABEL_T:
if( m_wires->GetValue() && aItem->IsType( { SCH_LABEL_LOCATE_WIRE_T } ) )
if( m_wires->GetValue() && aItem->IsType( wireLabelTypes ) )
processItem( aCommit, aSheetPath, aItem );
if( m_buses->GetValue() && aItem->IsType( { SCH_LABEL_LOCATE_BUS_T } ) )
if( m_buses->GetValue() && aItem->IsType( busLabelTypes ) )
processItem( aCommit, aSheetPath, aItem );
if( m_globalLabels->GetValue() && aItem->Type() == SCH_GLOBAL_LABEL_T )

View File

@ -1605,14 +1605,14 @@ void SCH_EDIT_FRAME::RefreshOperatingPointDisplay()
for( SCH_ITEM* item : subgraph->GetItems() )
{
if( item->IsType( { SCH_ITEM_LOCATE_WIRE_T } ) )
if( item->Type() == SCH_LINE_T )
{
SCH_LINE* wire = static_cast<SCH_LINE*>( item );
SCH_LINE* line = static_cast<SCH_LINE*>( item );
if( wire->GetLength() > length )
if( line->IsWire() && line->GetLength() > length )
{
longestWire = wire;
length = wire->GetLength();
longestWire = line;
length = line->GetLength();
}
}
}
@ -1630,7 +1630,7 @@ void SCH_EDIT_FRAME::RefreshOperatingPointDisplay()
void SCH_EDIT_FRAME::AutoRotateItem( SCH_SCREEN* aScreen, SCH_ITEM* aItem )
{
if( aItem->IsType( { SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T } ) )
if( aItem->Type() == SCH_GLOBAL_LABEL_T || aItem->Type() == SCH_HIER_LABEL_T )
{
SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( aItem );

View File

@ -52,6 +52,9 @@
#include <font/outline_font.h>
#include "sim/sim_lib_mgr.h"
static const std::vector<KICAD_T> labelTypes = { SCH_LABEL_LOCATE_ANY_T };
SCH_FIELD::SCH_FIELD( const VECTOR2I& aPos, int aFieldId, SCH_ITEM* aParent,
const wxString& aName ) :
SCH_ITEM( aParent, SCH_FIELD_T ),
@ -173,7 +176,7 @@ void SCH_FIELD::SetId( int aId )
default: SetLayer( LAYER_FIELDS ); break;
}
}
else if( m_parent && m_parent->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
else if( m_parent && m_parent->IsType( labelTypes ) )
{
// We can't use defined IDs for labels because there can be multiple net class
// assignments.
@ -271,7 +274,7 @@ wxString SCH_FIELD::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraT
text = ExpandTextVars( text, &symbolResolver );
else if( m_parent && m_parent->Type() == SCH_SHEET_T )
text = ExpandTextVars( text, &sheetResolver );
else if( m_parent && m_parent->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
else if( m_parent && m_parent->IsType( labelTypes ) )
text = ExpandTextVars( text, &labelResolver );
else if( Schematic() )
{
@ -1178,7 +1181,7 @@ wxString SCH_FIELD::GetName( bool aUseDefaultName ) const
else if( m_name.IsEmpty() && aUseDefaultName )
return SCH_SHEET::GetDefaultFieldName( m_id );
}
else if( m_parent && m_parent->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
else if( m_parent && m_parent->IsType( labelTypes ) )
{
return SCH_LABEL_BASE::GetDefaultFieldName( m_name, aUseDefaultName );
}
@ -1201,7 +1204,7 @@ wxString SCH_FIELD::GetCanonicalName() const
else if( m_id == SHEETFILENAME )
return wxT( "Sheetfile" );
}
else if( m_parent && m_parent->IsType( { SCH_LABEL_LOCATE_ANY_T } ) )
else if( m_parent && m_parent->IsType( labelTypes ) )
{
// These should be stored in canonical format, but just in case:
if( m_name == _( "Net Class" ) || m_name == wxT( "Net Class" ) )

View File

@ -259,6 +259,9 @@ const wxString SCH_LABEL_BASE::GetDefaultFieldName( const wxString& aName, bool
bool SCH_LABEL_BASE::IsType( const std::vector<KICAD_T>& aScanTypes ) const
{
static const std::vector<KICAD_T> wireAndPinTypes = { SCH_ITEM_LOCATE_WIRE_T, SCH_PIN_T };
static const std::vector<KICAD_T> busTypes = { SCH_ITEM_LOCATE_BUS_T };
if( SCH_TEXT::IsType( aScanTypes ) )
return true;
@ -283,7 +286,7 @@ bool SCH_LABEL_BASE::IsType( const std::vector<KICAD_T>& aScanTypes ) const
{
for( SCH_ITEM* connection : item_set )
{
if( connection->IsType( { SCH_ITEM_LOCATE_WIRE_T, SCH_PIN_T } ) )
if( connection->IsType( wireAndPinTypes ) )
return true;
}
}
@ -292,7 +295,7 @@ bool SCH_LABEL_BASE::IsType( const std::vector<KICAD_T>& aScanTypes ) const
{
for( SCH_ITEM* connection : item_set )
{
if( connection->IsType( { SCH_ITEM_LOCATE_BUS_T } ) )
if( connection->IsType( busTypes ) )
return true;
}
}

View File

@ -1224,9 +1224,13 @@ void SCH_SCREEN::EnsureAlternateReferencesExist()
void SCH_SCREEN::GetHierarchicalItems( std::vector<SCH_ITEM*>* aItems ) const
{
static const std::vector<KICAD_T> hierarchicalTypes = { SCH_SYMBOL_T,
SCH_SHEET_T,
SCH_LABEL_LOCATE_ANY_T };
for( SCH_ITEM* item : Items() )
{
if( item->IsType( { SCH_SYMBOL_T, SCH_SHEET_T, SCH_LABEL_LOCATE_ANY_T } ) )
if( item->IsType( hierarchicalTypes ) )
aItems->push_back( item );
}
}

View File

@ -40,9 +40,15 @@ using namespace std::placeholders;
#include <sch_sheet.h>
#include <sch_textbox.h>
#include <sch_table.h>
#include <sch_tablecell.h>
#include <sch_shape.h>
#include <symbol_edit_frame.h>
static const std::vector<KICAD_T> pointEditorTypes = { SCH_SHAPE_T,
SCH_RULE_AREA_T,
SCH_TEXTBOX_T,
SCH_TABLECELL_T,
SCH_SHEET_T,
SCH_ITEM_LOCATE_GRAPHIC_LINE_T,
SCH_BITMAP_T };
// Few constants to avoid using bare numbers for point indices
@ -380,13 +386,7 @@ int EE_POINT_EDITOR::Main( const TOOL_EVENT& aEvent )
const EE_SELECTION& selection = m_selectionTool->GetSelection();
if( selection.Size() != 1 || !selection.Front()->IsType( { SCH_SHAPE_T,
SCH_RULE_AREA_T,
SCH_TEXTBOX_T,
SCH_TABLECELL_T,
SCH_SHEET_T,
SCH_ITEM_LOCATE_GRAPHIC_LINE_T,
SCH_BITMAP_T } ) )
if( selection.Size() != 1 || !selection.Front()->IsType( pointEditorTypes ) )
{
return 0;
}

View File

@ -198,6 +198,22 @@ static std::vector<KICAD_T> connectedTypes =
SCH_JUNCTION_T
};
static std::vector<KICAD_T> connectedLineTypes =
{
SCH_ITEM_LOCATE_WIRE_T,
SCH_ITEM_LOCATE_BUS_T
};
static std::vector<KICAD_T> crossProbingTypes =
{
SCH_SYMBOL_T,
SCH_PIN_T,
SCH_SHEET_T
};
static std::vector<KICAD_T> lineTypes = { SCH_LINE_T };
static std::vector<KICAD_T> sheetTypes = { SCH_SHEET_T };
static std::vector<KICAD_T> tableCellTypes = { SCH_TABLECELL_T };
bool EE_SELECTION_TOOL::Init()
{
@ -217,16 +233,12 @@ bool EE_SELECTION_TOOL::Init()
m_isSymbolViewer = symbolViewerFrame != nullptr;
}
auto linesSelection = E_C::MoreThan( 0 ) &&
E_C::OnlyTypes( { SCH_ITEM_LOCATE_WIRE_T, SCH_ITEM_LOCATE_BUS_T,
SCH_ITEM_LOCATE_GRAPHIC_LINE_T } );
auto wireOrBusSelection = E_C::Count( 1 ) &&
E_C::OnlyTypes( { SCH_ITEM_LOCATE_WIRE_T,
SCH_ITEM_LOCATE_BUS_T } );
auto linesSelection = E_C::MoreThan( 0 ) && E_C::OnlyTypes( lineTypes );
auto wireOrBusSelection = E_C::Count( 1 ) && E_C::OnlyTypes( connectedLineTypes );
auto connectedSelection = E_C::Count( 1 ) && E_C::OnlyTypes( connectedTypes );
auto sheetSelection = E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_SHEET_T } );
auto crossProbingSelection = E_C::MoreThan( 0 ) && E_C::HasTypes( { SCH_SYMBOL_T, SCH_PIN_T, SCH_SHEET_T } );
auto tableCellSelection = E_C::MoreThan( 0 ) && E_C::OnlyTypes( { SCH_TABLECELL_T } );
auto sheetSelection = E_C::Count( 1 ) && E_C::OnlyTypes( sheetTypes );
auto crossProbingSelection = E_C::MoreThan( 0 ) && E_C::HasTypes( crossProbingTypes );
auto tableCellSelection = E_C::MoreThan( 0 ) && E_C::OnlyTypes( tableCellTypes );
auto schEditSheetPageNumberCondition =
[&] ( const SELECTION& aSel )
@ -234,7 +246,7 @@ bool EE_SELECTION_TOOL::Init()
if( m_isSymbolEditor || m_isSymbolViewer )
return false;
return E_C::LessThan( 2 )( aSel ) && E_C::OnlyTypes( { SCH_SHEET_T } )( aSel );
return E_C::LessThan( 2 )( aSel ) && E_C::OnlyTypes( sheetTypes )( aSel );
};
auto schEditCondition =

View File

@ -243,7 +243,9 @@ bool SCH_EDIT_TOOL::Init()
return false;
};
auto sheetSelection = E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_SHEET_T } );
static const std::vector<KICAD_T> sheetTypes = { SCH_SHEET_T };
auto sheetSelection = E_C::Count( 1 ) && E_C::OnlyTypes( sheetTypes );
auto haveHighlight =
[&]( const SELECTION& sel )
@ -378,7 +380,7 @@ bool SCH_EDIT_TOOL::Init()
// allTextTypes does not include SCH_SHEET_PIN_T because one cannot convert other
// types to/from this type, living only in a SHEET
static std::vector<KICAD_T> allTextTypes = { SCH_LABEL_T,
static const std::vector<KICAD_T> allTextTypes = { SCH_LABEL_T,
SCH_DIRECTIVE_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_HIER_LABEL_T,
@ -387,52 +389,65 @@ bool SCH_EDIT_TOOL::Init()
auto toChangeCondition = ( E_C::OnlyTypes( allTextTypes ) );
auto toLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_DIRECTIVE_LABEL_T,
static const std::vector<KICAD_T> toLabelTypes = { SCH_DIRECTIVE_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_HIER_LABEL_T,
SCH_TEXT_T,
SCH_TEXTBOX_T } ) )
SCH_TEXTBOX_T };
auto toLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toLabelTypes ) )
|| ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
auto toCLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
static const std::vector<KICAD_T> toCLabelTypes = { SCH_LABEL_T,
SCH_HIER_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_TEXT_T,
SCH_TEXTBOX_T } ) )
SCH_TEXTBOX_T };
auto toCLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toCLabelTypes ) )
|| ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
auto toHLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
static const std::vector<KICAD_T> toHLabelTypes = { SCH_LABEL_T,
SCH_DIRECTIVE_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_TEXT_T,
SCH_TEXTBOX_T } ) )
SCH_TEXTBOX_T };
auto toHLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toHLabelTypes ) )
|| ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
auto toGLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
static const std::vector<KICAD_T> toGLabelTypes = { SCH_LABEL_T,
SCH_DIRECTIVE_LABEL_T,
SCH_HIER_LABEL_T,
SCH_TEXT_T,
SCH_TEXTBOX_T } ) )
SCH_TEXTBOX_T };
auto toGLabelCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toGLabelTypes ) )
|| ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
auto toTextCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
static const std::vector<KICAD_T> toTextTypes = { SCH_LABEL_T,
SCH_DIRECTIVE_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_HIER_LABEL_T,
SCH_TEXTBOX_T } ) )
SCH_TEXTBOX_T };
auto toTextCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toTextTypes ) )
|| ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
auto toTextBoxCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_LABEL_T,
static const std::vector<KICAD_T> toTextBoxTypes = { SCH_LABEL_T,
SCH_DIRECTIVE_LABEL_T,
SCH_GLOBAL_LABEL_T,
SCH_HIER_LABEL_T,
SCH_TEXT_T } ) )
SCH_TEXT_T };
auto toTextBoxCondition = ( E_C::Count( 1 ) && E_C::OnlyTypes( toTextBoxTypes ) )
|| ( E_C::MoreThan( 1 ) && E_C::OnlyTypes( allTextTypes ) );
auto entryCondition = E_C::MoreThan( 0 ) && E_C::OnlyTypes( { SCH_BUS_WIRE_ENTRY_T,
SCH_BUS_BUS_ENTRY_T} );
static const std::vector<KICAD_T> busEntryTypes = { SCH_BUS_WIRE_ENTRY_T, SCH_BUS_BUS_ENTRY_T};
auto singleSheetCondition = E_C::Count( 1 ) && E_C::OnlyTypes( { SCH_SHEET_T } );
auto entryCondition = E_C::MoreThan( 0 ) && E_C::OnlyTypes( busEntryTypes );
auto singleSheetCondition = E_C::Count( 1 ) && E_C::OnlyTypes( sheetTypes );
auto makeSymbolUnitMenu =
[&]( TOOL_INTERACTIVE* tool )

View File

@ -103,7 +103,9 @@ bool SYMBOL_EDITOR_PIN_TOOL::Init()
return editor->IsSymbolEditable() && !editor->IsSymbolAlias();
};
auto singlePinCondition = EE_CONDITIONS::Count( 1 ) && EE_CONDITIONS::OnlyTypes( { SCH_PIN_T } );
static const std::vector<KICAD_T> pinTypes = { SCH_PIN_T };
auto singlePinCondition = EE_CONDITIONS::Count( 1 ) && EE_CONDITIONS::OnlyTypes( pinTypes );
CONDITIONAL_MENU& selToolMenu = m_selectionTool->GetToolMenu().GetMenu();

View File

@ -2188,9 +2188,12 @@ std::tuple<int, double, double> BOARD::GetTrackLength( const PCB_TRACK& aTrack )
BOARD_STACKUP& stackup = GetDesignSettings().GetStackupDescriptor();
bool useHeight = GetDesignSettings().m_UseHeightForLengthCalcs;
for( BOARD_CONNECTED_ITEM* item : connectivity->GetConnectedItems(
static_cast<const BOARD_CONNECTED_ITEM*>( &aTrack ),
{ PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T } ) )
static const std::vector<KICAD_T> baseConnectedTypes = { PCB_TRACE_T,
PCB_ARC_T,
PCB_VIA_T,
PCB_PAD_T };
for( BOARD_CONNECTED_ITEM* item : connectivity->GetConnectedItems( &aTrack, baseConnectedTypes ) )
{
count++;

View File

@ -317,26 +317,26 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUSTER_SEARCH_MODE aMode )
{
if( aMode == CSM_PROPAGATE )
{
return SearchClusters( aMode,
{ PCB_TRACE_T, PCB_ARC_T, PCB_PAD_T, PCB_VIA_T, PCB_FOOTPRINT_T,
PCB_SHAPE_T },
-1 );
}
else
{
return SearchClusters( aMode,
{ PCB_TRACE_T, PCB_ARC_T, PCB_PAD_T, PCB_VIA_T, PCB_ZONE_T,
PCB_FOOTPRINT_T, PCB_SHAPE_T },
-1 );
}
static const std::vector<KICAD_T> withoutZones = { PCB_TRACE_T,
PCB_ARC_T,
PCB_PAD_T,
PCB_VIA_T,
PCB_FOOTPRINT_T,
PCB_SHAPE_T };
static const std::vector<KICAD_T> withZones = { PCB_TRACE_T,
PCB_ARC_T,
PCB_PAD_T,
PCB_VIA_T,
PCB_ZONE_T,
PCB_FOOTPRINT_T,
PCB_SHAPE_T };
return SearchClusters( aMode, aMode == CSM_PROPAGATE ? withoutZones : withZones, -1 );
}
const CN_CONNECTIVITY_ALGO::CLUSTERS
CN_CONNECTIVITY_ALGO::SearchClusters( CLUSTER_SEARCH_MODE aMode,
const std::initializer_list<KICAD_T>& aTypes,
CN_CONNECTIVITY_ALGO::SearchClusters( CLUSTER_SEARCH_MODE aMode, const std::vector<KICAD_T>& aTypes,
int aSingleNet, CN_ITEM* rootItem )
{
bool withinAnyNet = ( aMode != CSM_PROPAGATE );

View File

@ -226,8 +226,7 @@ public:
bool Remove( BOARD_ITEM* aItem );
bool Add( BOARD_ITEM* aItem );
const CLUSTERS SearchClusters( CLUSTER_SEARCH_MODE aMode,
const std::initializer_list<KICAD_T>& aTypes,
const CLUSTERS SearchClusters( CLUSTER_SEARCH_MODE aMode, const std::vector<KICAD_T>& aTypes,
int aSingleNet, CN_ITEM* rootItem = nullptr );
const CLUSTERS SearchClusters( CLUSTER_SEARCH_MODE aMode );

View File

@ -531,7 +531,7 @@ void CONNECTIVITY_DATA::ClearRatsnest()
const std::vector<BOARD_CONNECTED_ITEM*>
CONNECTIVITY_DATA::GetConnectedItems( const BOARD_CONNECTED_ITEM *aItem,
const std::initializer_list<KICAD_T>& aTypes,
const std::vector<KICAD_T>& aTypes,
bool aIgnoreNetcodes ) const
{
std::vector<BOARD_CONNECTED_ITEM*> rv;
@ -562,7 +562,7 @@ CONNECTIVITY_DATA::GetConnectedItems( const BOARD_CONNECTED_ITEM *aItem,
const std::vector<BOARD_CONNECTED_ITEM*>
CONNECTIVITY_DATA::GetNetItems( int aNetCode, const std::initializer_list<KICAD_T>& aTypes ) const
CONNECTIVITY_DATA::GetNetItems( int aNetCode, const std::vector<KICAD_T>& aTypes ) const
{
std::vector<BOARD_CONNECTED_ITEM*> items;
items.reserve( 32 );
@ -877,7 +877,7 @@ bool CONNECTIVITY_DATA::TestTrackEndpointDangling( PCB_TRACK* aTrack, bool aIgno
const std::vector<BOARD_CONNECTED_ITEM*>
CONNECTIVITY_DATA::GetConnectedItemsAtAnchor( const BOARD_CONNECTED_ITEM* aItem,
const VECTOR2I& aAnchor,
const std::initializer_list<KICAD_T>& aTypes,
const std::vector<KICAD_T>& aTypes,
const int& aMaxError ) const
{
CN_CONNECTIVITY_ALGO::ITEM_MAP_ENTRY& entry = m_connAlgo->ItemEntry( aItem );

View File

@ -211,8 +211,7 @@ public:
*/
const std::vector<BOARD_CONNECTED_ITEM*>
GetConnectedItemsAtAnchor( const BOARD_CONNECTED_ITEM* aItem, const VECTOR2I& aAnchor,
const std::initializer_list<KICAD_T>& aTypes,
const int& aMaxError = 0 ) const;
const std::vector<KICAD_T>& aTypes, const int& aMaxError = 0 ) const;
void RunOnUnconnectedEdges( std::function<bool( CN_EDGE& )> aFunc );
@ -248,8 +247,7 @@ public:
* @param aTypes allows one to filter by item types.
*/
const std::vector<BOARD_CONNECTED_ITEM*>
GetConnectedItems( const BOARD_CONNECTED_ITEM* aItem,
const std::initializer_list<KICAD_T>& aTypes,
GetConnectedItems( const BOARD_CONNECTED_ITEM* aItem, const std::vector<KICAD_T>& aTypes,
bool aIgnoreNetcodes = false ) const;
/**
@ -259,7 +257,7 @@ public:
* @param aTypes allows one to filter by item types.
*/
const std::vector<BOARD_CONNECTED_ITEM*>
GetNetItems( int aNetCode, const std::initializer_list<KICAD_T>& aTypes ) const;
GetNetItems( int aNetCode, const std::vector<KICAD_T>& aTypes ) const;
void BlockRatsnestItems( const std::vector<BOARD_ITEM*>& aItems );

View File

@ -151,14 +151,18 @@ bool NETINFO_ITEM::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
const BOX2I NETINFO_ITEM::GetBoundingBox() const
{
static const std::vector<KICAD_T> netItemTypes = { PCB_TRACE_T,
PCB_ARC_T,
PCB_VIA_T,
PCB_ZONE_T,
PCB_PAD_T,
PCB_SHAPE_T };
std::shared_ptr<CONNECTIVITY_DATA> conn = GetBoard()->GetConnectivity();
BOX2I bbox;
for( BOARD_ITEM* item : conn->GetNetItems( m_netCode, { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T,
PCB_ZONE_T, PCB_PAD_T } ) )
{
for( BOARD_ITEM* item : conn->GetNetItems( m_netCode, netItemTypes ) )
bbox.Merge( item->GetBoundingBox() );
}
return bbox;
}

View File

@ -744,6 +744,7 @@ void PCB_EDIT_FRAME::setupUIConditions()
#define ENABLE( x ) ACTION_CONDITIONS().Enable( x )
#define CHECK( x ) ACTION_CONDITIONS().Check( x )
// clang-format off
mgr->SetConditions( ACTIONS::save, ENABLE( SELECTION_CONDITIONS::ShowAlways ) );
mgr->SetConditions( ACTIONS::undo, ENABLE( undoCond ) );
@ -759,18 +760,17 @@ void PCB_EDIT_FRAME::setupUIConditions()
mgr->SetConditions( ACTIONS::cut, ENABLE( cond.HasItems() ) );
mgr->SetConditions( ACTIONS::copy, ENABLE( cond.HasItems() ) );
mgr->SetConditions( ACTIONS::paste,
ENABLE( SELECTION_CONDITIONS::Idle && cond.NoActiveTool() ) );
mgr->SetConditions( ACTIONS::pasteSpecial,
ENABLE( SELECTION_CONDITIONS::Idle && cond.NoActiveTool() ) );
mgr->SetConditions( ACTIONS::paste, ENABLE( SELECTION_CONDITIONS::Idle && cond.NoActiveTool() ) );
mgr->SetConditions( ACTIONS::pasteSpecial, ENABLE( SELECTION_CONDITIONS::Idle && cond.NoActiveTool() ) );
mgr->SetConditions( ACTIONS::selectAll, ENABLE( cond.HasItems() ) );
mgr->SetConditions( ACTIONS::unselectAll, ENABLE( cond.HasItems() ) );
mgr->SetConditions( ACTIONS::doDelete, ENABLE( cond.HasItems() ) );
mgr->SetConditions( ACTIONS::duplicate, ENABLE( cond.HasItems() ) );
static const std::vector<KICAD_T> groupTypes = { PCB_GROUP_T, PCB_GENERATOR_T };
mgr->SetConditions( PCB_ACTIONS::group, ENABLE( SELECTION_CONDITIONS::NotEmpty ) );
mgr->SetConditions( PCB_ACTIONS::ungroup, ENABLE( SELECTION_CONDITIONS::HasTypes(
{ PCB_GROUP_T, PCB_GENERATOR_T } ) ) );
mgr->SetConditions( PCB_ACTIONS::ungroup, ENABLE( SELECTION_CONDITIONS::HasTypes( groupTypes ) ) );
mgr->SetConditions( PCB_ACTIONS::lock, ENABLE( PCB_SELECTION_CONDITIONS::HasUnlockedItems ) );
mgr->SetConditions( PCB_ACTIONS::unlock, ENABLE( PCB_SELECTION_CONDITIONS::HasLockedItems ) );
@ -945,23 +945,24 @@ void PCB_EDIT_FRAME::setupUIConditions()
mgr->SetConditions( PCB_ACTIONS::highlightNet, ENABLE( SELECTION_CONDITIONS::ShowAlways ) );
mgr->SetConditions( PCB_ACTIONS::highlightNetSelection, ENABLE( SELECTION_CONDITIONS::ShowAlways ) );
mgr->SetConditions( PCB_ACTIONS::selectNet,
ENABLE( SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } ) ) );
mgr->SetConditions( PCB_ACTIONS::deselectNet,
ENABLE( SELECTION_CONDITIONS::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } ) ) );
mgr->SetConditions( PCB_ACTIONS::selectUnconnected,
ENABLE( SELECTION_CONDITIONS::OnlyTypes( { PCB_FOOTPRINT_T, PCB_PAD_T, PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } ) ) );
mgr->SetConditions( PCB_ACTIONS::selectSameSheet,
ENABLE( SELECTION_CONDITIONS::OnlyTypes( { PCB_FOOTPRINT_T } ) ) );
mgr->SetConditions( PCB_ACTIONS::selectOnSchematic,
ENABLE( SELECTION_CONDITIONS::HasTypes( { PCB_PAD_T, PCB_FOOTPRINT_T, PCB_GROUP_T } ) ) );
static const std::vector<KICAD_T> trackTypes = { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T };
static const std::vector<KICAD_T> padOwnerTypes = { PCB_FOOTPRINT_T, PCB_PAD_T };
static const std::vector<KICAD_T> footprintTypes = { PCB_FOOTPRINT_T };
static const std::vector<KICAD_T> crossProbeTypes = { PCB_PAD_T, PCB_FOOTPRINT_T, PCB_GROUP_T };
static const std::vector<KICAD_T> zoneTypes = { PCB_ZONE_T };
mgr->SetConditions( PCB_ACTIONS::selectNet, ENABLE( SELECTION_CONDITIONS::OnlyTypes( trackTypes ) ) );
mgr->SetConditions( PCB_ACTIONS::deselectNet, ENABLE( SELECTION_CONDITIONS::OnlyTypes( trackTypes ) ) );
mgr->SetConditions( PCB_ACTIONS::selectUnconnected, ENABLE( SELECTION_CONDITIONS::OnlyTypes( padOwnerTypes ) ) );
mgr->SetConditions( PCB_ACTIONS::selectSameSheet, ENABLE( SELECTION_CONDITIONS::OnlyTypes( footprintTypes ) ) );
mgr->SetConditions( PCB_ACTIONS::selectOnSchematic, ENABLE( SELECTION_CONDITIONS::HasTypes( crossProbeTypes ) ) );
SELECTION_CONDITION singleZoneCond = SELECTION_CONDITIONS::Count( 1 )
&& SELECTION_CONDITIONS::OnlyTypes( { PCB_ZONE_T } );
&& SELECTION_CONDITIONS::OnlyTypes( zoneTypes );
SELECTION_CONDITION zoneMergeCond = SELECTION_CONDITIONS::MoreThan( 1 )
&& SELECTION_CONDITIONS::OnlyTypes( { PCB_ZONE_T } );
&& SELECTION_CONDITIONS::OnlyTypes( zoneTypes );
mgr->SetConditions( PCB_ACTIONS::zoneDuplicate, ENABLE( singleZoneCond ) );
mgr->SetConditions( PCB_ACTIONS::drawZoneCutout, ENABLE( singleZoneCond ) );
@ -978,7 +979,6 @@ void PCB_EDIT_FRAME::setupUIConditions()
CURRENT_TOOL( ACTIONS::selectionTool );
CURRENT_TOOL( PCB_ACTIONS::localRatsnestTool );
auto isDRCIdle =
[this] ( const SELECTION& )
{
@ -1028,6 +1028,7 @@ void PCB_EDIT_FRAME::setupUIConditions()
#undef CURRENT_EDIT_TOOL
#undef ENABLE
#undef CHECK
// clang-format on
}

View File

@ -2104,7 +2104,7 @@ bool ROUTER_TOOL::CanInlineDrag( int aDragMode )
if( item->IsType( GENERAL_COLLECTOR::DraggableItems ) )
{
// Footprints cannot be dragged freely.
if( item->IsType( { PCB_FOOTPRINT_T } ) )
if( item->Type() == PCB_FOOTPRINT_T )
return !( aDragMode & PNS::DM_FREE_ANGLE );
else
return true;

View File

@ -259,43 +259,52 @@ bool CONVERT_TOOL::Init()
m_menu->SetIcon( BITMAPS::convert );
m_menu->SetTitle( _( "Create from Selection" ) );
auto shapes = S_C::OnlyTypes( { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_RECT_T,
PCB_SHAPE_LOCATE_CIRCLE_T, PCB_SHAPE_LOCATE_ARC_T,
static const std::vector<KICAD_T> padTypes = { PCB_PAD_T };
static const std::vector<KICAD_T> segmentTypes = { PCB_TRACE_T,
PCB_SHAPE_LOCATE_SEGMENT_T };
static const std::vector<KICAD_T> shapeTypes = { PCB_SHAPE_LOCATE_SEGMENT_T,
PCB_SHAPE_LOCATE_RECT_T,
PCB_SHAPE_LOCATE_CIRCLE_T,
PCB_SHAPE_LOCATE_ARC_T,
PCB_SHAPE_LOCATE_BEZIER_T,
PCB_FIELD_T, PCB_TEXT_T } )
&& P_S_C::SameLayer();
PCB_FIELD_T,
PCB_TEXT_T };
static const std::vector<KICAD_T> trackTypes = { PCB_TRACE_T,
PCB_ARC_T,
PCB_VIA_T };
static const std::vector<KICAD_T> toTrackTypes = { PCB_SHAPE_LOCATE_SEGMENT_T,
PCB_SHAPE_LOCATE_ARC_T };
static const std::vector<KICAD_T> polyTypes = { PCB_ZONE_T,
PCB_SHAPE_LOCATE_POLY_T,
PCB_SHAPE_LOCATE_RECT_T };
auto graphicToTrack = S_C::OnlyTypes( { PCB_SHAPE_LOCATE_SEGMENT_T, PCB_SHAPE_LOCATE_ARC_T } );
auto shapes = S_C::OnlyTypes( shapeTypes ) && P_S_C::SameLayer();
auto graphicToTrack = S_C::OnlyTypes( toTrackTypes );
auto anyTracks = S_C::MoreThan( 0 ) && S_C::OnlyTypes( trackTypes ) && P_S_C::SameLayer();
auto anyPolys = S_C::OnlyTypes( polyTypes );
auto anyPads = S_C::OnlyTypes( padTypes );
auto anyTracks = S_C::MoreThan( 0 ) && S_C::OnlyTypes( { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T } )
&& P_S_C::SameLayer();
auto anyPolys = S_C::OnlyTypes( { PCB_ZONE_T, PCB_SHAPE_LOCATE_POLY_T, PCB_SHAPE_LOCATE_RECT_T } );
auto anyPads = S_C::OnlyTypes( { PCB_PAD_T } );
auto canCreateArcs = S_C::Count( 1 )
&& S_C::OnlyTypes( { PCB_TRACE_T, PCB_SHAPE_LOCATE_SEGMENT_T } );
auto canCreateArcs = S_C::Count( 1 ) && S_C::OnlyTypes( segmentTypes );
auto canCreateArray = S_C::MoreThan( 0 );
auto canCreatePolyType = shapes || anyPolys || anyTracks;
auto canCreatePoly = shapes || anyPolys || anyTracks;
if( m_frame->IsType( FRAME_FOOTPRINT_EDITOR ) )
canCreatePolyType = shapes || anyPolys || anyTracks || anyPads;
canCreatePoly = shapes || anyPolys || anyTracks || anyPads;
auto canCreateLines = anyPolys;
auto canCreateTracks = anyPolys || graphicToTrack;
auto canCreate = canCreatePolyType
auto canCreate = canCreatePoly
|| canCreateLines
|| canCreateTracks
|| canCreateArcs
|| canCreateArray;
m_menu->AddItem( PCB_ACTIONS::convertToPoly, canCreatePolyType );
m_menu->AddItem( PCB_ACTIONS::convertToPoly, canCreatePoly );
if( m_frame->IsType( FRAME_PCB_EDITOR ) )
m_menu->AddItem( PCB_ACTIONS::convertToZone, canCreatePolyType );
m_menu->AddItem( PCB_ACTIONS::convertToZone, canCreatePoly );
m_menu->AddItem( PCB_ACTIONS::convertToKeepout, canCreatePolyType );
m_menu->AddItem( PCB_ACTIONS::convertToKeepout, canCreatePoly );
m_menu->AddItem( PCB_ACTIONS::convertToLines, canCreateLines );
m_menu->AppendSeparator();

View File

@ -73,6 +73,34 @@ using namespace std::placeholders;
const unsigned int EDIT_TOOL::COORDS_PADDING = pcbIUScale.mmToIU( 20 );
static const std::vector<KICAD_T> padTypes = { PCB_PAD_T };
static const std::vector<KICAD_T> footprintTypes = { PCB_FOOTPRINT_T };
static const std::vector<KICAD_T> groupTypes = { PCB_GROUP_T };
static const std::vector<KICAD_T> trackTypes = { PCB_TRACE_T,
PCB_ARC_T,
PCB_VIA_T };
static const std::vector<KICAD_T> baseConnectedTypes = { PCB_PAD_T,
PCB_VIA_T,
PCB_TRACE_T,
PCB_ARC_T };
static const std::vector<KICAD_T> connectedTypes = { PCB_TRACE_T,
PCB_ARC_T,
PCB_VIA_T,
PCB_PAD_T,
PCB_ZONE_T };
static const std::vector<KICAD_T> unroutableTypes = { PCB_TRACE_T,
PCB_ARC_T,
PCB_VIA_T,
PCB_PAD_T,
PCB_FOOTPRINT_T };
EDIT_TOOL::EDIT_TOOL() :
PCB_TOOL_BASE( "pcbnew.InteractiveEdit" ),
m_selectionTool( nullptr ),
@ -239,18 +267,18 @@ bool EDIT_TOOL::Init()
[ this ]( const SELECTION& aSelection )
{
if( !m_isFootprintEditor
&& SELECTION_CONDITIONS::OnlyTypes( { PCB_PAD_T } )( aSelection ) )
&& SELECTION_CONDITIONS::OnlyTypes( padTypes )( aSelection ) )
{
return false;
}
if( SELECTION_CONDITIONS::HasTypes( { PCB_GROUP_T } )( aSelection ) )
if( SELECTION_CONDITIONS::HasTypes( groupTypes )( aSelection ) )
return true;
return SELECTION_CONDITIONS::HasTypes( EDIT_TOOL::MirrorableItems )( aSelection );
};
auto singleFootprintCondition = SELECTION_CONDITIONS::OnlyTypes( { PCB_FOOTPRINT_T } )
auto singleFootprintCondition = SELECTION_CONDITIONS::OnlyTypes( footprintTypes )
&& SELECTION_CONDITIONS::Count( 1 );
auto multipleFootprintsCondition =
@ -296,22 +324,6 @@ bool EDIT_TOOL::Init()
return frame()->IsCurrentTool( PCB_ACTIONS::moveIndividually );
};
static std::vector<KICAD_T> connectedTypes = { PCB_TRACE_T,
PCB_ARC_T,
PCB_VIA_T,
PCB_PAD_T,
PCB_ZONE_T };
static std::vector<KICAD_T> unroutableTypes = { PCB_TRACE_T,
PCB_ARC_T,
PCB_VIA_T,
PCB_PAD_T,
PCB_FOOTPRINT_T };
static std::vector<KICAD_T> trackTypes = { PCB_TRACE_T,
PCB_ARC_T,
PCB_VIA_T };
// Add context menu entries that are displayed when selection tool is active
CONDITIONAL_MENU& menu = m_selectionTool->GetToolMenu().GetMenu();
@ -331,7 +343,7 @@ bool EDIT_TOOL::Init()
&& SELECTION_CONDITIONS::OnlyTypes( GENERAL_COLLECTOR::DraggableItems ) );
menu.AddItem( PCB_ACTIONS::dragFreeAngle, SELECTION_CONDITIONS::Count( 1 )
&& SELECTION_CONDITIONS::OnlyTypes( GENERAL_COLLECTOR::DraggableItems )
&& !SELECTION_CONDITIONS::OnlyTypes( { PCB_FOOTPRINT_T } ) );
&& !SELECTION_CONDITIONS::OnlyTypes( footprintTypes ) );
menu.AddItem( PCB_ACTIONS::filletTracks, SELECTION_CONDITIONS::OnlyTypes( trackTypes ) );
menu.AddItem( PCB_ACTIONS::rotateCcw, SELECTION_CONDITIONS::NotEmpty );
menu.AddItem( PCB_ACTIONS::rotateCw, SELECTION_CONDITIONS::NotEmpty );
@ -613,8 +625,7 @@ int EDIT_TOOL::DragArcTrack( const TOOL_EVENT& aEvent )
for( int i = 0; i < 3; i++ )
{
itemsOnAnchor = conn->GetConnectedItemsAtAnchor( theArc, aAnchor,
{ PCB_PAD_T, PCB_VIA_T,
PCB_TRACE_T, PCB_ARC_T },
baseConnectedTypes,
allowedDeviation );
allowedDeviation /= 2;
@ -1029,9 +1040,7 @@ int EDIT_TOOL::FilletTracks( const TOOL_EVENT& aEvent )
VECTOR2I anchor = aStartPoint ? aTrack->GetStart() : aTrack->GetEnd();
std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
itemsOnAnchor = c->GetConnectedItemsAtAnchor( aTrack, anchor,
{ PCB_PAD_T, PCB_VIA_T,
PCB_TRACE_T, PCB_ARC_T } );
itemsOnAnchor = c->GetConnectedItemsAtAnchor( aTrack, anchor, baseConnectedTypes );
if( itemsOnAnchor.size() > 0
&& selection.Contains( itemsOnAnchor.at( 0 ) )

View File

@ -84,6 +84,8 @@ void PAD_TOOL::Reset( RESET_REASON aReason )
bool PAD_TOOL::Init()
{
static const std::vector<KICAD_T> padTypes = { PCB_PAD_T };
PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
if( selTool )
@ -93,7 +95,7 @@ bool PAD_TOOL::Init()
SELECTION_CONDITION padSel = SELECTION_CONDITIONS::HasType( PCB_PAD_T );
SELECTION_CONDITION singlePadSel = SELECTION_CONDITIONS::Count( 1 ) &&
SELECTION_CONDITIONS::OnlyTypes( { PCB_PAD_T } );
SELECTION_CONDITIONS::OnlyTypes( padTypes );
auto explodeCondition =
[&]( const SELECTION& aSel )

View File

@ -172,6 +172,8 @@ bool PCB_SELECTION_TOOL::Init()
selectMenu->SetTool( this );
m_menu.RegisterSubMenu( selectMenu );
static const std::vector<KICAD_T> tableCellTypes = { PCB_TABLECELL_T };
auto& menu = m_menu.GetMenu();
auto activeToolCondition =
@ -198,7 +200,7 @@ bool PCB_SELECTION_TOOL::Init()
};
auto tableCellSelection = SELECTION_CONDITIONS::MoreThan( 0 )
&& SELECTION_CONDITIONS::OnlyTypes( { PCB_TABLECELL_T } );
&& SELECTION_CONDITIONS::OnlyTypes( tableCellTypes );
if( frame && frame->IsType( FRAME_PCB_EDITOR ) )
{

View File

@ -560,14 +560,16 @@ void TRACKS_CLEANER::cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegment
const std::vector<BOARD_CONNECTED_ITEM*>& TRACKS_CLEANER::getConnectedItems( PCB_TRACK* aTrack )
{
static const std::vector<KICAD_T> connectedTypes = { PCB_TRACE_T,
PCB_ARC_T,
PCB_VIA_T,
PCB_PAD_T,
PCB_ZONE_T };
const std::shared_ptr<CONNECTIVITY_DATA>& connectivity = m_brd->GetConnectivity();
if( m_connectedItemsCache.count( aTrack ) == 0 )
{
m_connectedItemsCache[ aTrack ] =
connectivity->GetConnectedItems( aTrack, { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T,
PCB_PAD_T, PCB_ZONE_T } );
}
m_connectedItemsCache[ aTrack ] = connectivity->GetConnectedItems( aTrack, connectedTypes );
return m_connectedItemsCache[ aTrack ];
}