diff --git a/common/hash_eda.cpp b/common/hash_eda.cpp index 053583275b..6689886a59 100644 --- a/common/hash_eda.cpp +++ b/common/hash_eda.cpp @@ -83,8 +83,11 @@ size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags ) hash_combine( ret, via->TopLayer() ); hash_combine( ret, via->BottomLayer() ); - for( PCB_LAYER_ID layer : via->GetLayerSet().Seq() ) - hash_combine( ret, via->FlashLayer( layer ) ); + via->GetLayerSet().RunOnLayers( + [&]( PCB_LAYER_ID layer ) + { + hash_combine( ret, via->FlashLayer( layer ) ); + } ); break; } @@ -102,8 +105,11 @@ size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags ) hash_combine( ret, pad->GetDrillSizeX(), pad->GetDrillSizeY() ); hash_combine( ret, pad->GetDrillShape() ); - for( PCB_LAYER_ID layer : pad->GetLayerSet().Seq() ) - hash_combine( ret, pad->FlashLayer( layer ) ); + pad->GetLayerSet().RunOnLayers( + [&]( PCB_LAYER_ID layer ) + { + hash_combine( ret, pad->FlashLayer( layer ) ); + } ); } hash_combine( ret, pad->GetSize().x, pad->GetSize().y ); diff --git a/include/layer_ids.h b/include/layer_ids.h index c54ede2987..d4f8c11a36 100644 --- a/include/layer_ids.h +++ b/include/layer_ids.h @@ -815,6 +815,18 @@ public: */ LSEQ SeqStackupForPlotting() const; + /** + * Execute a function on each layer of the LSET. + */ + void RunOnLayers( const std::function& aFunction ) const + { + for( size_t ii = 0; ii < size(); ++ii ) + { + if( test( ii ) ) + aFunction( PCB_LAYER_ID( ii ) ); + } + } + /** * Return a hex string showing contents of this LSEQ. */ diff --git a/pcbnew/board_connected_item.cpp b/pcbnew/board_connected_item.cpp index 5729e7f3e5..4234bfbfdc 100644 --- a/pcbnew/board_connected_item.cpp +++ b/pcbnew/board_connected_item.cpp @@ -132,16 +132,20 @@ wxString BOARD_CONNECTED_ITEM::GetNetnameMsg() const } -wxString BOARD_CONNECTED_ITEM::GetShortNetname() const +const wxString& BOARD_CONNECTED_ITEM::GetShortNetname() const { - return m_netinfo ? m_netinfo->GetShortNetname() : wxString(); + static wxString emptyString; + + return m_netinfo ? m_netinfo->GetShortNetname() : emptyString; } -wxString BOARD_CONNECTED_ITEM::GetDisplayNetname() const +const wxString& BOARD_CONNECTED_ITEM::GetDisplayNetname() const { + static wxString emptyString; + if( !m_netinfo ) - return wxString(); + return emptyString; if( const BOARD* board = GetBoard() ) { diff --git a/pcbnew/board_connected_item.h b/pcbnew/board_connected_item.h index 885e593999..ef6f91f22e 100644 --- a/pcbnew/board_connected_item.h +++ b/pcbnew/board_connected_item.h @@ -124,12 +124,12 @@ public: /** * @return the short netname. */ - wxString GetShortNetname() const; + const wxString& GetShortNetname() const; /** * @return the unescaped short netname. */ - wxString GetDisplayNetname() const; + const wxString& GetDisplayNetname() const; /** * Return an item's "own" clearance in internal units. diff --git a/pcbnew/connectivity/connectivity_algo.cpp b/pcbnew/connectivity/connectivity_algo.cpp index 093a6415c8..cecb1566f0 100644 --- a/pcbnew/connectivity/connectivity_algo.cpp +++ b/pcbnew/connectivity/connectivity_algo.cpp @@ -200,11 +200,12 @@ bool CN_CONNECTIVITY_ALGO::Add( BOARD_ITEM* aItem ) BOARD* board = zone->GetBoard(); LSET layerset = board->GetEnabledLayers() & zone->GetLayerSet(); - for( PCB_LAYER_ID layer : layerset.Seq() ) - { - for( CN_ITEM* zitem : m_itemList.Add( zone, layer ) ) - m_itemMap[zone].Link( zitem ); - } + layerset.RunOnLayers( + [&]( PCB_LAYER_ID layer ) + { + for( CN_ITEM* zitem : m_itemList.Add( zone, layer ) ) + m_itemMap[zone].Link( zitem ); + } ); } break; @@ -456,11 +457,12 @@ void CN_CONNECTIVITY_ALGO::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter ) BOARD* board = zone->GetBoard(); LSET layerset = board->GetEnabledLayers() & zone->GetLayerSet() & LSET::AllCuMask(); - for( PCB_LAYER_ID layer : layerset.Seq() ) - { - for( int j = 0; j < zone->GetFilledPolysList( layer )->OutlineCount(); j++ ) - zitems.push_back( new CN_ZONE_LAYER( zone, layer, j ) ); - } + layerset.RunOnLayers( + [&]( PCB_LAYER_ID layer ) + { + for( int j = 0; j < zone->GetFilledPolysList( layer )->OutlineCount(); j++ ) + zitems.push_back( new CN_ZONE_LAYER( zone, layer, j ) ); + } ); } } @@ -899,39 +901,43 @@ bool CN_VISITOR::operator()( CN_ITEM* aCandidate ) LSET commonLayers = parentA->GetLayerSet() & parentB->GetLayerSet(); - for( PCB_LAYER_ID layer : commonLayers.Seq() ) + for( size_t ii = 0; ii < commonLayers.size(); ++ii ) { - FLASHING flashingA = FLASHING::NEVER_FLASHED; - FLASHING flashingB = FLASHING::NEVER_FLASHED; + if( commonLayers.test( ii ) ) + { + PCB_LAYER_ID layer = PCB_LAYER_ID( ii ); + FLASHING flashingA = FLASHING::NEVER_FLASHED; + FLASHING flashingB = FLASHING::NEVER_FLASHED; - if( parentA->Type() == PCB_PAD_T ) - { - if( !static_cast( parentA )->ConditionallyFlashed( layer ) ) - flashingA = FLASHING::ALWAYS_FLASHED; - } - else if( parentA->Type() == PCB_VIA_T ) - { - if( !static_cast( parentA )->ConditionallyFlashed( layer ) ) - flashingA = FLASHING::ALWAYS_FLASHED; - } + if( parentA->Type() == PCB_PAD_T ) + { + if( !static_cast( parentA )->ConditionallyFlashed( layer ) ) + flashingA = FLASHING::ALWAYS_FLASHED; + } + else if( parentA->Type() == PCB_VIA_T ) + { + if( !static_cast( parentA )->ConditionallyFlashed( layer ) ) + flashingA = FLASHING::ALWAYS_FLASHED; + } - if( parentB->Type() == PCB_PAD_T ) - { - if( !static_cast( parentB )->ConditionallyFlashed( layer ) ) - flashingB = FLASHING::ALWAYS_FLASHED; - } - else if( parentB->Type() == PCB_VIA_T ) - { - if( !static_cast( parentB )->ConditionallyFlashed( layer ) ) - flashingB = FLASHING::ALWAYS_FLASHED; - } + if( parentB->Type() == PCB_PAD_T ) + { + if( !static_cast( parentB )->ConditionallyFlashed( layer ) ) + flashingB = FLASHING::ALWAYS_FLASHED; + } + else if( parentB->Type() == PCB_VIA_T ) + { + if( !static_cast( parentB )->ConditionallyFlashed( layer ) ) + flashingB = FLASHING::ALWAYS_FLASHED; + } - if( parentA->GetEffectiveShape( layer, flashingA )->Collide( - parentB->GetEffectiveShape( layer, flashingB ).get() ) ) - { - m_item->Connect( aCandidate ); - aCandidate->Connect( m_item ); - return true; + if( parentA->GetEffectiveShape( layer, flashingA )->Collide( + parentB->GetEffectiveShape( layer, flashingB ).get() ) ) + { + m_item->Connect( aCandidate ); + aCandidate->Connect( m_item ); + return true; + } } } diff --git a/pcbnew/drc/drc_cache_generator.cpp b/pcbnew/drc/drc_cache_generator.cpp index 73c57c798e..4ef61c11ae 100644 --- a/pcbnew/drc/drc_cache_generator.cpp +++ b/pcbnew/drc/drc_cache_generator.cpp @@ -111,11 +111,11 @@ bool DRC_CACHE_GENERATOR::Run() copperLayers = boardCopperLayers; } - for( PCB_LAYER_ID layer : copperLayers.Seq() ) - { - if( IsCopperLayer( layer ) ) - m_board->m_CopperItemRTreeCache->Insert( item, layer, largestClearance ); - } + copperLayers.RunOnLayers( + [&]( PCB_LAYER_ID layer ) + { + m_board->m_CopperItemRTreeCache->Insert( item, layer, largestClearance ); + } ); done.fetch_add( 1 ); return true; @@ -179,11 +179,12 @@ bool DRC_CACHE_GENERATOR::Run() { std::unique_ptr rtree = std::make_unique(); - for( PCB_LAYER_ID layer : aZone->GetLayerSet().Seq() ) - { - if( IsCopperLayer( layer ) ) - rtree->Insert( aZone, layer ); - } + aZone->GetLayerSet().RunOnLayers( + [&]( PCB_LAYER_ID layer ) + { + if( IsCopperLayer( layer ) ) + rtree->Insert( aZone, layer ); + } ); { std::unique_lock writeLock( m_board->m_CachesMutex ); @@ -218,8 +219,11 @@ bool DRC_CACHE_GENERATOR::Run() { if( !zone->GetIsRuleArea() && !zone->IsTeardropArea() ) { - for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() ) - m_board->m_ZoneIsolatedIslandsMap[ zone ][ layer ] = ISOLATED_ISLANDS(); + zone->GetLayerSet().RunOnLayers( + [&]( PCB_LAYER_ID layer ) + { + m_board->m_ZoneIsolatedIslandsMap[ zone ][ layer ] = ISOLATED_ISLANDS(); + } ); } } diff --git a/pcbnew/drc/drc_test_provider_disallow.cpp b/pcbnew/drc/drc_test_provider_disallow.cpp index dba0f8273a..e0bdf8fb17 100644 --- a/pcbnew/drc/drc_test_provider_disallow.cpp +++ b/pcbnew/drc/drc_test_provider_disallow.cpp @@ -134,16 +134,21 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run() if( zoneRTree ) { - for( PCB_LAYER_ID layer : ruleArea->GetLayerSet().Seq() ) + for( size_t ii = 0; ii < ruleArea->GetLayerSet().size(); ++ii ) { - if( zoneRTree->QueryColliding( areaBBox, &areaPoly, layer ) ) + if( ruleArea->GetLayerSet().test( ii ) ) { - isInside = true; - break; - } + PCB_LAYER_ID layer = PCB_LAYER_ID( ii ); - if( m_drcEngine->IsCancelled() ) - return 0; + if( zoneRTree->QueryColliding( areaBBox, &areaPoly, layer ) ) + { + isInside = true; + break; + } + + if( m_drcEngine->IsCancelled() ) + return 0; + } } } } @@ -217,7 +222,7 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run() std::shared_ptr drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS ); DRC_RULE* rule = constraint.GetParentRule(); VECTOR2I pos = item->GetPosition(); - PCB_LAYER_ID layer = UNDEFINED_LAYER; + PCB_LAYER_ID layer = item->GetLayerSet().ExtractLayer(); wxString msg; msg.Printf( drcItem->GetErrorText() + wxS( " (%s)" ), constraint.GetName() ); @@ -226,9 +231,6 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run() drcItem->SetItems( item ); drcItem->SetViolatingRule( rule ); - if( item->GetLayerSet().count() ) - layer = item->GetLayerSet().Seq().front(); - if( rule->m_Implicit ) { // Provide a better location for keepout area collisions. diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index f6f2454555..8547c2a968 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -572,7 +572,7 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer ) { // For single-layer objects, exclude all layers including ancillary layers // such as holes, netnames, etc. - PCB_LAYER_ID singleLayer = item->GetLayerSet().Seq()[0]; + PCB_LAYER_ID singleLayer = item->GetLayerSet().ExtractLayer(); if( parentFP->GetPrivateLayers().test( singleLayer ) ) return false; diff --git a/pcbnew/pcb_track.cpp b/pcbnew/pcb_track.cpp index 05e5bba9db..330d060dd9 100644 --- a/pcbnew/pcb_track.cpp +++ b/pcbnew/pcb_track.cpp @@ -908,20 +908,21 @@ void PCB_VIA::SetLayerSet( LSET aLayerSet ) { bool first = true; - for( PCB_LAYER_ID layer : aLayerSet.Seq() ) - { - // m_layer and m_bottomLayer are copper layers, so consider only copper layers in aLayerSet - if( !IsCopperLayer( layer ) ) - continue; + aLayerSet.RunOnLayers( + [&]( PCB_LAYER_ID layer ) + { + // m_layer and m_bottomLayer are copper layers, so consider only copper layers + if( IsCopperLayer( layer ) ) + { + if( first ) + { + Padstack().Drill().start = layer; + first = false; + } - if( first ) - { - Padstack().Drill().start = layer; - first = false; - } - - Padstack().Drill().end = layer; - } + Padstack().Drill().end = layer; + } + } ); } @@ -995,10 +996,15 @@ void PCB_VIA::SanitizeLayers() bool PCB_VIA::FlashLayer( LSET aLayers ) const { - for( PCB_LAYER_ID layer : aLayers.Seq() ) + for( size_t ii = 0; ii < aLayers.size(); ++ii ) { - if( FlashLayer( layer ) ) - return true; + if( aLayers.test( ii ) ) + { + PCB_LAYER_ID layer = PCB_LAYER_ID( ii ); + + if( FlashLayer( layer ) ) + return true; + } } return false; @@ -1116,18 +1122,16 @@ double PCB_TRACK::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const return HIDE; } - // Pick the approximate size of the netname (square chars) - wxString netName = GetDisplayNetname(); - size_t num_chars = netName.size(); - - if( GetLength() < num_chars * GetWidth() ) - return HIDE; - - // When drawing netnames, clip the track to the viewport VECTOR2I start( GetStart() ); VECTOR2I end( GetEnd() ); - BOX2D viewport = aView->GetViewport(); - BOX2I clipBox = BOX2ISafe( viewport ); + + // Calc the approximate size of the netname (assume square chars) + SEG::ecoord nameSize = GetDisplayNetname().size() * GetWidth(); + + if( VECTOR2I( end - start ).SquaredEuclideanNorm() < nameSize * nameSize ) + return HIDE; + + BOX2I clipBox = BOX2ISafe( aView->GetViewport() ); ClipLine( &clipBox, start.x, start.y, end.x, end.y ); diff --git a/pcbnew/pcbexpr_functions.cpp b/pcbnew/pcbexpr_functions.cpp index d4bdfeec6e..b5bd74cc7c 100644 --- a/pcbnew/pcbexpr_functions.cpp +++ b/pcbnew/pcbexpr_functions.cpp @@ -528,12 +528,17 @@ bool collidesWithArea( BOARD_ITEM* aItem, PCBEXPR_CONTEXT* aCtx, ZONE* aArea ) if( zoneRTree ) { - for( PCB_LAYER_ID layer : aArea->GetLayerSet().Seq() ) + for( size_t ii = 0; ii < aArea->GetLayerSet().size(); ++ii ) { - if( aCtx->GetLayer() == layer || aCtx->GetLayer() == UNDEFINED_LAYER ) + if( aArea->GetLayerSet().test( ii ) ) { - if( zoneRTree->QueryColliding( areaBBox, &areaOutline, layer ) ) - return true; + PCB_LAYER_ID layer = PCB_LAYER_ID( ii ); + + if( aCtx->GetLayer() == layer || aCtx->GetLayer() == UNDEFINED_LAYER ) + { + if( zoneRTree->QueryColliding( areaBBox, &areaOutline, layer ) ) + return true; + } } } } diff --git a/pcbnew/ratsnest/ratsnest_view_item.cpp b/pcbnew/ratsnest/ratsnest_view_item.cpp index fcbca134d5..4113ca1c65 100644 --- a/pcbnew/ratsnest/ratsnest_view_item.cpp +++ b/pcbnew/ratsnest/ratsnest_view_item.cpp @@ -102,11 +102,12 @@ void RATSNEST_VIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const } else { - for( PCB_LAYER_ID layer : LSET::AllCuMask().Seq() ) - { - if( aView->IsLayerVisible( layer ) ) - visibleLayers.set( layer ); - } + LSET::AllCuMask().RunOnLayers( + [&]( PCB_LAYER_ID layer ) + { + if( aView->IsLayerVisible( layer ) ) + visibleLayers.set( layer ); + } ); } auto adjustColor = diff --git a/pcbnew/tools/zone_filler_tool.cpp b/pcbnew/tools/zone_filler_tool.cpp index 55cc764a56..c7a193641a 100644 --- a/pcbnew/tools/zone_filler_tool.cpp +++ b/pcbnew/tools/zone_filler_tool.cpp @@ -246,8 +246,11 @@ int ZONE_FILLER_TOOL::ZoneFillDirty( const TOOL_EVENT& aEvent ) for( ZONE* zone : toFill ) { - for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() ) - pts += zone->GetFilledPolysList( layer )->FullPointCount(); + zone->GetLayerSet().RunOnLayers( + [&]( PCB_LAYER_ID layer ) + { + pts += zone->GetFilledPolysList( layer )->FullPointCount(); + } ); if( pts > 1000 ) { diff --git a/pcbnew/zone.cpp b/pcbnew/zone.cpp index 0590fb98a3..bbad0eba73 100644 --- a/pcbnew/zone.cpp +++ b/pcbnew/zone.cpp @@ -150,18 +150,19 @@ void ZONE::InitDataFromSrcInCopyCtor( const ZONE& aZone ) delete m_CornerSelection; m_CornerSelection = nullptr; - for( PCB_LAYER_ID layer : aZone.GetLayerSet().Seq() ) - { - std::shared_ptr fill = aZone.m_FilledPolysList.at( layer ); + aZone.GetLayerSet().RunOnLayers( + [&]( PCB_LAYER_ID layer ) + { + std::shared_ptr fill = aZone.m_FilledPolysList.at( layer ); - if( fill ) - m_FilledPolysList[layer] = std::make_shared( *fill ); - else - m_FilledPolysList[layer] = std::make_shared(); + if( fill ) + m_FilledPolysList[layer] = std::make_shared( *fill ); + else + m_FilledPolysList[layer] = std::make_shared(); - m_filledPolysHash[layer] = aZone.m_filledPolysHash.at( layer ); - m_insulatedIslands[layer] = aZone.m_insulatedIslands.at( layer ); - } + m_filledPolysHash[layer] = aZone.m_filledPolysHash.at( layer ); + m_insulatedIslands[layer] = aZone.m_insulatedIslands.at( layer ); + } ); m_borderStyle = aZone.m_borderStyle; m_borderHatchPitch = aZone.m_borderHatchPitch; @@ -279,12 +280,13 @@ void ZONE::SetLayerSet( LSET aLayerSet ) m_filledPolysHash.clear(); m_insulatedIslands.clear(); - for( PCB_LAYER_ID layer : aLayerSet.Seq() ) - { - m_FilledPolysList[layer] = std::make_shared(); - m_filledPolysHash[layer] = {}; - m_insulatedIslands[layer] = {}; - } + aLayerSet.RunOnLayers( + [&]( PCB_LAYER_ID layer ) + { + m_FilledPolysList[layer] = std::make_shared(); + m_filledPolysHash[layer] = {}; + m_insulatedIslands[layer] = {}; + } ); } m_layerSet = aLayerSet; @@ -294,13 +296,13 @@ void ZONE::SetLayerSet( LSET aLayerSet ) void ZONE::ViewGetLayers( int aLayers[], int& aCount ) const { aCount = 0; - LSEQ layers = m_layerSet.Seq(); - for( PCB_LAYER_ID layer : m_layerSet.Seq() ) - { - aLayers[ aCount++ ] = layer; // For outline (always full opacity) - aLayers[ aCount++ ] = layer + static_cast( LAYER_ZONE_START ); // For fill (obeys global zone opacity) - } + m_layerSet.RunOnLayers( + [&]( PCB_LAYER_ID layer ) + { + aLayers[ aCount++ ] = layer; + aLayers[ aCount++ ] = layer + static_cast( LAYER_ZONE_START ); + } ); if( IsConflicting() ) aLayers[ aCount++ ] = LAYER_CONFLICTS_SHADOW;