29#include <magic_enum.hpp>
32#include <wx/tokenzr.h>
33#include "../../3d-viewer/3d_viewer/eda_3d_viewer_settings.h"
36#define ARG_BACKGROUND "--background"
37#define ARG_QUALITY "--quality"
39#define ARG_WIDTH "--width"
40#define ARG_WIDTH_SHORT "-w"
42#define ARG_HEIGHT "--height"
43#define ARG_HEIGHT_SHORT "-h"
45#define ARG_SIDE "--side"
46#define ARG_PRESET "--preset"
47#define ARG_USE_BOARD_STACKUP_COLORS "--use-board-stackup-colors"
48#define ARG_PAN "--pan"
49#define ARG_PIVOT "--pivot"
50#define ARG_ROTATE "--rotate"
51#define ARG_ZOOM "--zoom"
52#define ARG_PERSPECTIVE "--perspective"
53#define ARG_FLOOR "--floor"
55#define ARG_LIGHT_TOP "--light-top"
56#define ARG_LIGHT_BOTTOM "--light-bottom"
57#define ARG_LIGHT_SIDE "--light-side"
58#define ARG_LIGHT_CAMERA "--light-camera"
60#define ARG_LIGHT_SIDE_ELEVATION "--light-side-elevation"
67 auto names = magic_enum::enum_names<T>();
69 for(
size_t i = 0; i < names.size(); i++ )
71 std::string
name = { names[i].begin(), names[i].end() };
79 return std::tolower( c );
92 std::vector<std::string> out;
94 for(
auto& strView : magic_enum::enum_names<T>() )
96 std::string
name = { strView.begin(), strView.end() };
101 return std::tolower( c );
104 out.emplace_back(
name );
114 return magic_enum::enum_cast<T>( aInput, magic_enum::case_insensitive );
119static bool getToEnum(
const std::string& aInput,
T& aOutput )
125 if(
auto opt = magic_enum::enum_cast<T>( aInput, magic_enum::case_insensitive ) )
144 if( wxStr[0] ==
'\'' )
145 wxStr = wxStr.AfterFirst(
'\'' );
147 if( wxStr[wxStr.length() - 1] ==
'\'' )
148 wxStr = wxStr.BeforeLast(
'\'' );
150 wxArrayString arr = wxSplit( wxStr,
',', 0 );
152 if( arr.size() != 3 )
157 success &= arr[0].Trim().ToCDouble( &vec.
x );
158 success &= arr[1].Trim().ToCDouble( &vec.
y );
159 success &= arr[2].Trim().ToCDouble( &vec.
z );
178 if( wxStr[0] ==
'\'' )
179 wxStr = wxStr.AfterFirst(
'\'' );
181 if( wxStr[wxStr.length() - 1] ==
'\'' )
182 wxStr = wxStr.BeforeLast(
'\'' );
184 wxArrayString arr = wxSplit( wxStr,
',', 0 );
186 if( arr.size() == 3 )
190 success &= arr[0].Trim().ToCDouble( &vec.
x );
191 success &= arr[1].Trim().ToCDouble( &vec.
y );
192 success &= arr[2].Trim().ToCDouble( &vec.
z );
200 else if( arr.size() == 1 )
203 if( arr[0].Trim().ToCDouble( &val ) )
205 aOutput =
VECTOR3D( val, val, val );
220 UTF8STDSTR(
_(
"Renders the PCB in 3D view to PNG or JPEG image" ) ) );
223 .default_value( 1600 )
229 .default_value( 900 )
235 .default_value( std::string(
"top" ) )
236 .add_choices( enumChoices<JOB_PCB_RENDER::SIDE>() )
238 .help(
UTF8STDSTR( wxString::Format(
_(
"Render from side. Options: %s" ),
239 enumString<JOB_PCB_RENDER::SIDE>() ) ) );
242 .default_value( std::string(
"" ) )
243 .
help(
UTF8STDSTR( wxString::Format(
_(
"Image background. Options: %s. Default: "
244 "transparent for PNG, opaque for JPEG" ),
245 enumString<JOB_PCB_RENDER::BG_STYLE>() ) ) )
249 .default_value( std::string(
"basic" ) )
250 .add_choices( enumChoices<JOB_PCB_RENDER::QUALITY>() )
251 .metavar(
"QUALITY" )
252 .help(
UTF8STDSTR( wxString::Format(
_(
"Render quality. Options: %s" ),
253 enumString<JOB_PCB_RENDER::QUALITY>() ) ) );
258 .help(
UTF8STDSTR( wxString::Format(
_(
"Appearance preset. Options: %s, %s, or user-defined "
264 .default_value(
true )
265 .implicit_value(
true )
266 .help(
UTF8STDSTR(
_(
"Colors defined in board stackup override those in preset" ) ) );
270 .help(
UTF8STDSTR(
_(
"Enables floor, shadows and post-processing, even if disabled in "
271 "quality setting" ) ) );
275 .help(
UTF8STDSTR(
_(
"Use perspective projection instead of orthogonal" ) ) );
278 .default_value( 1.0 )
284 .default_value( std::string(
"" ) )
286 .help(
UTF8STDSTR(
_(
"Pan camera, format 'X,Y,Z' e.g.: '3,0,0'" ) ) );
289 .default_value( std::string(
"" ) )
291 .help(
UTF8STDSTR(
_(
"Set pivot point relative to the board center in centimeters, format 'X,Y,Z' "
292 "e.g.: '-10,2,0'" ) ) );
295 .default_value( std::string(
"" ) )
298 _(
"Rotate board, format 'X,Y,Z' e.g.: '-45,0,45' for isometric view" ) ) );
301 .default_value( std::string(
"" ) )
303 .help(
UTF8STDSTR(
_(
"Top light intensity, format 'R,G,B' or a single number, range: 0-1" ) ) );
306 .default_value( std::string(
"" ) )
308 .help(
UTF8STDSTR(
_(
"Bottom light intensity, format 'R,G,B' or a single number, range: 0-1" ) ) );
311 .default_value( std::string(
"" ) )
313 .help(
UTF8STDSTR(
_(
"Side lights intensity, format 'R,G,B' or a single number, range: 0-1" ) ) );
316 .default_value( std::string(
"" ) )
318 .help(
UTF8STDSTR(
_(
"Camera light intensity, format 'R,G,B' or a single number, range: 0-1" ) ) );
324 .help(
UTF8STDSTR(
_(
"Side lights elevation angle in degrees, range: 0-90" ) ) );
330 std::unique_ptr<JOB_PCB_RENDER> renderJob(
new JOB_PCB_RENDER() );
332 renderJob->SetConfiguredOutputPath( m_argOutput );
333 renderJob->m_filename = m_argInput;
334 renderJob->SetVarOverrides( m_argDefineVars );
336 renderJob->m_appearancePreset = m_argParser.get<std::string>(
ARG_PRESET );
338 if( renderJob->m_appearancePreset == std::string(wxString(
LEGACY_PRESET_FLAG).ToUTF8().data()) )
340 wxFprintf( stderr,
_(
"Invalid preset\n" ) );
346 renderJob->m_width = m_argParser.get<
int>(
ARG_WIDTH );
347 renderJob->m_height = m_argParser.get<
int>(
ARG_HEIGHT );
348 renderJob->m_zoom = m_argParser.get<
double>(
ARG_ZOOM );
350 renderJob->m_floor = m_argParser.get<
bool>(
ARG_FLOOR );
358 wxFprintf( stderr,
_(
"Invalid background\n" ) );
364 wxFprintf( stderr,
_(
"Invalid rotation format\n" ) );
370 wxFprintf( stderr,
_(
"Invalid pan format\n" ) );
376 wxFprintf( stderr,
_(
"Invalid pivot format\n" ) );
381 renderJob->m_lightTopIntensity ) )
383 wxFprintf( stderr,
_(
"Invalid light top intensity format\n" ) );
388 renderJob->m_lightBottomIntensity ) )
390 wxFprintf( stderr,
_(
"Invalid light bottom intensity format\n" ) );
395 renderJob->m_lightSideIntensity ) )
397 wxFprintf( stderr,
_(
"Invalid light side intensity format\n" ) );
402 renderJob->m_lightCameraIntensity ) )
404 wxFprintf( stderr,
_(
"Invalid light camera intensity format\n" ) );
408 if( m_argOutput.Lower().EndsWith( wxS(
".png" ) ) )
412 else if( m_argOutput.Lower().EndsWith( wxS(
".jpg" ) )
413 || m_argOutput.Lower().EndsWith( wxS(
".jpeg" ) ) )
419 wxFprintf( stderr,
_(
"Invalid image format\n" ) );
void addCommonArgs(bool aInput, bool aOutput, bool aInputCanBeDir, bool aOutputIsDir)
Set up the most common of args used across cli.
argparse::ArgumentParser m_argParser
void addDefineArg()
Set up the drawing sheet arg used by many of the export commands.
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...
int ProcessJob(KIWAY::FACE_T aFace, JOB *aJob, REPORTER *aReporter=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
#define ARG_USE_BOARD_STACKUP_COLORS
static bool getToVector3(const std::string &aInput, VECTOR3D &aOutput)
static bool getColorOrIntensity(const std::string &aInput, VECTOR3D &aOutput)
static bool getToEnum(const std::string &aInput, T &aOutput)
static std::vector< std::string > enumChoices()
#define ARG_LIGHT_SIDE_ELEVATION
static wxString enumString()
static std::optional< T > strToEnum(std::string &aInput)
#define FOLLOW_PLOT_SETTINGS
#define LEGACY_PRESET_FLAG
This file contains miscellaneous commonly used macros and functions.
static const int ERR_ARGS
wxString From_UTF8(const char *cstring)
VECTOR3< double > VECTOR3D