Improve consistency of clearance line painting.

Showing the clearance area is not obvious as the clearance
extends from the pad on flashed copper layers and from the
hole on non-flashed copper layers.  Because of this, we
choose to not display clearance lines at all on non-copper
active layers as it's not clear which we'd be displaying.

We follow the same rule for tracks for consistency (even
though they don't have the same issue).

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18287
This commit is contained in:
Jeff Young 2024-06-28 21:46:32 +01:00
parent a68b3a7778
commit 7962ab07e7
1 changed files with 72 additions and 46 deletions

View File

@ -744,9 +744,20 @@ void PCB_PAINTER::draw( const PCB_TRACK* aTrack, int aLayer )
// Clearance lines // Clearance lines
if( pcbconfig() && pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS if( pcbconfig() && pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
&& !m_pcbSettings.m_isPrinting && aLayer != LAYER_LOCKED_ITEM_SHADOW ) && !m_pcbSettings.m_isPrinting
&& aLayer != LAYER_LOCKED_ITEM_SHADOW )
{ {
int clearance = aTrack->GetOwnClearance( m_pcbSettings.GetActiveLayer() ); /*
* Showing the clearance area is not obvious for optionally-flashed pads and vias, so we
* choose to not display clearance lines at all on non-copper active layers. We follow
* the same rule for tracks to be consistent (even though they don't have the same issue).
*/
PCB_LAYER_ID activeLayer = m_pcbSettings.GetActiveLayer();
const BOARD* board = aTrack->GetBoard();
if( IsCopperLayer( activeLayer ) && board->GetVisibleLayers().test( activeLayer ) )
{
int clearance = aTrack->GetOwnClearance( activeLayer );
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
m_gal->SetIsFill( false ); m_gal->SetIsFill( false );
@ -754,6 +765,7 @@ void PCB_PAINTER::draw( const PCB_TRACK* aTrack, int aLayer )
m_gal->SetStrokeColor( color ); m_gal->SetStrokeColor( color );
m_gal->DrawSegment( start, end, track_width + clearance * 2 ); m_gal->DrawSegment( start, end, track_width + clearance * 2 );
} }
}
} }
@ -864,9 +876,20 @@ void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer )
// Clearance lines // Clearance lines
if( pcbconfig() && pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS if( pcbconfig() && pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
&& !m_pcbSettings.m_isPrinting && aLayer != LAYER_LOCKED_ITEM_SHADOW ) && !m_pcbSettings.m_isPrinting
&& aLayer != LAYER_LOCKED_ITEM_SHADOW )
{ {
int clearance = aArc->GetOwnClearance( m_pcbSettings.GetActiveLayer() ); /*
* Showing the clearance area is not obvious for optionally-flashed pads and vias, so we
* choose to not display clearance lines at all on non-copper active layers. We follow
* the same rule for tracks to be consistent (even though they don't have the same issue).
*/
PCB_LAYER_ID activeLayer = m_pcbSettings.GetActiveLayer();
const BOARD* board = aArc->GetBoard();
if( IsCopperLayer( activeLayer ) && board->GetVisibleLayers().test( activeLayer ) )
{
int clearance = aArc->GetOwnClearance( activeLayer );
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
m_gal->SetIsFill( false ); m_gal->SetIsFill( false );
@ -876,6 +899,7 @@ void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer )
m_gal->DrawArcSegment( center, radius, start_angle, angle, width + clearance * 2, m_gal->DrawArcSegment( center, radius, start_angle, angle, width + clearance * 2,
m_maxError ); m_maxError );
} }
}
// Debug only: enable this code only to test the TransformArcToPolygon function // Debug only: enable this code only to test the TransformArcToPolygon function
// and display the polygon outline created by it. // and display the polygon outline created by it.
@ -1121,9 +1145,19 @@ void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer )
// Clearance lines // Clearance lines
if( pcbconfig() && pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS if( pcbconfig() && pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
&& aLayer != LAYER_VIA_HOLES && aLayer != LAYER_VIA_HOLES
&& !m_pcbSettings.m_isPrinting ) && !m_pcbSettings.m_isPrinting
&& aLayer != LAYER_LOCKED_ITEM_SHADOW )
{ {
/*
* Showing the clearance area is not obvious as the clearance extends from the via's pad
* on flashed copper layers and from the via's hole on non-flashed copper layers. Because
* of this, we choose to not display clearance lines at all on non-copper active layers as
* it's not clear which we'd be displaying.
*/
PCB_LAYER_ID activeLayer = m_pcbSettings.GetActiveLayer(); PCB_LAYER_ID activeLayer = m_pcbSettings.GetActiveLayer();
if( IsCopperLayer( activeLayer ) && board->GetVisibleLayers().test( activeLayer ) )
{
double radius; double radius;
if( aVia->FlashLayer( activeLayer ) ) if( aVia->FlashLayer( activeLayer ) )
@ -1137,6 +1171,7 @@ void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer )
m_gal->SetStrokeColor( color ); m_gal->SetStrokeColor( color );
m_gal->DrawCircle( center, radius + aVia->GetOwnClearance( activeLayer ) ); m_gal->DrawCircle( center, radius + aVia->GetOwnClearance( activeLayer ) );
} }
}
} }
@ -1634,24 +1669,15 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
&& ( aLayer == LAYER_PADS_SMD_FR || aLayer == LAYER_PADS_SMD_BK || aLayer == LAYER_PADS_TH ) && ( aLayer == LAYER_PADS_SMD_FR || aLayer == LAYER_PADS_SMD_BK || aLayer == LAYER_PADS_TH )
&& !m_pcbSettings.m_isPrinting ) && !m_pcbSettings.m_isPrinting )
{ {
/* Showing the clearance area is not obvious. /*
* - A pad can be removed from some copper layers. * Showing the clearance area is not obvious as the clearance extends from the pad on
* - For non copper layers, what is the clearance area? * flashed copper layers and from the hole on non-flashed copper layers. Because of this,
* So for copper layers, the clearance area is the shape if the pad is flashed on this * we choose to not display clearance lines at all on non-copper active layers as it's
* layer and the hole clearance area for other copper layers. * not clear which we'd be displaying.
* For other layers, use the pad shape, although one can use an other criteria,
* depending on the non copper layer.
*/ */
int activeLayer = m_pcbSettings.GetActiveLayer(); PCB_LAYER_ID activeLayer = m_pcbSettings.GetActiveLayer();
bool flashActiveLayer = true;
if( IsCopperLayer( activeLayer ) ) if( IsCopperLayer( activeLayer ) && board->GetVisibleLayers().test( activeLayer ) )
flashActiveLayer = aPad->FlashLayer( activeLayer );
if( !board->GetVisibleLayers().test( activeLayer ) )
flashActiveLayer = false;
if( flashActiveLayer || aPad->GetDrillSize().x )
{ {
if( aPad->GetAttribute() == PAD_ATTRIB::NPTH ) if( aPad->GetAttribute() == PAD_ATTRIB::NPTH )
color = m_pcbSettings.GetLayerColor( LAYER_NON_PLATEDHOLES ); color = m_pcbSettings.GetLayerColor( LAYER_NON_PLATEDHOLES );
@ -1661,9 +1687,9 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
m_gal->SetIsFill( false ); m_gal->SetIsFill( false );
m_gal->SetStrokeColor( color ); m_gal->SetStrokeColor( color );
int clearance = aPad->GetOwnClearance( m_pcbSettings.GetActiveLayer() ); int clearance = aPad->GetOwnClearance( activeLayer );
if( flashActiveLayer && clearance > 0 ) if( aPad->FlashLayer( activeLayer ) && clearance > 0 )
{ {
auto shape = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() ); auto shape = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape() );
@ -1683,8 +1709,8 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
SHAPE_POLY_SET polySet; SHAPE_POLY_SET polySet;
// Use ERROR_INSIDE because it avoids Clipper and is therefore much faster. // Use ERROR_INSIDE because it avoids Clipper and is therefore much faster.
aPad->TransformShapeToPolygon( polySet, ToLAYER_ID( aLayer ), clearance, aPad->TransformShapeToPolygon( polySet, activeLayer, clearance, m_maxError,
m_maxError, ERROR_INSIDE ); ERROR_INSIDE );
if( polySet.Outline( 0 ).PointCount() > 2 ) // Careful of empty pads if( polySet.Outline( 0 ).PointCount() > 2 ) // Careful of empty pads
m_gal->DrawPolygon( polySet ); m_gal->DrawPolygon( polySet );