KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_plot_edge_cuts_drill_marks.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
22
23#include <board.h>
24#include <footprint.h>
25#include <pad.h>
26#include <pcbplot.h>
28#include <pcb_plot_params.h>
29#include <layer_ids.h>
30#include <lset.h>
31
32#include <wx/filename.h>
33#include <wx/ffile.h>
34
35#include <memory>
36#include <regex>
37#include <string>
38
39BOOST_AUTO_TEST_SUITE( PlotEdgeCutsDrillMarks )
40
41// Regression for #24416: drill marks must never be flashed onto a layer the pad
42// isn't on (Edge_Cuts, paste, silk). Plot Edge_Cuts with drill marks enabled and
43// assert the gerber contains no flash (D03) apertures.
44BOOST_AUTO_TEST_CASE( NoDrillFlashesOnEdgeCuts )
45{
46 const int padDia = pcbIUScale.mmToIU( 1.4 );
47 const int drill = pcbIUScale.mmToIU( 0.8 );
48
49 BOARD board;
50 auto footprint = std::make_unique<FOOTPRINT>( &board );
51 footprint->SetPosition( VECTOR2I( pcbIUScale.mmToIU( 50.0 ), pcbIUScale.mmToIU( 50.0 ) ) );
52
53 auto pad = new PAD( footprint.get() );
54 pad->SetAttribute( PAD_ATTRIB::PTH );
56 pad->SetSize( PADSTACK::ALL_LAYERS, VECTOR2I( padDia, padDia ) );
57 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
58 pad->SetDrillSize( VECTOR2I( drill, drill ) );
59 pad->SetLayerSet( LSET::AllCuMask() | LSET( { F_Mask, B_Mask } ) ); // THT pad: NOT on Edge_Cuts
60 pad->SetPosition( footprint->GetPosition() );
61 footprint->Add( pad );
62 board.Add( footprint.release() );
63
64 GERBER_PLOTTER plotter;
65 SIMPLE_RENDER_SETTINGS renderSettings;
66 plotter.SetRenderSettings( &renderSettings );
67
68 wxString gbrPath = wxFileName::CreateTempFileName( wxT( "kicad_gbr_24416" ) );
69 BOOST_REQUIRE( !gbrPath.IsEmpty() );
70 BOOST_REQUIRE( plotter.OpenFile( gbrPath ) );
71 plotter.SetViewport( VECTOR2I( 0, 0 ), pcbIUScale.IU_PER_MILS / 10, 1.0, false );
72 BOOST_REQUIRE( plotter.StartPlot( wxT( "1" ) ) );
73
74 PCB_PLOT_PARAMS plotOpts;
76 plotOpts.SetDrillMarksType( DRILL_MARKS::FULL_DRILL_SHAPE ); // triggers PlotDrillMarks()
77
78 PlotBoardLayers( &board, &plotter, LSEQ{ Edge_Cuts }, plotOpts );
79 BOOST_REQUIRE( plotter.EndPlot() );
80
81 wxFFile file( gbrPath, wxT( "rb" ) );
82 BOOST_REQUIRE( file.IsOpened() );
83 wxString contents;
84 BOOST_REQUIRE( file.ReadAll( &contents ) );
85 file.Close();
86 wxRemoveFile( gbrPath );
87
88 std::string buf = contents.ToStdString();
89 std::regex flashRe( R"(D0*3\*)" ); // D03 = flash a pad/aperture
90 long flashes = std::distance( std::sregex_iterator( buf.begin(), buf.end(), flashRe ), std::sregex_iterator() );
91
92 BOOST_CHECK_MESSAGE( flashes == 0,
93 "Edge_Cuts gerber unexpectedly contains " << flashes << " drill-mark flash(es) (#24416)" );
94}
95
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:121
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:373
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1346
virtual void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror) override
Set the plot offset and scaling for the current plot.
virtual bool EndPlot() override
virtual bool StartPlot(const wxString &pageNumber) override
Write GERBER header to file initialize global variable g_Plot_PlotOutputFile.
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Definition lseq.h:47
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition lset.cpp:595
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
Definition padstack.h:177
Parameters and options when plotting/printing a board.
void SetDrillMarksType(DRILL_MARKS aVal)
void SetFormat(PLOT_FORMAT aFormat)
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
Definition plotter.cpp:73
void SetRenderSettings(RENDER_SETTINGS *aSettings)
Definition plotter.h:163
Minimal concrete render settings suitable for plotters in tests.
@ Edge_Cuts
Definition layer_ids.h:108
@ B_Mask
Definition layer_ids.h:94
@ F_Mask
Definition layer_ids.h:93
@ PTH
Plated through hole pad.
Definition padstack.h:98
void PlotBoardLayers(BOARD *aBoard, PLOTTER *aPlotter, const LSEQ &aLayerSequence, const PCB_PLOT_PARAMS &aPlotOptions)
Plot a sequence of board layer IDs.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683