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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 */
20
23
24#include <board.h>
25#include <footprint.h>
26#include <pad.h>
27#include <pcbplot.h>
29#include <pcb_plot_params.h>
30#include <layer_ids.h>
31#include <lset.h>
32
33#include <wx/filename.h>
34#include <wx/ffile.h>
35
36#include <memory>
37#include <regex>
38#include <string>
39
40BOOST_AUTO_TEST_SUITE( PlotEdgeCutsDrillMarks )
41
42// Regression for #24416: drill marks must never be flashed onto a layer the pad
43// isn't on (Edge_Cuts, paste, silk). Plot Edge_Cuts with drill marks enabled and
44// assert the gerber contains no flash (D03) apertures.
45BOOST_AUTO_TEST_CASE( NoDrillFlashesOnEdgeCuts )
46{
47 const int padDia = pcbIUScale.mmToIU( 1.4 );
48 const int drill = pcbIUScale.mmToIU( 0.8 );
49
50 BOARD board;
51 auto footprint = std::make_unique<FOOTPRINT>( &board );
52 footprint->SetPosition( VECTOR2I( pcbIUScale.mmToIU( 50.0 ), pcbIUScale.mmToIU( 50.0 ) ) );
53
54 auto pad = new PAD( footprint.get() );
55 pad->SetAttribute( PAD_ATTRIB::PTH );
57 pad->SetSize( PADSTACK::ALL_LAYERS, VECTOR2I( padDia, padDia ) );
58 pad->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
59 pad->SetDrillSize( VECTOR2I( drill, drill ) );
60 pad->SetLayerSet( LSET::AllCuMask() | LSET( { F_Mask, B_Mask } ) ); // THT pad: NOT on Edge_Cuts
61 pad->SetPosition( footprint->GetPosition() );
62 footprint->Add( pad );
63 board.Add( footprint.release() );
64
65 GERBER_PLOTTER plotter;
66 SIMPLE_RENDER_SETTINGS renderSettings;
67 plotter.SetRenderSettings( &renderSettings );
68
69 wxString gbrPath = wxFileName::CreateTempFileName( wxT( "kicad_gbr_24416" ) );
70 BOOST_REQUIRE( !gbrPath.IsEmpty() );
71 BOOST_REQUIRE( plotter.OpenFile( gbrPath ) );
72 plotter.SetViewport( VECTOR2I( 0, 0 ), pcbIUScale.IU_PER_MILS / 10, 1.0, false );
73 BOOST_REQUIRE( plotter.StartPlot( wxT( "1" ) ) );
74
75 PCB_PLOT_PARAMS plotOpts;
77 plotOpts.SetDrillMarksType( DRILL_MARKS::FULL_DRILL_SHAPE ); // triggers PlotDrillMarks()
78
79 PlotBoardLayers( &board, &plotter, LSEQ{ Edge_Cuts }, plotOpts );
80 BOOST_REQUIRE( plotter.EndPlot() );
81
82 wxFFile file( gbrPath, wxT( "rb" ) );
83 BOOST_REQUIRE( file.IsOpened() );
84 wxString contents;
85 BOOST_REQUIRE( file.ReadAll( &contents ) );
86 file.Close();
87 wxRemoveFile( gbrPath );
88
89 std::string buf = contents.ToStdString();
90 std::regex flashRe( R"(D0*3\*)" ); // D03 = flash a pad/aperture
91 long flashes = std::distance( std::sregex_iterator( buf.begin(), buf.end(), flashRe ), std::sregex_iterator() );
92
93 BOOST_CHECK_MESSAGE( flashes == 0,
94 "Edge_Cuts gerber unexpectedly contains " << flashes << " drill-mark flash(es) (#24416)" );
95}
96
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:125
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:323
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1247
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:599
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:77
void SetRenderSettings(RENDER_SETTINGS *aSettings)
Definition plotter.h:167
Minimal concrete render settings suitable for plotters in tests.
@ Edge_Cuts
Definition layer_ids.h:112
@ B_Mask
Definition layer_ids.h:98
@ F_Mask
Definition layer_ids.h:97
@ 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:687