KiCad PCB EDA Suite
pcbnew_jobs_handler.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2022 Mark Roszko <[email protected]>
5 * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "pcbnew_jobs_handler.h"
23#include <jobs/job_fp_upgrade.h>
32#include <cli/exit_codes.h>
39#include <pgm_base.h>
40#include <pcbplot.h>
42#include <pad.h>
43#include <pcbnew_settings.h>
44#include <wx/crt.h>
45#include <wx/dir.h>
46#include <pcb_plot_svg.h>
52
54
56{
57 Register( "step",
58 std::bind( &PCBNEW_JOBS_HANDLER::JobExportStep, this, std::placeholders::_1 ) );
59 Register( "svg", std::bind( &PCBNEW_JOBS_HANDLER::JobExportSvg, this, std::placeholders::_1 ) );
60 Register( "dxf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDxf, this, std::placeholders::_1 ) );
61 Register( "pdf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPdf, this, std::placeholders::_1 ) );
62 Register( "gerber",
63 std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerber, this, std::placeholders::_1 ) );
64 Register( "gerbers",
65 std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerbers, this, std::placeholders::_1 ) );
66 Register( "drill",
67 std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrill, this, std::placeholders::_1 ) );
68 Register( "pos", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPos, this, std::placeholders::_1 ) );
69 Register( "fpupgrade",
70 std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpUpgrade, this, std::placeholders::_1 ) );
71 Register( "fpsvg",
72 std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpSvg, this, std::placeholders::_1 ) );
73}
74
75
77{
78 JOB_EXPORT_PCB_STEP* aStepJob = dynamic_cast<JOB_EXPORT_PCB_STEP*>( aJob );
79
80 if( aStepJob == nullptr )
82
83 if( aJob->IsCli() )
84 wxPrintf( _( "Loading board\n" ) );
85
86 BOARD* brd = LoadBoard( aStepJob->m_filename );
87
88 if( aStepJob->m_outputFile.IsEmpty() )
89 {
90 wxFileName fn = brd->GetFileName();
91 fn.SetName( fn.GetName() );
92 fn.SetExt( wxS( "step" ) );
93
94 aStepJob->m_outputFile = fn.GetFullName();
95 }
96
99 params.m_minDistance = aStepJob->m_minDistance;
100 params.m_overwrite = aStepJob->m_overwrite;
101 params.m_substModels = aStepJob->m_substModels;
102 params.m_origin = VECTOR2D( aStepJob->m_xOrigin, aStepJob->m_yOrigin );
103 params.m_useDrillOrigin = aStepJob->m_useDrillOrigin;
104 params.m_useGridOrigin = aStepJob->m_useGridOrigin;
105 params.m_boardOnly = aStepJob->m_boardOnly;
106
107 EXPORTER_STEP stepExporter( brd, params );
108 stepExporter.m_outputFile = aStepJob->m_outputFile;
109
110 if( !stepExporter.Export() )
111 {
113 }
114
115 return CLI::EXIT_CODES::OK;
116}
117
118
120{
121 JOB_EXPORT_PCB_SVG* aSvgJob = dynamic_cast<JOB_EXPORT_PCB_SVG*>( aJob );
122
123 if( aSvgJob == nullptr )
125
126 PCB_PLOT_SVG_OPTIONS svgPlotOptions;
127 svgPlotOptions.m_blackAndWhite = aSvgJob->m_blackAndWhite;
128 svgPlotOptions.m_colorTheme = aSvgJob->m_colorTheme;
129 svgPlotOptions.m_outputFile = aSvgJob->m_outputFile;
130 svgPlotOptions.m_mirror = aSvgJob->m_mirror;
131 svgPlotOptions.m_pageSizeMode = aSvgJob->m_pageSizeMode;
132 svgPlotOptions.m_printMaskLayer = aSvgJob->m_printMaskLayer;
133 svgPlotOptions.m_plotFrame = aSvgJob->m_plotDrawingSheet;
134
135 if( aJob->IsCli() )
136 wxPrintf( _( "Loading board\n" ) );
137
138 BOARD* brd = LoadBoard( aSvgJob->m_filename );
139
140 if( aJob->IsCli() )
141 {
142 if( PCB_PLOT_SVG::Plot( brd, svgPlotOptions ) )
143 wxPrintf( _( "Successfully created svg file" ) );
144 else
145 wxPrintf( _( "Error creating svg file" ) );
146 }
147
148 return CLI::EXIT_CODES::OK;
149}
150
151
153{
154 JOB_EXPORT_PCB_DXF* aDxfJob = dynamic_cast<JOB_EXPORT_PCB_DXF*>( aJob );
155
156 if( aDxfJob == nullptr )
158
159 if( aJob->IsCli() )
160 wxPrintf( _( "Loading board\n" ) );
161
162 BOARD* brd = LoadBoard( aDxfJob->m_filename );
163
164 if( aDxfJob->m_outputFile.IsEmpty() )
165 {
166 wxFileName fn = brd->GetFileName();
167 fn.SetName( fn.GetName() );
169
170 aDxfJob->m_outputFile = fn.GetFullName();
171 }
172
173 PCB_PLOT_PARAMS plotOpts;
174 plotOpts.SetFormat( PLOT_FORMAT::DXF );
175
176
178
180 {
182 }
183 else
184 {
186 }
187 plotOpts.SetPlotFrameRef( aDxfJob->m_plotBorderTitleBlocks );
188 plotOpts.SetPlotValue( aDxfJob->m_plotFootprintValues );
189 plotOpts.SetPlotReference( aDxfJob->m_plotRefDes );
190
191 plotOpts.SetLayerSelection( aDxfJob->m_printMaskLayer );
192
194 brd, &plotOpts, UNDEFINED_LAYER, aDxfJob->m_outputFile, wxEmptyString, wxEmptyString );
195
196 if( plotter )
197 {
198 PlotBoardLayers( brd, plotter, aDxfJob->m_printMaskLayer.SeqStackupBottom2Top(), plotOpts );
199 plotter->EndPlot();
200 }
201
202 delete plotter;
203
204 return CLI::EXIT_CODES::OK;
205}
206
207
209{
210 JOB_EXPORT_PCB_PDF* aPdfJob = dynamic_cast<JOB_EXPORT_PCB_PDF*>( aJob );
211
212 if( aPdfJob == nullptr )
214
215 if( aJob->IsCli() )
216 wxPrintf( _( "Loading board\n" ) );
217
218 BOARD* brd = LoadBoard( aPdfJob->m_filename );
219
220 if( aPdfJob->m_outputFile.IsEmpty() )
221 {
222 wxFileName fn = brd->GetFileName();
223 fn.SetName( fn.GetName() );
225
226 aPdfJob->m_outputFile = fn.GetFullName();
227 }
228
229 PCB_PLOT_PARAMS plotOpts;
230 plotOpts.SetFormat( PLOT_FORMAT::PDF );
231
232 plotOpts.SetPlotFrameRef( aPdfJob->m_plotBorderTitleBlocks );
233 plotOpts.SetPlotValue( aPdfJob->m_plotFootprintValues );
234 plotOpts.SetPlotReference( aPdfJob->m_plotRefDes );
235
236 plotOpts.SetLayerSelection( aPdfJob->m_printMaskLayer );
237
239 brd, &plotOpts, UNDEFINED_LAYER, aPdfJob->m_outputFile, wxEmptyString, wxEmptyString );
240
241 if( plotter )
242 {
243 PlotBoardLayers( brd, plotter, aPdfJob->m_printMaskLayer.SeqStackupBottom2Top(), plotOpts );
244 PlotInteractiveLayer( brd, plotter );
245 plotter->EndPlot();
246 }
247
248 delete plotter;
249
250 return CLI::EXIT_CODES::OK;
251}
252
253
255{
256 JOB_EXPORT_PCB_GERBERS* aGerberJob = dynamic_cast<JOB_EXPORT_PCB_GERBERS*>( aJob );
257
258 if( aGerberJob == nullptr )
260
261 if( aJob->IsCli() )
262 wxPrintf( _( "Loading board\n" ) );
263
264 BOARD* brd = LoadBoard( aGerberJob->m_filename );
265 PCB_PLOT_PARAMS boardPlotOptions = brd->GetPlotOptions();
266 LSET plotOnAllLayersSelection = boardPlotOptions.GetPlotOnAllLayersSelection();
267 GERBER_JOBFILE_WRITER jobfile_writer( brd );
268
269 wxString fileExt;
270
271 if( aGerberJob->m_useBoardPlotParams )
272 {
273 aGerberJob->m_printMaskLayer = boardPlotOptions.GetLayerSelection();
274 aGerberJob->m_layersIncludeOnAll = boardPlotOptions.GetPlotOnAllLayersSelection();
275 }
276 else
277 {
278 // default to the board enabled layers
279 if( aGerberJob->m_printMaskLayer == 0 )
280 aGerberJob->m_printMaskLayer = brd->GetEnabledLayers();
281
282 if( aGerberJob->m_layersIncludeOnAllSet )
283 aGerberJob->m_layersIncludeOnAll = plotOnAllLayersSelection;
284 }
285
286 for( LSEQ seq = aGerberJob->m_printMaskLayer.UIOrder(); seq; ++seq )
287 {
288 LSEQ plotSequence;
289
290 // Base layer always gets plotted first.
291 plotSequence.push_back( *seq );
292
293 // Now all the "include on all" layers
294 for( LSEQ seqAll = aGerberJob->m_layersIncludeOnAll.UIOrder(); seqAll; ++seqAll )
295 {
296 // Don't plot the same layer more than once;
297 if( find( plotSequence.begin(), plotSequence.end(), *seqAll ) != plotSequence.end() )
298 continue;
299
300 plotSequence.push_back( *seqAll );
301 }
302
303 // Pick the basename from the board file
304 wxFileName fn( brd->GetFileName() );
305 PCB_LAYER_ID layer = *seq;
306 fileExt = GetGerberProtelExtension( layer );
307
308 PCB_PLOT_PARAMS plotOpts;
309
310 if( aGerberJob->m_useBoardPlotParams )
311 plotOpts = boardPlotOptions;
312 else
313 populateGerberPlotOptionsFromJob( plotOpts, aGerberJob );
314
315 BuildPlotFileName( &fn, aGerberJob->m_outputFile, brd->GetLayerName( layer ), fileExt );
316 wxString fullname = fn.GetFullName();
317
318 jobfile_writer.AddGbrFile( layer, fullname );
319
320 // We are feeding it one layer at the start here to silence a logic check
322 brd, &plotOpts, layer, fn.GetFullPath(), wxEmptyString, wxEmptyString );
323
324 if( plotter )
325 {
326 wxPrintf( _( "Plotted to '%s'.\n" ), fn.GetFullPath() );
327 PlotBoardLayers( brd, plotter, plotSequence, plotOpts );
328 plotter->EndPlot();
329 }
330
331 delete plotter;
332 }
333
334 wxFileName fn( aGerberJob->m_filename );
335 // Build gerber job file from basename
336 BuildPlotFileName( &fn, aGerberJob->m_outputFile, wxT( "job" ), GerberJobFileExtension );
337 jobfile_writer.CreateJobFile( fn.GetFullPath() );
338
339 return CLI::EXIT_CODES::OK;
340}
341
342
345{
346 aPlotOpts.SetFormat( PLOT_FORMAT::GERBER );
347
348 aPlotOpts.SetPlotFrameRef( aJob->m_plotBorderTitleBlocks );
349 aPlotOpts.SetPlotValue( aJob->m_plotFootprintValues );
350 aPlotOpts.SetPlotReference( aJob->m_plotRefDes );
351
353 // Always disable plot pad holes
355
357 aPlotOpts.SetUseGerberX2format( aJob->m_useX2Format );
359
360 aPlotOpts.SetGerberPrecision( aJob->m_precision );
361}
362
363
365{
366 JOB_EXPORT_PCB_GERBER* aGerberJob = dynamic_cast<JOB_EXPORT_PCB_GERBER*>( aJob );
367
368 if( aGerberJob == nullptr )
370
371 if( aJob->IsCli() )
372 wxPrintf( _( "Loading board\n" ) );
373
374 BOARD* brd = LoadBoard( aGerberJob->m_filename );
375
376 if( aGerberJob->m_outputFile.IsEmpty() )
377 {
378 wxFileName fn = brd->GetFileName();
379 fn.SetName( fn.GetName() );
381
382 aGerberJob->m_outputFile = fn.GetFullName();
383 }
384
385 PCB_PLOT_PARAMS plotOpts;
386 populateGerberPlotOptionsFromJob( plotOpts, aGerberJob );
387 plotOpts.SetLayerSelection( aGerberJob->m_printMaskLayer );
388
389 // We are feeding it one layer at the start here to silence a logic check
391 brd, &plotOpts, aGerberJob->m_printMaskLayer.Seq().front(), aGerberJob->m_outputFile,
392 wxEmptyString, wxEmptyString );
393
394 if( plotter )
395 {
396 PlotBoardLayers( brd, plotter, aGerberJob->m_printMaskLayer.SeqStackupBottom2Top(),
397 plotOpts );
398 plotter->EndPlot();
399 }
400
401 delete plotter;
402
403 return CLI::EXIT_CODES::OK;
404}
405
408
410{
411 JOB_EXPORT_PCB_DRILL* aDrillJob = dynamic_cast<JOB_EXPORT_PCB_DRILL*>( aJob );
412
413 if( aDrillJob == nullptr )
415
416 if( aJob->IsCli() )
417 wxPrintf( _( "Loading board\n" ) );
418
419 BOARD* brd = LoadBoard( aDrillJob->m_filename );
420
421 std::unique_ptr<GENDRILL_WRITER_BASE> drillWriter;
423 {
424 drillWriter = std::make_unique<EXCELLON_WRITER>( brd );
425 }
426 else
427 {
428 drillWriter = std::make_unique<GERBER_WRITER>( brd );
429 }
430
431 VECTOR2I offset;
433 offset = VECTOR2I( 0, 0 );
434 else
435 offset = brd->GetDesignSettings().GetAuxOrigin();
436
437
438 PLOT_FORMAT mapFormat = PLOT_FORMAT::PDF;
439 switch( aDrillJob->m_mapFormat )
440 {
445 default:
447 }
448
450 {
452 switch( aDrillJob->m_zeroFormat )
453 {
456 break;
459 break;
462 break;
464 default:
466 break;
467 }
468
469 DRILL_PRECISION precision;
471 precision = precisionListForInches;
472 else
473 precision = precisionListForMetric;
474
475
476 EXCELLON_WRITER* excellonWriter = dynamic_cast<EXCELLON_WRITER*>( drillWriter.get() );
477 excellonWriter->SetFormat( aDrillJob->m_drillUnits
479 zeroFmt, precision.m_Lhs, precision.m_Rhs );
480 excellonWriter->SetOptions( aDrillJob->m_excellonMirrorY, aDrillJob->m_excellonMinimalHeader,
481 offset, aDrillJob->m_excellonCombinePTHNPTH );
482 excellonWriter->SetRouteModeForOvalHoles( aDrillJob->m_excellonOvalDrillRoute );
483 excellonWriter->SetMapFileFormat( mapFormat );
484
485 excellonWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true,
486 aDrillJob->m_generateMap, nullptr );
487 }
489 {
490 GERBER_WRITER* gerberWriter = dynamic_cast<GERBER_WRITER*>( drillWriter.get() );
491 // Set gerber precision: only 5 or 6 digits for mantissa are allowed
492 // (SetFormat() accept 5 or 6, and any other value set the precision to 5)
493 // the integer part precision is always 4, and units always mm
494 gerberWriter->SetFormat( aDrillJob->m_gerberPrecision );
495 gerberWriter->SetOptions( offset );
496 gerberWriter->SetMapFileFormat( mapFormat );
497
498 gerberWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true,
499 aDrillJob->m_generateMap, nullptr );
500 }
501
502 return CLI::EXIT_CODES::OK;
503}
504
505
507{
508 JOB_EXPORT_PCB_POS* aPosJob = dynamic_cast<JOB_EXPORT_PCB_POS*>( aJob );
509
510 if( aPosJob == nullptr )
512
513 if( aJob->IsCli() )
514 wxPrintf( _( "Loading board\n" ) );
515
516 BOARD* brd = LoadBoard( aPosJob->m_filename );
517
518 if( aPosJob->m_outputFile.IsEmpty() )
519 {
520 wxFileName fn = brd->GetFileName();
521 fn.SetName( fn.GetName() );
522
524 fn.SetExt( FootprintPlaceFileExtension );
525 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::CSV )
526 fn.SetExt( CsvFileExtension );
527 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::GERBER )
528 fn.SetExt( GerberFileExtension );
529
530 aPosJob->m_outputFile = fn.GetFullName();
531 }
532
534 {
535 FILE* file = nullptr;
536 file = wxFopen( aPosJob->m_outputFile, wxS( "wt" ) );
537
538 if( file == nullptr )
540
541 std::string data;
542
543 bool frontSide = aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::FRONT
545
546 bool backSide = aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::BACK
548
550 aPosJob->m_smdOnly, aPosJob->m_excludeFootprintsWithTh,
551 frontSide, backSide,
554 aPosJob->m_negateBottomX );
555 data = exporter.GenPositionData();
556
557 fputs( data.c_str(), file );
558 fclose( file );
559 }
560 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::GERBER )
561 {
562 PLACEFILE_GERBER_WRITER exporter( brd );
563
564 PCB_LAYER_ID gbrLayer = F_Cu;
565
566 if( aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::BACK )
567 gbrLayer = B_Cu;
568
569 exporter.CreatePlaceFile( aPosJob->m_outputFile, gbrLayer, aPosJob->m_gerberBoardEdge );
570 }
571
572 return CLI::EXIT_CODES::OK;
573}
574
575extern FOOTPRINT* try_load_footprint( const wxFileName& aFileName, IO_MGR::PCB_FILE_T aFileType,
576 const wxString& aName );
577
578
580{
581 JOB_FP_UPGRADE* upgradeJob = dynamic_cast<JOB_FP_UPGRADE*>( aJob );
582
583 if( upgradeJob == nullptr )
585
586 if( aJob->IsCli() )
587 wxPrintf( _( "Loading footprint library\n" ) );
588
589 if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
590 {
591 if( wxFile::Exists( upgradeJob->m_outputLibraryPath ) ||
592 wxDir::Exists( upgradeJob->m_outputLibraryPath) )
593 {
594 wxFprintf( stderr, _( "Output path must not conflict with existing path\n" ) );
596 }
597 }
598
599 PCB_PLUGIN pcb_io( CTL_FOR_LIBRARY );
600 FP_CACHE fpLib( &pcb_io, upgradeJob->m_libraryPath );
601
602 try
603 {
604 fpLib.Load();
605 }
606 catch(...)
607 {
608 wxFprintf( stderr, _( "Unable to load library\n" ) );
610 }
611
612 bool shouldSave = upgradeJob->m_force;
613
614 for( const auto& footprint : fpLib.GetFootprints() )
615 {
616 if( footprint.second->GetFootprint()->GetFileFormatVersionAtLoad() < SEXPR_BOARD_FILE_VERSION )
617 {
618 shouldSave = true;
619 }
620 }
621
622 if( shouldSave )
623 {
624 wxPrintf( _( "Saving footprint library\n" ) );
625
626 try
627 {
628 if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
629 {
630 fpLib.SetPath( upgradeJob->m_outputLibraryPath );
631 }
632
633 fpLib.Save();
634 }
635 catch( ... )
636 {
637 wxFprintf( stderr, _( "Unable to save library\n" ) );
639 }
640 }
641 else
642 {
643 wxPrintf( _( "Footprint library was not updated\n" ) );
644 }
645
646 return CLI::EXIT_CODES::OK;
647}
648
649
651{
652 JOB_FP_EXPORT_SVG* svgJob = dynamic_cast<JOB_FP_EXPORT_SVG*>( aJob );
653
654 if( svgJob == nullptr )
656
657 if( aJob->IsCli() )
658 wxPrintf( _( "Loading footprint library\n" ) );
659
660 PCB_PLUGIN pcb_io( CTL_FOR_LIBRARY );
661 FP_CACHE fpLib( &pcb_io, svgJob->m_libraryPath );
662
663 try
664 {
665 fpLib.Load();
666 }
667 catch( ... )
668 {
669 wxFprintf( stderr, _( "Unable to load library\n" ) );
671 }
672
673 if( !svgJob->m_outputDirectory.IsEmpty() && !wxDir::Exists( svgJob->m_outputDirectory ) )
674 {
675 wxFileName::Mkdir( svgJob->m_outputDirectory );
676 }
677
678 int exitCode = CLI::EXIT_CODES::OK;
679
680 // Just plot all the symbols we can
681 FP_CACHE_FOOTPRINT_MAP& footprintMap = fpLib.GetFootprints();
682
683 bool singleFpPlotted = false;
684 for( FP_CACHE_FOOTPRINT_MAP::iterator it = footprintMap.begin(); it != footprintMap.end();
685 ++it )
686 {
687 const FOOTPRINT* fp = it->second->GetFootprint();
688 if( !svgJob->m_footprint.IsEmpty() )
689 {
690 if( fp->GetFPID().GetLibItemName().wx_str() != svgJob->m_footprint )
691 {
692 // skip until we find the right footprint
693 continue;
694 }
695 else
696 {
697 singleFpPlotted = true;
698 }
699 }
700
701 exitCode = doFpExportSvg( svgJob, fp );
702 if( exitCode != CLI::EXIT_CODES::OK )
703 break;
704 }
705
706 if( !svgJob->m_footprint.IsEmpty() && !singleFpPlotted )
707 wxFprintf( stderr, _( "The given footprint could not be found to export." ) );
708
709 return CLI::EXIT_CODES::OK;
710}
711
712
714{
715 // the hack for now is we create fake boards containing the footprint and plot the board
716 // until we refactor better plot api later
717 std::unique_ptr<BOARD> brd;
718 brd.reset( CreateEmptyBoard() );
719
720 FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( aFootprint->Clone() );
721
722 fp->SetLink( niluuid );
723 fp->SetFlags( IS_NEW );
724 fp->SetParent( brd.get() );
725
726 for( PAD* pad : fp->Pads() )
727 {
728 pad->SetLocalRatsnestVisible( false );
729 pad->SetNetCode( 0 );
730 }
731
732 fp->SetOrientation( ANGLE_0 );
733 fp->SetPosition( VECTOR2I( 0, 0 ) );
734
735 brd->Add( fp, ADD_MODE::INSERT, true );
736
737 wxFileName outputFile;
738 outputFile.SetPath( aSvgJob->m_outputDirectory );
739 outputFile.SetName( aFootprint->GetFPID().GetLibItemName().wx_str() );
740 outputFile.SetExt( SVGFileExtension );
741
742 wxPrintf( _( "Plotting footprint '%s' to '%s'\n" ),
743 aFootprint->GetFPID().GetLibItemName().wx_str(), outputFile.GetFullPath() );
744
745
746 PCB_PLOT_SVG_OPTIONS svgPlotOptions;
747 svgPlotOptions.m_blackAndWhite = aSvgJob->m_blackAndWhite;
748 svgPlotOptions.m_colorTheme = aSvgJob->m_colorTheme;
749 svgPlotOptions.m_outputFile = outputFile.GetFullPath();
750 svgPlotOptions.m_mirror = false;
751 svgPlotOptions.m_pageSizeMode = 2; // board bounding box
752 svgPlotOptions.m_printMaskLayer = aSvgJob->m_printMaskLayer;
753 svgPlotOptions.m_plotFrame = false;
754
755 if( !PCB_PLOT_SVG::Plot( brd.get(), svgPlotOptions ) )
756 wxFprintf( stderr, _( "Error creating svg file" ) );
757
758
759 return CLI::EXIT_CODES::OK;
760}
const VECTOR2I & GetAuxOrigin()
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:265
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:569
const wxString & GetFileName() const
Definition: board.h:302
const PCB_PLOT_PARAMS & GetPlotOptions() const
Definition: board.h:629
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:456
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:686
Helper to handle drill precision format in excellon files.
virtual bool EndPlot() override
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:139
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:100
Create Excellon drill, drill map, and drill report files.
void SetFormat(bool aMetric, ZEROS_FMT aZerosFmt=DECIMAL_FORMAT, int aLeftDigits=0, int aRightDigits=0)
Initialize internal parameters to match the given format.
void SetOptions(bool aMirror, bool aMinimalHeader, const VECTOR2I &aOffset, bool aMerge_PTH_NPTH)
Initialize internal parameters to match drill options.
void SetRouteModeForOvalHoles(bool aUseRouteModeForOvalHoles)
void CreateDrillandMapFilesSet(const wxString &aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER *aReporter=nullptr)
Create the full set of Excellon drill file for the board.
wxString m_outputFile
Definition: exporter_step.h:72
void SetPosition(const VECTOR2I &aPos) override
Definition: footprint.cpp:1676
void SetLink(const KIID &aLink)
Definition: footprint.h:681
void SetOrientation(const EDA_ANGLE &aNewAngle)
Definition: footprint.cpp:1808
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: footprint.cpp:1375
PADS & Pads()
Definition: footprint.h:170
const LIB_ID & GetFPID() const
Definition: footprint.h:212
FP_CACHE_FOOTPRINT_MAP & GetFootprints()
Definition: pcb_plugin.h:209
void Save(FOOTPRINT *aFootprint=nullptr)
Save the footprint cache or a single footprint from it to disk.
Definition: pcb_plugin.cpp:85
void SetPath(const wxString &aPath)
Definition: pcb_plugin.cpp:242
void Load()
Definition: pcb_plugin.cpp:152
void SetMapFileFormat(PLOT_FORMAT aMapFmt)
Initialize the format for the drill map file.
GERBER_JOBFILE_WRITER is a class used to create Gerber job file a Gerber job file stores info to make...
bool CreateJobFile(const wxString &aFullFilename)
Creates a Gerber job file.
void AddGbrFile(PCB_LAYER_ID aLayer, wxString &aFilename)
add a gerber file name and type in job file list
virtual bool EndPlot() override
Used to create Gerber drill files.
void CreateDrillandMapFilesSet(const wxString &aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER *aReporter=nullptr)
Create the full set of Excellon drill file for the board filenames are computed from the board name,...
void SetOptions(const VECTOR2I &aOffset)
Initialize internal parameters to match drill options.
void SetFormat(int aRightDigits=6)
Initialize internal parameters to match the given format.
PCB_FILE_T
The set of file types that the IO_MGR knows about, and for which there has been a plugin written.
Definition: io_mgr.h:54
void Register(const std::string &aJobTypeName, std::function< int(JOB *job)> aHandler)
wxString m_libraryPath
wxString m_outputLibraryPath
An simple container class that lets us dispatch output jobs to kifaces.
Definition: job.h:28
bool IsCli() const
Definition: job.h:35
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Definition: layer_ids.h:491
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:530
LSEQ UIOrder() const
Definition: lset.cpp:922
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
LSEQ SeqStackupBottom2Top() const
Return the sequence that is typical for a bottom-to-top stack-up.
Definition: lset.cpp:475
Definition: pad.h:59
int JobExportStep(JOB *aJob)
void populateGerberPlotOptionsFromJob(PCB_PLOT_PARAMS &aPlotOpts, JOB_EXPORT_PCB_GERBER *aJob)
int JobExportFpUpgrade(JOB *aJob)
int JobExportGerber(JOB *aJob)
int JobExportGerbers(JOB *aJob)
int doFpExportSvg(JOB_FP_EXPORT_SVG *aSvgJob, const FOOTPRINT *aFootprint)
Parameters and options when plotting/printing a board.
void SetDrillMarksType(DRILL_MARKS aVal)
void SetLayerSelection(LSET aSelection)
void SetPlotReference(bool aFlag)
void SetUseGerberX2format(bool aUse)
void SetDXFPlotPolygonMode(bool aFlag)
void SetPlotFrameRef(bool aFlag)
LSET GetLayerSelection() const
LSET GetPlotOnAllLayersSelection() const
void SetDisableGerberMacros(bool aDisable)
void SetGerberPrecision(int aPrecision)
void SetSubtractMaskFromSilk(bool aSubtract)
void SetPlotValue(bool aFlag)
void SetDXFPlotUnits(DXF_UNITS aUnit)
void SetIncludeGerberNetlistInfo(bool aUse)
void SetFormat(PLOT_FORMAT aFormat)
static bool Plot(BOARD *aBoard, const PCB_PLOT_SVG_OPTIONS &aSvgPlotOptions)
A PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
Definition: pcb_plugin.h:261
virtual bool EndPlot() override
Used to create Gerber drill files.
int CreatePlaceFile(wxString &aFullFilename, PCB_LAYER_ID aLayer, bool aIncludeBrdEdges)
Create an pnp gerber file.
The ASCII format of the kicad place file is:
std::string GenPositionData()
build a string filled with the position data
wxString wx_str() const
Definition: utf8.cpp:46
wxString GetDefaultPlotExtension(PLOT_FORMAT aFormat)
Returns the default plot extension for a format.
#define _(s)
static constexpr EDA_ANGLE & ANGLE_0
Definition: eda_angle.h:423
#define IS_NEW
New item, just created.
Classes used in drill files, map files and report files generation.
Classes used in drill files, map files and report files generation.
Classes used to generate a Gerber job file in JSON.
Classes used in place file generation.
const std::string FootprintPlaceFileExtension
const std::string GerberJobFileExtension
const std::string SVGFileExtension
const std::string CsvFileExtension
const std::string GerberFileExtension
KIID niluuid(0)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ B_Cu
Definition: layer_ids.h:95
@ UNDEFINED_LAYER
Definition: layer_ids.h:60
@ F_Cu
Definition: layer_ids.h:64
static const int OK
Definition: exit_codes.h:30
static const int ERR_INVALID_OUTPUT_CONFLICT
Definition: exit_codes.h:34
static const int ERR_UNKNOWN
Definition: exit_codes.h:32
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
Definition: pcb_plugin.h:133
boost::ptr_map< wxString, FP_CACHE_ITEM > FP_CACHE_FOOTPRINT_MAP
Definition: pcb_plugin.h:186
#define CTL_FOR_LIBRARY
Format output for a footprint library instead of clipboard or BOARD.
Definition: pcb_plugin.h:158
static DRILL_PRECISION precisionListForInches(2, 4)
static DRILL_PRECISION precisionListForMetric(3, 3)
FOOTPRINT * try_load_footprint(const wxFileName &aFileName, IO_MGR::PCB_FILE_T aFileType, const wxString &aName)
Try to load a footprint, returning nullptr if the file couldn't be accessed.
BOARD * CreateEmptyBoard()
Construct a default BOARD with a temporary (no filename) project.
BOARD * LoadBoard(wxString &aFileName)
const wxString GetGerberProtelExtension(int aLayer)
Definition: pcbplot.cpp:42
void BuildPlotFileName(wxFileName *aFilename, const wxString &aOutputDir, const wxString &aSuffix, const wxString &aExtension)
Complete a plot filename.
Definition: pcbplot.cpp:361
void PlotInteractiveLayer(BOARD *aBoard, PLOTTER *aPlotter)
Plot interactive items (hypertext links, properties, etc.).
PLOTTER * StartPlotBoard(BOARD *aBoard, const PCB_PLOT_PARAMS *aPlotOpts, int aLayer, const wxString &aFullFileName, const wxString &aSheetName, const wxString &aSheetPath)
Open a new plotfile using the options (and especially the format) specified in the options and prepar...
void PlotBoardLayers(BOARD *aBoard, PLOTTER *aPlotter, const LSEQ &aLayerSequence, const PCB_PLOT_PARAMS &aPlotOptions)
Plot a sequence of board layer IDs.
see class PGM_BASE
PLOT_FORMAT
The set of supported output plot formats.
Definition: plotter.h:70
Plotting engine (DXF)
Plotting engine (Gerber)
Plotting engines similar to ps (PostScript, Gerber, svg)
VECTOR2< double > VECTOR2D
Definition: vector2d.h:617
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618
Definition of file extensions used in Kicad.