KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2024 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 <wx/dir.h>
22#include "pcbnew_jobs_handler.h"
23#include <board_commit.h>
25#include <drc/drc_item.h>
26#include <drc/drc_report.h>
30#include <jobs/job_fp_upgrade.h>
40#include <jobs/job_pcb_drc.h>
41#include <cli/exit_codes.h>
47#include <tool/tool_manager.h>
48#include <tools/drc_tool.h>
53#include <kiface_base.h>
54#include <macros.h>
55#include <pad.h>
56#include <pcb_marker.h>
59#include <kiface_ids.h>
62#include <pcbnew_settings.h>
63#include <pcbplot.h>
64#include <pgm_base.h>
66#include <reporter.h>
67#include <string_utf8_map.h>
69#include <export_vrml.h>
70#include <wx/wfstream.h>
71#include <wx/zipstrm.h>
72
74
75
77 JOB_DISPATCHER( aKiway )
78{
79 Register( "3d", std::bind( &PCBNEW_JOBS_HANDLER::JobExportStep, this, std::placeholders::_1 ) );
80 Register( "svg", std::bind( &PCBNEW_JOBS_HANDLER::JobExportSvg, this, std::placeholders::_1 ) );
81 Register( "dxf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDxf, this, std::placeholders::_1 ) );
82 Register( "pdf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPdf, this, std::placeholders::_1 ) );
83 Register( "gerber",
84 std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerber, this, std::placeholders::_1 ) );
85 Register( "gerbers",
86 std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerbers, this, std::placeholders::_1 ) );
87 Register( "drill",
88 std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrill, this, std::placeholders::_1 ) );
89 Register( "pos", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPos, this, std::placeholders::_1 ) );
90 Register( "fpupgrade",
91 std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpUpgrade, this, std::placeholders::_1 ) );
92 Register( "fpsvg",
93 std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpSvg, this, std::placeholders::_1 ) );
94 Register( "drc", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrc, this, std::placeholders::_1 ) );
95 Register( "ipc2581",
96 std::bind( &PCBNEW_JOBS_HANDLER::JobExportIpc2581, this, std::placeholders::_1 ) );
97}
98
99
101{
102 JOB_EXPORT_PCB_3D* aStepJob = dynamic_cast<JOB_EXPORT_PCB_3D*>( aJob );
103
104 if( aStepJob == nullptr )
106
107 if( aJob->IsCli() )
108 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
109
110 BOARD* brd = LoadBoard( aStepJob->m_filename, true );
111 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
112
113 if( aStepJob->m_outputFile.IsEmpty() )
114 {
115 wxFileName fn = brd->GetFileName();
116 fn.SetName( fn.GetName() );
117
118 switch( aStepJob->m_format )
119 {
121 break;
123 break;
125 break;
126 default:
127 return CLI::EXIT_CODES::ERR_UNKNOWN; // shouldnt have gotten here
128 }
129
130 aStepJob->m_outputFile = fn.GetFullName();
131 }
132
134 {
135
136 double scale = 0.0;
137 switch ( aStepJob->m_vrmlUnits )
138 {
140 case JOB_EXPORT_PCB_3D::VRML_UNITS::METERS: scale = 0.001; break;
141 case JOB_EXPORT_PCB_3D::VRML_UNITS::TENTHS: scale = 10.0 / 25.4; break;
142 case JOB_EXPORT_PCB_3D::VRML_UNITS::INCHES: scale = 1.0 / 25.4; break;
143 }
144
145 EXPORTER_VRML vrmlExporter( brd );
146 wxString messages;
147
148 double originX = pcbIUScale.IUTomm( aStepJob->m_xOrigin );
149 double originY = pcbIUScale.IUTomm( aStepJob->m_yOrigin );
150
151 if( !aStepJob->m_hasUserOrigin )
152 {
153 BOX2I bbox = brd->ComputeBoundingBox( true );
154 originX = pcbIUScale.IUTomm( bbox.GetCenter().x );
155 originY = pcbIUScale.IUTomm( bbox.GetCenter().y );
156 }
157
158 bool success = vrmlExporter.ExportVRML_File(
159 brd->GetProject(), &messages, aStepJob->m_outputFile, scale,
160 !aStepJob->m_vrmlModelDir.IsEmpty(), aStepJob->m_vrmlRelativePaths,
161 aStepJob->m_vrmlModelDir, originX, originY );
162
163 if ( success )
164 {
165 m_reporter->Report( wxString::Format( _( "Successfully exported VRML to %s" ),
166 aStepJob->m_outputFile ),
168 }
169 else
170 {
171 m_reporter->Report( _( "Error exporting VRML" ), RPT_SEVERITY_ERROR );
173 }
174 }
175 else
176 {
178 params.m_exportTracks = aStepJob->m_exportTracks;
179 params.m_exportZones = aStepJob->m_exportZones;
181 params.m_includeDNP = aStepJob->m_includeDNP;
183 params.m_overwrite = aStepJob->m_overwrite;
184 params.m_substModels = aStepJob->m_substModels;
185 params.m_origin = VECTOR2D( aStepJob->m_xOrigin, aStepJob->m_yOrigin );
186 params.m_useDrillOrigin = aStepJob->m_useDrillOrigin;
187 params.m_useGridOrigin = aStepJob->m_useGridOrigin;
188 params.m_boardOnly = aStepJob->m_boardOnly;
189 params.m_optimizeStep = aStepJob->m_optimizeStep;
190
191 switch( aStepJob->m_format )
192 {
195 break;
198 break;
199 default:
200 return CLI::EXIT_CODES::ERR_UNKNOWN; // shouldnt have gotten here
201 }
202
203 EXPORTER_STEP stepExporter( brd, params );
204 stepExporter.m_outputFile = aStepJob->m_outputFile;
205
206 if( !stepExporter.Export() )
208 }
209
210 return CLI::EXIT_CODES::OK;
211}
212
213
215{
216 JOB_EXPORT_PCB_SVG* aSvgJob = dynamic_cast<JOB_EXPORT_PCB_SVG*>( aJob );
217
218 if( aSvgJob == nullptr )
220
221 PCB_PLOT_SVG_OPTIONS svgPlotOptions;
222 svgPlotOptions.m_blackAndWhite = aSvgJob->m_blackAndWhite;
223 svgPlotOptions.m_colorTheme = aSvgJob->m_colorTheme;
224 svgPlotOptions.m_outputFile = aSvgJob->m_outputFile;
225 svgPlotOptions.m_mirror = aSvgJob->m_mirror;
226 svgPlotOptions.m_negative = aSvgJob->m_negative;
227 svgPlotOptions.m_pageSizeMode = aSvgJob->m_pageSizeMode;
228 svgPlotOptions.m_printMaskLayer = aSvgJob->m_printMaskLayer;
229 svgPlotOptions.m_plotFrame = aSvgJob->m_plotDrawingSheet;
230 svgPlotOptions.m_drillShapeOption = aSvgJob->m_drillShapeOption;
231
232 if( aJob->IsCli() )
233 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
234
235 BOARD* brd = LoadBoard( aSvgJob->m_filename, true );
237 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
238
239 if( aJob->IsCli() )
240 {
241 if( EXPORT_SVG::Plot( brd, svgPlotOptions ) )
242 m_reporter->Report( _( "Successfully created svg file" ) + wxS( "\n" ), RPT_SEVERITY_INFO );
243 else
244 m_reporter->Report( _( "Error creating svg file" ) + wxS( "\n" ), RPT_SEVERITY_ERROR );
245 }
246
247 return CLI::EXIT_CODES::OK;
248}
249
250
252{
253 JOB_EXPORT_PCB_DXF* aDxfJob = dynamic_cast<JOB_EXPORT_PCB_DXF*>( aJob );
254
255 if( aDxfJob == nullptr )
257
258 if( aJob->IsCli() )
259 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
260
261 BOARD* brd = LoadBoard( aDxfJob->m_filename, true );
263 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
264
265 if( aDxfJob->m_outputFile.IsEmpty() )
266 {
267 wxFileName fn = brd->GetFileName();
268 fn.SetName( fn.GetName() );
269 fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::DXF ) );
270
271 aDxfJob->m_outputFile = fn.GetFullName();
272 }
273
274 PCB_PLOT_PARAMS plotOpts;
275 plotOpts.SetFormat( PLOT_FORMAT::DXF );
276
278
280 plotOpts.SetDXFPlotUnits( DXF_UNITS::MILLIMETERS );
281 else
282 plotOpts.SetDXFPlotUnits( DXF_UNITS::INCHES );
283
284 plotOpts.SetPlotFrameRef( aDxfJob->m_plotBorderTitleBlocks );
285 plotOpts.SetPlotValue( aDxfJob->m_plotFootprintValues );
286 plotOpts.SetPlotReference( aDxfJob->m_plotRefDes );
287 plotOpts.SetLayerSelection( aDxfJob->m_printMaskLayer );
288
290 brd, &plotOpts, UNDEFINED_LAYER, aDxfJob->m_outputFile, wxEmptyString, wxEmptyString );
291
292 if( plotter )
293 {
294 PlotBoardLayers( brd, plotter, aDxfJob->m_printMaskLayer, plotOpts );
295 plotter->EndPlot();
296 }
297
298 delete plotter;
299
300 return CLI::EXIT_CODES::OK;
301}
302
303
305{
306 JOB_EXPORT_PCB_PDF* aPdfJob = dynamic_cast<JOB_EXPORT_PCB_PDF*>( aJob );
307
308 if( aPdfJob == nullptr )
310
311 if( aJob->IsCli() )
312 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
313
314 BOARD* brd = LoadBoard( aPdfJob->m_filename, true );
316 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
317
318 if( aPdfJob->m_outputFile.IsEmpty() )
319 {
320 wxFileName fn = brd->GetFileName();
321 fn.SetName( fn.GetName() );
322 fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::PDF ) );
323
324 aPdfJob->m_outputFile = fn.GetFullName();
325 }
326
327 PCB_PLOT_PARAMS plotOpts;
328 plotOpts.SetFormat( PLOT_FORMAT::PDF );
329
330 plotOpts.SetPlotFrameRef( aPdfJob->m_plotBorderTitleBlocks );
331 plotOpts.SetPlotValue( aPdfJob->m_plotFootprintValues );
332 plotOpts.SetPlotReference( aPdfJob->m_plotRefDes );
333
334 plotOpts.SetLayerSelection( aPdfJob->m_printMaskLayer );
335
336 SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
337 plotOpts.SetColorSettings( mgr.GetColorSettings( aPdfJob->m_colorTheme ) );
338 plotOpts.SetMirror( aPdfJob->m_mirror );
339 plotOpts.SetBlackAndWhite( aPdfJob->m_blackAndWhite );
340 plotOpts.SetNegative( aPdfJob->m_negative );
341
342 switch( aPdfJob->m_drillShapeOption )
343 {
344 default:
345 case 0: plotOpts.SetDrillMarksType( DRILL_MARKS::NO_DRILL_SHAPE ); break;
346 case 1: plotOpts.SetDrillMarksType( DRILL_MARKS::SMALL_DRILL_SHAPE ); break;
347 case 2: plotOpts.SetDrillMarksType( DRILL_MARKS::FULL_DRILL_SHAPE ); break;
348 }
349
351 brd, &plotOpts, UNDEFINED_LAYER, aPdfJob->m_outputFile, wxEmptyString, wxEmptyString );
352
353 if( plotter )
354 {
355 PlotBoardLayers( brd, plotter, aPdfJob->m_printMaskLayer, plotOpts );
356 PlotInteractiveLayer( brd, plotter, plotOpts );
357 plotter->EndPlot();
358 }
359
360 delete plotter;
361
362 return CLI::EXIT_CODES::OK;
363}
364
365
367{
368 int exitCode = CLI::EXIT_CODES::OK;
369 JOB_EXPORT_PCB_GERBERS* aGerberJob = dynamic_cast<JOB_EXPORT_PCB_GERBERS*>( aJob );
370
371 if( aGerberJob == nullptr )
373
374 if( aJob->IsCli() )
375 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
376
377 BOARD* brd = LoadBoard( aGerberJob->m_filename, true );
378 loadOverrideDrawingSheet( brd, aGerberJob->m_drawingSheet );
379
380 PCB_PLOT_PARAMS boardPlotOptions = brd->GetPlotOptions();
381 LSET plotOnAllLayersSelection = boardPlotOptions.GetPlotOnAllLayersSelection();
382 GERBER_JOBFILE_WRITER jobfile_writer( brd );
383
384 wxString fileExt;
385
386 if( aGerberJob->m_useBoardPlotParams )
387 {
388 // The board plot options are saved with all copper layers enabled, even those that don't
389 // exist in the current stackup. This is done so the layers are automatically enabled in the plot
390 // dialog when the user enables them. We need to filter out these not-enabled layers here so
391 // we don't plot 32 layers when we only have 4, etc.
392 LSET plotLayers = ( boardPlotOptions.GetLayerSelection() & LSET::AllNonCuMask() )
393 | ( brd->GetEnabledLayers() & LSET::AllCuMask() );
394 aGerberJob->m_printMaskLayer = plotLayers.SeqStackupForPlotting();
395 aGerberJob->m_layersIncludeOnAll = boardPlotOptions.GetPlotOnAllLayersSelection();
396 }
397 else
398 {
399 // default to the board enabled layers
400 if( aGerberJob->m_printMaskLayer == 0 )
402
403 if( aGerberJob->m_layersIncludeOnAllSet )
404 aGerberJob->m_layersIncludeOnAll = plotOnAllLayersSelection;
405 }
406
407 for( LSEQ seq = LSET( aGerberJob->m_printMaskLayer ).UIOrder(); seq; ++seq )
408 {
409 LSEQ plotSequence;
410
411 // Base layer always gets plotted first.
412 plotSequence.push_back( *seq );
413
414 // Now all the "include on all" layers
415 for( LSEQ seqAll = aGerberJob->m_layersIncludeOnAll.UIOrder(); seqAll; ++seqAll )
416 {
417 // Don't plot the same layer more than once;
418 if( find( plotSequence.begin(), plotSequence.end(), *seqAll ) != plotSequence.end() )
419 continue;
420
421 plotSequence.push_back( *seqAll );
422 }
423
424 // Pick the basename from the board file
425 wxFileName fn( brd->GetFileName() );
426 PCB_LAYER_ID layer = *seq;
427 PCB_PLOT_PARAMS plotOpts;
428
429 if( aGerberJob->m_useBoardPlotParams )
430 plotOpts = boardPlotOptions;
431 else
432 populateGerberPlotOptionsFromJob( plotOpts, aGerberJob );
433
434 if( plotOpts.GetUseGerberProtelExtensions() )
435 fileExt = GetGerberProtelExtension( layer );
436 else
438
439 BuildPlotFileName( &fn, aGerberJob->m_outputFile, brd->GetLayerName( layer ), fileExt );
440 wxString fullname = fn.GetFullName();
441
442 jobfile_writer.AddGbrFile( layer, fullname );
443
444 // We are feeding it one layer at the start here to silence a logic check
446 brd, &plotOpts, layer, fn.GetFullPath(), wxEmptyString, wxEmptyString );
447
448 if( plotter )
449 {
450 m_reporter->Report( wxString::Format( _( "Plotted to '%s'.\n" ), fn.GetFullPath() ),
452 PlotBoardLayers( brd, plotter, plotSequence, plotOpts );
453 plotter->EndPlot();
454 }
455 else
456 {
457 m_reporter->Report( wxString::Format( _( "Failed to plot to '%s'.\n" ),
458 fn.GetFullPath() ),
461 }
462
463 delete plotter;
464 }
465
466 wxFileName fn( aGerberJob->m_filename );
467
468 // Build gerber job file from basename
469 BuildPlotFileName( &fn, aGerberJob->m_outputFile, wxT( "job" ),
471 jobfile_writer.CreateJobFile( fn.GetFullPath() );
472
473 return exitCode;
474}
475
476
479{
480 aPlotOpts.SetFormat( PLOT_FORMAT::GERBER );
481
482 aPlotOpts.SetPlotFrameRef( aJob->m_plotBorderTitleBlocks );
483 aPlotOpts.SetPlotValue( aJob->m_plotFootprintValues );
484 aPlotOpts.SetPlotReference( aJob->m_plotRefDes );
485
487
488 // Always disable plot pad holes
489 aPlotOpts.SetDrillMarksType( DRILL_MARKS::NO_DRILL_SHAPE );
490
492 aPlotOpts.SetUseGerberX2format( aJob->m_useX2Format );
494 aPlotOpts.SetUseAuxOrigin( aJob->m_useAuxOrigin );
496 aPlotOpts.SetGerberPrecision( aJob->m_precision );
497}
498
499
501{
502 int exitCode = CLI::EXIT_CODES::OK;
503 JOB_EXPORT_PCB_GERBER* aGerberJob = dynamic_cast<JOB_EXPORT_PCB_GERBER*>( aJob );
504
505 if( aGerberJob == nullptr )
507
508 if( aJob->IsCli() )
509 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
510
511 BOARD* brd = LoadBoard( aGerberJob->m_filename, true );
512 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
513
514 if( aGerberJob->m_outputFile.IsEmpty() )
515 {
516 wxFileName fn = brd->GetFileName();
517 fn.SetName( fn.GetName() );
518 fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::GERBER ) );
519
520 aGerberJob->m_outputFile = fn.GetFullName();
521 }
522
523 PCB_PLOT_PARAMS plotOpts;
524 populateGerberPlotOptionsFromJob( plotOpts, aGerberJob );
525 plotOpts.SetLayerSelection( aGerberJob->m_printMaskLayer );
526
527 // We are feeding it one layer at the start here to silence a logic check
529 brd, &plotOpts, aGerberJob->m_printMaskLayer.front(), aGerberJob->m_outputFile,
530 wxEmptyString, wxEmptyString );
531
532 if( plotter )
533 {
534 PlotBoardLayers( brd, plotter, aGerberJob->m_printMaskLayer, plotOpts );
535 plotter->EndPlot();
536 }
537 else
538 {
539 m_reporter->Report( wxString::Format( _( "Failed to plot to '%s'.\n" ),
540 aGerberJob->m_outputFile ),
543 }
544
545 delete plotter;
546
547 return exitCode;
548}
549
552
553
555{
556 JOB_EXPORT_PCB_DRILL* aDrillJob = dynamic_cast<JOB_EXPORT_PCB_DRILL*>( aJob );
557
558 if( aDrillJob == nullptr )
560
561 if( aJob->IsCli() )
562 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
563
564 BOARD* brd = LoadBoard( aDrillJob->m_filename, true );
565
566 // ensure output dir exists
567 wxFileName fn( aDrillJob->m_outputDir + wxT( "/" ) );
568
569 if( !fn.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
570 {
571 m_reporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
573 }
574
575 std::unique_ptr<GENDRILL_WRITER_BASE> drillWriter;
576
578 drillWriter = std::make_unique<EXCELLON_WRITER>( brd );
579 else
580 drillWriter = std::make_unique<GERBER_WRITER>( brd );
581
582 VECTOR2I offset;
583
585 offset = VECTOR2I( 0, 0 );
586 else
587 offset = brd->GetDesignSettings().GetAuxOrigin();
588
589 PLOT_FORMAT mapFormat = PLOT_FORMAT::PDF;
590
591 switch( aDrillJob->m_mapFormat )
592 {
593 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::POSTSCRIPT: mapFormat = PLOT_FORMAT::POST; break;
594 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::GERBER_X2: mapFormat = PLOT_FORMAT::GERBER; break;
595 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::DXF: mapFormat = PLOT_FORMAT::DXF; break;
596 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::SVG: mapFormat = PLOT_FORMAT::SVG; break;
597 default:
598 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::PDF: mapFormat = PLOT_FORMAT::PDF; break;
599 }
600
602 {
604 switch( aDrillJob->m_zeroFormat )
605 {
608 break;
611 break;
614 break;
616 default:
618 break;
619 }
620
621 DRILL_PRECISION precision;
622
624 precision = precisionListForInches;
625 else
626 precision = precisionListForMetric;
627
628 EXCELLON_WRITER* excellonWriter = dynamic_cast<EXCELLON_WRITER*>( drillWriter.get() );
629
630 if( excellonWriter == nullptr )
632
633 excellonWriter->SetFormat( aDrillJob->m_drillUnits
635 zeroFmt, precision.m_Lhs, precision.m_Rhs );
636 excellonWriter->SetOptions( aDrillJob->m_excellonMirrorY,
637 aDrillJob->m_excellonMinimalHeader,
638 offset, aDrillJob->m_excellonCombinePTHNPTH );
639 excellonWriter->SetRouteModeForOvalHoles( aDrillJob->m_excellonOvalDrillRoute );
640 excellonWriter->SetMapFileFormat( mapFormat );
641
642 if( !excellonWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true,
643 aDrillJob->m_generateMap, m_reporter ) )
644 {
646 }
647 }
649 {
650 GERBER_WRITER* gerberWriter = dynamic_cast<GERBER_WRITER*>( drillWriter.get() );
651
652 if( gerberWriter == nullptr )
654
655 // Set gerber precision: only 5 or 6 digits for mantissa are allowed
656 // (SetFormat() accept 5 or 6, and any other value set the precision to 5)
657 // the integer part precision is always 4, and units always mm
658 gerberWriter->SetFormat( aDrillJob->m_gerberPrecision );
659 gerberWriter->SetOptions( offset );
660 gerberWriter->SetMapFileFormat( mapFormat );
661
662 if( !gerberWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true,
663 aDrillJob->m_generateMap, m_reporter ) )
664 {
666 }
667 }
668
669 return CLI::EXIT_CODES::OK;
670}
671
672
674{
675 JOB_EXPORT_PCB_POS* aPosJob = dynamic_cast<JOB_EXPORT_PCB_POS*>( aJob );
676
677 if( aPosJob == nullptr )
679
680 if( aJob->IsCli() )
681 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
682
683 BOARD* brd = LoadBoard( aPosJob->m_filename, true );
684
685 if( aPosJob->m_outputFile.IsEmpty() )
686 {
687 wxFileName fn = brd->GetFileName();
688 fn.SetName( fn.GetName() );
689
692 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::CSV )
693 fn.SetExt( FILEEXT::CsvFileExtension );
694 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::GERBER )
695 fn.SetExt( FILEEXT::GerberFileExtension );
696
697 aPosJob->m_outputFile = fn.GetFullName();
698 }
699
702 {
703 FILE* file = nullptr;
704 file = wxFopen( aPosJob->m_outputFile, wxS( "wt" ) );
705
706 if( file == nullptr )
708
709 std::string data;
710
711 bool frontSide = aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::FRONT
713
714 bool backSide = aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::BACK
716
717 PLACE_FILE_EXPORTER exporter( brd,
719 aPosJob->m_smdOnly, aPosJob->m_excludeFootprintsWithTh,
720 aPosJob->m_excludeDNP,
721 frontSide, backSide,
724 aPosJob->m_negateBottomX );
725 data = exporter.GenPositionData();
726
727 fputs( data.c_str(), file );
728 fclose( file );
729 }
730 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::GERBER )
731 {
732 PLACEFILE_GERBER_WRITER exporter( brd );
733
734 PCB_LAYER_ID gbrLayer = F_Cu;
735
736 if( aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::BACK )
737 gbrLayer = B_Cu;
738
739 exporter.CreatePlaceFile( aPosJob->m_outputFile, gbrLayer, aPosJob->m_gerberBoardEdge );
740 }
741
742 return CLI::EXIT_CODES::OK;
743}
744
745extern FOOTPRINT* try_load_footprint( const wxFileName& aFileName, PCB_IO_MGR::PCB_FILE_T aFileType,
746 const wxString& aName );
747
748
750{
751 JOB_FP_UPGRADE* upgradeJob = dynamic_cast<JOB_FP_UPGRADE*>( aJob );
752
753 if( upgradeJob == nullptr )
755
756 if( aJob->IsCli() )
757 m_reporter->Report( _( "Loading footprint library\n" ), RPT_SEVERITY_INFO );
758
759 if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
760 {
761 if( wxFile::Exists( upgradeJob->m_outputLibraryPath ) ||
762 wxDir::Exists( upgradeJob->m_outputLibraryPath) )
763 {
764 m_reporter->Report( _( "Output path must not conflict with existing path\n" ),
767 }
768 }
769
771 FP_CACHE fpLib( &pcb_io, upgradeJob->m_libraryPath );
772
773 try
774 {
775 fpLib.Load();
776 }
777 catch(...)
778 {
779 m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
781 }
782
783 bool shouldSave = upgradeJob->m_force;
784
785 for( const auto& footprint : fpLib.GetFootprints() )
786 {
787 if( footprint.second->GetFootprint()->GetFileFormatVersionAtLoad() < SEXPR_BOARD_FILE_VERSION )
788 {
789 shouldSave = true;
790 }
791 }
792
793 if( shouldSave )
794 {
795 m_reporter->Report( _( "Saving footprint library\n" ), RPT_SEVERITY_INFO );
796
797 try
798 {
799 if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
800 {
801 fpLib.SetPath( upgradeJob->m_outputLibraryPath );
802 }
803
804 fpLib.Save();
805 }
806 catch( ... )
807 {
808 m_reporter->Report( _( "Unable to save library\n" ), RPT_SEVERITY_ERROR );
810 }
811 }
812 else
813 {
814 m_reporter->Report( _( "Footprint library was not updated\n" ), RPT_SEVERITY_INFO );
815 }
816
817 return CLI::EXIT_CODES::OK;
818}
819
820
822{
823 JOB_FP_EXPORT_SVG* svgJob = dynamic_cast<JOB_FP_EXPORT_SVG*>( aJob );
824
825 if( svgJob == nullptr )
827
828 if( aJob->IsCli() )
829 m_reporter->Report( _( "Loading footprint library\n" ), RPT_SEVERITY_INFO );
830
832 FP_CACHE fpLib( &pcb_io, svgJob->m_libraryPath );
833
834 try
835 {
836 fpLib.Load();
837 }
838 catch( ... )
839 {
840 m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
842 }
843
844 if( !svgJob->m_outputDirectory.IsEmpty() && !wxDir::Exists( svgJob->m_outputDirectory ) )
845 {
846 wxFileName::Mkdir( svgJob->m_outputDirectory );
847 }
848
849 int exitCode = CLI::EXIT_CODES::OK;
850
851 // Just plot all the symbols we can
852 FP_CACHE_FOOTPRINT_MAP& footprintMap = fpLib.GetFootprints();
853
854 bool singleFpPlotted = false;
855 for( FP_CACHE_FOOTPRINT_MAP::iterator it = footprintMap.begin(); it != footprintMap.end();
856 ++it )
857 {
858 const FOOTPRINT* fp = it->second->GetFootprint();
859 if( !svgJob->m_footprint.IsEmpty() )
860 {
861 if( fp->GetFPID().GetLibItemName().wx_str() != svgJob->m_footprint )
862 {
863 // skip until we find the right footprint
864 continue;
865 }
866 else
867 {
868 singleFpPlotted = true;
869 }
870 }
871
872 exitCode = doFpExportSvg( svgJob, fp );
873 if( exitCode != CLI::EXIT_CODES::OK )
874 break;
875 }
876
877 if( !svgJob->m_footprint.IsEmpty() && !singleFpPlotted )
878 {
879 m_reporter->Report( _( "The given footprint could not be found to export." ) + wxS( "\n" ),
881 }
882
883 return CLI::EXIT_CODES::OK;
884}
885
886
888{
889 // the hack for now is we create fake boards containing the footprint and plot the board
890 // until we refactor better plot api later
891 std::unique_ptr<BOARD> brd;
892 brd.reset( CreateEmptyBoard() );
893 brd->GetProject()->ApplyTextVars( aSvgJob->GetVarOverrides() );
894
895 FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( aFootprint->Clone() );
896
897 if( fp == nullptr )
899
900 fp->SetLink( niluuid );
901 fp->SetFlags( IS_NEW );
902 fp->SetParent( brd.get() );
903
904 for( PAD* pad : fp->Pads() )
905 {
906 pad->SetLocalRatsnestVisible( false );
907 pad->SetNetCode( 0 );
908 }
909
910 fp->SetOrientation( ANGLE_0 );
911 fp->SetPosition( VECTOR2I( 0, 0 ) );
912
913 brd->Add( fp, ADD_MODE::INSERT, true );
914
915 wxFileName outputFile;
916 outputFile.SetPath( aSvgJob->m_outputDirectory );
917 outputFile.SetName( aFootprint->GetFPID().GetLibItemName().wx_str() );
918 outputFile.SetExt( FILEEXT::SVGFileExtension );
919
920 m_reporter->Report( wxString::Format( _( "Plotting footprint '%s' to '%s'\n" ),
921 aFootprint->GetFPID().GetLibItemName().wx_str(),
922 outputFile.GetFullPath() ),
924
925
926 PCB_PLOT_SVG_OPTIONS svgPlotOptions;
927 svgPlotOptions.m_blackAndWhite = aSvgJob->m_blackAndWhite;
928 svgPlotOptions.m_colorTheme = aSvgJob->m_colorTheme;
929 svgPlotOptions.m_outputFile = outputFile.GetFullPath();
930 svgPlotOptions.m_mirror = false;
931 svgPlotOptions.m_pageSizeMode = 2; // board bounding box
932 svgPlotOptions.m_printMaskLayer = aSvgJob->m_printMaskLayer;
933 svgPlotOptions.m_plotFrame = false;
934
935 if( !EXPORT_SVG::Plot( brd.get(), svgPlotOptions ) )
936 m_reporter->Report( _( "Error creating svg file" ) + wxS( "\n" ), RPT_SEVERITY_ERROR );
937
938
939 return CLI::EXIT_CODES::OK;
940}
941
942
944{
945 JOB_PCB_DRC* drcJob = dynamic_cast<JOB_PCB_DRC*>( aJob );
946
947 if( drcJob == nullptr )
949
950 if( aJob->IsCli() )
951 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
952
953 BOARD* brd = LoadBoard( drcJob->m_filename, true );
954 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
955
956 if( drcJob->m_outputFile.IsEmpty() )
957 {
958 wxFileName fn = brd->GetFileName();
959 fn.SetName( fn.GetName() );
960
962 fn.SetExt( FILEEXT::JsonFileExtension );
963 else
964 fn.SetExt( FILEEXT::ReportFileExtension );
965
966 drcJob->m_outputFile = fn.GetFullName();
967 }
968
969 EDA_UNITS units;
970
971 switch( drcJob->m_units )
972 {
973 case JOB_PCB_DRC::UNITS::INCHES: units = EDA_UNITS::INCHES; break;
974 case JOB_PCB_DRC::UNITS::MILS: units = EDA_UNITS::MILS; break;
975 case JOB_PCB_DRC::UNITS::MILLIMETERS: units = EDA_UNITS::MILLIMETRES; break;
976 default: units = EDA_UNITS::MILLIMETRES; break;
977 }
978
979 std::shared_ptr<DRC_ENGINE> drcEngine = brd->GetDesignSettings().m_DRCEngine;
980 std::unique_ptr<NETLIST> netlist = std::make_unique<NETLIST>();
981
982 drcEngine->SetDrawingSheet( getDrawingSheetProxyView( brd ) );
983
984 // BOARD_COMMIT uses TOOL_MANAGER to grab the board internally so we must give it one
985 TOOL_MANAGER* toolManager = new TOOL_MANAGER;
986 toolManager->SetEnvironment( brd, nullptr, nullptr, Kiface().KifaceSettings(), nullptr );
987
988 BOARD_COMMIT commit( toolManager );
989
990 m_reporter->Report( _( "Running DRC...\n" ), RPT_SEVERITY_INFO );
991
992 if( drcJob->m_parity )
993 {
994 typedef bool (*NETLIST_FN_PTR)( const wxString&, std::string& );
995
997 wxFileName schematicPath( drcJob->m_filename );
998 NETLIST_FN_PTR netlister = (NETLIST_FN_PTR) eeschema->IfaceOrAddress( KIFACE_NETLIST_SCHEMATIC );
999 std::string netlist_str;
1000
1001 schematicPath.SetExt( FILEEXT::KiCadSchematicFileExtension );
1002
1003 if( !schematicPath.Exists() )
1004 schematicPath.SetExt( FILEEXT::LegacySchematicFileExtension );
1005
1006 if( !schematicPath.Exists() )
1007 {
1008 m_reporter->Report( _( "Failed to find schematic for parity tests.\n" ),
1010 }
1011 else
1012 {
1013 (*netlister)( schematicPath.GetFullPath(), netlist_str );
1014
1015 try
1016 {
1017 auto lineReader = new STRING_LINE_READER( netlist_str, _( "Eeschema netlist" ) );
1018 KICAD_NETLIST_READER netlistReader( lineReader, netlist.get() );
1019 netlistReader.LoadNetlist();
1020 }
1021 catch( const IO_ERROR& e )
1022 {
1023 m_reporter->Report( _( "Failed to fetch schematic netlist for parity tests.\n" ),
1025 }
1026
1027 drcEngine->SetSchematicNetlist( netlist.get() );
1028 }
1029 }
1030
1031 drcEngine->SetProgressReporter( nullptr );
1032 drcEngine->SetViolationHandler(
1033 [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
1034 {
1035 PCB_MARKER* marker = new PCB_MARKER( aItem, aPos, aLayer );
1036 commit.Add( marker );
1037 } );
1038
1039 brd->RecordDRCExclusions();
1040 brd->DeleteMARKERs( true, true );
1041 drcEngine->RunTests( units, drcJob->m_reportAllTrackErrors, drcJob->m_parity );
1042 drcEngine->ClearViolationHandler();
1043
1044 commit.Push( _( "DRC" ), SKIP_UNDO | SKIP_SET_DIRTY );
1045
1046 // now "resolve" the drc exclusions again because its the only way to set exclusion status on
1047 // a marker
1048 for( PCB_MARKER* marker : brd->ResolveDRCExclusions( false ) )
1049 brd->Add( marker );
1050
1051 std::shared_ptr<DRC_ITEMS_PROVIDER> markersProvider = std::make_shared<DRC_ITEMS_PROVIDER>(
1053
1054 std::shared_ptr<DRC_ITEMS_PROVIDER> ratsnestProvider =
1055 std::make_shared<DRC_ITEMS_PROVIDER>( brd, MARKER_BASE::MARKER_RATSNEST );
1056
1057 std::shared_ptr<DRC_ITEMS_PROVIDER> fpWarningsProvider =
1058 std::make_shared<DRC_ITEMS_PROVIDER>( brd, MARKER_BASE::MARKER_PARITY );
1059
1060 markersProvider->SetSeverities( drcJob->m_severity );
1061 ratsnestProvider->SetSeverities( drcJob->m_severity );
1062 fpWarningsProvider->SetSeverities( drcJob->m_severity );
1063
1064 m_reporter->Report( wxString::Format( _( "Found %d violations\n" ),
1065 markersProvider->GetCount() ),
1067 m_reporter->Report( wxString::Format( _( "Found %d unconnected items\n" ),
1068 ratsnestProvider->GetCount() ),
1070
1071 if( drcJob->m_parity )
1072 {
1073 m_reporter->Report( wxString::Format( _( "Found %d schematic parity issues\n" ),
1074 fpWarningsProvider->GetCount() ),
1076 }
1077
1078 DRC_REPORT reportWriter( brd, units, markersProvider, ratsnestProvider, fpWarningsProvider );
1079
1080 bool wroteReport = false;
1081
1083 wroteReport = reportWriter.WriteJsonReport( drcJob->m_outputFile );
1084 else
1085 wroteReport = reportWriter.WriteTextReport( drcJob->m_outputFile );
1086
1087 if( !wroteReport )
1088 {
1089 m_reporter->Report( wxString::Format( _( "Unable to save DRC report to %s\n" ),
1090 drcJob->m_outputFile ),
1093 }
1094
1095 m_reporter->Report( wxString::Format( _( "Saved DRC Report to %s\n" ),
1096 drcJob->m_outputFile ),
1098
1099 if( drcJob->m_exitCodeViolations )
1100 {
1101 if( markersProvider->GetCount() > 0 || ratsnestProvider->GetCount() > 0
1102 || fpWarningsProvider->GetCount() > 0 )
1103 {
1105 }
1106 }
1107
1109}
1110
1111
1113{
1114 JOB_EXPORT_PCB_IPC2581* job = dynamic_cast<JOB_EXPORT_PCB_IPC2581*>( aJob );
1115
1116 if( job == nullptr )
1118
1119 if( job->IsCli() )
1120 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
1121
1122 BOARD* brd = LoadBoard( job->m_filename, true );
1123
1124 if( job->m_outputFile.IsEmpty() )
1125 {
1126 wxFileName fn = brd->GetFileName();
1127 fn.SetName( fn.GetName() );
1128 fn.SetExt( FILEEXT::Ipc2581FileExtension );
1129
1130 job->m_outputFile = fn.GetFullName();
1131 }
1132
1133 STRING_UTF8_MAP props;
1134 props["units"] = job->m_units == JOB_EXPORT_PCB_IPC2581::IPC2581_UNITS::MILLIMETERS ? "mm"
1135 : "inch";
1136 props["sigfig"] = wxString::Format( "%d", job->m_units );
1137 props["version"] = job->m_version == JOB_EXPORT_PCB_IPC2581::IPC2581_VERSION::C ? "C" : "B";
1138 props["OEMRef"] = job->m_colInternalId;
1139 props["mpn"] = job->m_colMfgPn;
1140 props["mfg"] = job->m_colMfg;
1141 props["dist"] = job->m_colDist;
1142 props["distpn"] = job->m_colDistPn;
1143
1144 wxString tempFile = wxFileName::CreateTempFileName( wxS( "pcbnew_ipc" ) );
1145 try
1146 {
1148 pi->SetProgressReporter( m_progressReporter );
1149 pi->SaveBoard( tempFile, brd, &props );
1150 }
1151 catch( const IO_ERROR& ioe )
1152 {
1153 m_reporter->Report( wxString::Format( _( "Error generating IPC2581 file '%s'.\n%s" ),
1154 job->m_filename, ioe.What() ),
1156
1157 wxRemoveFile( tempFile );
1158
1160 }
1161
1162 if( job->m_compress )
1163 {
1164 wxFileName tempfn = job->m_outputFile;
1165 tempfn.SetExt( FILEEXT::Ipc2581FileExtension );
1166 wxFileName zipfn = tempFile;
1167 zipfn.SetExt( "zip" );
1168
1169 wxFFileOutputStream fnout( zipfn.GetFullPath() );
1170 wxZipOutputStream zip( fnout );
1171 wxFFileInputStream fnin( tempFile );
1172
1173 zip.PutNextEntry( tempfn.GetFullName() );
1174 fnin.Read( zip );
1175 zip.Close();
1176 fnout.Close();
1177
1178 wxRemoveFile( tempFile );
1179 tempFile = zipfn.GetFullPath();
1180 }
1181
1182 // If save succeeded, replace the original with what we just wrote
1183 if( !wxRenameFile( tempFile, job->m_outputFile ) )
1184 {
1185 m_reporter->Report( wxString::Format( _( "Error generating IPC2581 file '%s'.\n"
1186 "Failed to rename temporary file '%s." )
1187 + wxS( "\n" ),
1188 job->m_outputFile, tempFile ),
1190 }
1191
1193}
1194
1195
1197{
1199 &aBrd->GetPageSettings(),
1200 aBrd->GetProject(),
1201 &aBrd->GetTitleBlock(),
1202 &aBrd->GetProperties() );
1203
1204 drawingSheet->SetSheetName( std::string() );
1205 drawingSheet->SetSheetPath( std::string() );
1206 drawingSheet->SetIsFirstPage( true );
1207
1208 drawingSheet->SetFileName( TO_UTF8( aBrd->GetFileName() ) );
1209
1210 return drawingSheet;
1211}
1212
1213
1214void PCBNEW_JOBS_HANDLER::loadOverrideDrawingSheet( BOARD* aBrd, const wxString& aSheetPath )
1215{
1216 // dont bother attempting to load a empty path, if there was one
1217 if( aSheetPath.IsEmpty() )
1218 return;
1219
1220 auto loadSheet =
1221 [&]( const wxString& path ) -> bool
1222 {
1225 aBrd->GetProject()->GetProjectPath() );
1226
1227 if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( filename ) )
1228 {
1229 m_reporter->Report( wxString::Format( _( "Error loading drawing sheet '%s'." ) + wxS( "\n" ),
1230 path ),
1232 return false;
1233 }
1234
1235 return true;
1236 };
1237
1238 if( loadSheet( aSheetPath ) )
1239 return;
1240
1241 // failed loading custom path, revert back to default
1242 loadSheet( aBrd->GetProject()->GetProjectFile().m_BoardDrawingSheetFile );
1243}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
static wxString m_DrawingSheetFileName
the name of the drawing sheet file, or empty to use the default drawing sheet
Definition: base_screen.h:85
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
std::shared_ptr< DRC_ENGINE > m_DRCEngine
const VECTOR2I & GetAuxOrigin()
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:276
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:652
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition: board.cpp:850
const PAGE_INFO & GetPageSettings() const
Definition: board.h:650
void RecordDRCExclusions()
Scan existing markers and record data from any that are Excluded.
Definition: board.cpp:2738
TITLE_BLOCK & GetTitleBlock()
Definition: board.h:656
BOX2I ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Calculate the bounding box containing all board items (or board edge segments).
Definition: board.cpp:1380
const std::map< wxString, wxString > & GetProperties() const
Definition: board.h:348
const wxString & GetFileName() const
Definition: board.h:313
std::vector< PCB_MARKER * > ResolveDRCExclusions(bool aCreateMarkers)
Rebuild DRC markers from the serialized data in BOARD_DESIGN_SETTINGS.
Definition: board.cpp:322
const PCB_PLOT_PARAMS & GetPlotOptions() const
Definition: board.h:653
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:539
PROJECT * GetProject() const
Definition: board.h:457
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:769
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition: board.cpp:1080
const Vec GetCenter() const
Definition: box2.h:196
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
Definition: commit.h:80
bool WriteJsonReport(const wxString &aFullFileName)
Definition: drc_report.cpp:114
bool WriteTextReport(const wxString &aFullFileName)
Definition: drc_report.cpp:47
Helper to handle drill precision format in excellon files.
static DS_DATA_MODEL & GetTheInstance()
static function: returns the instance of DS_DATA_MODEL used in the application
static const wxString ResolvePath(const wxString &aPath, const wxString &aProjectPath)
Resolve a path which might be project-relative or contain env variable references.
void SetSheetPath(const std::string &aSheetPath)
Set the sheet path displayed in the title block.
void SetSheetName(const std::string &aSheetName)
Set the sheet name displayed in the title block.
void SetIsFirstPage(bool aIsFirstPage)
Change if this is first page.
void SetFileName(const std::string &aFileName)
Set the file name displayed in the title block.
virtual bool EndPlot() override
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:123
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.
bool CreateDrillandMapFilesSet(const wxString &aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER *aReporter=nullptr)
Create the full set of Excellon drill file for the board.
void SetOptions(bool aMirror, bool aMinimalHeader, const VECTOR2I &aOffset, bool aMerge_PTH_NPTH)
Initialize internal parameters to match drill options.
void SetRouteModeForOvalHoles(bool aUseRouteModeForOvalHoles)
double m_BoardOutlinesChainingEpsilon
Definition: exporter_step.h:79
wxString m_outputFile
Definition: exporter_step.h:98
Wrapper to expose an API for writing VRML files, without exposing all the many structures used in the...
Definition: export_vrml.h:33
bool ExportVRML_File(PROJECT *aProject, wxString *aMessages, const wxString &aFullFileName, double aMMtoWRMLunit, bool aExport3DFiles, bool aUseRelativePaths, const wxString &a3D_Subdir, double aXRef, double aYRef)
Exports the board and its footprint shapes 3D (vrml files only) as a vrml file.
static bool Plot(BOARD *aBoard, const PCB_PLOT_SVG_OPTIONS &aSvgPlotOptions)
Definition: export_svg.cpp:30
void SetPosition(const VECTOR2I &aPos) override
Definition: footprint.cpp:2047
void SetLink(const KIID &aLink)
Definition: footprint.h:823
void SetOrientation(const EDA_ANGLE &aNewAngle)
Definition: footprint.cpp:2119
EDA_ITEM * Clone() const override
Invoke a function on all children.
Definition: footprint.cpp:1734
PADS & Pads()
Definition: footprint.h:188
const LIB_ID & GetFPID() const
Definition: footprint.h:230
FP_CACHE_FOOTPRINT_MAP & GetFootprints()
void Save(FOOTPRINT *aFootprint=nullptr)
Save the footprint cache or a single footprint from it to disk.
void SetPath(const wxString &aPath)
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.
bool 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.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
PROGRESS_REPORTER * m_progressReporter
void Register(const std::string &aJobTypeName, std::function< int(JOB *job)> aHandler)
REPORTER * m_reporter
double m_BoardOutlinesChainingEpsilon
JOB_EXPORT_PCB_3D::FORMAT m_format
wxString m_libraryPath
wxString m_outputLibraryPath
OUTPUT_FORMAT m_format
Definition: job_pcb_drc.h:57
UNITS m_units
Definition: job_pcb_drc.h:47
bool m_parity
Definition: job_pcb_drc.h:60
wxString m_filename
Definition: job_pcb_drc.h:35
int m_severity
Definition: job_pcb_drc.h:49
bool m_reportAllTrackErrors
Definition: job_pcb_drc.h:38
wxString m_outputFile
Definition: job_pcb_drc.h:36
bool m_exitCodeViolations
Definition: job_pcb_drc.h:59
An simple container class that lets us dispatch output jobs to kifaces.
Definition: job.h:32
bool IsCli() const
Definition: job.h:39
const std::map< wxString, wxString > & GetVarOverrides() const
Definition: job.h:41
Read the new s-expression based KiCad netlist format.
virtual void LoadNetlist() override
Load the contents of the netlist file into aNetlist.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:279
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition: kiway.cpp:202
@ FACE_SCH
eeschema DSO
Definition: kiway.h:286
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:519
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:573
LSEQ UIOrder() const
Definition: lset.cpp:1012
LSEQ SeqStackupForPlotting() const
Return the sequence that is typical for a bottom-to-top stack-up.
Definition: lset.cpp:563
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
Definition: lset.cpp:884
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:863
@ MARKER_DRAWING_SHEET
Definition: marker_base.h:56
Definition: pad.h:59
void populateGerberPlotOptionsFromJob(PCB_PLOT_PARAMS &aPlotOpts, JOB_EXPORT_PCB_GERBER *aJob)
int JobExportFpUpgrade(JOB *aJob)
int JobExportGerber(JOB *aJob)
DS_PROXY_VIEW_ITEM * getDrawingSheetProxyView(BOARD *aBrd)
void loadOverrideDrawingSheet(BOARD *brd, const wxString &aSheetPath)
PCBNEW_JOBS_HANDLER(KIWAY *aKiway)
int JobExportGerbers(JOB *aJob)
int doFpExportSvg(JOB_FP_EXPORT_SVG *aSvgJob, const FOOTPRINT *aFootprint)
A #PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
static PCB_IO * PluginFind(PCB_FILE_T aFileType)
Return a #PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: pcb_io_mgr.cpp:65
PCB_FILE_T
The set of file types that the PCB_IO_MGR knows about, and for which there has been a plugin written,...
Definition: pcb_io_mgr.h:56
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 SetMirror(bool aFlag)
void SetBlackAndWhite(bool blackAndWhite)
void SetGerberPrecision(int aPrecision)
void SetSubtractMaskFromSilk(bool aSubtract)
void SetPlotValue(bool aFlag)
void SetUseGerberProtelExtensions(bool aUse)
void SetDXFPlotUnits(DXF_UNITS aUnit)
void SetColorSettings(COLOR_SETTINGS *aSettings)
void SetIncludeGerberNetlistInfo(bool aUse)
void SetNegative(bool aFlag)
void SetUseAuxOrigin(bool aAux)
bool GetUseGerberProtelExtensions() const
void SetFormat(PLOT_FORMAT aFormat)
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 m_BoardDrawingSheetFile
PcbNew params.
Definition: project_file.h:154
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:135
virtual void ApplyTextVars(const std::map< wxString, wxString > &aVarsMap)
Applies the given var map, it will create or update existing vars.
Definition: project.cpp:90
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:166
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
COLOR_SETTINGS * GetColorSettings(const wxString &aName="user")
Retrieves a color settings object that applications can read colors from.
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition: richio.h:253
A name/value tuple with unique names and optional values.
Master controller class:
Definition: tool_manager.h:57
void SetEnvironment(EDA_ITEM *aModel, KIGFX::VIEW *aView, KIGFX::VIEW_CONTROLS *aViewControls, APP_SETTINGS_BASE *aSettings, TOOLS_HOLDER *aFrame)
Set the work environment (model, view, view controls and the parent window).
wxString wx_str() const
Definition: utf8.cpp:45
wxString GetDefaultPlotExtension(PLOT_FORMAT aFormat)
Returns the default plot extension for a format.
static DRILL_PRECISION precisionListForInches(2, 4)
static DRILL_PRECISION precisionListForMetric(3, 3)
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition: eda_angle.h:435
#define IS_NEW
New item, just created.
EDA_UNITS
Definition: eda_units.h:46
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.
static const std::string LegacySchematicFileExtension
static const std::string GerberJobFileExtension
static const std::string GerberFileExtension
static const std::string ReportFileExtension
static const std::string GltfBinaryFileExtension
static const std::string FootprintPlaceFileExtension
static const std::string JsonFileExtension
static const std::string KiCadSchematicFileExtension
static const std::string CsvFileExtension
static const std::string Ipc2581FileExtension
static const std::string StepFileExtension
static const std::string SVGFileExtension
static const std::string VrmlFileExtension
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition: io_mgr.h:33
@ KIFACE_NETLIST_SCHEMATIC
Definition: kiface_ids.h:56
KIID niluuid(0)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ B_Cu
Definition: layer_ids.h:96
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
@ F_Cu
Definition: layer_ids.h:65
This file contains miscellaneous commonly used macros and functions.
static const int OK
Definition: exit_codes.h:30
static const int ERR_RC_VIOLATIONS
Definition: exit_codes.h:36
static const int SUCCESS
Definition: exit_codes.h:29
static const int ERR_INVALID_OUTPUT_CONFLICT
Rules check violation count was greater than 0.
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.
boost::ptr_map< wxString, FP_CACHE_ITEM > FP_CACHE_FOOTPRINT_MAP
#define CTL_FOR_LIBRARY
Format output for a footprint library instead of clipboard or BOARD.
static DRILL_PRECISION precisionListForInches(2, 4)
static DRILL_PRECISION precisionListForMetric(3, 3)
FOOTPRINT * try_load_footprint(const wxFileName &aFileName, PCB_IO_MGR::PCB_FILE_T aFileType, const wxString &aName)
BOARD * LoadBoard(wxString &aFileName, bool aSetActive)
Loads a board from file This function identifies the file type by extension and determines the correc...
BOARD * CreateEmptyBoard()
Construct a default BOARD with a temporary (no filename) project.
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
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.
void PlotInteractiveLayer(BOARD *aBoard, PLOTTER *aPlotter, const PCB_PLOT_PARAMS &aPlotOpt)
Plot interactive items (hypertext links, properties, etc.).
see class PGM_BASE
PLOT_FORMAT
The set of supported output plot formats.
Definition: plotter.h:64
Plotting engines similar to ps (PostScript, Gerber, svg)
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_INFO
@ RPT_SEVERITY_ACTION
#define SKIP_SET_DIRTY
Definition: sch_commit.h:42
#define SKIP_UNDO
Definition: sch_commit.h:40
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:119
const int scale
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: string_utils.h:391
constexpr double IUTomm(int iu) const
Definition: base_units.h:87
Implement a participant in the KIWAY alchemy.
Definition: kiway.h:151
wxString m_colorTheme
Definition: export_svg.h:27
wxString m_outputFile
Definition: export_svg.h:26
VECTOR2< double > VECTOR2D
Definition: vector2d.h:587
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588
Definition of file extensions used in Kicad.