7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-21 00:21:25 +00:00

Pcbnew: draw clearance lines on their own GAL layers

This tidies up quite a performance hit on layer change
caused by repainting vias, pads and tracks for their
clearances.

Instead, on a layer change, just disable any old clearance
layer and enable the new one (if any).

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/19404
This commit is contained in:
John Beard 2024-12-29 23:38:40 +08:00
parent 5520b524f6
commit f7aded00c7
9 changed files with 194 additions and 170 deletions

View File

@ -164,6 +164,10 @@ void VIEW_GROUP::ViewDraw( int aLayer, VIEW* aView ) const
{
draw = aView->IsLayerVisible( layer - LAYER_VIA_COPPER_START );
}
else if( IsClearanceLayer( layer ) )
{
draw = aView->IsLayerVisible( layer - LAYER_CLEARANCE_START );
}
if( isSelection )
{

View File

@ -266,6 +266,10 @@ enum GAL_LAYER_ID: int
LAYER_VIA_COPPER_START,
LAYER_VIA_COPPER_END = LAYER_VIA_COPPER_START + PCB_LAYER_ID_COUNT,
/// Virtual layers for pad/via/track clearance outlines for a given copper layer
LAYER_CLEARANCE_START,
LAYER_CLEARANCE_END = LAYER_CLEARANCE_START + PCB_LAYER_ID_COUNT,
/// Virtual layers for background images per board layer
LAYER_BITMAP_START,
LAYER_BITMAP_END = LAYER_BITMAP_START + PCB_LAYER_ID_COUNT,
@ -285,6 +289,7 @@ enum GAL_LAYER_ID: int
#define ZONE_LAYER_FOR( boardLayer ) ( LAYER_ZONE_START + boardLayer )
#define PAD_COPPER_LAYER_FOR( boardLayer ) ( LAYER_PAD_COPPER_START + boardLayer )
#define VIA_COPPER_LAYER_FOR( boardLayer ) ( LAYER_VIA_COPPER_START + boardLayer )
#define CLEARANCE_LAYER_FOR( boardLayer ) ( LAYER_CLEARANCE_START + boardLayer )
constexpr int GAL_LAYER_ID_COUNT = GAL_LAYER_ID_END - GAL_LAYER_ID_START;
@ -753,6 +758,12 @@ inline bool IsViaCopperLayer( int aLayer )
}
inline bool IsClearanceLayer( int aLayer )
{
return aLayer >= LAYER_CLEARANCE_START && aLayer <= LAYER_CLEARANCE_END;
}
inline bool IsDCodeLayer( int aLayer )
{
return aLayer >= ( GERBVIEW_LAYER_ID_START + GERBER_DRAWLAYERS_COUNT )

View File

@ -1634,13 +1634,17 @@ std::vector<int> PAD::ViewGetLayers() const
{
// Multi layer pad
for( PCB_LAYER_ID layer : cuLayers.Seq() )
{
layers.push_back( LAYER_PAD_COPPER_START + layer );
layers.push_back( LAYER_CLEARANCE_START + layer );
}
layers.push_back( LAYER_PAD_NETNAMES );
}
else if( IsOnLayer( F_Cu ) )
{
layers.push_back( LAYER_PAD_COPPER_START );
layers.push_back( LAYER_CLEARANCE_START );
// Is this a PTH pad that has only front copper? If so, we need to also display the
// net name on the PTH netname layer so that it isn't blocked by the drill hole.
@ -1652,6 +1656,7 @@ std::vector<int> PAD::ViewGetLayers() const
else if( IsOnLayer( B_Cu ) )
{
layers.push_back( LAYER_PAD_COPPER_START + B_Cu );
layers.push_back( LAYER_CLEARANCE_START + B_Cu );
// Is this a PTH pad that has only back copper? If so, we need to also display the
// net name on the PTH netname layer so that it isn't blocked by the drill hole.

View File

@ -954,6 +954,8 @@ PCB_LAYER_ID PADSTACK::EffectiveLayerFor( PCB_LAYER_ID aLayer ) const
boardCuLayer = ToLAYER_ID( static_cast<int>( aLayer ) - LAYER_VIA_COPPER_START );
else if( IsPadCopperLayer( aLayer ) )
boardCuLayer = ToLAYER_ID( static_cast<int>( aLayer ) - LAYER_PAD_COPPER_START );
else if( IsClearanceLayer( aLayer ) )
boardCuLayer = ToLAYER_ID( static_cast<int>( aLayer ) - LAYER_CLEARANCE_START );
if( IsFrontLayer( boardCuLayer ) )
return F_Cu;

View File

@ -106,6 +106,7 @@ const int GAL_LAYER_ORDER[] =
NETNAMES_LAYER_INDEX( F_Cu ),
PAD_COPPER_LAYER_FOR( F_Cu ),
VIA_COPPER_LAYER_FOR( F_Cu ),
CLEARANCE_LAYER_FOR( F_Cu ),
F_Cu, ZONE_LAYER_FOR( F_Cu ),
F_Mask, ZONE_LAYER_FOR( F_Mask ),
F_SilkS, ZONE_LAYER_FOR( F_SilkS ),
@ -115,70 +116,101 @@ const int GAL_LAYER_ORDER[] =
F_Fab, ZONE_LAYER_FOR( F_Fab ),
NETNAMES_LAYER_INDEX( In1_Cu ), PAD_COPPER_LAYER_FOR( In1_Cu ),
VIA_COPPER_LAYER_FOR( In1_Cu ), In1_Cu, ZONE_LAYER_FOR( In1_Cu ),
VIA_COPPER_LAYER_FOR( In1_Cu ), CLEARANCE_LAYER_FOR( In1_Cu ),
In1_Cu, ZONE_LAYER_FOR( In1_Cu ),
NETNAMES_LAYER_INDEX( In2_Cu ), PAD_COPPER_LAYER_FOR( In2_Cu ),
VIA_COPPER_LAYER_FOR( In2_Cu ), In2_Cu, ZONE_LAYER_FOR( In2_Cu ),
VIA_COPPER_LAYER_FOR( In2_Cu ), CLEARANCE_LAYER_FOR( In2_Cu ),
In2_Cu, ZONE_LAYER_FOR( In2_Cu ),
NETNAMES_LAYER_INDEX( In3_Cu ), PAD_COPPER_LAYER_FOR( In3_Cu ),
VIA_COPPER_LAYER_FOR( In3_Cu ), In3_Cu, ZONE_LAYER_FOR( In3_Cu ),
VIA_COPPER_LAYER_FOR( In3_Cu ), CLEARANCE_LAYER_FOR( In3_Cu ),
In3_Cu, ZONE_LAYER_FOR( In3_Cu ),
NETNAMES_LAYER_INDEX( In4_Cu ), PAD_COPPER_LAYER_FOR( In4_Cu ),
VIA_COPPER_LAYER_FOR( In4_Cu ), In4_Cu, ZONE_LAYER_FOR( In4_Cu ),
VIA_COPPER_LAYER_FOR( In4_Cu ), CLEARANCE_LAYER_FOR( In4_Cu ),
In4_Cu, ZONE_LAYER_FOR( In4_Cu ),
NETNAMES_LAYER_INDEX( In5_Cu ), PAD_COPPER_LAYER_FOR( In5_Cu ),
VIA_COPPER_LAYER_FOR( In5_Cu ), In5_Cu, ZONE_LAYER_FOR( In5_Cu ),
VIA_COPPER_LAYER_FOR( In5_Cu ), CLEARANCE_LAYER_FOR( In5_Cu ),
In5_Cu, ZONE_LAYER_FOR( In5_Cu ),
NETNAMES_LAYER_INDEX( In6_Cu ), PAD_COPPER_LAYER_FOR( In6_Cu ),
VIA_COPPER_LAYER_FOR( In6_Cu ), In6_Cu, ZONE_LAYER_FOR( In6_Cu ),
VIA_COPPER_LAYER_FOR( In6_Cu ), CLEARANCE_LAYER_FOR( In6_Cu ),
In6_Cu, ZONE_LAYER_FOR( In6_Cu ),
NETNAMES_LAYER_INDEX( In7_Cu ), PAD_COPPER_LAYER_FOR( In7_Cu ),
VIA_COPPER_LAYER_FOR( In7_Cu ), In7_Cu, ZONE_LAYER_FOR( In7_Cu ),
VIA_COPPER_LAYER_FOR( In7_Cu ), CLEARANCE_LAYER_FOR( In7_Cu ),
In7_Cu, ZONE_LAYER_FOR( In7_Cu ),
NETNAMES_LAYER_INDEX( In8_Cu ), PAD_COPPER_LAYER_FOR( In8_Cu ),
VIA_COPPER_LAYER_FOR( In8_Cu ), In8_Cu, ZONE_LAYER_FOR( In8_Cu ),
VIA_COPPER_LAYER_FOR( In8_Cu ), CLEARANCE_LAYER_FOR( In8_Cu ),
In8_Cu, ZONE_LAYER_FOR( In8_Cu ),
NETNAMES_LAYER_INDEX( In9_Cu ), PAD_COPPER_LAYER_FOR( In9_Cu ),
VIA_COPPER_LAYER_FOR( In9_Cu ), In9_Cu, ZONE_LAYER_FOR( In9_Cu ),
VIA_COPPER_LAYER_FOR( In9_Cu ), CLEARANCE_LAYER_FOR( In9_Cu ),
In9_Cu, ZONE_LAYER_FOR( In9_Cu ),
NETNAMES_LAYER_INDEX( In10_Cu ), PAD_COPPER_LAYER_FOR( In10_Cu ),
VIA_COPPER_LAYER_FOR( In10_Cu ), In10_Cu, ZONE_LAYER_FOR( In10_Cu ),
VIA_COPPER_LAYER_FOR( In10_Cu ), CLEARANCE_LAYER_FOR( In10_Cu ),
In10_Cu, ZONE_LAYER_FOR( In10_Cu ),
NETNAMES_LAYER_INDEX( In11_Cu ), PAD_COPPER_LAYER_FOR( In11_Cu ),
VIA_COPPER_LAYER_FOR( In11_Cu ), In11_Cu, ZONE_LAYER_FOR( In11_Cu ),
VIA_COPPER_LAYER_FOR( In11_Cu ), CLEARANCE_LAYER_FOR( In11_Cu ),
In11_Cu, ZONE_LAYER_FOR( In11_Cu ),
NETNAMES_LAYER_INDEX( In12_Cu ), PAD_COPPER_LAYER_FOR( In12_Cu ),
VIA_COPPER_LAYER_FOR( In12_Cu ), In12_Cu, ZONE_LAYER_FOR( In12_Cu ),
VIA_COPPER_LAYER_FOR( In12_Cu ), CLEARANCE_LAYER_FOR( In12_Cu ),
In12_Cu, ZONE_LAYER_FOR( In12_Cu ),
NETNAMES_LAYER_INDEX( In13_Cu ), PAD_COPPER_LAYER_FOR( In13_Cu ),
VIA_COPPER_LAYER_FOR( In13_Cu ), In13_Cu, ZONE_LAYER_FOR( In13_Cu ),
VIA_COPPER_LAYER_FOR( In13_Cu ), CLEARANCE_LAYER_FOR( In13_Cu ),
In13_Cu, ZONE_LAYER_FOR( In13_Cu ),
NETNAMES_LAYER_INDEX( In14_Cu ), PAD_COPPER_LAYER_FOR( In14_Cu ),
VIA_COPPER_LAYER_FOR( In14_Cu ), In14_Cu, ZONE_LAYER_FOR( In14_Cu ),
VIA_COPPER_LAYER_FOR( In14_Cu ), CLEARANCE_LAYER_FOR( In14_Cu ),
In14_Cu, ZONE_LAYER_FOR( In14_Cu ),
NETNAMES_LAYER_INDEX( In15_Cu ), PAD_COPPER_LAYER_FOR( In15_Cu ),
VIA_COPPER_LAYER_FOR( In15_Cu ), In15_Cu, ZONE_LAYER_FOR( In15_Cu ),
VIA_COPPER_LAYER_FOR( In15_Cu ), CLEARANCE_LAYER_FOR( In15_Cu ),
In15_Cu, ZONE_LAYER_FOR( In15_Cu ),
NETNAMES_LAYER_INDEX( In16_Cu ), PAD_COPPER_LAYER_FOR( In16_Cu ),
VIA_COPPER_LAYER_FOR( In16_Cu ), In16_Cu, ZONE_LAYER_FOR( In16_Cu ),
VIA_COPPER_LAYER_FOR( In16_Cu ), CLEARANCE_LAYER_FOR( In16_Cu ),
In16_Cu, ZONE_LAYER_FOR( In16_Cu ),
NETNAMES_LAYER_INDEX( In17_Cu ), PAD_COPPER_LAYER_FOR( In17_Cu ),
VIA_COPPER_LAYER_FOR( In17_Cu ), In17_Cu, ZONE_LAYER_FOR( In17_Cu ),
VIA_COPPER_LAYER_FOR( In17_Cu ), CLEARANCE_LAYER_FOR( In17_Cu ),
In17_Cu, ZONE_LAYER_FOR( In17_Cu ),
NETNAMES_LAYER_INDEX( In18_Cu ), PAD_COPPER_LAYER_FOR( In18_Cu ),
VIA_COPPER_LAYER_FOR( In18_Cu ), In18_Cu, ZONE_LAYER_FOR( In18_Cu ),
VIA_COPPER_LAYER_FOR( In18_Cu ), CLEARANCE_LAYER_FOR( In18_Cu ),
In18_Cu, ZONE_LAYER_FOR( In18_Cu ),
NETNAMES_LAYER_INDEX( In19_Cu ), PAD_COPPER_LAYER_FOR( In19_Cu ),
VIA_COPPER_LAYER_FOR( In19_Cu ), In19_Cu, ZONE_LAYER_FOR( In19_Cu ),
VIA_COPPER_LAYER_FOR( In19_Cu ), CLEARANCE_LAYER_FOR( In19_Cu ),
In19_Cu, ZONE_LAYER_FOR( In19_Cu ),
NETNAMES_LAYER_INDEX( In20_Cu ), PAD_COPPER_LAYER_FOR( In20_Cu ),
VIA_COPPER_LAYER_FOR( In20_Cu ), In20_Cu, ZONE_LAYER_FOR( In20_Cu ),
VIA_COPPER_LAYER_FOR( In20_Cu ), CLEARANCE_LAYER_FOR( In20_Cu ),
In20_Cu, ZONE_LAYER_FOR( In20_Cu ),
NETNAMES_LAYER_INDEX( In21_Cu ), PAD_COPPER_LAYER_FOR( In21_Cu ),
VIA_COPPER_LAYER_FOR( In21_Cu ), In21_Cu, ZONE_LAYER_FOR( In21_Cu ),
VIA_COPPER_LAYER_FOR( In21_Cu ), CLEARANCE_LAYER_FOR( In21_Cu ),
In21_Cu, ZONE_LAYER_FOR( In21_Cu ),
NETNAMES_LAYER_INDEX( In22_Cu ), PAD_COPPER_LAYER_FOR( In22_Cu ),
VIA_COPPER_LAYER_FOR( In22_Cu ), In22_Cu, ZONE_LAYER_FOR( In22_Cu ),
VIA_COPPER_LAYER_FOR( In22_Cu ), CLEARANCE_LAYER_FOR( In22_Cu ),
In22_Cu, ZONE_LAYER_FOR( In22_Cu ),
NETNAMES_LAYER_INDEX( In23_Cu ), PAD_COPPER_LAYER_FOR( In23_Cu ),
VIA_COPPER_LAYER_FOR( In23_Cu ), In23_Cu, ZONE_LAYER_FOR( In23_Cu ),
VIA_COPPER_LAYER_FOR( In23_Cu ), CLEARANCE_LAYER_FOR( In23_Cu ),
In23_Cu, ZONE_LAYER_FOR( In23_Cu ),
NETNAMES_LAYER_INDEX( In24_Cu ), PAD_COPPER_LAYER_FOR( In24_Cu ),
VIA_COPPER_LAYER_FOR( In24_Cu ), In24_Cu, ZONE_LAYER_FOR( In24_Cu ),
VIA_COPPER_LAYER_FOR( In24_Cu ), CLEARANCE_LAYER_FOR( In24_Cu ),
In24_Cu, ZONE_LAYER_FOR( In24_Cu ),
NETNAMES_LAYER_INDEX( In25_Cu ), PAD_COPPER_LAYER_FOR( In25_Cu ),
VIA_COPPER_LAYER_FOR( In25_Cu ), In25_Cu, ZONE_LAYER_FOR( In25_Cu ),
VIA_COPPER_LAYER_FOR( In25_Cu ), CLEARANCE_LAYER_FOR( In25_Cu ),
In25_Cu, ZONE_LAYER_FOR( In25_Cu ),
NETNAMES_LAYER_INDEX( In26_Cu ), PAD_COPPER_LAYER_FOR( In26_Cu ),
VIA_COPPER_LAYER_FOR( In26_Cu ), In26_Cu, ZONE_LAYER_FOR( In26_Cu ),
VIA_COPPER_LAYER_FOR( In26_Cu ), CLEARANCE_LAYER_FOR( In26_Cu ),
In26_Cu, ZONE_LAYER_FOR( In26_Cu ),
NETNAMES_LAYER_INDEX( In27_Cu ), PAD_COPPER_LAYER_FOR( In27_Cu ),
VIA_COPPER_LAYER_FOR( In27_Cu ), In27_Cu, ZONE_LAYER_FOR( In27_Cu ),
VIA_COPPER_LAYER_FOR( In27_Cu ), CLEARANCE_LAYER_FOR( In27_Cu ),
In27_Cu, ZONE_LAYER_FOR( In27_Cu ),
NETNAMES_LAYER_INDEX( In28_Cu ), PAD_COPPER_LAYER_FOR( In28_Cu ),
VIA_COPPER_LAYER_FOR( In28_Cu ), In28_Cu, ZONE_LAYER_FOR( In28_Cu ),
VIA_COPPER_LAYER_FOR( In28_Cu ), CLEARANCE_LAYER_FOR( In28_Cu ),
In28_Cu, ZONE_LAYER_FOR( In28_Cu ),
NETNAMES_LAYER_INDEX( In29_Cu ), PAD_COPPER_LAYER_FOR( In29_Cu ),
VIA_COPPER_LAYER_FOR( In29_Cu ), In29_Cu, ZONE_LAYER_FOR( In29_Cu ),
VIA_COPPER_LAYER_FOR( In29_Cu ), CLEARANCE_LAYER_FOR( In29_Cu ),
In29_Cu, ZONE_LAYER_FOR( In29_Cu ),
NETNAMES_LAYER_INDEX( In30_Cu ), PAD_COPPER_LAYER_FOR( In30_Cu ),
VIA_COPPER_LAYER_FOR( In30_Cu ), In30_Cu, ZONE_LAYER_FOR( In30_Cu ),
VIA_COPPER_LAYER_FOR( In30_Cu ), CLEARANCE_LAYER_FOR( In30_Cu ),
In30_Cu, ZONE_LAYER_FOR( In30_Cu ),
LAYER_PAD_BK_NETNAMES,
NETNAMES_LAYER_INDEX( B_Cu ),
PAD_COPPER_LAYER_FOR( B_Cu ),
VIA_COPPER_LAYER_FOR( B_Cu ),
CLEARANCE_LAYER_FOR( B_Cu ),
B_Cu, ZONE_LAYER_FOR( B_Cu ),
B_Mask, ZONE_LAYER_FOR( B_Mask ),
B_SilkS, ZONE_LAYER_FOR( B_SilkS ),
@ -487,6 +519,7 @@ void PCB_DRAW_PANEL_GAL::SetTopLayer( PCB_LAYER_ID aLayer )
m_view->SetTopLayer( ZONE_LAYER_FOR( layer ) );
m_view->SetTopLayer( PAD_COPPER_LAYER_FOR( layer ) );
m_view->SetTopLayer( VIA_COPPER_LAYER_FOR( layer ) );
m_view->SetTopLayer( CLEARANCE_LAYER_FOR( layer ) );
}
}
@ -511,6 +544,7 @@ void PCB_DRAW_PANEL_GAL::SetTopLayer( PCB_LAYER_ID aLayer )
m_view->SetTopLayer( ZONE_LAYER_FOR( aLayer ) );
m_view->SetTopLayer( PAD_COPPER_LAYER_FOR( aLayer ) );
m_view->SetTopLayer( VIA_COPPER_LAYER_FOR( aLayer ) );
m_view->SetTopLayer( CLEARANCE_LAYER_FOR( aLayer ) );
// Display labels for copper layers on the top
m_view->SetTopLayer( GetNetnameLayer( aLayer ) );
@ -549,6 +583,9 @@ void PCB_DRAW_PANEL_GAL::SyncLayersVisibility( const BOARD* aBoard )
for( int i = LAYER_VIA_COPPER_START; i < LAYER_VIA_COPPER_END; i++ )
m_view->SetLayerVisible( i, true );
for( int i = LAYER_CLEARANCE_START; i < LAYER_CLEARANCE_END; i++ )
m_view->SetLayerVisible( i, false );
for( int i = LAYER_BITMAP_START; i < LAYER_BITMAP_END; i++ )
m_view->SetLayerVisible( i, true );
@ -709,6 +746,7 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
m_view->SetRequired( ZONE_LAYER_FOR( layer ), layer );
m_view->SetRequired( PAD_COPPER_LAYER_FOR( layer ), layer );
m_view->SetRequired( VIA_COPPER_LAYER_FOR( layer ), layer );
m_view->SetRequired( CLEARANCE_LAYER_FOR( layer ), layer );
m_view->SetRequired( BITMAP_LAYER_FOR( layer ), layer );
m_view->SetLayerTarget( BITMAP_LAYER_FOR( layer ), KIGFX::TARGET_NONCACHED );

View File

@ -1506,6 +1506,28 @@ void PCB_EDIT_FRAME::SetActiveLayer( PCB_LAYER_ID aLayer )
GetCanvas()->SetFocus(); // allow capture of hotkeys
GetCanvas()->SetHighContrastLayer( aLayer );
/*
* Only show pad, via and track clearances when a copper layer is active
* and then only show the clearance layer for that copper layer.
*
* For pads/vias, this is to avoid clutter when there are pad/via layers
* that vary in flash (i.e. clearance from the hole or pad edge), padstack
* shape on eahc layer or clearances on each layer.
*
* For tracks, this follows the same logic as pads/vias, but in theory could
* have their own set of independent clearance layers to allow track clearance
* to be shown for more layers.
*/
if( IsCopperLayer( oldLayer ) )
{
GetCanvas()->GetView()->SetLayerVisible( CLEARANCE_LAYER_FOR( oldLayer ), false );
}
if( IsCopperLayer( aLayer ) )
{
GetCanvas()->GetView()->SetLayerVisible( CLEARANCE_LAYER_FOR( aLayer ), true );
}
GetCanvas()->GetView()->UpdateAllItemsConditionally(
[&]( KIGFX::VIEW_ITEM* aItem ) -> int
{
@ -1536,11 +1558,6 @@ void PCB_EDIT_FRAME::SetActiveLayer( PCB_LAYER_ID aLayer )
if( via->GetRemoveUnconnected() )
return KIGFX::ALL;
// Clearances could be layer-dependent so redraw them when the active layer
// is changed
if( GetPcbNewSettings()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS )
return KIGFX::REPAINT;
}
else if( item->Type() == PCB_PAD_T )
{
@ -1548,40 +1565,6 @@ void PCB_EDIT_FRAME::SetActiveLayer( PCB_LAYER_ID aLayer )
if( pad->GetRemoveUnconnected() )
return KIGFX::ALL;
// Clearances could be layer-dependent so redraw them when the active layer
// is changed
if( GetPcbNewSettings()->m_Display.m_PadClearance )
{
// Round-corner rects are expensive to draw, but are mostly found on
// SMD pads which only need redrawing on an active-to-not-active
// switch.
if( pad->GetAttribute() == PAD_ATTRIB::SMD )
{
if( ( oldLayer == F_Cu || aLayer == F_Cu ) && pad->IsOnLayer( F_Cu ) )
return KIGFX::REPAINT;
if( ( oldLayer == B_Cu || aLayer == B_Cu ) && pad->IsOnLayer( B_Cu ) )
return KIGFX::REPAINT;
}
else if( pad->IsOnLayer( oldLayer ) || pad->IsOnLayer( aLayer ) )
{
return KIGFX::REPAINT;
}
}
}
else if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T )
{
PCB_TRACK* track = static_cast<PCB_TRACK*>( item );
// Clearances could be layer-dependent so redraw them when the active layer
// is changed
if( GetPcbNewSettings()->m_Display.m_TrackClearance )
{
// Tracks aren't particularly expensive to draw, but it's an easy check.
if( track->IsOnLayer( oldLayer ) || track->IsOnLayer( aLayer ) )
return KIGFX::REPAINT;
}
}
return 0;

View File

@ -244,11 +244,13 @@ COLOR4D PCB_RENDER_SETTINGS::GetColor( const BOARD_ITEM* aItem, int aLayer ) con
aLayer = aLayer - LAYER_ZONE_START;
}
// Pad and via copper take their color from the copper layer
// Pad and via copper and clearance outlines take their color from the copper layer
if( IsPadCopperLayer( aLayer ) )
aLayer = aLayer - LAYER_PAD_COPPER_START;
else if( IsViaCopperLayer( aLayer ) )
aLayer = aLayer - LAYER_VIA_COPPER_START;
else if( IsClearanceLayer( aLayer ) )
aLayer = aLayer - LAYER_CLEARANCE_START;
// Use via "golden copper" hole color for pad hole walls for contrast
else if( aLayer == LAYER_PAD_HOLEWALLS )
@ -787,28 +789,19 @@ void PCB_PAINTER::draw( const PCB_TRACK* aTrack, int aLayer )
}
// Clearance lines
if( pcbconfig() && pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
&& !m_pcbSettings.m_isPrinting
&& aLayer != LAYER_LOCKED_ITEM_SHADOW )
if( IsClearanceLayer( aLayer ) && pcbconfig()
&& pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
&& !m_pcbSettings.m_isPrinting )
{
/*
* 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();
const PCB_LAYER_ID copperLayerForClearance = ToLAYER_ID( aLayer - LAYER_CLEARANCE_START );
if( IsCopperLayer( activeLayer ) && board->GetVisibleLayers().test( activeLayer ) )
{
int clearance = aTrack->GetOwnClearance( activeLayer );
int clearance = aTrack->GetOwnClearance( copperLayerForClearance );
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetStrokeColor( color );
m_gal->DrawSegment( start, end, track_width + clearance * 2 );
}
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetStrokeColor( color );
m_gal->DrawSegment( start, end, track_width + clearance * 2 );
}
}
@ -923,19 +916,19 @@ void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer )
}
// Clearance lines
if( pcbconfig() && pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
&& !m_pcbSettings.m_isPrinting
&& aLayer != LAYER_LOCKED_ITEM_SHADOW )
if( IsClearanceLayer( aLayer ) && pcbconfig()
&& pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
&& !m_pcbSettings.m_isPrinting )
{
/*
* 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();
const PCB_LAYER_ID activeLayer = m_pcbSettings.GetActiveLayer();
const BOARD& board = *aArc->GetBoard();
if( IsCopperLayer( activeLayer ) && board->GetVisibleLayers().test( activeLayer ) )
if( IsCopperLayer( activeLayer ) && board.GetVisibleLayers().test( activeLayer ) )
{
int clearance = aArc->GetOwnClearance( activeLayer );
@ -1207,35 +1200,24 @@ void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer )
}
// Clearance lines
if( pcbconfig() && pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
&& aLayer != LAYER_VIA_HOLES
&& !m_pcbSettings.m_isPrinting
&& aLayer != LAYER_LOCKED_ITEM_SHADOW )
if( IsClearanceLayer( aLayer ) && pcbconfig()
&& pcbconfig()->m_Display.m_TrackClearance == SHOW_WITH_VIA_ALWAYS
&& !m_pcbSettings.m_isPrinting )
{
/*
* 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.
*/
const PCB_LAYER_ID activeLayer = m_pcbSettings.GetActiveLayer();
const PCB_LAYER_ID copperLayerForClearance = ToLAYER_ID( aLayer - LAYER_CLEARANCE_START );
if( activeLayer == copperLayer && IsCopperLayer( activeLayer )
&& board->GetVisibleLayers().test( activeLayer ) )
{
double radius;
double radius;
if( aVia->FlashLayer( activeLayer ) )
radius = aVia->GetWidth( activeLayer ) / 2.0;
else
radius = getViaDrillSize( aVia ) / 2.0 + m_holePlatingThickness;
if( aVia->FlashLayer( copperLayerForClearance ) )
radius = aVia->GetWidth( copperLayerForClearance ) / 2.0;
else
radius = getViaDrillSize( aVia ) / 2.0 + m_holePlatingThickness;
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetStrokeColor( color );
m_gal->DrawCircle( center, radius + aVia->GetOwnClearance( activeLayer ) );
}
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetStrokeColor( color );
m_gal->DrawCircle( center, radius + aVia->GetOwnClearance( copperLayerForClearance ) );
}
}
@ -1753,63 +1735,55 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
}
}
if( ( ( pcbconfig() && pcbconfig()->m_Display.m_PadClearance ) || !pcbconfig() )
if( IsClearanceLayer( aLayer )
&& ( ( pcbconfig() && pcbconfig()->m_Display.m_PadClearance ) || !pcbconfig() )
&& !m_pcbSettings.m_isPrinting )
{
/*
* 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.
*/
const PCB_LAYER_ID activeLayer = m_pcbSettings.GetActiveLayer();
const PCB_LAYER_ID copperLayerForClearance = ToLAYER_ID( aLayer - LAYER_CLEARANCE_START );
if( activeLayer == copperLayer && IsCopperLayer( activeLayer )
&& board->GetVisibleLayers().test( activeLayer ) )
if( aPad->GetAttribute() == PAD_ATTRIB::NPTH )
color = m_pcbSettings.GetLayerColor( LAYER_NON_PLATEDHOLES );
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
m_gal->SetIsStroke( true );
m_gal->SetIsFill( false );
m_gal->SetStrokeColor( color );
const int clearance = aPad->GetOwnClearance( copperLayerForClearance );
if( aPad->FlashLayer( copperLayerForClearance ) && clearance > 0 )
{
if( aPad->GetAttribute() == PAD_ATTRIB::NPTH )
color = m_pcbSettings.GetLayerColor( LAYER_NON_PLATEDHOLES );
auto shape = std::dynamic_pointer_cast<SHAPE_COMPOUND>(
aPad->GetEffectiveShape( pcbLayer ) );
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
m_gal->SetIsStroke( true );
m_gal->SetIsFill( false );
m_gal->SetStrokeColor( color );
int clearance = aPad->GetOwnClearance( activeLayer );
if( aPad->FlashLayer( activeLayer ) && clearance > 0 )
if( shape && shape->Size() == 1 && shape->Shapes()[0]->Type() == SH_SEGMENT )
{
auto shape = std::dynamic_pointer_cast<SHAPE_COMPOUND>( aPad->GetEffectiveShape( pcbLayer ) );
if( shape && shape->Size() == 1 && shape->Shapes()[0]->Type() == SH_SEGMENT )
{
const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shape->Shapes()[0];
m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B,
seg->GetWidth() + 2 * clearance );
}
else if( shape && shape->Size() == 1 && shape->Shapes()[0]->Type() == SH_CIRCLE )
{
const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shape->Shapes()[0];
m_gal->DrawCircle( circle->GetCenter(), circle->GetRadius() + clearance );
}
else
{
SHAPE_POLY_SET polySet;
// Use ERROR_INSIDE because it avoids Clipper and is therefore much faster.
aPad->TransformShapeToPolygon( polySet, activeLayer, clearance, m_maxError,
ERROR_INSIDE );
if( polySet.Outline( 0 ).PointCount() > 2 ) // Careful of empty pads
m_gal->DrawPolygon( polySet );
}
const SHAPE_SEGMENT* seg = (SHAPE_SEGMENT*) shape->Shapes()[0];
m_gal->DrawSegment( seg->GetSeg().A, seg->GetSeg().B,
seg->GetWidth() + 2 * clearance );
}
else if( aPad->GetEffectiveHoleShape() && clearance > 0 )
else if( shape && shape->Size() == 1 && shape->Shapes()[0]->Type() == SH_CIRCLE )
{
std::shared_ptr<SHAPE_SEGMENT> slot = aPad->GetEffectiveHoleShape();
m_gal->DrawSegment( slot->GetSeg().A, slot->GetSeg().B,
slot->GetWidth() + 2 * clearance );
const SHAPE_CIRCLE* circle = (SHAPE_CIRCLE*) shape->Shapes()[0];
m_gal->DrawCircle( circle->GetCenter(), circle->GetRadius() + clearance );
}
else
{
SHAPE_POLY_SET polySet;
// Use ERROR_INSIDE because it avoids Clipper and is therefore much faster.
aPad->TransformShapeToPolygon( polySet, copperLayerForClearance, clearance,
m_maxError, ERROR_INSIDE );
if( polySet.Outline( 0 ).PointCount() > 2 ) // Careful of empty pads
m_gal->DrawPolygon( polySet );
}
}
else if( aPad->GetEffectiveHoleShape() && clearance > 0 )
{
std::shared_ptr<SHAPE_SEGMENT> slot = aPad->GetEffectiveHoleShape();
m_gal->DrawSegment( slot->GetSeg().A, slot->GetSeg().B,
slot->GetWidth() + 2 * clearance );
}
}
}

View File

@ -1326,9 +1326,14 @@ void PCB_VIA::GetOutermostConnectedLayers( PCB_LAYER_ID* aTopmost,
std::vector<int> PCB_TRACK::ViewGetLayers() const
{
// Show the track and its netname on different layers
std::vector<int> layers { GetLayer(), GetNetnameLayer( GetLayer() ) };
const PCB_LAYER_ID layer = GetLayer();
std::vector<int> layers{
layer,
GetNetnameLayer( layer ),
LAYER_CLEARANCE_START + layer,
};
layers.reserve( 5 );
layers.reserve( 6 );
if( m_hasSolderMask )
{
@ -1446,6 +1451,7 @@ std::vector<int> PCB_VIA::ViewGetLayers() const
continue;
ret_layers.push_back( LAYER_VIA_COPPER_START + layer );
ret_layers.push_back( LAYER_CLEARANCE_START + layer );
}
if( IsLocked() )

View File

@ -3036,6 +3036,7 @@ void APPEARANCE_CONTROLS::OnColorSwatchChanged( wxCommandEvent& aEvent )
view->UpdateLayerColor( ZONE_LAYER_FOR( layer ) );
view->UpdateLayerColor( VIA_COPPER_LAYER_FOR( layer ) );
view->UpdateLayerColor( PAD_COPPER_LAYER_FOR( layer ) );
view->UpdateLayerColor( CLEARANCE_LAYER_FOR( layer ) );
}
// Update the bitmap of the layer box