KiCad PCB EDA Suite
command_export_pcb_step.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 <regex>
26#include <locale_io.h>
27
28#include <macros.h>
29
30#define ARG_DRILL_ORIGIN "--drill-origin"
31#define ARG_GRID_ORIGIN "--grid-origin"
32#define ARG_NO_VIRTUAL "--no-virtual"
33#define ARG_SUBST_MODELS "--subst-models"
34#define ARG_FORCE "--force"
35#define ARG_OUTPUT "--output"
36#define ARG_INPUT "input"
37#define ARG_MIN_DISTANCE "--min-distance"
38#define ARG_USER_ORIGIN "--user-origin"
39#define ARG_BOARD_ONLY "--board-only"
40#define ARG_EXPORT_TRACKS "--export-tracks"
41
42#define REGEX_QUANTITY "([\\s]*[+-]?[\\d]*[.]?[\\d]*)"
43#define REGEX_DELIMITER "(?:[\\s]*x)"
44#define REGEX_UNIT "([m]{2}|(?:in))"
45
47{
48 m_argParser.add_argument( ARG_DRILL_ORIGIN )
49 .help( UTF8STDSTR( _( "Use Drill Origin for output origin" ) ) )
50 .implicit_value( true )
51 .default_value( false );
52
53 m_argParser.add_argument( ARG_GRID_ORIGIN )
54 .help( UTF8STDSTR( _( "Use Grid Origin for output origin" ) ) )
55 .implicit_value( true )
56 .default_value( false );
57
58 m_argParser.add_argument( ARG_NO_VIRTUAL )
59 .help( UTF8STDSTR( _( "Exclude 3D models for components with 'virtual' attribute" ) ) )
60 .implicit_value( true )
61 .default_value( false );
62
63 m_argParser.add_argument( "--subst-models" )
64 .help( UTF8STDSTR( _( "Substitute STEP or IGS models with the same name in place of VRML models" ) ) )
65 .implicit_value( true )
66 .default_value( false );
67
68 m_argParser.add_argument( ARG_FORCE, "-f" )
69 .help( UTF8STDSTR( _( "Overwrite output file" ) ) )
70 .implicit_value( true )
71 .default_value( false );
72
73 m_argParser.add_argument( ARG_BOARD_ONLY )
74 .help( UTF8STDSTR( _( "Only generate a board with no components" ) ) )
75 .implicit_value( true )
76 .default_value( false );
77
78 m_argParser.add_argument( ARG_EXPORT_TRACKS )
79 .help( UTF8STDSTR( _( "Export tracks (extremely time consuming)" ) ) )
80 .implicit_value( true )
81 .default_value( false );
82
83 m_argParser.add_argument( ARG_MIN_DISTANCE )
84 .default_value( std::string( "0.01mm" ) )
85 .help( UTF8STDSTR( _( "Minimum distance between points to treat them as separate ones" ) ) );
86
87 m_argParser.add_argument( ARG_USER_ORIGIN )
88 .default_value( std::string() )
89 .help( UTF8STDSTR( _( "User-specified output origin ex. 1x1in, 1x1inch, 25.4x25.4mm (default unit mm)" ) ) );
90
91 m_argParser.add_argument( "-o", ARG_OUTPUT )
92 .default_value( std::string() )
93 .help( UTF8STDSTR( _( "Output file name" ) ) );
94
95 m_argParser.add_argument( ARG_INPUT ).help( UTF8STDSTR( _( "Input file" ) ) );
96}
97
99{
100 std::unique_ptr<JOB_EXPORT_PCB_STEP> step( new JOB_EXPORT_PCB_STEP( true ) );
101
102 step->m_useDrillOrigin = m_argParser.get<bool>( ARG_DRILL_ORIGIN );
103 step->m_useGridOrigin = m_argParser.get<bool>( ARG_GRID_ORIGIN );
104 step->m_includeExcludedBom = !m_argParser.get<bool>( ARG_NO_VIRTUAL );
105 step->m_substModels = m_argParser.get<bool>( ARG_SUBST_MODELS );
106 step->m_overwrite = m_argParser.get<bool>( ARG_FORCE );
107 step->m_filename = FROM_UTF8( m_argParser.get<std::string>( ARG_INPUT ).c_str() );
108 step->m_outputFile = FROM_UTF8( m_argParser.get<std::string>( ARG_OUTPUT ).c_str() );
109 step->m_boardOnly = m_argParser.get<bool>( ARG_BOARD_ONLY );
110 step->m_exportTracks = m_argParser.get<bool>( ARG_EXPORT_TRACKS );
111
112 wxString userOrigin = FROM_UTF8( m_argParser.get<std::string>( ARG_USER_ORIGIN ).c_str() );
113
114 LOCALE_IO dummy; // Switch to "C" locale
115
116 if( !userOrigin.IsEmpty() )
117 {
119 std::regex_constants::icase );
120 std::smatch sm;
121 std::string str( userOrigin.ToUTF8() );
122 std::regex_search( str, sm, re_pattern );
123 step->m_xOrigin = atof( sm.str( 1 ).c_str() );
124 step->m_yOrigin = atof( sm.str( 2 ).c_str() );
125
126 std::string tunit( sm[3] );
127
128 if( tunit.size() > 0 ) // No unit accepted ( default = mm )
129 {
130 if( ( !sm.str( 1 ).compare( " " ) || !sm.str( 2 ).compare( " " ) )
131 || ( sm.size() != 4 ) )
132 {
133 std::cout << m_argParser;
135 }
136
137 // only in, inch and mm are valid:
138 if( !tunit.compare( "in" ) || !tunit.compare( "inch" ) )
139 {
140 step->m_xOrigin *= 25.4;
141 step->m_yOrigin *= 25.4;
142 }
143 else if( tunit.compare( "mm" ) )
144 {
145 std::cout << m_argParser;
147 }
148 }
149 }
150
151 wxString minDistance = FROM_UTF8( m_argParser.get<std::string>( ARG_MIN_DISTANCE ).c_str() );
152
153 if( !minDistance.IsEmpty() )
154 {
155 std::regex re_pattern( REGEX_QUANTITY REGEX_UNIT,
156 std::regex_constants::icase );
157 std::smatch sm;
158 std::string str( minDistance.ToUTF8() );
159 std::regex_search( str, sm, re_pattern );
160 step->m_BoardOutlinesChainingEpsilon = atof( sm.str( 1 ).c_str() );
161
162 std::string tunit( sm[2] );
163
164 if( tunit.size() > 0 ) // No unit accepted ( default = mm )
165 {
166 if( !tunit.compare( "in" ) || !tunit.compare( "inch" ) )
167 {
168 step->m_BoardOutlinesChainingEpsilon *= 25.4;
169 }
170 else if( tunit.compare( "mm" ) )
171 {
172 std::cout << m_argParser;
174 }
175 }
176 }
177
178 int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, step.get() );
179
180 return exitCode;
181}
argparse::ArgumentParser m_argParser
Definition: command.h:68
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
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:41
#define UTF8STDSTR(s)
Definition: command.h:27
#define ARG_OUTPUT
#define ARG_INPUT
#define ARG_MIN_DISTANCE
#define ARG_FORCE
#define ARG_NO_VIRTUAL
#define ARG_EXPORT_TRACKS
#define REGEX_QUANTITY
#define REGEX_UNIT
#define ARG_BOARD_ONLY
#define REGEX_DELIMITER
#define ARG_SUBST_MODELS
#define ARG_GRID_ORIGIN
#define ARG_USER_ORIGIN
#define ARG_DRILL_ORIGIN
#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
std::vector< FAB_LAYER_COLOR > dummy
int doPerform(KIWAY &aKiway) override
The internal handler that should be overloaded to implement command specific processing and work.