Add a bulk gerber export that's a wee bit smarter
This commit is contained in:
parent
e890986e01
commit
7e53663d5d
|
@ -28,8 +28,8 @@
|
||||||
class JOB_EXPORT_PCB_GERBER : public JOB
|
class JOB_EXPORT_PCB_GERBER : public JOB
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
JOB_EXPORT_PCB_GERBER( bool aIsCli ) :
|
JOB_EXPORT_PCB_GERBER( const std::string& aType, bool aIsCli ) :
|
||||||
JOB( "gerber", aIsCli ),
|
JOB( aType, aIsCli ),
|
||||||
m_filename(),
|
m_filename(),
|
||||||
m_outputFile(),
|
m_outputFile(),
|
||||||
m_plotFootprintValues( true ),
|
m_plotFootprintValues( true ),
|
||||||
|
@ -44,6 +44,11 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JOB_EXPORT_PCB_GERBER( bool aIsCli ) :
|
||||||
|
JOB_EXPORT_PCB_GERBER( "gerber", aIsCli )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
wxString m_filename;
|
wxString m_filename;
|
||||||
wxString m_outputFile;
|
wxString m_outputFile;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* 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_GERBERS_H
|
||||||
|
#define JOB_EXPORT_PCB_GERBERS_H
|
||||||
|
|
||||||
|
#include "job_export_pcb_gerber.h"
|
||||||
|
#include <layer_ids.h>
|
||||||
|
#include <wx/string.h>
|
||||||
|
#include "job.h"
|
||||||
|
|
||||||
|
class JOB_EXPORT_PCB_GERBERS : public JOB_EXPORT_PCB_GERBER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
JOB_EXPORT_PCB_GERBERS( bool aIsCli ) :
|
||||||
|
JOB_EXPORT_PCB_GERBER( "gerbers", aIsCli ),
|
||||||
|
m_layersIncludeOnAll(),
|
||||||
|
m_layersIncludeOnAllSet( false ),
|
||||||
|
m_useBoardPlotParams( false )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LSET m_layersIncludeOnAll;
|
||||||
|
|
||||||
|
bool m_layersIncludeOnAllSet;
|
||||||
|
bool m_useBoardPlotParams;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -21,6 +21,7 @@ set( KICAD_SRCS
|
||||||
cli/command_export_pcb_drill.cpp
|
cli/command_export_pcb_drill.cpp
|
||||||
cli/command_export_pcb_dxf.cpp
|
cli/command_export_pcb_dxf.cpp
|
||||||
cli/command_export_pcb_gerber.cpp
|
cli/command_export_pcb_gerber.cpp
|
||||||
|
cli/command_export_pcb_gerbers.cpp
|
||||||
cli/command_export_pcb_pdf.cpp
|
cli/command_export_pcb_pdf.cpp
|
||||||
cli/command_export_pcb_pos.cpp
|
cli/command_export_pcb_pos.cpp
|
||||||
cli/command_export_pcb_step.cpp
|
cli/command_export_pcb_step.cpp
|
||||||
|
|
|
@ -32,10 +32,10 @@ namespace CLI
|
||||||
class COMMAND
|
class COMMAND
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
COMMAND( std::string aName,
|
COMMAND( const std::string& aName,
|
||||||
argparse::default_arguments aDefaultArgs = argparse::default_arguments::help ) :
|
argparse::default_arguments aDefaultArgs = argparse::default_arguments::help ) :
|
||||||
m_name( aName ),
|
m_name( aName ),
|
||||||
m_argParser( aName, "", aDefaultArgs ){};
|
m_argParser( aName, "", aDefaultArgs ){};
|
||||||
|
|
||||||
virtual int Perform( KIWAY& aKiway );
|
virtual int Perform( KIWAY& aKiway );
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,12 @@
|
||||||
#include <wx/tokenzr.h>
|
#include <wx/tokenzr.h>
|
||||||
#include <wx/crt.h>
|
#include <wx/crt.h>
|
||||||
|
|
||||||
CLI::EXPORT_PCB_BASE_COMMAND::EXPORT_PCB_BASE_COMMAND( std::string aName ) : COMMAND( aName )
|
CLI::EXPORT_PCB_BASE_COMMAND::EXPORT_PCB_BASE_COMMAND( const std::string& aName ) : COMMAND( aName )
|
||||||
{
|
{
|
||||||
|
m_selectedLayersSet = false;
|
||||||
|
m_requireLayers = false;
|
||||||
|
m_hasLayerArg = false;
|
||||||
|
|
||||||
m_argParser.add_argument( "-o", ARG_OUTPUT )
|
m_argParser.add_argument( "-o", ARG_OUTPUT )
|
||||||
.default_value( std::string() )
|
.default_value( std::string() )
|
||||||
.help( UTF8STDSTR( _( "Output file name" ) ) );
|
.help( UTF8STDSTR( _( "Output file name" ) ) );
|
||||||
|
@ -57,7 +61,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 CLI::EXPORT_PCB_BASE_COMMAND::convertLayerStringList( wxString& aLayerString, bool& aLayerArgSet ) const
|
||||||
{
|
{
|
||||||
LSET layerMask;
|
LSET layerMask;
|
||||||
|
|
||||||
|
@ -71,6 +75,7 @@ LSET CLI::EXPORT_PCB_BASE_COMMAND::convertLayerStringList( wxString& aLayerStrin
|
||||||
if( m_layerMasks.count( token ) )
|
if( m_layerMasks.count( token ) )
|
||||||
{
|
{
|
||||||
layerMask |= m_layerMasks.at(token);
|
layerMask |= m_layerMasks.at(token);
|
||||||
|
aLayerArgSet = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -91,18 +96,19 @@ void CLI::EXPORT_PCB_BASE_COMMAND::addLayerArg( bool aRequire )
|
||||||
_( "Comma separated list of untranslated layer names to include such as "
|
_( "Comma separated list of untranslated layer names to include such as "
|
||||||
"F.Cu,B.Cu" ) ) );
|
"F.Cu,B.Cu" ) ) );
|
||||||
|
|
||||||
|
m_hasLayerArg = true;
|
||||||
m_requireLayers = aRequire;
|
m_requireLayers = aRequire;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CLI::EXPORT_PCB_BASE_COMMAND::Perform( KIWAY& aKiway )
|
int CLI::EXPORT_PCB_BASE_COMMAND::Perform( KIWAY& aKiway )
|
||||||
{
|
{
|
||||||
if( m_requireLayers )
|
if( m_hasLayerArg )
|
||||||
{
|
{
|
||||||
wxString layers = FROM_UTF8( m_argParser.get<std::string>( ARG_LAYERS ).c_str() );
|
wxString layers = FROM_UTF8( m_argParser.get<std::string>( ARG_LAYERS ).c_str() );
|
||||||
|
|
||||||
LSET layerMask = convertLayerStringList( layers );
|
LSET layerMask = convertLayerStringList( layers, m_selectedLayersSet );
|
||||||
if( layerMask.Seq().size() < 1 )
|
if( m_requireLayers && layerMask.Seq().size() < 1 )
|
||||||
{
|
{
|
||||||
wxFprintf( stderr, _( "At least one or more layers must be specified\n" ) );
|
wxFprintf( stderr, _( "At least one or more layers must be specified\n" ) );
|
||||||
return EXIT_CODES::ERR_ARGS;
|
return EXIT_CODES::ERR_ARGS;
|
||||||
|
|
|
@ -37,18 +37,20 @@ namespace CLI
|
||||||
|
|
||||||
struct EXPORT_PCB_BASE_COMMAND : public COMMAND
|
struct EXPORT_PCB_BASE_COMMAND : public COMMAND
|
||||||
{
|
{
|
||||||
EXPORT_PCB_BASE_COMMAND( std::string aName );
|
EXPORT_PCB_BASE_COMMAND( const std::string& aName );
|
||||||
|
|
||||||
int Perform( KIWAY& aKiway ) override;
|
int Perform( KIWAY& aKiway ) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LSET convertLayerStringList( wxString& aLayerString ) const;
|
LSET convertLayerStringList( wxString& aLayerString, bool& aLayerArgSet ) const;
|
||||||
void addLayerArg( bool aRequire );
|
void addLayerArg( bool aRequire );
|
||||||
|
|
||||||
std::map<std::string, LSET> m_layerMasks;
|
std::map<std::string, LSET> m_layerMasks;
|
||||||
LSET m_selectedLayers;
|
LSET m_selectedLayers;
|
||||||
|
bool m_selectedLayersSet;
|
||||||
|
|
||||||
bool m_requireLayers;
|
bool m_hasLayerArg;
|
||||||
|
bool m_requireLayers;
|
||||||
};
|
};
|
||||||
} // namespace CLI
|
} // namespace CLI
|
||||||
|
|
||||||
|
|
|
@ -30,13 +30,9 @@
|
||||||
|
|
||||||
#include <locale_io.h>
|
#include <locale_io.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" )
|
CLI::EXPORT_PCB_GERBER_COMMAND::EXPORT_PCB_GERBER_COMMAND( const std::string& aName ) :
|
||||||
|
EXPORT_PCB_BASE_COMMAND( aName )
|
||||||
{
|
{
|
||||||
addLayerArg( true );
|
addLayerArg( true );
|
||||||
|
|
||||||
|
@ -76,49 +72,62 @@ CLI::EXPORT_PCB_GERBER_COMMAND::EXPORT_PCB_GERBER_COMMAND() : EXPORT_PCB_BASE_CO
|
||||||
.default_value( false );
|
.default_value( false );
|
||||||
|
|
||||||
m_argParser.add_argument( ARG_PRECISION )
|
m_argParser.add_argument( ARG_PRECISION )
|
||||||
.help( UTF8STDSTR(
|
.help( UTF8STDSTR( _( "Precision of gerber coordinates, valid options: 5 or 6" ) ) )
|
||||||
_( "Precision of gerber coordinates, valid options: 5 or 6" ) ) )
|
|
||||||
.scan<'i', int>()
|
.scan<'i', int>()
|
||||||
.default_value( 6 );
|
.default_value( 6 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CLI::EXPORT_PCB_GERBER_COMMAND::Perform( KIWAY& aKiway )
|
CLI::EXPORT_PCB_GERBER_COMMAND::EXPORT_PCB_GERBER_COMMAND() : EXPORT_PCB_GERBER_COMMAND( "gerber" )
|
||||||
{
|
{
|
||||||
int baseExit = EXPORT_PCB_BASE_COMMAND::Perform( aKiway );
|
}
|
||||||
if( baseExit != EXIT_CODES::OK )
|
|
||||||
return baseExit;
|
|
||||||
|
|
||||||
std::unique_ptr<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() );
|
int CLI::EXPORT_PCB_GERBER_COMMAND::populateJob( JOB_EXPORT_PCB_GERBER* aJob )
|
||||||
gerberJob->m_outputFile = FROM_UTF8( m_argParser.get<std::string>( ARG_OUTPUT ).c_str() );
|
{
|
||||||
|
aJob->m_filename = FROM_UTF8( m_argParser.get<std::string>( ARG_INPUT ).c_str() );
|
||||||
|
aJob->m_outputFile = FROM_UTF8( m_argParser.get<std::string>( ARG_OUTPUT ).c_str() );
|
||||||
|
|
||||||
if( !wxFile::Exists( gerberJob->m_filename ) )
|
aJob->m_plotFootprintValues = m_argParser.get<bool>( ARG_INCLUDE_VALUE );
|
||||||
|
aJob->m_plotRefDes = m_argParser.get<bool>( ARG_INCLUDE_VALUE );
|
||||||
|
aJob->m_plotBorderTitleBlocks = m_argParser.get<bool>( ARG_INCLUDE_BORDER_TITLE );
|
||||||
|
aJob->m_disableApertureMacros = m_argParser.get<bool>( ARG_DISABLE_APERTURE_MACROS );
|
||||||
|
aJob->m_subtractSolderMaskFromSilk = m_argParser.get<bool>( ARG_SUBTRACT_SOLDERMASK );
|
||||||
|
aJob->m_includeNetlistAttributes = !m_argParser.get<bool>( ARG_NO_NETLIST );
|
||||||
|
aJob->m_useX2Format = !m_argParser.get<bool>( ARG_NO_X2 );
|
||||||
|
aJob->m_precision = m_argParser.get<int>( ARG_PRECISION );
|
||||||
|
aJob->m_printMaskLayer = m_selectedLayers;
|
||||||
|
|
||||||
|
if( !wxFile::Exists( aJob->m_filename ) )
|
||||||
{
|
{
|
||||||
wxFprintf( stderr, _( "Board file does not exist or is not accessible\n" ) );
|
wxFprintf( stderr, _( "Board file does not exist or is not accessible\n" ) );
|
||||||
return EXIT_CODES::ERR_INVALID_INPUT_FILE;
|
return EXIT_CODES::ERR_INVALID_INPUT_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gerberJob->m_plotFootprintValues = m_argParser.get<bool>( ARG_INCLUDE_VALUE );
|
if( aJob->m_precision != 5 && aJob->m_precision != 6 )
|
||||||
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" ) );
|
wxFprintf( stderr, _( "Gerber coordinate precision should be either 5 or 6\n" ) );
|
||||||
return EXIT_CODES::ERR_ARGS;
|
return EXIT_CODES::ERR_ARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
gerberJob->m_printMaskLayer = m_selectedLayers;
|
return EXIT_CODES::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int CLI::EXPORT_PCB_GERBER_COMMAND::Perform( KIWAY& aKiway )
|
||||||
|
{
|
||||||
|
int exitCode = EXPORT_PCB_BASE_COMMAND::Perform( aKiway );
|
||||||
|
if( exitCode != EXIT_CODES::OK )
|
||||||
|
return exitCode;
|
||||||
|
|
||||||
|
std::unique_ptr<JOB_EXPORT_PCB_GERBER> gerberJob( new JOB_EXPORT_PCB_GERBER( true ) );
|
||||||
|
|
||||||
|
exitCode = populateJob( gerberJob.get() );
|
||||||
|
if( exitCode != EXIT_CODES::OK )
|
||||||
|
return exitCode;
|
||||||
|
|
||||||
LOCALE_IO dummy;
|
LOCALE_IO dummy;
|
||||||
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, gerberJob.get() );
|
exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, gerberJob.get() );
|
||||||
|
|
||||||
return exitCode;
|
return exitCode;
|
||||||
}
|
}
|
|
@ -23,14 +23,26 @@
|
||||||
|
|
||||||
#include "command_export_pcb_base.h"
|
#include "command_export_pcb_base.h"
|
||||||
|
|
||||||
|
class JOB_EXPORT_PCB_GERBER;
|
||||||
|
|
||||||
namespace CLI
|
namespace CLI
|
||||||
{
|
{
|
||||||
|
#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"
|
||||||
|
|
||||||
class EXPORT_PCB_GERBER_COMMAND : public EXPORT_PCB_BASE_COMMAND
|
class EXPORT_PCB_GERBER_COMMAND : public EXPORT_PCB_BASE_COMMAND
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
EXPORT_PCB_GERBER_COMMAND( const std::string& aName );
|
||||||
EXPORT_PCB_GERBER_COMMAND();
|
EXPORT_PCB_GERBER_COMMAND();
|
||||||
|
|
||||||
int Perform( KIWAY& aKiway ) override;
|
int Perform( KIWAY& aKiway ) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int populateJob( JOB_EXPORT_PCB_GERBER* aJob );
|
||||||
};
|
};
|
||||||
} // namespace CLI
|
} // namespace CLI
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* 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_gerbers.h"
|
||||||
|
#include <cli/exit_codes.h>
|
||||||
|
#include "jobs/job_export_pcb_gerbers.h"
|
||||||
|
#include <kiface_base.h>
|
||||||
|
#include <layer_ids.h>
|
||||||
|
#include <wx/crt.h>
|
||||||
|
|
||||||
|
#include <macros.h>
|
||||||
|
#include <wx/tokenzr.h>
|
||||||
|
|
||||||
|
#include <locale_io.h>
|
||||||
|
|
||||||
|
#define ARG_COMMON_LAYERS "--common-layers"
|
||||||
|
#define ARG_USE_BOARD_PLOT_PARAMS "--board-plot-params"
|
||||||
|
|
||||||
|
CLI::EXPORT_PCB_GERBERS_COMMAND::EXPORT_PCB_GERBERS_COMMAND() :
|
||||||
|
EXPORT_PCB_GERBER_COMMAND( "gerbers" )
|
||||||
|
{
|
||||||
|
m_requireLayers = false;
|
||||||
|
|
||||||
|
m_argParser.add_argument( "-cl", ARG_COMMON_LAYERS )
|
||||||
|
.default_value( std::string() )
|
||||||
|
.help( UTF8STDSTR(
|
||||||
|
_( "Layers to include on each plot, comma separated list of untranslated layer names to include such as "
|
||||||
|
"F.Cu,B.Cu" ) ) );
|
||||||
|
|
||||||
|
m_argParser.add_argument( ARG_USE_BOARD_PLOT_PARAMS )
|
||||||
|
.help( UTF8STDSTR( _( "Use the gerber plot settings already configured in the board file" ) ) )
|
||||||
|
.implicit_value( true )
|
||||||
|
.default_value( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int CLI::EXPORT_PCB_GERBERS_COMMAND::Perform( KIWAY& aKiway )
|
||||||
|
{
|
||||||
|
int exitCode = EXPORT_PCB_BASE_COMMAND::Perform( aKiway );
|
||||||
|
if( exitCode != EXIT_CODES::OK )
|
||||||
|
return exitCode;
|
||||||
|
|
||||||
|
std::unique_ptr<JOB_EXPORT_PCB_GERBERS> gerberJob( new JOB_EXPORT_PCB_GERBERS( true ) );
|
||||||
|
|
||||||
|
exitCode = populateJob( gerberJob.get() );
|
||||||
|
if( exitCode != EXIT_CODES::OK )
|
||||||
|
return exitCode;
|
||||||
|
|
||||||
|
wxString layers = FROM_UTF8( m_argParser.get<std::string>( ARG_COMMON_LAYERS ).c_str() );
|
||||||
|
gerberJob->m_layersIncludeOnAll =
|
||||||
|
convertLayerStringList( layers, gerberJob->m_layersIncludeOnAllSet );
|
||||||
|
|
||||||
|
LOCALE_IO dummy;
|
||||||
|
exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, gerberJob.get() );
|
||||||
|
|
||||||
|
return exitCode;
|
||||||
|
}
|
|
@ -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_GERBERS_H
|
||||||
|
#define COMMAND_EXPORT_PCB_GERBERS_H
|
||||||
|
|
||||||
|
#include "command_export_pcb_gerber.h"
|
||||||
|
|
||||||
|
namespace CLI
|
||||||
|
{
|
||||||
|
class EXPORT_PCB_GERBERS_COMMAND : public EXPORT_PCB_GERBER_COMMAND
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EXPORT_PCB_GERBERS_COMMAND();
|
||||||
|
|
||||||
|
int Perform( KIWAY& aKiway ) override;
|
||||||
|
};
|
||||||
|
} // namespace CLI
|
||||||
|
|
||||||
|
#endif
|
|
@ -52,6 +52,7 @@
|
||||||
#include "cli/command_export_pcb_drill.h"
|
#include "cli/command_export_pcb_drill.h"
|
||||||
#include "cli/command_export_pcb_dxf.h"
|
#include "cli/command_export_pcb_dxf.h"
|
||||||
#include "cli/command_export_pcb_gerber.h"
|
#include "cli/command_export_pcb_gerber.h"
|
||||||
|
#include "cli/command_export_pcb_gerbers.h"
|
||||||
#include "cli/command_export_pcb_pdf.h"
|
#include "cli/command_export_pcb_pdf.h"
|
||||||
#include "cli/command_export_pcb_pos.h"
|
#include "cli/command_export_pcb_pos.h"
|
||||||
#include "cli/command_export_pcb_svg.h"
|
#include "cli/command_export_pcb_svg.h"
|
||||||
|
@ -121,6 +122,7 @@ static CLI::EXPORT_PCB_SVG_COMMAND exportPcbSvgCmd{};
|
||||||
static CLI::EXPORT_PCB_PDF_COMMAND exportPcbPdfCmd{};
|
static CLI::EXPORT_PCB_PDF_COMMAND exportPcbPdfCmd{};
|
||||||
static CLI::EXPORT_PCB_POS_COMMAND exportPcbPosCmd{};
|
static CLI::EXPORT_PCB_POS_COMMAND exportPcbPosCmd{};
|
||||||
static CLI::EXPORT_PCB_GERBER_COMMAND exportPcbGerberCmd{};
|
static CLI::EXPORT_PCB_GERBER_COMMAND exportPcbGerberCmd{};
|
||||||
|
static CLI::EXPORT_PCB_GERBERS_COMMAND exportPcbGerbersCmd{};
|
||||||
static CLI::EXPORT_PCB_COMMAND exportPcbCmd{};
|
static CLI::EXPORT_PCB_COMMAND exportPcbCmd{};
|
||||||
static CLI::PCB_COMMAND pcbCmd{};
|
static CLI::PCB_COMMAND pcbCmd{};
|
||||||
static CLI::EXPORT_SCH_COMMAND exportSchCmd{};
|
static CLI::EXPORT_SCH_COMMAND exportSchCmd{};
|
||||||
|
@ -151,6 +153,7 @@ static std::vector<COMMAND_ENTRY> commandStack = {
|
||||||
&exportPcbDrillCmd,
|
&exportPcbDrillCmd,
|
||||||
&exportPcbDxfCmd,
|
&exportPcbDxfCmd,
|
||||||
&exportPcbGerberCmd,
|
&exportPcbGerberCmd,
|
||||||
|
&exportPcbGerbersCmd,
|
||||||
&exportPcbPdfCmd,
|
&exportPcbPdfCmd,
|
||||||
&exportPcbPosCmd,
|
&exportPcbPosCmd,
|
||||||
&exportPcbStepCmd,
|
&exportPcbStepCmd,
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "pcbnew_jobs_handler.h"
|
#include "pcbnew_jobs_handler.h"
|
||||||
#include <jobs/job_fp_upgrade.h>
|
#include <jobs/job_fp_upgrade.h>
|
||||||
#include <jobs/job_export_pcb_gerber.h>
|
#include <jobs/job_export_pcb_gerber.h>
|
||||||
|
#include <jobs/job_export_pcb_gerbers.h>
|
||||||
#include <jobs/job_export_pcb_drill.h>
|
#include <jobs/job_export_pcb_drill.h>
|
||||||
#include <jobs/job_export_pcb_dxf.h>
|
#include <jobs/job_export_pcb_dxf.h>
|
||||||
#include <jobs/job_export_pcb_pdf.h>
|
#include <jobs/job_export_pcb_pdf.h>
|
||||||
|
@ -57,6 +58,8 @@ PCBNEW_JOBS_HANDLER::PCBNEW_JOBS_HANDLER()
|
||||||
Register( "pdf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPdf, this, std::placeholders::_1 ) );
|
Register( "pdf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPdf, this, std::placeholders::_1 ) );
|
||||||
Register( "gerber",
|
Register( "gerber",
|
||||||
std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerber, this, std::placeholders::_1 ) );
|
std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerber, this, std::placeholders::_1 ) );
|
||||||
|
Register( "gerbers",
|
||||||
|
std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerbers, this, std::placeholders::_1 ) );
|
||||||
Register( "drill",
|
Register( "drill",
|
||||||
std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrill, this, std::placeholders::_1 ) );
|
std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrill, this, std::placeholders::_1 ) );
|
||||||
Register( "pos", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPos, this, std::placeholders::_1 ) );
|
Register( "pos", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPos, this, std::placeholders::_1 ) );
|
||||||
|
@ -241,6 +244,108 @@ int PCBNEW_JOBS_HANDLER::JobExportPdf( JOB* aJob )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PCBNEW_JOBS_HANDLER::JobExportGerbers( JOB* aJob )
|
||||||
|
{
|
||||||
|
JOB_EXPORT_PCB_GERBERS* aGerberJob = dynamic_cast<JOB_EXPORT_PCB_GERBERS*>( aJob );
|
||||||
|
|
||||||
|
if( aGerberJob == nullptr )
|
||||||
|
return CLI::EXIT_CODES::ERR_UNKNOWN;
|
||||||
|
|
||||||
|
if( aJob->IsCli() )
|
||||||
|
wxPrintf( _( "Loading board\n" ) );
|
||||||
|
|
||||||
|
BOARD* brd = LoadBoard( aGerberJob->m_filename );
|
||||||
|
PCB_PLOT_PARAMS boardPlotOptions = brd->GetPlotOptions();
|
||||||
|
LSET plotOnAllLayersSelection = boardPlotOptions.GetPlotOnAllLayersSelection();
|
||||||
|
|
||||||
|
wxString fileExt;
|
||||||
|
|
||||||
|
if( aGerberJob->m_useBoardPlotParams )
|
||||||
|
{
|
||||||
|
aGerberJob->m_printMaskLayer = boardPlotOptions.GetLayerSelection();
|
||||||
|
aGerberJob->m_layersIncludeOnAll = boardPlotOptions.GetPlotOnAllLayersSelection();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// default to the board enabled layers
|
||||||
|
if( aGerberJob->m_printMaskLayer == 0 )
|
||||||
|
aGerberJob->m_printMaskLayer = brd->GetEnabledLayers();
|
||||||
|
|
||||||
|
if( aGerberJob->m_layersIncludeOnAllSet )
|
||||||
|
aGerberJob->m_layersIncludeOnAll = plotOnAllLayersSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( LSEQ seq = aGerberJob->m_printMaskLayer.UIOrder(); seq; ++seq )
|
||||||
|
{
|
||||||
|
LSEQ plotSequence;
|
||||||
|
|
||||||
|
// Base layer always gets plotted first.
|
||||||
|
plotSequence.push_back( *seq );
|
||||||
|
|
||||||
|
// Now all the "include on all" layers
|
||||||
|
for( LSEQ seqAll = aGerberJob->m_layersIncludeOnAll.UIOrder(); seqAll; ++seqAll )
|
||||||
|
{
|
||||||
|
// Don't plot the same layer more than once;
|
||||||
|
if( find( plotSequence.begin(), plotSequence.end(), *seqAll ) != plotSequence.end() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
plotSequence.push_back( *seqAll );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pick the basename from the board file
|
||||||
|
wxFileName fn( brd->GetFileName() );
|
||||||
|
PCB_LAYER_ID layer = *seq;
|
||||||
|
fileExt = GetGerberProtelExtension( layer );
|
||||||
|
|
||||||
|
PCB_PLOT_PARAMS plotOpts;
|
||||||
|
|
||||||
|
if( aGerberJob->m_useBoardPlotParams )
|
||||||
|
plotOpts = boardPlotOptions;
|
||||||
|
else
|
||||||
|
populateGerberPlotOptionsFromJob( plotOpts, aGerberJob );
|
||||||
|
|
||||||
|
BuildPlotFileName( &fn, aGerberJob->m_outputFile, brd->GetLayerName( layer ), fileExt );
|
||||||
|
wxString fullname = fn.GetFullName();
|
||||||
|
|
||||||
|
// We are feeding it one layer at the start here to silence a logic check
|
||||||
|
GERBER_PLOTTER* plotter = (GERBER_PLOTTER*) StartPlotBoard(
|
||||||
|
brd, &plotOpts, layer, fullname, wxEmptyString, wxEmptyString );
|
||||||
|
|
||||||
|
if( plotter )
|
||||||
|
{
|
||||||
|
wxPrintf( _( "Plotted to '%s'.\n" ), fn.GetFullPath() );
|
||||||
|
PlotBoardLayers( brd, plotter, plotSequence, plotOpts );
|
||||||
|
plotter->EndPlot();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete plotter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CLI::EXIT_CODES::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PCBNEW_JOBS_HANDLER::populateGerberPlotOptionsFromJob( PCB_PLOT_PARAMS& aPlotOpts,
|
||||||
|
JOB_EXPORT_PCB_GERBER* aJob )
|
||||||
|
{
|
||||||
|
aPlotOpts.SetFormat( PLOT_FORMAT::GERBER );
|
||||||
|
|
||||||
|
aPlotOpts.SetPlotFrameRef( aJob->m_plotBorderTitleBlocks );
|
||||||
|
aPlotOpts.SetPlotValue( aJob->m_plotFootprintValues );
|
||||||
|
aPlotOpts.SetPlotReference( aJob->m_plotRefDes );
|
||||||
|
|
||||||
|
aPlotOpts.SetSubtractMaskFromSilk( aJob->m_subtractSolderMaskFromSilk );
|
||||||
|
// Always disable plot pad holes
|
||||||
|
aPlotOpts.SetDrillMarksType( DRILL_MARKS::NO_DRILL_SHAPE );
|
||||||
|
|
||||||
|
aPlotOpts.SetDisableGerberMacros( aJob->m_disableApertureMacros );
|
||||||
|
aPlotOpts.SetUseGerberX2format( aJob->m_useX2Format );
|
||||||
|
aPlotOpts.SetIncludeGerberNetlistInfo( aJob->m_includeNetlistAttributes );
|
||||||
|
|
||||||
|
aPlotOpts.SetGerberPrecision( aJob->m_precision );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob )
|
int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob )
|
||||||
{
|
{
|
||||||
JOB_EXPORT_PCB_GERBER* aGerberJob = dynamic_cast<JOB_EXPORT_PCB_GERBER*>( aJob );
|
JOB_EXPORT_PCB_GERBER* aGerberJob = dynamic_cast<JOB_EXPORT_PCB_GERBER*>( aJob );
|
||||||
|
@ -263,24 +368,9 @@ int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob )
|
||||||
}
|
}
|
||||||
|
|
||||||
PCB_PLOT_PARAMS plotOpts;
|
PCB_PLOT_PARAMS plotOpts;
|
||||||
plotOpts.SetFormat( PLOT_FORMAT::GERBER );
|
populateGerberPlotOptionsFromJob( plotOpts, aGerberJob );
|
||||||
|
|
||||||
plotOpts.SetPlotFrameRef( aGerberJob->m_plotBorderTitleBlocks );
|
|
||||||
plotOpts.SetPlotValue( aGerberJob->m_plotFootprintValues );
|
|
||||||
plotOpts.SetPlotReference( aGerberJob->m_plotRefDes );
|
|
||||||
|
|
||||||
plotOpts.SetLayerSelection( aGerberJob->m_printMaskLayer );
|
plotOpts.SetLayerSelection( aGerberJob->m_printMaskLayer );
|
||||||
|
|
||||||
plotOpts.SetSubtractMaskFromSilk( aGerberJob->m_subtractSolderMaskFromSilk );
|
|
||||||
// Always disable plot pad holes
|
|
||||||
plotOpts.SetDrillMarksType( DRILL_MARKS::NO_DRILL_SHAPE );
|
|
||||||
|
|
||||||
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
|
// We are feeding it one layer at the start here to silence a logic check
|
||||||
GERBER_PLOTTER* plotter = (GERBER_PLOTTER*) StartPlotBoard(
|
GERBER_PLOTTER* plotter = (GERBER_PLOTTER*) StartPlotBoard(
|
||||||
brd, &plotOpts, aGerberJob->m_printMaskLayer.Seq().front(), aGerberJob->m_outputFile,
|
brd, &plotOpts, aGerberJob->m_printMaskLayer.Seq().front(), aGerberJob->m_outputFile,
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
#define PCBNEW_JOBS_HANDLER_H
|
#define PCBNEW_JOBS_HANDLER_H
|
||||||
|
|
||||||
#include <jobs/job_dispatcher.h>
|
#include <jobs/job_dispatcher.h>
|
||||||
|
#include <pcb_plot_params.h>
|
||||||
|
|
||||||
|
class JOB_EXPORT_PCB_GERBER;
|
||||||
|
|
||||||
class PCBNEW_JOBS_HANDLER : public JOB_DISPATCHER
|
class PCBNEW_JOBS_HANDLER : public JOB_DISPATCHER
|
||||||
{
|
{
|
||||||
|
@ -32,9 +35,13 @@ public:
|
||||||
int JobExportDxf( JOB* aJob );
|
int JobExportDxf( JOB* aJob );
|
||||||
int JobExportPdf( JOB* aJob );
|
int JobExportPdf( JOB* aJob );
|
||||||
int JobExportGerber( JOB* aJob );
|
int JobExportGerber( JOB* aJob );
|
||||||
|
int JobExportGerbers( JOB* aJob );
|
||||||
int JobExportDrill( JOB* aJob );
|
int JobExportDrill( JOB* aJob );
|
||||||
int JobExportPos( JOB* aJob );
|
int JobExportPos( JOB* aJob );
|
||||||
int JobExportFpUpgrade( JOB* aJob );
|
int JobExportFpUpgrade( JOB* aJob );
|
||||||
|
|
||||||
|
private:
|
||||||
|
void populateGerberPlotOptionsFromJob( PCB_PLOT_PARAMS& aPlotOpts, JOB_EXPORT_PCB_GERBER* aJob );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue