Implement cli for gerber, drill, pdf export of pcb

This commit is contained in:
Marek Roszko 2022-10-28 09:43:35 -04:00
parent 30211da69f
commit 0a134788d0
28 changed files with 1087 additions and 48 deletions

View File

@ -0,0 +1,107 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JOB_EXPORT_PCB_DRILL_H
#define JOB_EXPORT_PCB_DRILL_H
#include <layer_ids.h>
#include <wx/string.h>
#include "job.h"
class JOB_EXPORT_PCB_DRILL : public JOB
{
public:
JOB_EXPORT_PCB_DRILL( bool aIsCli ) :
JOB( "drill", aIsCli ),
m_filename(),
m_outputDir(),
m_excellonMirrorY( false ),
m_excellonMinimalHeader( false ),
m_excellonCombinePTHNPTH( true ),
m_excellonOvalDrillRoute( false ),
m_format( DRILL_FORMAT::EXCELLON ),
m_drillOrigin( DRILL_ORIGIN::ABSOLUTE ),
m_drillUnits( DRILL_UNITS::INCHES ),
m_zeroFormat( ZEROS_FORMAT::DECIMAL ),
m_mapFormat( MAP_FORMAT::PDF ),
m_gerberPrecision( 5 ),
m_generateMap( false )
{
}
wxString m_filename;
wxString m_outputDir;
bool m_excellonMirrorY;
bool m_excellonMinimalHeader;
bool m_excellonCombinePTHNPTH;
bool m_excellonOvalDrillRoute;
enum class DRILL_FORMAT
{
EXCELLON,
GERBER
};
DRILL_FORMAT m_format;
enum class DRILL_ORIGIN
{
ABSOLUTE,
PLOT
};
DRILL_ORIGIN m_drillOrigin;
enum class DRILL_UNITS
{
INCHES,
MILLIMETERS
};
DRILL_UNITS m_drillUnits;
enum class ZEROS_FORMAT
{
DECIMAL,
SUPRESS_LEADING,
SUPRESS_TRAILING,
KEEP_ZEROS
};
ZEROS_FORMAT m_zeroFormat;
enum class MAP_FORMAT
{
POSTSCRIPT,
GERBER_X2,
DXF,
SVG,
PDF
};
MAP_FORMAT m_mapFormat;
int m_gerberPrecision;
bool m_generateMap;
};
#endif

View File

@ -35,7 +35,8 @@ public:
m_plotFootprintValues( true ),
m_plotRefDes( true ),
m_plotGraphicItemsUsingContours( true ),
m_pageSizeMode( 0 ),
m_plotBorderTitleBlocks( false ),
m_dxfUnits( DXF_UNITS::INCHES ),
m_printMaskLayer()
{
}
@ -52,10 +53,9 @@ public:
bool m_plotFootprintValues;
bool m_plotRefDes;
bool m_plotGraphicItemsUsingContours;
bool m_plotBorderTitleBlocks;
DXF_UNITS m_dxfUnits;
int m_pageSizeMode;
LSET m_printMaskLayer;
};

View File

@ -0,0 +1,64 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JOB_EXPORT_PCB_GERBER_H
#define JOB_EXPORT_PCB_GERBER_H
#include <layer_ids.h>
#include <wx/string.h>
#include "job.h"
class JOB_EXPORT_PCB_GERBER : public JOB
{
public:
JOB_EXPORT_PCB_GERBER( bool aIsCli ) :
JOB( "gerber", aIsCli ),
m_filename(),
m_outputFile(),
m_plotFootprintValues( true ),
m_plotRefDes( true ),
m_plotBorderTitleBlocks( false ),
m_subtractSolderMaskFromSilk( false ),
m_includeNetlistAttributes( true ),
m_useX2Format( true ),
m_disableApertureMacros( false ),
m_precision( 5 ),
m_printMaskLayer()
{
}
wxString m_filename;
wxString m_outputFile;
bool m_plotFootprintValues;
bool m_plotRefDes;
bool m_plotBorderTitleBlocks;
bool m_subtractSolderMaskFromSilk;
bool m_includeNetlistAttributes;
bool m_useX2Format;
bool m_disableApertureMacros;
int m_precision;
LSET m_printMaskLayer;
};
#endif

View File

@ -0,0 +1,52 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JOB_EXPORT_PCB_PDF_H
#define JOB_EXPORT_PCB_PDF_H
#include <layer_ids.h>
#include <wx/string.h>
#include "job.h"
class JOB_EXPORT_PCB_PDF : public JOB
{
public:
JOB_EXPORT_PCB_PDF( bool aIsCli ) :
JOB( "pdf", aIsCli ),
m_filename(),
m_outputFile(),
m_plotFootprintValues( true ),
m_plotRefDes( true ),
m_plotBorderTitleBlocks( false ),
m_printMaskLayer()
{
}
wxString m_filename;
wxString m_outputFile;
bool m_plotFootprintValues;
bool m_plotRefDes;
bool m_plotBorderTitleBlocks;
LSET m_printMaskLayer;
};
#endif

View File

@ -17,7 +17,10 @@ include_directories(
set( KICAD_SRCS
cli/command_export_pcb_base.cpp
cli/command_export_pcb_drill.cpp
cli/command_export_pcb_dxf.cpp
cli/command_export_pcb_gerber.cpp
cli/command_export_pcb_pdf.cpp
cli/command_export_pcb_step.cpp
cli/command_export_pcb_svg.cpp
cli/command_pcb.cpp

View File

@ -32,7 +32,7 @@ class COMMAND
public:
COMMAND( std::string aName ) : m_name( aName ), m_argParser( aName ){};
virtual int Perform( KIWAY& aKiway ) const = 0;
virtual int Perform( KIWAY& aKiway ) = 0;
virtual ~COMMAND() = default;

View File

@ -21,9 +21,12 @@
#include "command_export_pcb_base.h"
#include <cli/exit_codes.h>
#include <kiface_base.h>
#include <bitset>
#include <layer_ids.h>
#include <macros.h>
#include <wx/tokenzr.h>
#include <wx/crt.h>
CLI::EXPORT_PCB_BASE_COMMAND::EXPORT_PCB_BASE_COMMAND( std::string aName ) : COMMAND( aName )
{
@ -33,7 +36,6 @@ CLI::EXPORT_PCB_BASE_COMMAND::EXPORT_PCB_BASE_COMMAND( std::string aName ) : COM
m_argParser.add_argument( ARG_INPUT ).help( "input file" );
for( int layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
{
std::string untranslated = TO_UTF8( wxString( LSET::Name( PCB_LAYER_ID( layer ) ) ) );
@ -41,6 +43,7 @@ CLI::EXPORT_PCB_BASE_COMMAND::EXPORT_PCB_BASE_COMMAND( std::string aName ) : COM
//m_layerIndices[untranslated] = PCB_LAYER_ID( layer );
m_layerMasks[untranslated] = LSET( PCB_LAYER_ID( layer ) );
}
m_layerMasks["*.Cu"] = LSET::AllCuMask();
m_layerMasks["*In.Cu"] = LSET::InternalCuMask();
m_layerMasks["F&B.Cu"] = LSET( 2, F_Cu, B_Cu );
@ -55,7 +58,7 @@ CLI::EXPORT_PCB_BASE_COMMAND::EXPORT_PCB_BASE_COMMAND( std::string aName ) : COM
LSET CLI::EXPORT_PCB_BASE_COMMAND::convertLayerStringList( wxString& aLayerString ) const
{
LSET layerMask = LSET::AllCuMask();
LSET layerMask;
if( !aLayerString.IsEmpty() )
{
@ -68,8 +71,43 @@ LSET CLI::EXPORT_PCB_BASE_COMMAND::convertLayerStringList( wxString& aLayerStrin
{
layerMask |= m_layerMasks.at(token);
}
else
{
wxFprintf( stderr, _( "Invalid layer name \"%s\"\n" ), token );
}
}
}
return layerMask;
}
void CLI::EXPORT_PCB_BASE_COMMAND::addLayerArg( bool aRequire )
{
m_argParser.add_argument( "-l", ARG_LAYERS )
.default_value( std::string() )
.help( "comma separated list of untranslated layer names to include such as "
"F.Cu,B.Cu" );
m_requireLayers = aRequire;
}
int CLI::EXPORT_PCB_BASE_COMMAND::Perform( KIWAY& aKiway )
{
if( m_requireLayers )
{
wxString layers = FROM_UTF8( m_argParser.get<std::string>( ARG_LAYERS ).c_str() );
LSET layerMask = convertLayerStringList( layers );
if( layerMask.Seq().size() < 1 )
{
wxFprintf( stderr, _( "At least one or more layers must be specified\n" ) );
return EXIT_CODES::ERR_ARGS;
}
m_selectedLayers = layerMask;
}
return EXIT_CODES::OK;
}

View File

@ -28,15 +28,27 @@ namespace CLI
{
#define ARG_OUTPUT "--output"
#define ARG_INPUT "input"
#define ARG_BLACKANDWHITE "--black-and-white"
#define ARG_LAYERS "--layers"
#define ARG_INCLUDE_REFDES "--include-refdes"
#define ARG_INCLUDE_VALUE "--include-value"
#define ARG_THEME "--theme"
#define ARG_INCLUDE_BORDER_TITLE "--include-border-title"
struct EXPORT_PCB_BASE_COMMAND : public COMMAND
{
EXPORT_PCB_BASE_COMMAND( std::string aName );
int Perform( KIWAY& aKiway ) override;
protected:
LSET convertLayerStringList( wxString& aLayerString ) const;
void addLayerArg( bool aRequire );
std::map<std::string, LSET> m_layerMasks;
LSET m_selectedLayers;
bool m_requireLayers;
};
} // namespace CLI

View File

@ -0,0 +1,226 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "command_export_pcb_drill.h"
#include <cli/exit_codes.h>
#include "jobs/job_export_pcb_drill.h"
#include <kiface_base.h>
#include <layer_ids.h>
#include <wx/crt.h>
#include <macros.h>
#include <wx/tokenzr.h>
#define ARG_FORMAT "--format"
#define ARG_EXCELLON_MIRRORY "--excellon-mirror-y"
#define ARG_EXCELLON_MINIMALHEAD "--excellon-min-header"
#define ARG_EXCELLON_SEPARATE_TH "--excellon-separate-th"
#define ARG_EXCELLON_ZEROS_FORMAT "--excellon-zeros-format"
#define ARG_GERBER_PRECISION "--gerber-precision"
#define ARG_UNITS "--units"
#define ARG_GENERATE_MAP "--generate-map"
#define ARG_MAP_FORMAT "--map-format"
#define ARG_DRILL_ORIGIN "--drill-origin"
#define ARG_SEPARATE_FILES "--separate-files"
CLI::EXPORT_PCB_DRILL_COMMAND::EXPORT_PCB_DRILL_COMMAND() : EXPORT_PCB_BASE_COMMAND( "drill" )
{
m_argParser.add_argument( ARG_FORMAT )
.default_value( std::string( "excellon" ) )
.help( "valid options are either excellon or gerber" );
m_argParser.add_argument( ARG_EXCELLON_ZEROS_FORMAT )
.default_value( std::string( "decimal" ) )
.help( "valid options are: decimal,supressleading,surpresstrailing,keep" );
m_argParser.add_argument( ARG_DRILL_ORIGIN )
.default_value( std::string( "absolute" ) )
.help( "valid options are: absolute,plot" );
m_argParser.add_argument( "-u", ARG_UNITS )
.default_value( std::string( "in" ) )
.help( "output units, valid options are in or mm" );
m_argParser.add_argument( ARG_EXCELLON_MIRRORY )
.help( "Mirror Y axis" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_EXCELLON_MINIMALHEAD )
.help( "Minimal header" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_EXCELLON_SEPARATE_TH )
.help( "PTH and NPTH in separate files file" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_GENERATE_MAP )
.help( "Generate map / summary of drill hits" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_MAP_FORMAT )
.default_value( std::string( "pdf" ) )
.help( "valid options are: pdf,gerberx2,ps,dxf,svg" );
m_argParser.add_argument( ARG_SEPARATE_FILES )
.help( "Generate independent files for NPTH and PTH holes" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_GERBER_PRECISION )
.help( "Precision of gerber coordinates (5 or 6)" )
.default_value( 5 );
}
int CLI::EXPORT_PCB_DRILL_COMMAND::Perform( KIWAY& aKiway )
{
JOB_EXPORT_PCB_DRILL* drillJob = new JOB_EXPORT_PCB_DRILL( true );
drillJob->m_filename = FROM_UTF8( m_argParser.get<std::string>( ARG_INPUT ).c_str() );
drillJob->m_outputDir = FROM_UTF8( m_argParser.get<std::string>( ARG_OUTPUT ).c_str() );
if( !drillJob->m_outputDir.IsEmpty() )
{
wxFileName fn( drillJob->m_outputDir );
if( !fn.IsDir() )
{
wxFprintf( stderr, _( "Output must be a directory\n" ) );
return EXIT_CODES::ERR_ARGS;
}
}
wxString format = FROM_UTF8( m_argParser.get<std::string>( ARG_FORMAT ).c_str() );
if( format == "excellon" )
{
drillJob->m_format = JOB_EXPORT_PCB_DRILL::DRILL_FORMAT::EXCELLON;
}
else if( format == "gerber" )
{
drillJob->m_format = JOB_EXPORT_PCB_DRILL::DRILL_FORMAT::GERBER;
}
else
{
wxFprintf( stderr, _( "Invalid drill format\n" ) );
return EXIT_CODES::ERR_ARGS;
}
wxString units = FROM_UTF8( m_argParser.get<std::string>( ARG_UNITS ).c_str() );
if( units == wxS( "mm" ) )
{
drillJob->m_drillUnits = JOB_EXPORT_PCB_DRILL::DRILL_UNITS::MILLIMETERS;
}
else if( units == wxS( "in" ) )
{
drillJob->m_drillUnits = JOB_EXPORT_PCB_DRILL::DRILL_UNITS::INCHES;
}
else
{
wxFprintf( stderr, _( "Invalid units specified\n" ) );
return EXIT_CODES::ERR_ARGS;
}
wxString zeroFormat = FROM_UTF8( m_argParser.get<std::string>( ARG_EXCELLON_ZEROS_FORMAT ).c_str() );
if( zeroFormat == wxS( "decimal" ) )
{
drillJob->m_zeroFormat = JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT::DECIMAL;
}
else if( zeroFormat == wxS( "supressleading" ) )
{
drillJob->m_zeroFormat = JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT::SUPRESS_LEADING;
}
else if( zeroFormat == wxS( "surpresstrailing" ) )
{
drillJob->m_zeroFormat = JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT::SUPRESS_TRAILING;
}
else if( zeroFormat == wxS( "keep" ) )
{
drillJob->m_zeroFormat = JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT::KEEP_ZEROS;
}
else
{
wxFprintf( stderr, _( "Invalid zeros format specified\n" ) );
return EXIT_CODES::ERR_ARGS;
}
wxString mapFormat = FROM_UTF8( m_argParser.get<std::string>( ARG_MAP_FORMAT ).c_str() );
if( mapFormat == wxS( "pdf" ) )
{
drillJob->m_mapFormat = JOB_EXPORT_PCB_DRILL::MAP_FORMAT::PDF;
}
else if( mapFormat == wxS( "ps" ) )
{
drillJob->m_mapFormat = JOB_EXPORT_PCB_DRILL::MAP_FORMAT::POSTSCRIPT;
}
else if( mapFormat == wxS( "gerberx2" ) )
{
drillJob->m_mapFormat = JOB_EXPORT_PCB_DRILL::MAP_FORMAT::GERBER_X2;
}
else if( mapFormat == wxS( "dxf" ) )
{
drillJob->m_mapFormat = JOB_EXPORT_PCB_DRILL::MAP_FORMAT::DXF;
}
else if( mapFormat == wxS( "svg" ) )
{
drillJob->m_mapFormat = JOB_EXPORT_PCB_DRILL::MAP_FORMAT::SVG;
}
else
{
wxFprintf( stderr, _( "Invalid map format specified\n" ) );
return EXIT_CODES::ERR_ARGS;
}
wxString origin = FROM_UTF8( m_argParser.get<std::string>( ARG_DRILL_ORIGIN ).c_str() );
if( origin == wxS( "absolute" ) )
{
drillJob->m_drillOrigin = JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN::ABSOLUTE;
}
else if( origin == wxS( "plot" ) )
{
drillJob->m_drillOrigin = JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN::PLOT;
}
else
{
wxFprintf( stderr, _( "Invalid origin mode specified\n" ) );
return EXIT_CODES::ERR_ARGS;
}
drillJob->m_excellonMirrorY = m_argParser.get<bool>( ARG_EXCELLON_MIRRORY );
drillJob->m_excellonMinimalHeader = m_argParser.get<bool>( ARG_EXCELLON_MINIMALHEAD );
drillJob->m_excellonCombinePTHNPTH = !m_argParser.get<bool>( ARG_EXCELLON_SEPARATE_TH );
drillJob->m_generateMap = m_argParser.get<bool>( ARG_GENERATE_MAP );
if( drillJob->m_gerberPrecision != 5 && drillJob->m_gerberPrecision != 6 )
{
wxFprintf( stderr, _( "Gerber coordinate precision should be either 5 or 6\n" ) );
return EXIT_CODES::ERR_ARGS;
}
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, drillJob );
return exitCode;
}

View File

@ -0,0 +1,37 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef COMMAND_EXPORT_PCB_DRILL_H
#define COMMAND_EXPORT_PCB_DRILL_H
#include "command_export_pcb_base.h"
namespace CLI
{
class EXPORT_PCB_DRILL_COMMAND : public EXPORT_PCB_BASE_COMMAND
{
public:
EXPORT_PCB_DRILL_COMMAND();
int Perform( KIWAY& aKiway ) override;
};
} // namespace CLI
#endif

View File

@ -38,9 +38,7 @@
CLI::EXPORT_PCB_DXF_COMMAND::EXPORT_PCB_DXF_COMMAND() : EXPORT_PCB_BASE_COMMAND( "dxf" )
{
m_argParser.add_argument( "-l", ARG_LAYERS )
.default_value( std::string() )
.help( "comma separated list of untranslated layer names to include such as F.Cu,B.Cu" );
addLayerArg( true );
m_argParser.add_argument( "-ird", ARG_INCLUDE_REFDES )
.help( "Include the reference designator text" )
@ -63,8 +61,12 @@ CLI::EXPORT_PCB_DXF_COMMAND::EXPORT_PCB_DXF_COMMAND() : EXPORT_PCB_BASE_COMMAND(
}
int CLI::EXPORT_PCB_DXF_COMMAND::Perform( KIWAY& aKiway ) const
int CLI::EXPORT_PCB_DXF_COMMAND::Perform( KIWAY& aKiway )
{
int baseExit = EXPORT_PCB_BASE_COMMAND::Perform( aKiway );
if( baseExit != EXIT_CODES::OK )
return baseExit;
std::unique_ptr<JOB_EXPORT_PCB_DXF> dxfJob( new JOB_EXPORT_PCB_DXF( true ) );
dxfJob->m_filename = FROM_UTF8( m_argParser.get<std::string>( ARG_INPUT ).c_str() );
@ -96,11 +98,7 @@ int CLI::EXPORT_PCB_DXF_COMMAND::Perform( KIWAY& aKiway ) const
return EXIT_CODES::ERR_ARGS;
}
wxString layers = FROM_UTF8( m_argParser.get<std::string>( ARG_LAYERS ).c_str() );
LSET layerMask = convertLayerStringList( layers );
dxfJob->m_printMaskLayer = layerMask;
dxfJob->m_printMaskLayer = m_selectedLayers;
LOCALE_IO dummy; // Switch to "C" locale
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, dxfJob.get() );

View File

@ -30,7 +30,7 @@ class EXPORT_PCB_DXF_COMMAND : public EXPORT_PCB_BASE_COMMAND
public:
EXPORT_PCB_DXF_COMMAND();
int Perform( KIWAY& aKiway ) const override;
int Perform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -0,0 +1,119 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "command_export_pcb_gerber.h"
#include <cli/exit_codes.h>
#include "jobs/job_export_pcb_gerber.h"
#include <kiface_base.h>
#include <layer_ids.h>
#include <wx/crt.h>
#include <macros.h>
#include <wx/tokenzr.h>
#define ARG_NO_X2 "--no-x2"
#define ARG_NO_NETLIST "--no-netlist"
#define ARG_SUBTRACT_SOLDERMASK "--subtract-soldermask"
#define ARG_DISABLE_APERTURE_MACROS "--disable-aperture-macros"
#define ARG_PRECISION "--precision"
CLI::EXPORT_PCB_GERBER_COMMAND::EXPORT_PCB_GERBER_COMMAND() : EXPORT_PCB_BASE_COMMAND( "gerber" )
{
addLayerArg( true );
m_argParser.add_argument( "-ird", ARG_INCLUDE_REFDES )
.help( "Include the reference designator text" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( "-iv", ARG_INCLUDE_VALUE )
.help( "Include the value text" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( "-ibt", ARG_INCLUDE_BORDER_TITLE )
.help( "Include the border and title block" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_NO_X2 )
.help( "Do not use the extended X2 format" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_NO_NETLIST )
.help( "Do not generate netlist attributes" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_SUBTRACT_SOLDERMASK )
.help( "Subtract soldermask from silkscreen" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_DISABLE_APERTURE_MACROS )
.help( "Disable aperature macros" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_PRECISION )
.help( "Precision of gerber coordinates (5 or 6)" )
.default_value( 5 );
}
int CLI::EXPORT_PCB_GERBER_COMMAND::Perform( KIWAY& aKiway )
{
int baseExit = EXPORT_PCB_BASE_COMMAND::Perform( aKiway );
if( baseExit != EXIT_CODES::OK )
return baseExit;
JOB_EXPORT_PCB_GERBER* gerberJob = new JOB_EXPORT_PCB_GERBER( true );
gerberJob->m_filename = FROM_UTF8( m_argParser.get<std::string>( ARG_INPUT ).c_str() );
gerberJob->m_outputFile = FROM_UTF8( m_argParser.get<std::string>( ARG_OUTPUT ).c_str() );
if( !wxFile::Exists( gerberJob->m_filename ) )
{
wxFprintf( stderr, _( "Board file does not exist or is not accessible\n" ) );
return EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
gerberJob->m_plotFootprintValues = m_argParser.get<bool>( ARG_INCLUDE_VALUE );
gerberJob->m_plotRefDes = m_argParser.get<bool>( ARG_INCLUDE_VALUE );
gerberJob->m_plotBorderTitleBlocks = m_argParser.get<bool>( ARG_INCLUDE_BORDER_TITLE );
gerberJob->m_disableApertureMacros = m_argParser.get<bool>( ARG_DISABLE_APERTURE_MACROS );
gerberJob->m_subtractSolderMaskFromSilk = m_argParser.get<bool>( ARG_SUBTRACT_SOLDERMASK );
gerberJob->m_includeNetlistAttributes = !m_argParser.get<bool>( ARG_NO_NETLIST );
gerberJob->m_useX2Format = !m_argParser.get<bool>( ARG_NO_X2 );
gerberJob->m_precision = m_argParser.get<int>( ARG_PRECISION );
if( gerberJob->m_precision != 5 && gerberJob->m_precision != 6 )
{
wxFprintf( stderr, _( "Gerber coordinate precision should be either 5 or 6\n" ) );
return EXIT_CODES::ERR_ARGS;
}
gerberJob->m_printMaskLayer = m_selectedLayers;
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, gerberJob );
return exitCode;
}

View File

@ -0,0 +1,37 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef COMMAND_EXPORT_PCB_GERBER_H
#define COMMAND_EXPORT_PCB_GERBER_H
#include "command_export_pcb_base.h"
namespace CLI
{
class EXPORT_PCB_GERBER_COMMAND : public EXPORT_PCB_BASE_COMMAND
{
public:
EXPORT_PCB_GERBER_COMMAND();
int Perform( KIWAY& aKiway ) override;
};
} // namespace CLI
#endif

View File

@ -0,0 +1,88 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "command_export_pcb_pdf.h"
#include <cli/exit_codes.h>
#include "jobs/job_export_pcb_pdf.h"
#include <kiface_base.h>
#include <layer_ids.h>
#include <wx/crt.h>
#include <macros.h>
#include <wx/tokenzr.h>
CLI::EXPORT_PCB_PDF_COMMAND::EXPORT_PCB_PDF_COMMAND() : EXPORT_PCB_BASE_COMMAND( "pdf" )
{
addLayerArg( true );
m_argParser.add_argument( "-ird", ARG_INCLUDE_REFDES )
.help( "Include the reference designator text" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( "-iv", ARG_INCLUDE_VALUE )
.help( "Include the value text" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( "-ibt", ARG_INCLUDE_BORDER_TITLE )
.help( "Include the border and title block" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_BLACKANDWHITE )
.help( "Black and white only" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( "-t", ARG_THEME )
.default_value( std::string() )
.help( "Color theme to use (will default to pcbnew settings)" );
}
int CLI::EXPORT_PCB_PDF_COMMAND::Perform( KIWAY& aKiway )
{
int baseExit = EXPORT_PCB_BASE_COMMAND::Perform( aKiway );
if( baseExit != EXIT_CODES::OK )
return baseExit;
JOB_EXPORT_PCB_PDF* pdfJob = new JOB_EXPORT_PCB_PDF( true );
pdfJob->m_filename = FROM_UTF8( m_argParser.get<std::string>( ARG_INPUT ).c_str() );
pdfJob->m_outputFile = FROM_UTF8( m_argParser.get<std::string>( ARG_OUTPUT ).c_str() );
if( !wxFile::Exists( pdfJob->m_filename ) )
{
wxFprintf( stderr, _( "Board file does not exist or is not accessible\n" ) );
return EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
pdfJob->m_plotFootprintValues = m_argParser.get<bool>( ARG_INCLUDE_VALUE );
pdfJob->m_plotRefDes = m_argParser.get<bool>( ARG_INCLUDE_REFDES );
pdfJob->m_plotBorderTitleBlocks = m_argParser.get<bool>( ARG_INCLUDE_BORDER_TITLE );
pdfJob->m_printMaskLayer = m_selectedLayers;
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, pdfJob );
return exitCode;
}

View File

@ -0,0 +1,37 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef COMMAND_EXPORT_PCB_PDF_H
#define COMMAND_EXPORT_PCB_PDF_H
#include "command_export_pcb_base.h"
namespace CLI
{
class EXPORT_PCB_PDF_COMMAND : public EXPORT_PCB_BASE_COMMAND
{
public:
EXPORT_PCB_PDF_COMMAND();
int Perform( KIWAY& aKiway ) override;
};
} // namespace CLI
#endif

View File

@ -82,7 +82,7 @@ CLI::EXPORT_PCB_STEP_COMMAND::EXPORT_PCB_STEP_COMMAND() : COMMAND( "step" )
m_argParser.add_argument( ARG_INPUT ).help( "input file" );
}
int CLI::EXPORT_PCB_STEP_COMMAND::Perform( KIWAY& aKiway ) const
int CLI::EXPORT_PCB_STEP_COMMAND::Perform( KIWAY& aKiway )
{
std::unique_ptr<JOB_EXPORT_PCB_STEP> step( new JOB_EXPORT_PCB_STEP( true ) );

View File

@ -29,7 +29,7 @@ struct EXPORT_PCB_STEP_COMMAND : public COMMAND
{
EXPORT_PCB_STEP_COMMAND();
int Perform( KIWAY& aKiway ) const override;
int Perform( KIWAY& aKiway ) override;
};
}

View File

@ -32,16 +32,11 @@
#define ARG_PAGE_SIZE "--page-size-mode"
#define ARG_MIRROR "--mirror"
#define ARG_BLACKANDWHITE "--black-and-white"
#define ARG_THEME "--theme"
#define ARG_LAYERS "--layers"
CLI::EXPORT_PCB_SVG_COMMAND::EXPORT_PCB_SVG_COMMAND() : EXPORT_PCB_BASE_COMMAND( "svg" )
{
m_argParser.add_argument( "-l", ARG_LAYERS )
.default_value( std::string() )
.help( "comma separated list of untranslated layer names to include such as F.Cu,B.Cu" );
addLayerArg( true );
m_argParser.add_argument( "-m", ARG_MIRROR )
.help( "Mirror the board (useful for trying to show bottom layers)" )
@ -63,8 +58,12 @@ CLI::EXPORT_PCB_SVG_COMMAND::EXPORT_PCB_SVG_COMMAND() : EXPORT_PCB_BASE_COMMAND(
}
int CLI::EXPORT_PCB_SVG_COMMAND::Perform( KIWAY& aKiway ) const
int CLI::EXPORT_PCB_SVG_COMMAND::Perform( KIWAY& aKiway )
{
int baseExit = EXPORT_PCB_BASE_COMMAND::Perform( aKiway );
if( baseExit != EXIT_CODES::OK )
return baseExit;
std::unique_ptr<JOB_EXPORT_PCB_SVG> svgJob( new JOB_EXPORT_PCB_SVG( true ) );
svgJob->m_mirror = m_argParser.get<bool>( ARG_MIRROR );
@ -81,11 +80,7 @@ int CLI::EXPORT_PCB_SVG_COMMAND::Perform( KIWAY& aKiway ) const
return EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
wxString layers = FROM_UTF8( m_argParser.get<std::string>( ARG_LAYERS ).c_str() );
LSET layerMask = convertLayerStringList( layers );
svgJob->m_printMaskLayer = layerMask;
svgJob->m_printMaskLayer = m_selectedLayers;
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, svgJob.get() );

View File

@ -29,7 +29,7 @@ struct EXPORT_PCB_SVG_COMMAND : public EXPORT_PCB_BASE_COMMAND
{
EXPORT_PCB_SVG_COMMAND();
int Perform( KIWAY& aKiway ) const override;
int Perform( KIWAY& aKiway ) override;
};
} // namespace CLI

View File

@ -24,7 +24,7 @@ CLI::PCB_COMMAND::PCB_COMMAND() : COMMAND( "pcb" )
{
}
int CLI::PCB_COMMAND::Perform( KIWAY& aKiway ) const
int CLI::PCB_COMMAND::Perform( KIWAY& aKiway )
{
std::cout << m_argParser;

View File

@ -29,7 +29,7 @@ struct PCB_COMMAND : public COMMAND
{
PCB_COMMAND();
int Perform( KIWAY& aKiway ) const override;
int Perform( KIWAY& aKiway ) override;
};
}

View File

@ -25,7 +25,7 @@ CLI::EXPORT_PCB_COMMAND::EXPORT_PCB_COMMAND() : COMMAND( "export" )
}
int CLI::EXPORT_PCB_COMMAND::Perform( KIWAY& aKiway ) const
int CLI::EXPORT_PCB_COMMAND::Perform( KIWAY& aKiway )
{
std::cout << m_argParser;

View File

@ -29,7 +29,7 @@ struct EXPORT_PCB_COMMAND : public COMMAND
{
EXPORT_PCB_COMMAND();
int Perform( KIWAY& aKiway ) const override;
int Perform( KIWAY& aKiway ) override;
};
}

View File

@ -48,7 +48,10 @@
#include "cli/command_pcb.h"
#include "cli/command_pcb_export.h"
#include "cli/command_export_pcb_drill.h"
#include "cli/command_export_pcb_dxf.h"
#include "cli/command_export_pcb_gerber.h"
#include "cli/command_export_pcb_pdf.h"
#include "cli/command_export_pcb_svg.h"
#include "cli/command_export_pcb_step.h"
#include "cli/exit_codes.h"
@ -98,11 +101,14 @@ struct COMMAND_ENTRY
handler( aHandler ), subCommands( aSub ){};
};
static CLI::EXPORT_PCB_STEP_COMMAND stepCmd{};
static CLI::EXPORT_PCB_DXF_COMMAND dxfCmd{};
static CLI::EXPORT_PCB_SVG_COMMAND svgCmd{};
static CLI::EXPORT_PCB_COMMAND exportPcbCmd{};
static CLI::PCB_COMMAND pcbCmd{};
static CLI::EXPORT_PCB_DRILL_COMMAND exportPcbDrillCmd{};
static CLI::EXPORT_PCB_DXF_COMMAND exportPcbDxfCmd{};
static CLI::EXPORT_PCB_STEP_COMMAND exportPcbStepCmd{};
static CLI::EXPORT_PCB_SVG_COMMAND exportPcbSvgCmd{};
static CLI::EXPORT_PCB_PDF_COMMAND exportPcbPdfCmd{};
static CLI::EXPORT_PCB_GERBER_COMMAND exportPcbGerberCmd{};
static CLI::EXPORT_PCB_COMMAND exportPcbCmd{};
static CLI::PCB_COMMAND pcbCmd{};
static std::vector<COMMAND_ENTRY> commandStack = {
{
@ -110,9 +116,12 @@ static std::vector<COMMAND_ENTRY> commandStack = {
{
{ &exportPcbCmd,
{
&stepCmd,
&svgCmd,
&dxfCmd
&exportPcbDrillCmd,
&exportPcbDxfCmd,
&exportPcbGerberCmd,
&exportPcbPdfCmd,
&exportPcbStepCmd,
&exportPcbSvgCmd
}
}
}

View File

@ -264,6 +264,11 @@ public:
*/
bool GenDrillReportFile( const wxString& aFullFileName );
/**
* Returns the file extension of the drill writer format
*/
wxString GetDrillFileExt() const { return m_drillFileExtension; }
protected:
/**
* Plot a map of drill marks for holes.

View File

@ -20,18 +20,24 @@
#include "pcbnew_jobs_handler.h"
#include <kicad2step.h>
#include <jobs/job_export_pcb_gerber.h>
#include <jobs/job_export_pcb_drill.h>
#include <jobs/job_export_pcb_dxf.h>
#include <jobs/job_export_pcb_pdf.h>
#include <jobs/job_export_pcb_svg.h>
#include <jobs/job_export_pcb_step.h>
#include <cli/exit_codes.h>
#include <plotters/plotters_pslike.h>
#include <plotters/plotter_dxf.h>
#include <plotters/plotter_gerber.h>
#include <plotters/plotters_pslike.h>
#include <pgm_base.h>
#include <pcbplot.h>
#include <board_design_settings.h>
#include <pcbnew_settings.h>
#include <wx/crt.h>
#include <pcb_plot_svg.h>
#include <gendrill_Excellon_writer.h>
#include <gendrill_gerber_writer.h>
#include "pcbnew_scripting_helpers.h"
@ -41,6 +47,10 @@ PCBNEW_JOBS_HANDLER::PCBNEW_JOBS_HANDLER()
std::bind( &PCBNEW_JOBS_HANDLER::JobExportStep, this, std::placeholders::_1 ) );
Register( "svg", std::bind( &PCBNEW_JOBS_HANDLER::JobExportSvg, this, std::placeholders::_1 ) );
Register( "dxf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDxf, this, std::placeholders::_1 ) );
Register( "pdf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPdf, this, std::placeholders::_1 ) );
Register( "gerber",
std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerber, this, std::placeholders::_1 ) );
Register( "drill", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrill, this, std::placeholders::_1 ) );
}
@ -119,7 +129,7 @@ int PCBNEW_JOBS_HANDLER::JobExportDxf( JOB* aJob )
{
wxFileName fn = brd->GetFileName();
fn.SetName( fn.GetName() );
fn.SetExt( wxS( "dxf" ) );
fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::DXF ) );
aDxfJob->m_outputFile = fn.GetFullName();
}
@ -138,14 +148,12 @@ int PCBNEW_JOBS_HANDLER::JobExportDxf( JOB* aJob )
{
plotOpts.SetDXFPlotUnits( DXF_UNITS::INCHES );
}
plotOpts.SetPlotFrameRef( aDxfJob->m_plotBorderTitleBlocks );
plotOpts.SetPlotValue( aDxfJob->m_plotFootprintValues );
plotOpts.SetPlotReference( aDxfJob->m_plotRefDes );
plotOpts.SetLayerSelection( aDxfJob->m_printMaskLayer );
//@todo allow controlling the sheet name and path that will be displayed in the title block
// Leave blank for now
DXF_PLOTTER* plotter = (DXF_PLOTTER*) StartPlotBoard(
brd, &plotOpts, UNDEFINED_LAYER, aDxfJob->m_outputFile, wxEmptyString, wxEmptyString );
@ -157,5 +165,206 @@ int PCBNEW_JOBS_HANDLER::JobExportDxf( JOB* aJob )
delete plotter;
return CLI::EXIT_CODES::OK;
}
int PCBNEW_JOBS_HANDLER::JobExportPdf( JOB* aJob )
{
JOB_EXPORT_PCB_PDF* aPdfJob = dynamic_cast<JOB_EXPORT_PCB_PDF*>( aJob );
if( aPdfJob == nullptr )
return CLI::EXIT_CODES::ERR_UNKNOWN;
if( aJob->IsCli() )
wxPrintf( _( "Loading board\n" ) );
BOARD* brd = LoadBoard( aPdfJob->m_filename );
if( aPdfJob->m_outputFile.IsEmpty() )
{
wxFileName fn = brd->GetFileName();
fn.SetName( fn.GetName() );
fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::PDF ) );
aPdfJob->m_outputFile = fn.GetFullName();
}
PCB_PLOT_PARAMS plotOpts;
plotOpts.SetFormat( PLOT_FORMAT::PDF );
plotOpts.SetPlotFrameRef( aPdfJob->m_plotBorderTitleBlocks );
plotOpts.SetPlotValue( aPdfJob->m_plotFootprintValues );
plotOpts.SetPlotReference( aPdfJob->m_plotRefDes );
plotOpts.SetLayerSelection( aPdfJob->m_printMaskLayer );
PDF_PLOTTER* plotter = (PDF_PLOTTER*) StartPlotBoard(
brd, &plotOpts, UNDEFINED_LAYER, aPdfJob->m_outputFile, wxEmptyString, wxEmptyString );
if( plotter )
{
PlotBoardLayers( brd, plotter, aPdfJob->m_printMaskLayer.SeqStackupBottom2Top(), plotOpts );
PlotInteractiveLayer( brd, plotter );
plotter->EndPlot();
}
delete plotter;
return CLI::EXIT_CODES::OK;
}
int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob )
{
JOB_EXPORT_PCB_GERBER* aGerberJob = dynamic_cast<JOB_EXPORT_PCB_GERBER*>( aJob );
if( aGerberJob == nullptr )
return CLI::EXIT_CODES::ERR_UNKNOWN;
if( aJob->IsCli() )
wxPrintf( _( "Loading board\n" ) );
BOARD* brd = LoadBoard( aGerberJob->m_filename );
if( aGerberJob->m_outputFile.IsEmpty() )
{
wxFileName fn = brd->GetFileName();
fn.SetName( fn.GetName() );
fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::GERBER ) );
aGerberJob->m_outputFile = fn.GetFullName();
}
PCB_PLOT_PARAMS plotOpts;
plotOpts.SetFormat( PLOT_FORMAT::GERBER );
plotOpts.SetPlotFrameRef( aGerberJob->m_plotBorderTitleBlocks );
plotOpts.SetPlotValue( aGerberJob->m_plotFootprintValues );
plotOpts.SetPlotReference( aGerberJob->m_plotRefDes );
plotOpts.SetLayerSelection( aGerberJob->m_printMaskLayer );
plotOpts.SetSubtractMaskFromSilk( aGerberJob->m_subtractSolderMaskFromSilk );
plotOpts.SetDisableGerberMacros( aGerberJob->m_disableApertureMacros );
plotOpts.SetUseGerberX2format( aGerberJob->m_useX2Format );
plotOpts.SetIncludeGerberNetlistInfo( aGerberJob->m_includeNetlistAttributes );
plotOpts.SetGerberPrecision( aGerberJob->m_precision );
// We are feeding it one layer at the start here to silence a logic check
GERBER_PLOTTER* plotter = (GERBER_PLOTTER*) StartPlotBoard(
brd, &plotOpts, aGerberJob->m_printMaskLayer.Seq().front(), aGerberJob->m_outputFile,
wxEmptyString, wxEmptyString );
if( plotter )
{
PlotBoardLayers( brd, plotter, aGerberJob->m_printMaskLayer.SeqStackupBottom2Top(),
plotOpts );
plotter->EndPlot();
}
delete plotter;
return CLI::EXIT_CODES::OK;
}
static DRILL_PRECISION precisionListForInches( 2, 4 );
static DRILL_PRECISION precisionListForMetric( 3, 3 );
int PCBNEW_JOBS_HANDLER::JobExportDrill( JOB* aJob )
{
JOB_EXPORT_PCB_DRILL* aDrillJob = dynamic_cast<JOB_EXPORT_PCB_DRILL*>( aJob );
if( aDrillJob == nullptr )
return CLI::EXIT_CODES::ERR_UNKNOWN;
if( aJob->IsCli() )
wxPrintf( _( "Loading board\n" ) );
BOARD* brd = LoadBoard( aDrillJob->m_filename );
std::unique_ptr<GENDRILL_WRITER_BASE> drillWriter;
if( aDrillJob->m_format == JOB_EXPORT_PCB_DRILL::DRILL_FORMAT::EXCELLON )
{
drillWriter = std::make_unique<EXCELLON_WRITER>( brd );
}
else
{
drillWriter = std::make_unique<GERBER_WRITER>( brd );
}
VECTOR2I offset;
if( aDrillJob->m_drillOrigin == JOB_EXPORT_PCB_DRILL::DRILL_ORIGIN::ABSOLUTE )
offset = VECTOR2I( 0, 0 );
else
offset = brd->GetDesignSettings().GetAuxOrigin();
PLOT_FORMAT mapFormat = PLOT_FORMAT::PDF;
switch( aDrillJob->m_mapFormat )
{
case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::POSTSCRIPT: mapFormat = PLOT_FORMAT::POST; break;
case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::GERBER_X2: mapFormat = PLOT_FORMAT::GERBER; break;
case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::DXF: mapFormat = PLOT_FORMAT::DXF; break;
case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::SVG: mapFormat = PLOT_FORMAT::SVG; break;
default:
case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::PDF: mapFormat = PLOT_FORMAT::PDF; break;
}
if( aDrillJob->m_format == JOB_EXPORT_PCB_DRILL::DRILL_FORMAT::EXCELLON )
{
EXCELLON_WRITER::ZEROS_FMT zeroFmt;
switch( aDrillJob->m_zeroFormat )
{
case JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT::KEEP_ZEROS:
zeroFmt = EXCELLON_WRITER::KEEP_ZEROS;
break;
case JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT::SUPRESS_LEADING:
zeroFmt = EXCELLON_WRITER::SUPPRESS_LEADING;
break;
case JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT::SUPRESS_TRAILING:
zeroFmt = EXCELLON_WRITER::SUPPRESS_TRAILING;
break;
case JOB_EXPORT_PCB_DRILL::ZEROS_FORMAT::DECIMAL:
default:
zeroFmt = EXCELLON_WRITER::DECIMAL_FORMAT;
break;
}
DRILL_PRECISION precision;
if( aDrillJob->m_drillUnits == JOB_EXPORT_PCB_DRILL::DRILL_UNITS::INCHES )
precision = precisionListForInches;
else
precision = precisionListForMetric;
EXCELLON_WRITER* excellonWriter = dynamic_cast<EXCELLON_WRITER*>( drillWriter.get() );
excellonWriter->SetFormat( aDrillJob->m_drillUnits
== JOB_EXPORT_PCB_DRILL::DRILL_UNITS::MILLIMETERS,
zeroFmt, precision.m_Lhs, precision.m_Rhs );
excellonWriter->SetOptions( aDrillJob->m_excellonMirrorY, aDrillJob->m_excellonMinimalHeader,
offset, aDrillJob->m_excellonCombinePTHNPTH );
excellonWriter->SetRouteModeForOvalHoles( aDrillJob->m_excellonOvalDrillRoute );
excellonWriter->SetMapFileFormat( mapFormat );
excellonWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true,
aDrillJob->m_generateMap, nullptr );
}
else if( aDrillJob->m_format == JOB_EXPORT_PCB_DRILL::DRILL_FORMAT::GERBER )
{
GERBER_WRITER* gerberWriter = dynamic_cast<GERBER_WRITER*>( drillWriter.get() );
// Set gerber precision: only 5 or 6 digits for mantissa are allowed
// (SetFormat() accept 5 or 6, and any other value set the precision to 5)
// the integer part precision is always 4, and units always mm
gerberWriter->SetFormat( aDrillJob->m_gerberPrecision );
gerberWriter->SetOptions( offset );
gerberWriter->SetMapFileFormat( mapFormat );
gerberWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true,
aDrillJob->m_generateMap, nullptr );
}
return CLI::EXIT_CODES::OK;
}

View File

@ -30,6 +30,9 @@ public:
int JobExportStep( JOB* aJob );
int JobExportSvg( JOB* aJob );
int JobExportDxf( JOB* aJob );
int JobExportPdf( JOB* aJob );
int JobExportGerber( JOB* aJob );
int JobExportDrill( JOB* aJob );
};
#endif