diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp index 1eb2c6e13d..c347c49e44 100644 --- a/pcbnew/pad.cpp +++ b/pcbnew/pad.cpp @@ -247,7 +247,7 @@ bool PAD::FlashLayer( LSET aLayers ) const } -bool PAD::FlashLayer( int aLayer ) const +bool PAD::FlashLayer( int aLayer, bool aOnlyCheckIfPermitted ) const { if( aLayer == UNDEFINED_LAYER ) return true; @@ -304,9 +304,20 @@ bool PAD::FlashLayer( int aLayer ) const // clearance. // See https://gitlab.com/kicad/code/kicad/-/issues/11299. if( m_zoneLayerConnections[ aLayer ] == ZLC_CONNECTED ) + { return true; - - return board->GetConnectivity()->IsConnectedOnLayer( this, aLayer, types ); + } + else if( m_zoneLayerConnections[ aLayer ] == ZLC_UNCONNECTED ) + { + return false; + } + else /* ZLC_UNRESOLVED */ + { + if( aOnlyCheckIfPermitted ) + return true; + else + return board->GetConnectivity()->IsConnectedOnLayer( this, aLayer, types ); + } } } diff --git a/pcbnew/pad.h b/pcbnew/pad.h index cfff55fb11..5ce61fb3e9 100644 --- a/pcbnew/pad.h +++ b/pcbnew/pad.h @@ -631,9 +631,16 @@ public: * Check to see whether the pad should be flashed on the specific layer. * * @param aLayer Layer to check for connectivity + * @param aOnlyCheckIfPermitted indicates that the routine should just return whether or not + * a flashed connection is permitted on this layer (without checking for a connection) * @return true if connected by pad or track (or optionally zone) */ - bool FlashLayer( int aLayer ) const; + bool FlashLayer( int aLayer, bool aOnlyCheckIfPermitted = false ) const; + + bool CanFlashLayer( int aLayer ) + { + return FlashLayer( aLayer, true ); + } PCB_LAYER_ID GetLayer() const override; diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 0ce3598f92..88eb09f70f 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -305,6 +305,7 @@ COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) cons { PCB_LAYER_ID primary = GetPrimaryHighContrastLayer(); bool isActive = m_highContrastLayers.count( aLayer ); + bool hide = false; switch( originalLayer ) { @@ -313,7 +314,10 @@ COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) cons const PAD* pad = static_cast( item ); if( !pad->FlashLayer( primary ) ) + { isActive = false; + hide = true; + } if( m_PadEditModePad && pad != m_PadEditModePad ) isActive = false; @@ -328,7 +332,10 @@ COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) cons // Target graphic is active if the via crosses the primary layer if( via->GetLayerSet().test( primary ) == 0 ) + { isActive = false; + hide = true; + } break; } @@ -338,7 +345,10 @@ COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) cons const PCB_VIA* via = static_cast( item ); if( !via->FlashLayer( primary ) ) + { isActive = false; + hide = true; + } break; } @@ -380,8 +390,12 @@ COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) cons if( !isActive ) { - if( m_ContrastModeDisplay == HIGH_CONTRAST_MODE::HIDDEN || IsNetnameLayer( aLayer ) ) + if( m_ContrastModeDisplay == HIGH_CONTRAST_MODE::HIDDEN + || IsNetnameLayer( aLayer ) + || hide ) + { color = COLOR4D::CLEAR; + } else { color = color.Mix( m_layerColors[LAYER_PCB_BACKGROUND], m_hiContrastFactor ); diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp index da7cb85d5d..9096eff4ed 100644 --- a/pcbnew/zone_filler.cpp +++ b/pcbnew/zone_filler.cpp @@ -734,10 +734,16 @@ void ZONE_FILLER::knockoutThermalReliefs( const ZONE* aZone, PCB_LAYER_ID aLayer constraint = bds.m_DRCEngine->EvalRules( THERMAL_RELIEF_GAP_CONSTRAINT, pad, aZone, aLayer ); padClearance = constraint.GetValue().Min(); - holeClearance = padClearance; - if( pad->FlashLayer( aLayer ) ) + if( pad->CanFlashLayer( aLayer ) ) + { aThermalConnectionPads.push_back( pad ); + addKnockout( pad, aLayer, padClearance, holes ); + } + else if( pad->GetDrillSize().x > 0 ) + { + pad->TransformHoleToPolygon( holes, padClearance, m_maxError, ERROR_OUTSIDE ); + } break; @@ -750,13 +756,22 @@ void ZONE_FILLER::knockoutThermalReliefs( const ZONE* aZone, PCB_LAYER_ID aLayer else padClearance = aZone->GetLocalClearance(); - constraint = bds.m_DRCEngine->EvalRules( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT, pad, - aZone, aLayer ); + if( pad->FlashLayer( aLayer ) ) + { + addKnockout( pad, aLayer, padClearance, holes ); + } + else if( pad->GetDrillSize().x > 0 ) + { + constraint = bds.m_DRCEngine->EvalRules( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT, + pad, aZone, aLayer ); - if( constraint.GetValue().Min() > padClearance ) - holeClearance = constraint.GetValue().Min(); - else - holeClearance = padClearance; + if( constraint.GetValue().Min() > padClearance ) + holeClearance = constraint.GetValue().Min(); + else + holeClearance = padClearance; + + pad->TransformHoleToPolygon( holes, holeClearance, m_maxError, ERROR_OUTSIDE ); + } break; @@ -764,11 +779,6 @@ void ZONE_FILLER::knockoutThermalReliefs( const ZONE* aZone, PCB_LAYER_ID aLayer // No knockout continue; } - - if( pad->FlashLayer( aLayer ) ) - addKnockout( pad, aLayer, padClearance, holes ); - else if( pad->GetDrillSize().x > 0 ) - pad->TransformHoleToPolygon( holes, holeClearance, m_maxError, ERROR_OUTSIDE ); } }