KiCad PCB EDA Suite
command_export_pcb_drill.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 (C) 2022 Mark Roszko <[email protected]>
5 * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
22#include <cli/exit_codes.h>
24#include <kiface_base.h>
25#include <layer_ids.h>
26#include <wx/crt.h>
27
28#include <macros.h>
29#include <wx/tokenzr.h>
30
31#define ARG_FORMAT "--format"
32#define ARG_EXCELLON_MIRRORY "--excellon-mirror-y"
33#define ARG_EXCELLON_MINIMALHEAD "--excellon-min-header"
34#define ARG_EXCELLON_SEPARATE_TH "--excellon-separate-th"
35#define ARG_EXCELLON_ZEROS_FORMAT "--excellon-zeros-format"
36#define ARG_GERBER_PRECISION "--gerber-precision"
37#define ARG_UNITS "--units"
38#define ARG_GENERATE_MAP "--generate-map"
39#define ARG_MAP_FORMAT "--map-format"
40#define ARG_DRILL_ORIGIN "--drill-origin"
41#define ARG_SEPARATE_FILES "--separate-files"
42
44{
45 m_argParser.add_argument( ARG_FORMAT )
46 .default_value( std::string( "excellon" ) )
47 .help( UTF8STDSTR( _( "Valid options excellon, gerber." ) ) );
48
50 .default_value( std::string( "decimal" ) )
51 .help( UTF8STDSTR(
52 _( "Valid options are: decimal,suppressleading,suppresstrailing,keep." ) ) );
53
54 m_argParser.add_argument( ARG_DRILL_ORIGIN )
55 .default_value( std::string( "absolute" ) )
56 .help( UTF8STDSTR( _( "Valid options are: absolute,plot" ) ) );
57
58 m_argParser.add_argument( "-u", ARG_UNITS )
59 .default_value( std::string( "in" ) )
60 .help( UTF8STDSTR( _( "Output units, valid options:in,mm" ) ) );
61
62 m_argParser.add_argument( ARG_EXCELLON_MIRRORY )
63 .help( UTF8STDSTR( _( "Mirror Y axis" ) ) )
64 .implicit_value( true )
65 .default_value( false );
66
68 .help( UTF8STDSTR( _( "Minimal header" ) ) )
69 .implicit_value( true )
70 .default_value( false );
71
73 .help( UTF8STDSTR( _( "PTH and NPTH in separate files" ) ) )
74 .implicit_value( true )
75 .default_value( false );
76
77 m_argParser.add_argument( ARG_GENERATE_MAP )
78 .help( UTF8STDSTR( _( "Generate map / summary of drill hits" ) ) )
79 .implicit_value( true )
80 .default_value( false );
81
82 m_argParser.add_argument( ARG_MAP_FORMAT )
83 .default_value( std::string( "pdf" ) )
84 .help( UTF8STDSTR( _( "Valid options: pdf,gerberx2,ps,dxf,svg" ) ) );
85
86 m_argParser.add_argument( ARG_SEPARATE_FILES )
87 .help( UTF8STDSTR( _( "Generate independent files for NPTH and PTH holes" ) ) )
88 .implicit_value( true )
89 .default_value( false );
90
91 m_argParser.add_argument( ARG_GERBER_PRECISION )
92 .help( UTF8STDSTR( _( "Precision of gerber coordinates (5 or 6)" ) ) )
93 .default_value( 5 );
94}
95
96
98{
99 std::unique_ptr<JOB_EXPORT_PCB_DRILL> drillJob( new JOB_EXPORT_PCB_DRILL( true ) );
100
101 drillJob->m_filename = FROM_UTF8( m_argParser.get<std::string>( ARG_INPUT ).c_str() );
102 drillJob->m_outputDir = FROM_UTF8( m_argParser.get<std::string>( ARG_OUTPUT ).c_str() );
103
104 if( !drillJob->m_outputDir.IsEmpty() )
105 {
106 wxFileName fn( drillJob->m_outputDir );
107 if( !fn.IsDir() )
108 {
109 wxFprintf( stderr, _( "Output must be a directory\n" ) );
111 }
112 }
113
114 wxString format = FROM_UTF8( m_argParser.get<std::string>( ARG_FORMAT ).c_str() );
115 if( format == "excellon" )
116 {
118 }
119 else if( format == "gerber" )
120 {
122 }
123 else
124 {
125 wxFprintf( stderr, _( "Invalid drill format\n" ) );
127 }
128
129 wxString units = FROM_UTF8( m_argParser.get<std::string>( ARG_UNITS ).c_str() );
130
131 if( units == wxS( "mm" ) )
132 {
133 drillJob->m_drillUnits = JOB_EXPORT_PCB_DRILL::DRILL_UNITS::MILLIMETERS;
134 }
135 else if( units == wxS( "in" ) )
136 {
137 drillJob->m_drillUnits = JOB_EXPORT_PCB_DRILL::DRILL_UNITS::INCHES;
138 }
139 else
140 {
141 wxFprintf( stderr, _( "Invalid units specified\n" ) );
143 }
144
145 wxString zeroFormat = FROM_UTF8( m_argParser.get<std::string>( ARG_EXCELLON_ZEROS_FORMAT ).c_str() );
146
147 if( zeroFormat == wxS( "decimal" ) )
148 {
149 drillJob->m_zeroFormat = JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT::DECIMAL;
150 }
151 else if( zeroFormat == wxS( "suppressleading" ) )
152 {
154 }
155 else if( zeroFormat == wxS( "suppresstrailing" ) )
156 {
158 }
159 else if( zeroFormat == wxS( "keep" ) )
160 {
161 drillJob->m_zeroFormat = JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT::KEEP_ZEROS;
162 }
163 else
164 {
165 wxFprintf( stderr, _( "Invalid zeros format specified\n" ) );
167 }
168
169 wxString mapFormat = FROM_UTF8( m_argParser.get<std::string>( ARG_MAP_FORMAT ).c_str() );
170
171 if( mapFormat == wxS( "pdf" ) )
172 {
173 drillJob->m_mapFormat = JOB_EXPORT_PCB_DRILL::MAP_FORMAT::PDF;
174 }
175 else if( mapFormat == wxS( "ps" ) )
176 {
177 drillJob->m_mapFormat = JOB_EXPORT_PCB_DRILL::MAP_FORMAT::POSTSCRIPT;
178 }
179 else if( mapFormat == wxS( "gerberx2" ) )
180 {
181 drillJob->m_mapFormat = JOB_EXPORT_PCB_DRILL::MAP_FORMAT::GERBER_X2;
182 }
183 else if( mapFormat == wxS( "dxf" ) )
184 {
185 drillJob->m_mapFormat = JOB_EXPORT_PCB_DRILL::MAP_FORMAT::DXF;
186 }
187 else if( mapFormat == wxS( "svg" ) )
188 {
189 drillJob->m_mapFormat = JOB_EXPORT_PCB_DRILL::MAP_FORMAT::SVG;
190 }
191 else
192 {
193 wxFprintf( stderr, _( "Invalid map format specified\n" ) );
195 }
196
197 wxString origin = FROM_UTF8( m_argParser.get<std::string>( ARG_DRILL_ORIGIN ).c_str() );
198
199 if( origin == wxS( "absolute" ) )
200 {
201 drillJob->m_drillOrigin = JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN::ABSOLUTE;
202 }
203 else if( origin == wxS( "plot" ) )
204 {
205 drillJob->m_drillOrigin = JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN::PLOT;
206 }
207 else
208 {
209 wxFprintf( stderr, _( "Invalid origin mode specified\n" ) );
211 }
212
213 drillJob->m_excellonMirrorY = m_argParser.get<bool>( ARG_EXCELLON_MIRRORY );
214 drillJob->m_excellonMinimalHeader = m_argParser.get<bool>( ARG_EXCELLON_MINIMALHEAD );
215 drillJob->m_excellonCombinePTHNPTH = !m_argParser.get<bool>( ARG_EXCELLON_SEPARATE_TH );
216 drillJob->m_generateMap = m_argParser.get<bool>( ARG_GENERATE_MAP );
217
218 if( drillJob->m_gerberPrecision != 5 && drillJob->m_gerberPrecision != 6 )
219 {
220 wxFprintf( stderr, _( "Gerber coordinate precision should be either 5 or 6\n" ) );
222 }
223
224 int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, drillJob.get() );
225
226 return exitCode;
227}
argparse::ArgumentParser m_argParser
Definition: command.h:68
int doPerform(KIWAY &aKiway) override
The internal handler that should be overloaded to implement command specific processing and work.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:279
int ProcessJob(KIWAY::FACE_T aFace, JOB *job)
Definition: kiway.cpp:660
@ FACE_PCB
pcbnew DSO
Definition: kiway.h:287
#define UTF8STDSTR(s)
Definition: command.h:27
#define ARG_OUTPUT
#define ARG_INPUT
#define ARG_EXCELLON_SEPARATE_TH
#define ARG_GENERATE_MAP
#define ARG_MAP_FORMAT
#define ARG_SEPARATE_FILES
#define ARG_EXCELLON_MINIMALHEAD
#define ARG_EXCELLON_ZEROS_FORMAT
#define ARG_EXCELLON_MIRRORY
#define ARG_UNITS
#define ARG_GERBER_PRECISION
#define ARG_DRILL_ORIGIN
#define ARG_FORMAT
#define _(s)
This file contains miscellaneous commonly used macros and functions.
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
static const int ERR_ARGS
Definition: exit_codes.h:31