From d2de114d21e4f36bb6fc176c039efba782bab9ef Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 14 Feb 2022 13:34:45 +0000 Subject: [PATCH] More performance optimizations. --- pcbnew/connectivity/connectivity_algo.cpp | 28 ++++++++++++---------- pcbnew/connectivity/connectivity_items.cpp | 4 ++-- pcbnew/pcb_track.cpp | 25 +++++++++++++++---- pcbnew/tools/zone_filler_tool.cpp | 2 +- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/pcbnew/connectivity/connectivity_algo.cpp b/pcbnew/connectivity/connectivity_algo.cpp index b7b6083e0d..8734db5b0e 100644 --- a/pcbnew/connectivity/connectivity_algo.cpp +++ b/pcbnew/connectivity/connectivity_algo.cpp @@ -443,10 +443,12 @@ void CN_CONNECTIVITY_ALGO::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter ) for( FOOTPRINT* footprint : aBoard->Footprints() ) size += footprint->Pads().size(); - size *= 2; // Our caller us gets the other half of the progress bar + size *= 2; // Our caller gets the other half of the progress bar delta = std::max( delta, size / 10 ); + reportProgress( aReporter, 0, size, delta ); + for( ZONE* zone : aBoard->Zones() ) { Add( zone ); @@ -672,7 +674,12 @@ void CN_VISITOR::checkZoneItemConnection( CN_ZONE_LAYER* aZoneLayer, CN_ITEM* aI if( aZoneLayer->Net() != aItem->Net() && !aItem->CanChangeNet() ) return; - if( aZoneLayer->Collide( aItem->Parent()->GetEffectiveShape( aZoneLayer->GetLayer() ).get() ) ) + PCB_LAYER_ID layer = aZoneLayer->GetLayer(); + + if( !aItem->Parent()->IsOnLayer( layer ) ) + return; + + if( aZoneLayer->Collide( aItem->Parent()->GetEffectiveShape( layer ).get() ) ) { aZoneLayer->Connect( aItem ); aItem->Connect( aZoneLayer ); @@ -684,19 +691,19 @@ void CN_VISITOR::checkZoneZoneConnection( CN_ZONE_LAYER* aZoneLayerA, CN_ZONE_LA const ZONE* zoneA = static_cast( aZoneLayerA->Parent() ); const ZONE* zoneB = static_cast( aZoneLayerB->Parent() ); - if( aZoneLayerA->Layer() != aZoneLayerB->Layer() ) - return; - if( aZoneLayerB->Net() != aZoneLayerA->Net() ) return; // we only test zones belonging to the same net const BOX2I& boxA = aZoneLayerA->BBox(); const BOX2I& boxB = aZoneLayerB->BBox(); - if( !boxA.Intersects( boxB ) ) + PCB_LAYER_ID layer = aZoneLayerA->GetLayer(); + + if( aZoneLayerB->GetLayer() != layer ) return; - PCB_LAYER_ID layer = static_cast( aZoneLayerA->Layer() ); + if( !boxA.Intersects( boxB ) ) + return; const SHAPE_LINE_CHAIN& outline = zoneA->GetFilledPolysList( layer ).COutline( aZoneLayerA->SubpolyIndex() ); @@ -743,11 +750,6 @@ bool CN_VISITOR::operator()( CN_ITEM* aCandidate ) if( parentA == parentB ) return true; - LSET commonLayers = parentA->GetLayerSet() & parentB->GetLayerSet(); - - if( !commonLayers.any() ) - return true; - // If both m_item and aCandidate are marked dirty, they will both be searched // Since we are reciprocal in our connection, we arbitrarily pick one of the connections // to conduct the expensive search @@ -774,6 +776,8 @@ bool CN_VISITOR::operator()( CN_ITEM* aCandidate ) return true; } + LSET commonLayers = parentA->GetLayerSet() & parentB->GetLayerSet(); + for( PCB_LAYER_ID layer : commonLayers.Seq() ) { if( parentA->GetEffectiveShape( layer )->Collide( parentB->GetEffectiveShape( layer ).get() ) ) diff --git a/pcbnew/connectivity/connectivity_items.cpp b/pcbnew/connectivity/connectivity_items.cpp index 82b7678b0e..3b0c263c50 100644 --- a/pcbnew/connectivity/connectivity_items.cpp +++ b/pcbnew/connectivity/connectivity_items.cpp @@ -205,8 +205,8 @@ CN_ITEM* CN_LIST::Add( PCB_ARC* aArc ) for( int j = 0; j < polys.OutlineCount(); j++ ) { - CN_ZONE_LAYER* zitem = new CN_ZONE_LAYER( zone, aLayer, false, j ); - const auto& outline = zone->GetFilledPolysList( aLayer ).COutline( j ); + CN_ZONE_LAYER* zitem = new CN_ZONE_LAYER( zone, aLayer, false, j ); + const SHAPE_LINE_CHAIN& outline = zone->GetFilledPolysList( aLayer ).COutline( j ); for( int k = 0; k < outline.PointCount(); k++ ) zitem->AddAnchor( outline.CPoint( k ) ); diff --git a/pcbnew/pcb_track.cpp b/pcbnew/pcb_track.cpp index c4adf3c918..fe1d2d7d5e 100644 --- a/pcbnew/pcb_track.cpp +++ b/pcbnew/pcb_track.cpp @@ -381,7 +381,23 @@ int PCB_VIA::GetSolderMaskExpansion() const bool PCB_VIA::IsOnLayer( PCB_LAYER_ID aLayer ) const { +#if 0 + // Nice and simple, but raises its ugly head in performance profiles.... return GetLayerSet().test( aLayer ); +#endif + + if( aLayer >= m_layer && aLayer <= m_bottomLayer ) + return true; + + if( !IsTented() ) + { + if( m_layer == F_Mask ) + return IsOnLayer( F_Cu ); + else if( m_layer == B_Mask ) + return IsOnLayer( B_Cu ); + } + + return false; } @@ -510,9 +526,6 @@ bool PCB_VIA::FlashLayer( LSET aLayers ) const bool PCB_VIA::FlashLayer( int aLayer ) const { - std::vector types - { PCB_TRACE_T, PCB_ARC_T, PCB_PAD_T, PCB_ZONE_T, PCB_FP_ZONE_T }; - // Return the "normal" shape if the caller doesn't specify a particular layer if( aLayer == UNDEFINED_LAYER ) return true; @@ -531,7 +544,11 @@ bool PCB_VIA::FlashLayer( int aLayer ) const if( m_keepTopBottomLayer && ( aLayer == m_layer || aLayer == m_bottomLayer ) ) return true; - return board->GetConnectivity()->IsConnectedOnLayer( this, static_cast( aLayer ), types ); + // Must be static to keep from raising its ugly head in performance profiles + static std::vector connectedTypes = { PCB_TRACE_T, PCB_ARC_T, PCB_PAD_T, + PCB_ZONE_T, PCB_FP_ZONE_T }; + + return board->GetConnectivity()->IsConnectedOnLayer( this, aLayer, connectedTypes ); } diff --git a/pcbnew/tools/zone_filler_tool.cpp b/pcbnew/tools/zone_filler_tool.cpp index d4a0108dc5..91300b89a7 100644 --- a/pcbnew/tools/zone_filler_tool.cpp +++ b/pcbnew/tools/zone_filler_tool.cpp @@ -157,7 +157,7 @@ void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aRepo { if( filler.Fill( toFill ) ) { - board()->GetConnectivity()->Build( board() ); + board()->GetConnectivity()->Build( board(), reporter.get() ); commit.Push( _( "Fill Zone(s)" ), true ); // Allow undoing zone fill frame->m_ZoneFillsDirty = false; }