From 5e6ef67fce30849ca746a331cf846d9826a83387 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sat, 10 May 2025 18:15:43 +0100 Subject: [PATCH] Plot drill marks on mask layers if the pad exists there. Fixes https://gitlab.com/kicad/code/kicad/-/issues/20859 --- pcbnew/dialogs/dialog_plot.cpp | 2 - pcbnew/dialogs/dialog_plot.h | 4 -- pcbnew/plot_board_layers.cpp | 41 +++++-------------- pcbnew/plot_brditems_plotter.cpp | 70 ++++++++------------------------ 4 files changed, 27 insertions(+), 90 deletions(-) diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp index 120cadff0f..9c4a4108a3 100644 --- a/pcbnew/dialogs/dialog_plot.cpp +++ b/pcbnew/dialogs/dialog_plot.cpp @@ -59,8 +59,6 @@ #include -LSET DIALOG_PLOT::s_lastLayerSet; -LSET DIALOG_PLOT::s_lastAllLayersSet; LSEQ DIALOG_PLOT::s_lastAllLayersOrder; diff --git a/pcbnew/dialogs/dialog_plot.h b/pcbnew/dialogs/dialog_plot.h index 5c757f82c6..5ee5aaa5a0 100644 --- a/pcbnew/dialogs/dialog_plot.h +++ b/pcbnew/dialogs/dialog_plot.h @@ -104,10 +104,6 @@ private: JOB_EXPORT_PCB_PLOT* m_job; - /// The plot layer set that last time the dialog was opened. - static LSET s_lastLayerSet; - static LSET s_lastAllLayersSet; - /// The plot on all layers ordering the last time the dialog was opened. static LSEQ s_lastAllLayersOrder; }; diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index 815b3231b2..31f765937c 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -132,30 +132,16 @@ void PlotBoardLayers( BOARD* aBoard, PLOTTER* aPlotter, const LSEQ& aLayers, if( !aBoard || !aPlotter || aLayers.empty() ) return; - // if a drill mark must be plotted,it must be plotted as a filled - // white shape *after* all other shapes are plotted, provided that - // the other shapes are not copper layers - int copperLayers = 0; - int nonCopperLayers = 0; - - for( PCB_LAYER_ID layer : aLayers ) - { - if( IsCopperLayer( layer ) ) - copperLayers++; - else - nonCopperLayers++; - } - - bool plot_mark = ( aPlotOptions.GetDrillMarksType() != DRILL_MARKS::NO_DRILL_SHAPE - && copperLayers > 0 && nonCopperLayers > 0 ); - for( PCB_LAYER_ID layer : aLayers ) PlotOneBoardLayer( aBoard, aPlotter, layer, aPlotOptions, layer == aLayers[0] ); - if( plot_mark ) + // Drill marks are plotted in white to knockout the pad if any layers of the pad are + // being plotted, and in black if the pad is not being plotted. For the former, this + // must happen after all other layers are plotted. + if( aPlotOptions.GetDrillMarksType() != DRILL_MARKS::NO_DRILL_SHAPE ) { - aPlotter->SetColor( WHITE ); BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOptions ); + itemplotter.SetLayerSet( aLayers ); itemplotter.PlotDrillMarks(); } } @@ -256,9 +242,6 @@ void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, PCB_LAYER_ID aLayer, { case B_Mask: case F_Mask: - // Disable plot pad holes - plotOpt.SetDrillMarksType( DRILL_MARKS::NO_DRILL_SHAPE ); - // Use outline mode for DXF plotOpt.SetDXFPlotPolygonMode( true ); @@ -667,14 +650,14 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, const LSET& aLayerMask } auto getMetadata = - [&]() -> void* + [&]() { - if( aPlotter->GetPlotterType() == PLOT_FORMAT::DXF ) + if( aPlotter->GetPlotterType() == PLOT_FORMAT::GERBER ) + return (void*) &gbr_metadata; + else if( aPlotter->GetPlotterType() == PLOT_FORMAT::DXF ) return (void*) &aPlotOpt; - else if( aPlotter->GetPlotterType() == PLOT_FORMAT::GERBER ) - return &gbr_metadata; else - return nullptr; + return (void*) nullptr; }; aPlotter->StartBlock( nullptr ); @@ -843,10 +826,6 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, const LSET& aLayerMask } aPlotter->EndBlock( nullptr ); - - // Adding drill marks, if required and if the plotter is able to plot them: - if( aPlotOpt.GetDrillMarksType() != DRILL_MARKS::NO_DRILL_SHAPE ) - itemplotter.PlotDrillMarks(); } diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index b35c991245..402ac9782f 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -723,6 +723,11 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItems( const FOOTPRINT* aFootprint ) } +#define getMetadata() ( m_plotter->GetPlotterType() == PLOT_FORMAT::GERBER ? (void*) &gbr_metadata \ + : m_plotter->GetPlotterType() == PLOT_FORMAT::DXF ? (void*) this \ + : (void*) nullptr ) + + void BRDITEMS_PLOTTER::PlotText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer, bool aIsKnockout, const KIFONT::METRICS& aFontMetrics, bool aStrikeout ) { @@ -752,17 +757,6 @@ void BRDITEMS_PLOTTER::PlotText( const EDA_TEXT* aText, PCB_LAYER_ID aLayer, boo if( IsCopperLayer( aLayer ) ) gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_NONCONDUCTOR ); - auto getMetadata = - [&]() -> void* - { - if( m_plotter->GetPlotterType() == PLOT_FORMAT::DXF ) - return this; - else if( m_plotter->GetPlotterType() == PLOT_FORMAT::GERBER ) - return &gbr_metadata; - else - return nullptr; - }; - COLOR4D color = getColor( aLayer ); m_plotter->SetColor( color ); @@ -885,17 +879,6 @@ void BRDITEMS_PLOTTER::PlotZone( const ZONE* aZone, PCB_LAYER_ID aLayer, } } - auto getMetadata = - [&]() -> void* - { - if( m_plotter->GetPlotterType() == PLOT_FORMAT::DXF ) - return this; - else if( m_plotter->GetPlotterType() == PLOT_FORMAT::GERBER ) - return &gbr_metadata; - else - return nullptr; - }; - m_plotter->SetColor( getColor( aLayer ) ); m_plotter->StartBlock( nullptr ); // Clean current object attributes @@ -913,9 +896,10 @@ void BRDITEMS_PLOTTER::PlotZone( const ZONE* aZone, PCB_LAYER_ID aLayer, { static_cast( m_plotter )->PlotGerberRegion( outline, &gbr_metadata ); } - else if( m_plotter->GetPlotterType() == PLOT_FORMAT::DXF && GetDXFPlotMode() == SKETCH ) + else if( m_plotter->GetPlotterType() == PLOT_FORMAT::DXF ) { - m_plotter->SetCurrentLineWidth( PLOTTER::USE_DEFAULT_LINE_WIDTH ); + if( GetDXFPlotMode() == FILLED ) + m_plotter->PlotPoly( outline, FILL_T::FILLED_SHAPE, 0, getMetadata() ); } else { @@ -1002,17 +986,6 @@ void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape ) } } - auto getMetadata = - [&]() -> void* - { - if( m_plotter->GetPlotterType() == PLOT_FORMAT::DXF ) - return this; - else if( m_plotter->GetPlotterType() == PLOT_FORMAT::GERBER ) - return &gbr_metadata; - else - return nullptr; - }; - if( lineStyle <= LINE_STYLE::FIRST_TYPE ) { switch( aShape->GetShape() ) @@ -1212,17 +1185,6 @@ void BRDITEMS_PLOTTER::PlotTableBorders( const PCB_TABLE* aTable ) gbr_metadata.SetNetAttribType( GBR_NETLIST_METADATA::GBR_NETINFO_CMP ); } - auto getMetadata = - [&]() -> void* - { - if( m_plotter->GetPlotterType() == PLOT_FORMAT::DXF ) - return this; - else if( m_plotter->GetPlotterType() == PLOT_FORMAT::GERBER ) - return &gbr_metadata; - else - return nullptr; - }; - aTable->DrawBorders( [&]( const VECTOR2I& ptA, const VECTOR2I& ptB, const STROKE_PARAMS& stroke ) { @@ -1277,8 +1239,7 @@ void BRDITEMS_PLOTTER::plotOneDrillMark( PAD_DRILL_SHAPE aDrillShape, const VECT void BRDITEMS_PLOTTER::PlotDrillMarks() { - bool onCopperLayer = ( LSET::AllCuMask() & m_layerMask ).any(); - int smallDrill = 0; + int smallDrill = 0; if( GetDrillMarksType() == DRILL_MARKS::SMALL_DRILL_SHAPE ) smallDrill = pcbIUScale.mmToIU( ADVANCED_CFG::GetCfg().m_SmallDrillMarkSize ); @@ -1286,13 +1247,13 @@ void BRDITEMS_PLOTTER::PlotDrillMarks() /* Drill marks are drawn white-on-black to knock-out the underlying pad. This works only * for drivers supporting color change, obviously... it means that: - PS, SVG and PDF output is correct (i.e. you have a 'donut' pad) - - In gerbers you can't see them, too. This is arguably the right thing to do since having + - In gerbers you can't see them. This is arguably the right thing to do since having drill marks and high speed drill stations is a sure recipe for broken tools and angry - manufacturers. If you *really* want them you could start a layer with negative polarity - to knock-out the film. + manufacturers. If you *really* want them you could start a layer with negative + polarity to knock-out the film. - In DXF they go into the 'WHITE' layer. This could be useful. */ - if( onCopperLayer && ( m_plotter->GetPlotterType() != PLOT_FORMAT::DXF || GetDXFPlotMode() == FILLED ) ) + if( m_plotter->GetPlotterType() != PLOT_FORMAT::DXF || GetDXFPlotMode() == FILLED ) m_plotter->SetColor( WHITE ); for( PCB_TRACK* track : m_board->Tracks() ) @@ -1319,11 +1280,14 @@ void BRDITEMS_PLOTTER::PlotDrillMarks() if( pad->GetDrillSize().x == 0 ) continue; + if( m_plotter->GetPlotterType() != PLOT_FORMAT::DXF || GetDXFPlotMode() == FILLED ) + m_plotter->SetColor( ( pad->GetLayerSet() & m_layerMask ).any() ? WHITE : BLACK ); + plotOneDrillMark( pad->GetDrillShape(), pad->GetPosition(), pad->GetDrillSize(), pad->GetSize( PADSTACK::ALL_LAYERS ), pad->GetOrientation(), smallDrill ); } } - if( onCopperLayer && ( m_plotter->GetPlotterType() != PLOT_FORMAT::DXF || GetDXFPlotMode() == FILLED ) ) + if( m_plotter->GetPlotterType() != PLOT_FORMAT::DXF || GetDXFPlotMode() == FILLED ) m_plotter->SetColor( BLACK ); }