diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp index 0f9adc7d85..99635665cb 100644 --- a/pcbnew/pad.cpp +++ b/pcbnew/pad.cpp @@ -186,11 +186,11 @@ bool PAD::IsFlipped() const } -bool PAD::FlashLayer( LSET aLayers ) const +bool PAD::FlashLayer( LSET aLayers, bool aIncludeZones ) const { for( auto layer : aLayers.Seq() ) { - if( FlashLayer( layer ) ) + if( FlashLayer( layer, aIncludeZones ) ) return true; } @@ -198,8 +198,21 @@ bool PAD::FlashLayer( LSET aLayers ) const } -bool PAD::FlashLayer( int aLayer ) const +bool PAD::FlashLayer( int aLayer, bool aIncludeZones ) const { + std::vector types{ PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T }; + + /** + * Normally, we don't need to include zones in our flash check because the + * zones will fill over the hole. But, when we are drawing the pad in + * pcbnew, it is helpful to show the annular ring where the pad is connected + */ + if( aIncludeZones ) + { + types.push_back( PCB_ZONE_T ); + types.push_back( PCB_FP_ZONE_T ); + } + // Return the "normal" shape if the caller doesn't specify a particular layer if( aLayer == UNDEFINED_LAYER ) return true; @@ -226,7 +239,7 @@ bool PAD::FlashLayer( int aLayer ) const return IsOnLayer( static_cast( aLayer ) ); return board->GetConnectivity()->IsConnectedOnLayer( this, static_cast( aLayer ), - { PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T, PCB_PAD_T } ); + types ); } diff --git a/pcbnew/pad.h b/pcbnew/pad.h index 4609cd0f41..567f87014d 100644 --- a/pcbnew/pad.h +++ b/pcbnew/pad.h @@ -549,8 +549,21 @@ public: return m_layerMask[aLayer]; } - bool FlashLayer( int aLayer ) const; - bool FlashLayer( LSET aLayers ) const; + /** + * Checks to see whether the pad should be flashed on the specific layer + * @param aLayer Layer to check for connectivity + * @param aIncludeZones We include zones in potentially connected elements when drawing + * @return true if connected by pad or track (or optionally zone) + */ + bool FlashLayer( int aLayer, bool aIncludeZones = false ) const; + + /** + * Checks to see if the pad should be flashed to any of the layers in the set + * @param aLayers set of layers to check the via against + * @param aIncludeZones We include zones in potentially connected elements when drawing + * @return true if connected by pad or track (or optionally zone) on any of the associated layers + */ + bool FlashLayer( LSET aLayers, bool aIncludeZones = false ) const; bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 9108383475..a59b3775a8 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -640,7 +640,7 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer ) for( unsigned int layer : m_pcbSettings.GetHighContrastLayers() ) { - if( aVia->IsOnLayer( static_cast( layer ) ) ) + if( aVia->FlashLayer( static_cast( layer ), true ) ) { draw = true; break; @@ -692,6 +692,23 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer ) || ( aLayer == LAYER_VIA_BBLIND && aVia->GetViaType() == VIATYPE::BLIND_BURIED ) || ( aLayer == LAYER_VIA_MICROVIA && aVia->GetViaType() == VIATYPE::MICROVIA ) ) { + if( m_pcbSettings.GetHighContrast() ) + { + bool draw_annular = false; + + for( unsigned int layer : m_pcbSettings.GetHighContrastLayers() ) + { + if( aVia->FlashLayer( static_cast( layer ) , true ) ) + { + draw_annular = true; + break; + } + } + + if( !draw_annular ) + return; + } + radius = aVia->GetWidth() / 2.0; } else @@ -701,7 +718,7 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer ) /// Vias not connected to copper are optionally not drawn /// We draw instead the hole size to ensure we show the proper clearance - if( IsCopperLayer( aLayer ) && !aVia->FlashLayer( aLayer ) ) + if( IsCopperLayer( aLayer ) && !aVia->FlashLayer( aLayer, true ) ) radius = getDrillSize( aVia ) / 2.0 ; bool sketchMode = false; @@ -900,6 +917,27 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer ) // Pad drawing BOARD_DESIGN_SETTINGS& bds = aPad->GetBoard()->GetDesignSettings(); COLOR4D color = m_pcbSettings.GetColor( aPad, aLayer ); + bool draw_annular = true; + + if( aLayer == LAYER_PADS_TH + && aPad->GetSizeX() <= aPad->GetDrillSizeX() + && aPad->GetSizeY() <= aPad->GetDrillSizeY() ) + { + draw_annular = false; + } + else if( m_pcbSettings.GetHighContrast() ) + { + draw_annular = false; + + for( unsigned int layer : m_pcbSettings.GetHighContrastLayers() ) + { + if( aPad->FlashLayer( static_cast( layer ) , true ) ) + { + draw_annular = true; + break; + } + } + } if( m_pcbSettings.m_sketchMode[LAYER_PADS_TH] ) { @@ -927,9 +965,7 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer ) else m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B, seg->GetWidth() ); } - else if( aLayer == LAYER_PADS_TH - && aPad->GetSizeX() <= aPad->GetDrillSizeX() - && aPad->GetSizeY() <= aPad->GetDrillSizeY() ) + else if( !draw_annular ) { // no annular ring to draw } diff --git a/pcbnew/track.cpp b/pcbnew/track.cpp index 1cc8bd53d1..8fbd9ff1df 100644 --- a/pcbnew/track.cpp +++ b/pcbnew/track.cpp @@ -467,7 +467,7 @@ void VIA::SanitizeLayers() } -bool VIA::FlashLayer( LSET aLayers ) const +bool VIA::FlashLayer( LSET aLayers, bool aIncludeZones ) const { for( auto layer : aLayers.Seq() ) { @@ -479,8 +479,21 @@ bool VIA::FlashLayer( LSET aLayers ) const } -bool VIA::FlashLayer( int aLayer ) const +bool VIA::FlashLayer( int aLayer, bool aIncludeZones ) const { + std::vector types{ PCB_TRACE_T, PCB_ARC_T, PCB_PAD_T }; + + /** + * Normally, we don't need to include zones in our flash check because the + * zones will fill over the hole. But, when we are drawing the via in + * pcbnew, it is helpful to show the annular ring where the via is connected + */ + if( aIncludeZones ) + { + types.push_back( PCB_ZONE_T ); + types.push_back( PCB_FP_ZONE_T ); + } + // Return the "normal" shape if the caller doesn't specify a particular layer if( aLayer == UNDEFINED_LAYER ) return true; @@ -500,7 +513,7 @@ bool VIA::FlashLayer( int aLayer ) const return true; return board->GetConnectivity()->IsConnectedOnLayer( this, static_cast( aLayer ), - { PCB_TRACE_T, PCB_ARC_T, PCB_PAD_T } ); + types ); } diff --git a/pcbnew/track.h b/pcbnew/track.h index 6086702deb..df465ed517 100644 --- a/pcbnew/track.h +++ b/pcbnew/track.h @@ -466,16 +466,18 @@ public: /** * Checks to see whether the via should have a pad on the specific layer * @param aLayer Layer to check for connectivity - * @return true if connected by pad or track + * @param aIncludeZones We include zones in potentially connected elements when drawing + * @return true if connected by pad or track (or optionally zone) */ - bool FlashLayer( int aLayer ) const; + bool FlashLayer( int aLayer, bool aIncludeZones = false ) const; /** * Checks to see if the via is present on any of the layers in the set * @param aLayers set of layers to check the via against - * @return true if connected by pad or track on any of the associated layers + * @param aIncludeZones We include zones in potentially connected elements when drawing + * @return true if connected by pad or track (or optionally zone) on any of the associated layers */ - bool FlashLayer( LSET aLayers ) const; + bool FlashLayer( LSET aLayers, bool aIncludeZones = false ) const; /** * Function SetDrill