diff --git a/common/jobs/job_export_pcb_gerber.h b/common/jobs/job_export_pcb_gerber.h index e23826b747..3edf5346ac 100644 --- a/common/jobs/job_export_pcb_gerber.h +++ b/common/jobs/job_export_pcb_gerber.h @@ -28,8 +28,8 @@ class JOB_EXPORT_PCB_GERBER : public JOB { public: - JOB_EXPORT_PCB_GERBER( bool aIsCli ) : - JOB( "gerber", aIsCli ), + JOB_EXPORT_PCB_GERBER( const std::string& aType, bool aIsCli ) : + JOB( aType, aIsCli ), m_filename(), m_outputFile(), 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_outputFile; diff --git a/common/jobs/job_export_pcb_gerbers.h b/common/jobs/job_export_pcb_gerbers.h new file mode 100644 index 0000000000..d5428cc550 --- /dev/null +++ b/common/jobs/job_export_pcb_gerbers.h @@ -0,0 +1,46 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2022 Mark Roszko + * 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 . + */ + +#ifndef JOB_EXPORT_PCB_GERBERS_H +#define JOB_EXPORT_PCB_GERBERS_H + +#include "job_export_pcb_gerber.h" +#include +#include +#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 \ No newline at end of file diff --git a/kicad/CMakeLists.txt b/kicad/CMakeLists.txt index 5618b37a9f..36584ed9fa 100644 --- a/kicad/CMakeLists.txt +++ b/kicad/CMakeLists.txt @@ -21,6 +21,7 @@ set( KICAD_SRCS cli/command_export_pcb_drill.cpp cli/command_export_pcb_dxf.cpp cli/command_export_pcb_gerber.cpp + cli/command_export_pcb_gerbers.cpp cli/command_export_pcb_pdf.cpp cli/command_export_pcb_pos.cpp cli/command_export_pcb_step.cpp diff --git a/kicad/cli/command.h b/kicad/cli/command.h index da288ed454..3696446172 100644 --- a/kicad/cli/command.h +++ b/kicad/cli/command.h @@ -32,10 +32,10 @@ namespace CLI class COMMAND { public: - COMMAND( std::string aName, + COMMAND( const std::string& aName, argparse::default_arguments aDefaultArgs = argparse::default_arguments::help ) : - m_name( aName ), - m_argParser( aName, "", aDefaultArgs ){}; + m_name( aName ), + m_argParser( aName, "", aDefaultArgs ){}; virtual int Perform( KIWAY& aKiway ); diff --git a/kicad/cli/command_export_pcb_base.cpp b/kicad/cli/command_export_pcb_base.cpp index 029f7c5f63..514cb08134 100644 --- a/kicad/cli/command_export_pcb_base.cpp +++ b/kicad/cli/command_export_pcb_base.cpp @@ -28,8 +28,12 @@ #include #include -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 ) .default_value( std::string() ) .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; @@ -71,6 +75,7 @@ LSET CLI::EXPORT_PCB_BASE_COMMAND::convertLayerStringList( wxString& aLayerStrin if( m_layerMasks.count( token ) ) { layerMask |= m_layerMasks.at(token); + aLayerArgSet = true; } 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 " "F.Cu,B.Cu" ) ) ); + m_hasLayerArg = true; m_requireLayers = aRequire; } int CLI::EXPORT_PCB_BASE_COMMAND::Perform( KIWAY& aKiway ) { - if( m_requireLayers ) + if( m_hasLayerArg ) { wxString layers = FROM_UTF8( m_argParser.get( ARG_LAYERS ).c_str() ); - LSET layerMask = convertLayerStringList( layers ); - if( layerMask.Seq().size() < 1 ) + LSET layerMask = convertLayerStringList( layers, m_selectedLayersSet ); + if( m_requireLayers && layerMask.Seq().size() < 1 ) { wxFprintf( stderr, _( "At least one or more layers must be specified\n" ) ); return EXIT_CODES::ERR_ARGS; diff --git a/kicad/cli/command_export_pcb_base.h b/kicad/cli/command_export_pcb_base.h index cadc72ee2f..738f4a4def 100644 --- a/kicad/cli/command_export_pcb_base.h +++ b/kicad/cli/command_export_pcb_base.h @@ -37,18 +37,20 @@ namespace CLI 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; protected: - LSET convertLayerStringList( wxString& aLayerString ) const; + LSET convertLayerStringList( wxString& aLayerString, bool& aLayerArgSet ) const; void addLayerArg( bool aRequire ); std::map m_layerMasks; LSET m_selectedLayers; + bool m_selectedLayersSet; - bool m_requireLayers; + bool m_hasLayerArg; + bool m_requireLayers; }; } // namespace CLI diff --git a/kicad/cli/command_export_pcb_gerber.cpp b/kicad/cli/command_export_pcb_gerber.cpp index 2d2c19fbda..b380f9db3f 100644 --- a/kicad/cli/command_export_pcb_gerber.cpp +++ b/kicad/cli/command_export_pcb_gerber.cpp @@ -30,13 +30,9 @@ #include -#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 ); @@ -76,49 +72,62 @@ CLI::EXPORT_PCB_GERBER_COMMAND::EXPORT_PCB_GERBER_COMMAND() : EXPORT_PCB_BASE_CO .default_value( false ); m_argParser.add_argument( ARG_PRECISION ) - .help( UTF8STDSTR( - _( "Precision of gerber coordinates, valid options: 5 or 6" ) ) ) + .help( UTF8STDSTR( _( "Precision of gerber coordinates, valid options: 5 or 6" ) ) ) .scan<'i', int>() .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 gerberJob( new JOB_EXPORT_PCB_GERBER( true ) ); - gerberJob->m_filename = FROM_UTF8( m_argParser.get( ARG_INPUT ).c_str() ); - gerberJob->m_outputFile = FROM_UTF8( m_argParser.get( ARG_OUTPUT ).c_str() ); +int CLI::EXPORT_PCB_GERBER_COMMAND::populateJob( JOB_EXPORT_PCB_GERBER* aJob ) +{ + aJob->m_filename = FROM_UTF8( m_argParser.get( ARG_INPUT ).c_str() ); + aJob->m_outputFile = FROM_UTF8( m_argParser.get( ARG_OUTPUT ).c_str() ); - if( !wxFile::Exists( gerberJob->m_filename ) ) + aJob->m_plotFootprintValues = m_argParser.get( ARG_INCLUDE_VALUE ); + aJob->m_plotRefDes = m_argParser.get( ARG_INCLUDE_VALUE ); + aJob->m_plotBorderTitleBlocks = m_argParser.get( ARG_INCLUDE_BORDER_TITLE ); + aJob->m_disableApertureMacros = m_argParser.get( ARG_DISABLE_APERTURE_MACROS ); + aJob->m_subtractSolderMaskFromSilk = m_argParser.get( ARG_SUBTRACT_SOLDERMASK ); + aJob->m_includeNetlistAttributes = !m_argParser.get( ARG_NO_NETLIST ); + aJob->m_useX2Format = !m_argParser.get( ARG_NO_X2 ); + aJob->m_precision = m_argParser.get( 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" ) ); return EXIT_CODES::ERR_INVALID_INPUT_FILE; } - gerberJob->m_plotFootprintValues = m_argParser.get( ARG_INCLUDE_VALUE ); - gerberJob->m_plotRefDes = m_argParser.get( ARG_INCLUDE_VALUE ); - gerberJob->m_plotBorderTitleBlocks = m_argParser.get( ARG_INCLUDE_BORDER_TITLE ); - gerberJob->m_disableApertureMacros = m_argParser.get( ARG_DISABLE_APERTURE_MACROS ); - gerberJob->m_subtractSolderMaskFromSilk = m_argParser.get( ARG_SUBTRACT_SOLDERMASK ); - gerberJob->m_includeNetlistAttributes = !m_argParser.get( ARG_NO_NETLIST ); - gerberJob->m_useX2Format = !m_argParser.get( ARG_NO_X2 ); - gerberJob->m_precision = m_argParser.get( ARG_PRECISION ); - - if( gerberJob->m_precision != 5 && gerberJob->m_precision != 6 ) + if( aJob->m_precision != 5 && aJob->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; + 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 gerberJob( new JOB_EXPORT_PCB_GERBER( true ) ); + + exitCode = populateJob( gerberJob.get() ); + if( exitCode != EXIT_CODES::OK ) + return exitCode; LOCALE_IO dummy; - int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, gerberJob.get() ); + exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, gerberJob.get() ); return exitCode; } \ No newline at end of file diff --git a/kicad/cli/command_export_pcb_gerber.h b/kicad/cli/command_export_pcb_gerber.h index f1997da21a..231d7fa8fc 100644 --- a/kicad/cli/command_export_pcb_gerber.h +++ b/kicad/cli/command_export_pcb_gerber.h @@ -23,14 +23,26 @@ #include "command_export_pcb_base.h" +class JOB_EXPORT_PCB_GERBER; + 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 { public: + EXPORT_PCB_GERBER_COMMAND( const std::string& aName ); EXPORT_PCB_GERBER_COMMAND(); int Perform( KIWAY& aKiway ) override; + +protected: + int populateJob( JOB_EXPORT_PCB_GERBER* aJob ); }; } // namespace CLI diff --git a/kicad/cli/command_export_pcb_gerbers.cpp b/kicad/cli/command_export_pcb_gerbers.cpp new file mode 100644 index 0000000000..03e9a2842f --- /dev/null +++ b/kicad/cli/command_export_pcb_gerbers.cpp @@ -0,0 +1,74 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2022 Mark Roszko + * 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 . + */ + +#include "command_export_pcb_gerbers.h" +#include +#include "jobs/job_export_pcb_gerbers.h" +#include +#include +#include + +#include +#include + +#include + +#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 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( 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; +} \ No newline at end of file diff --git a/kicad/cli/command_export_pcb_gerbers.h b/kicad/cli/command_export_pcb_gerbers.h new file mode 100644 index 0000000000..141317fa93 --- /dev/null +++ b/kicad/cli/command_export_pcb_gerbers.h @@ -0,0 +1,37 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2022 Mark Roszko + * 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 . + */ + +#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 \ No newline at end of file diff --git a/kicad/kicad_cli.cpp b/kicad/kicad_cli.cpp index 9c42e6d4fc..aeffa8716e 100644 --- a/kicad/kicad_cli.cpp +++ b/kicad/kicad_cli.cpp @@ -52,6 +52,7 @@ #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_gerbers.h" #include "cli/command_export_pcb_pdf.h" #include "cli/command_export_pcb_pos.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_POS_COMMAND exportPcbPosCmd{}; static CLI::EXPORT_PCB_GERBER_COMMAND exportPcbGerberCmd{}; +static CLI::EXPORT_PCB_GERBERS_COMMAND exportPcbGerbersCmd{}; static CLI::EXPORT_PCB_COMMAND exportPcbCmd{}; static CLI::PCB_COMMAND pcbCmd{}; static CLI::EXPORT_SCH_COMMAND exportSchCmd{}; @@ -151,6 +153,7 @@ static std::vector commandStack = { &exportPcbDrillCmd, &exportPcbDxfCmd, &exportPcbGerberCmd, + &exportPcbGerbersCmd, &exportPcbPdfCmd, &exportPcbPosCmd, &exportPcbStepCmd, diff --git a/pcbnew/pcbnew_jobs_handler.cpp b/pcbnew/pcbnew_jobs_handler.cpp index 4b2c7593e3..355f5e5df0 100644 --- a/pcbnew/pcbnew_jobs_handler.cpp +++ b/pcbnew/pcbnew_jobs_handler.cpp @@ -21,6 +21,7 @@ #include "pcbnew_jobs_handler.h" #include #include +#include #include #include #include @@ -57,6 +58,8 @@ PCBNEW_JOBS_HANDLER::PCBNEW_JOBS_HANDLER() 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( "gerbers", + std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerbers, this, std::placeholders::_1 ) ); Register( "drill", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrill, 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( 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 ) { JOB_EXPORT_PCB_GERBER* aGerberJob = dynamic_cast( aJob ); @@ -263,24 +368,9 @@ int PCBNEW_JOBS_HANDLER::JobExportGerber( JOB* aJob ) } PCB_PLOT_PARAMS plotOpts; - plotOpts.SetFormat( PLOT_FORMAT::GERBER ); - - plotOpts.SetPlotFrameRef( aGerberJob->m_plotBorderTitleBlocks ); - plotOpts.SetPlotValue( aGerberJob->m_plotFootprintValues ); - plotOpts.SetPlotReference( aGerberJob->m_plotRefDes ); - + populateGerberPlotOptionsFromJob( plotOpts, aGerberJob ); 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 GERBER_PLOTTER* plotter = (GERBER_PLOTTER*) StartPlotBoard( brd, &plotOpts, aGerberJob->m_printMaskLayer.Seq().front(), aGerberJob->m_outputFile, diff --git a/pcbnew/pcbnew_jobs_handler.h b/pcbnew/pcbnew_jobs_handler.h index f2a9cdab79..725d7134ac 100644 --- a/pcbnew/pcbnew_jobs_handler.h +++ b/pcbnew/pcbnew_jobs_handler.h @@ -22,6 +22,9 @@ #define PCBNEW_JOBS_HANDLER_H #include +#include + +class JOB_EXPORT_PCB_GERBER; class PCBNEW_JOBS_HANDLER : public JOB_DISPATCHER { @@ -32,9 +35,13 @@ public: int JobExportDxf( JOB* aJob ); int JobExportPdf( JOB* aJob ); int JobExportGerber( JOB* aJob ); + int JobExportGerbers( JOB* aJob ); int JobExportDrill( JOB* aJob ); int JobExportPos( JOB* aJob ); int JobExportFpUpgrade( JOB* aJob ); + +private: + void populateGerberPlotOptionsFromJob( PCB_PLOT_PARAMS& aPlotOpts, JOB_EXPORT_PCB_GERBER* aJob ); }; #endif \ No newline at end of file