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>
41#include <jobs/job_pcb_render.h>
42#include <jobs/job_pcb_drc.h>
43#include <lset.h>
44#include <cli/exit_codes.h>
50#include <tool/tool_manager.h>
51#include <tools/drc_tool.h>
52#include <filename_resolver.h>
57#include <kiface_base.h>
58#include <macros.h>
59#include <pad.h>
60#include <pcb_marker.h>
64#include <kiface_ids.h>
67#include <pcbnew_settings.h>
68#include <pcbplot.h>
69#include <pgm_base.h>
72#include <project_pcb.h>
74#include <reporter.h>
76#include <export_vrml.h>
77#include <wx/wfstream.h>
78#include <wx/zipstrm.h>
85#include <dialogs/dialog_plot.h>
86
88
89
90#ifdef _WIN32
91#ifdef TRANSPARENT
92#undef TRANSPARENT
93#endif
94#endif
95
96
98 JOB_DISPATCHER( aKiway ),
99 m_cliBoard( nullptr )
100{
101 Register( "3d", std::bind( &PCBNEW_JOBS_HANDLER::JobExportStep, this, std::placeholders::_1 ),
102 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
103 {
104 JOB_EXPORT_PCB_3D* svgJob = dynamic_cast<JOB_EXPORT_PCB_3D*>( job );
105
106 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>(
107 aKiway->Player( FRAME_PCB_EDITOR, false ) );
108 DIALOG_EXPORT_STEP dlg( editFrame, aParent, "", svgJob );
109 dlg.ShowModal();
110
111 return dlg.GetReturnCode() == wxID_OK;
112 } );
113 Register( "render",
114 std::bind( &PCBNEW_JOBS_HANDLER::JobExportRender, this, std::placeholders::_1 ),
115 []( JOB* job, wxWindow* aParent ) -> bool
116 {
117 return false;
118 } );
119 Register( "svg", std::bind( &PCBNEW_JOBS_HANDLER::JobExportSvg, this, std::placeholders::_1 ),
120 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
121 {
122 JOB_EXPORT_PCB_SVG* svgJob = dynamic_cast<JOB_EXPORT_PCB_SVG*>( job );
123
124 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>(
125 aKiway->Player( FRAME_PCB_EDITOR, false ) );
126 DIALOG_EXPORT_SVG dlg( svgJob, editFrame, aParent );
127 dlg.ShowModal();
128
129 return dlg.GetReturnCode() == wxID_OK;
130 } );
131 Register( "gencad",
132 std::bind( &PCBNEW_JOBS_HANDLER::JobExportGencad, this, std::placeholders::_1 ),
133 []( JOB* job, wxWindow* aParent ) -> bool
134 {
135 return false;
136 } );
137 Register( "dxf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDxf, this, std::placeholders::_1 ),
138 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
139 {
140 JOB_EXPORT_PCB_DXF* dxfJob = dynamic_cast<JOB_EXPORT_PCB_DXF*>( job );
141
142 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>(
143 aKiway->Player( FRAME_PCB_EDITOR, false ) );
144
145 DIALOG_PLOT dlg( editFrame, aParent, dxfJob );
146 dlg.ShowModal();
147
148 return dlg.GetReturnCode() == wxID_OK;
149 } );
150 Register( "pdf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPdf, this, std::placeholders::_1 ),
151 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
152 {
153 JOB_EXPORT_PCB_PDF* pdfJob = dynamic_cast<JOB_EXPORT_PCB_PDF*>( job );
154
155 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>(
156 aKiway->Player( FRAME_PCB_EDITOR, false ) );
157
158 DIALOG_PLOT dlg( editFrame, aParent, pdfJob );
159 dlg.ShowModal();
160
161 return dlg.GetReturnCode() == wxID_OK;
162 } );
163 Register( "gerber",
164 std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerber, this, std::placeholders::_1 ),
165 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
166 {
167 JOB_EXPORT_PCB_GERBER* gJob = dynamic_cast<JOB_EXPORT_PCB_GERBER*>( job );
168
169 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>(
170 aKiway->Player( FRAME_PCB_EDITOR, false ) );
171
172 DIALOG_PLOT dlg( editFrame, aParent, gJob );
173 dlg.ShowModal();
174
175 return dlg.GetReturnCode() == wxID_OK;
176 } );
177 Register( "gerbers",
178 std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerbers, this, std::placeholders::_1 ),
179 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
180 {
181 JOB_EXPORT_PCB_GERBERS* gJob = dynamic_cast<JOB_EXPORT_PCB_GERBERS*>( job );
182
183 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>(
184 aKiway->Player( FRAME_PCB_EDITOR, false ) );
185
186 DIALOG_PLOT dlg( editFrame, aParent, gJob );
187 dlg.ShowModal();
188
189 return dlg.GetReturnCode() == wxID_OK;
190 } );
191 Register( "drill",
192 std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrill, this, std::placeholders::_1 ),
193 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
194 {
195 JOB_EXPORT_PCB_DRILL* drillJob = dynamic_cast<JOB_EXPORT_PCB_DRILL*>( job );
196
197 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( aKiway->Player( FRAME_PCB_EDITOR, false ) );
198 DIALOG_GENDRILL dlg( editFrame, drillJob, aParent );
199 dlg.ShowModal();
200 return dlg.GetReturnCode() == wxID_OK;
201 } );
202 Register( "pos", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPos, this, std::placeholders::_1 ),
203 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
204 {
205 JOB_EXPORT_PCB_POS* posJob = dynamic_cast<JOB_EXPORT_PCB_POS*>( job );
206
207 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( aKiway->Player( FRAME_PCB_EDITOR, false ) );
208 DIALOG_GEN_FOOTPRINT_POSITION dlg( posJob, editFrame, aParent );
209 dlg.ShowModal();
210 return dlg.GetReturnCode() == wxID_OK;
211 } );
212 Register( "fpupgrade",
213 std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpUpgrade, this, std::placeholders::_1 ),
214 []( JOB* job, wxWindow* aParent ) -> bool
215 {
216 return false;
217 } );
218 Register( "fpsvg",
219 std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpSvg, this, std::placeholders::_1 ),
220 []( JOB* job, wxWindow* aParent ) -> bool
221 {
222 return false;
223 } );
224 Register( "drc", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrc, this, std::placeholders::_1 ),
225 []( JOB* job, wxWindow* aParent ) -> bool
226 {
227 return false;
228 } );
229 Register( "ipc2581",
230 std::bind( &PCBNEW_JOBS_HANDLER::JobExportIpc2581, this, std::placeholders::_1 ),
231 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
232 {
233 JOB_EXPORT_PCB_IPC2581* ipcJob = dynamic_cast<JOB_EXPORT_PCB_IPC2581*>( job );
234
235 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( aKiway->Player( FRAME_PCB_EDITOR, false ) );
236
237 DIALOG_EXPORT_2581 dlg( ipcJob, editFrame, aParent );
238 dlg.ShowModal();
239
240 return dlg.GetReturnCode() == wxID_OK;
241 } );
242}
243
244
245BOARD* PCBNEW_JOBS_HANDLER::getBoard( const wxString& aPath )
246{
247 BOARD* brd = nullptr;
248
249 if( !Pgm().IsGUI() &&
250 Pgm().GetSettingsManager().IsProjectOpen() )
251 {
253
254 wxString pcbPath = aPath;
255 if( pcbPath.IsEmpty() )
256 {
257 wxFileName path = project.GetProjectFullName();
259 path.MakeAbsolute();
260 pcbPath = path.GetFullPath();
261 }
262
263 if( !m_cliBoard )
264 {
265 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
266 m_cliBoard = LoadBoard( pcbPath, true, &project );
267 }
268
269 brd = m_cliBoard;
270 }
271 else
272 {
273 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
274 brd = LoadBoard( aPath, true, &Pgm().GetSettingsManager().Prj() );
275 }
276
277 if ( !brd )
278 {
279 m_reporter->Report( _( "Failed to load board\n" ), RPT_SEVERITY_ERROR );
280 }
281
282 return brd;
283}
284
285
287{
288 JOB_EXPORT_PCB_3D* aStepJob = dynamic_cast<JOB_EXPORT_PCB_3D*>( aJob );
289
290 if( aStepJob == nullptr )
292
293 BOARD* brd = getBoard( aStepJob->m_filename );
294
295 if( !brd )
297
298 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
300
301 if( aStepJob->GetOutputPath().IsEmpty() )
302 {
303 wxFileName fn = brd->GetFileName();
304 fn.SetName( fn.GetName() );
305
306 switch( aStepJob->m_format )
307 {
309 break;
311 break;
313 break;
315 break;
317 break;
319 break;
321 break;
322 default:
323 return CLI::EXIT_CODES::ERR_UNKNOWN; // shouldnt have gotten here
324 }
325
326 aStepJob->SetOutputPath( fn.GetFullName() );
327 }
328
330 {
331
332 double scale = 0.0;
333 switch ( aStepJob->m_vrmlUnits )
334 {
336 case JOB_EXPORT_PCB_3D::VRML_UNITS::METERS: scale = 0.001; break;
337 case JOB_EXPORT_PCB_3D::VRML_UNITS::TENTHS: scale = 10.0 / 25.4; break;
338 case JOB_EXPORT_PCB_3D::VRML_UNITS::INCHES: scale = 1.0 / 25.4; break;
339 }
340
341 EXPORTER_VRML vrmlExporter( brd );
342 wxString messages;
343
344 double originX = pcbIUScale.IUTomm( aStepJob->m_3dparams.m_Origin.x );
345 double originY = pcbIUScale.IUTomm( aStepJob->m_3dparams.m_Origin.y );
346
347 if( !aStepJob->m_hasUserOrigin )
348 {
349 BOX2I bbox = brd->ComputeBoundingBox( true );
350 originX = pcbIUScale.IUTomm( bbox.GetCenter().x );
351 originY = pcbIUScale.IUTomm( bbox.GetCenter().y );
352 }
353
354 bool success = vrmlExporter.ExportVRML_File(
355 brd->GetProject(), &messages, aStepJob->GetFullOutputPath(), scale,
357 !aStepJob->m_vrmlModelDir.IsEmpty(), aStepJob->m_vrmlRelativePaths,
358 aStepJob->m_vrmlModelDir, originX, originY );
359
360 if ( success )
361 {
362 m_reporter->Report( wxString::Format( _( "Successfully exported VRML to %s" ),
363 aStepJob->GetFullOutputPath() ),
365 }
366 else
367 {
368 m_reporter->Report( _( "Error exporting VRML" ), RPT_SEVERITY_ERROR );
370 }
371 }
372 else
373 {
374 EXPORTER_STEP_PARAMS params = aStepJob->m_3dparams;
375
376 switch( aStepJob->m_format )
377 {
380 break;
383 break;
386 break;
389 break;
392 break;
395 break;
396 default:
397 return CLI::EXIT_CODES::ERR_UNKNOWN; // shouldnt have gotten here
398 }
399
400 EXPORTER_STEP stepExporter( brd, params );
401 stepExporter.m_outputFile = aStepJob->GetFullOutputPath();
402
403 if( !stepExporter.Export() )
405 }
406
407 return CLI::EXIT_CODES::OK;
408}
409
410
412{
413 JOB_PCB_RENDER* aRenderJob = dynamic_cast<JOB_PCB_RENDER*>( aJob );
414
415 if( aRenderJob == nullptr )
417
418 BOARD* brd = getBoard( aRenderJob->m_filename );
419
420 if( !brd )
422
423 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
425
426 BOARD_ADAPTER boardAdapter;
427
428 boardAdapter.SetBoard( brd );
429 boardAdapter.m_IsBoardView = false;
430 boardAdapter.m_IsPreviewer =
431 true; // Force display 3D models, regardless the 3D viewer options
432
435
436 if( aRenderJob->m_quality == JOB_PCB_RENDER::QUALITY::BASIC )
437 {
438 // Silkscreen is pixelated without antialiasing
440
441 cfg->m_Render.raytrace_backfloor = false;
443
445 cfg->m_Render.raytrace_reflections = false;
446 cfg->m_Render.raytrace_shadows = false;
447
448 // Better colors
450
451 // Tracks below soldermask are not visible without refractions
452 cfg->m_Render.raytrace_refractions = true;
454 }
455 else if( aRenderJob->m_quality == JOB_PCB_RENDER::QUALITY::HIGH )
456 {
458 cfg->m_Render.raytrace_backfloor = true;
461 cfg->m_Render.raytrace_reflections = true;
462 cfg->m_Render.raytrace_shadows = true;
463 cfg->m_Render.raytrace_refractions = true;
465 }
466
467 if( aRenderJob->m_floor )
468 {
469 cfg->m_Render.raytrace_backfloor = true;
470 cfg->m_Render.raytrace_shadows = true;
472 }
473
474 cfg->m_CurrentPreset = aRenderJob->m_colorPreset;
475 boardAdapter.m_Cfg = cfg;
476
479 && aRenderJob->m_format == JOB_PCB_RENDER::FORMAT::PNG ) )
480 {
481 boardAdapter.m_ColorOverrides[LAYER_3D_BACKGROUND_TOP] = COLOR4D( 1.0, 1.0, 1.0, 0.0 );
482 boardAdapter.m_ColorOverrides[LAYER_3D_BACKGROUND_BOTTOM] = COLOR4D( 1.0, 1.0, 1.0, 0.0 );
483 }
484
486
487 static std::map<JOB_PCB_RENDER::SIDE, VIEW3D_TYPE> s_viewCmdMap = {
488 { JOB_PCB_RENDER::SIDE::TOP, VIEW3D_TYPE::VIEW3D_TOP },
489 { JOB_PCB_RENDER::SIDE::BOTTOM, VIEW3D_TYPE::VIEW3D_BOTTOM },
490 { JOB_PCB_RENDER::SIDE::LEFT, VIEW3D_TYPE::VIEW3D_LEFT },
491 { JOB_PCB_RENDER::SIDE::RIGHT, VIEW3D_TYPE::VIEW3D_RIGHT },
492 { JOB_PCB_RENDER::SIDE::FRONT, VIEW3D_TYPE::VIEW3D_FRONT },
493 { JOB_PCB_RENDER::SIDE::BACK, VIEW3D_TYPE::VIEW3D_BACK },
494 };
495
496 PROJECTION_TYPE projection =
497 aRenderJob->m_perspective ? PROJECTION_TYPE::PERSPECTIVE : PROJECTION_TYPE::ORTHO;
498
499 wxSize windowSize( aRenderJob->m_width, aRenderJob->m_height );
500 TRACK_BALL camera( 2 * RANGE_SCALE_3D );
501
502 camera.SetProjection( projection );
503 camera.SetCurWindowSize( windowSize );
504
505 RENDER_3D_RAYTRACE_RAM raytrace( boardAdapter, camera );
506 raytrace.SetCurWindowSize( windowSize );
507
508 for( bool first = true; raytrace.Redraw( false, m_reporter, m_reporter ); first = false )
509 {
510 if( first )
511 {
512 const float cmTo3D = boardAdapter.BiuTo3dUnits() * pcbIUScale.mmToIU( 10.0 );
513
514 // First redraw resets lookat point to the board center, so set up the camera here
515 camera.ViewCommand_T1( s_viewCmdMap[aRenderJob->m_side] );
516
517 camera.SetLookAtPos_T1(
518 camera.GetLookAtPos_T1()
519 + SFVEC3F( aRenderJob->m_pivot.x, aRenderJob->m_pivot.y, aRenderJob->m_pivot.z )
520 * cmTo3D );
521
522 camera.Pan_T1(
523 SFVEC3F( aRenderJob->m_pan.x, aRenderJob->m_pan.y, aRenderJob->m_pan.z ) );
524
525 camera.Zoom_T1( aRenderJob->m_zoom );
526
527 camera.RotateX_T1( DEG2RAD( aRenderJob->m_rotation.x ) );
528 camera.RotateY_T1( DEG2RAD( aRenderJob->m_rotation.y ) );
529 camera.RotateZ_T1( DEG2RAD( aRenderJob->m_rotation.z ) );
530
531 camera.Interpolate( 1.0f );
532 camera.SetT0_and_T1_current_T();
533 camera.ParametersChanged();
534 }
535 }
536
537 uint8_t* rgbaBuffer = raytrace.GetBuffer();
538 wxSize realSize = raytrace.GetRealBufferSize();
539 bool success = !!rgbaBuffer;
540
541 if( rgbaBuffer )
542 {
543 const unsigned int wxh = realSize.x * realSize.y;
544
545 unsigned char* rgbBuffer = (unsigned char*) malloc( wxh * 3 );
546 unsigned char* alphaBuffer = (unsigned char*) malloc( wxh );
547
548 unsigned char* rgbaPtr = rgbaBuffer;
549 unsigned char* rgbPtr = rgbBuffer;
550 unsigned char* alphaPtr = alphaBuffer;
551
552 for( int y = 0; y < realSize.y; y++ )
553 {
554 for( int x = 0; x < realSize.x; x++ )
555 {
556 rgbPtr[0] = rgbaPtr[0];
557 rgbPtr[1] = rgbaPtr[1];
558 rgbPtr[2] = rgbaPtr[2];
559 alphaPtr[0] = rgbaPtr[3];
560
561 rgbaPtr += 4;
562 rgbPtr += 3;
563 alphaPtr += 1;
564 }
565 }
566
567 wxImage image( realSize );
568 image.SetData( rgbBuffer );
569 image.SetAlpha( alphaBuffer );
570 image = image.Mirror( false );
571
572 image.SetOption( wxIMAGE_OPTION_QUALITY, 90 );
573 image.SaveFile( aRenderJob->m_outputFile,
574 aRenderJob->m_format == JOB_PCB_RENDER::FORMAT::PNG ? wxBITMAP_TYPE_PNG
575 : wxBITMAP_TYPE_JPEG );
576 }
577
578 m_reporter->Report( wxString::Format( _( "Actual image size: %dx%d" ), realSize.x, realSize.y )
579 + wxS( "\n" ),
581
582 if( success )
583 m_reporter->Report( _( "Successfully created 3D render image" ) + wxS( "\n" ),
585 else
586 m_reporter->Report( _( "Error creating 3D render image" ) + wxS( "\n" ),
588
589 return CLI::EXIT_CODES::OK;
590}
591
592
594{
595 JOB_EXPORT_PCB_SVG* aSvgJob = dynamic_cast<JOB_EXPORT_PCB_SVG*>( aJob );
596
597 if( aSvgJob == nullptr )
599
600 PCB_PLOT_SVG_OPTIONS svgPlotOptions;
601 svgPlotOptions.m_blackAndWhite = aSvgJob->m_blackAndWhite;
602 svgPlotOptions.m_colorTheme = aSvgJob->m_colorTheme;
603 svgPlotOptions.m_outputFile = aSvgJob->GetFullOutputPath();
604 svgPlotOptions.m_mirror = aSvgJob->m_mirror;
605 svgPlotOptions.m_negative = aSvgJob->m_negative;
606 svgPlotOptions.m_pageSizeMode = aSvgJob->m_pageSizeMode;
607 svgPlotOptions.m_printMaskLayer = aSvgJob->m_printMaskLayer;
608 svgPlotOptions.m_plotFrame = aSvgJob->m_plotDrawingSheet;
609 svgPlotOptions.m_sketchPadsOnFabLayers = aSvgJob->m_sketchPadsOnFabLayers;
610 svgPlotOptions.m_hideDNPFPsOnFabLayers = aSvgJob->m_hideDNPFPsOnFabLayers;
613 svgPlotOptions.m_drillShapeOption = aSvgJob->m_drillShapeOption;
614
615 BOARD* brd = getBoard( aSvgJob->m_filename );
616
617 if( !brd )
619
621 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
623
624 if( EXPORT_SVG::Plot( brd, svgPlotOptions ) )
625 m_reporter->Report( _( "Successfully created svg file" ) + wxS( "\n" ), RPT_SEVERITY_INFO );
626 else
627 m_reporter->Report( _( "Error creating svg file" ) + wxS( "\n" ), RPT_SEVERITY_ERROR );
628
629 return CLI::EXIT_CODES::OK;
630}
631
632
634{
635 JOB_EXPORT_PCB_DXF* aDxfJob = dynamic_cast<JOB_EXPORT_PCB_DXF*>( aJob );
636
637 if( aDxfJob == nullptr )
639
640 BOARD* brd = getBoard( aDxfJob->m_filename );
641
642 if( !brd )
644
646 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
648
649 if( aDxfJob->GetOutputPath().IsEmpty() )
650 {
651 wxFileName fn = brd->GetFileName();
652 fn.SetName( fn.GetName() );
653 fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::DXF ) );
654
655 aDxfJob->SetOutputPath( fn.GetFullName() );
656 }
657
658 PCB_PLOT_PARAMS plotOpts;
659 plotOpts.SetFormat( PLOT_FORMAT::DXF );
660
662 plotOpts.SetUseAuxOrigin( aDxfJob->m_useDrillOrigin );
663
665 plotOpts.SetDXFPlotUnits( DXF_UNITS::MILLIMETERS );
666 else
667 plotOpts.SetDXFPlotUnits( DXF_UNITS::INCHES );
668
669 plotOpts.SetPlotFrameRef( aDxfJob->m_plotDrawingSheet );
670 plotOpts.SetPlotValue( aDxfJob->m_plotFootprintValues );
671 plotOpts.SetPlotReference( aDxfJob->m_plotRefDes );
672 plotOpts.SetLayerSelection( aDxfJob->m_printMaskLayer );
673
675 wxString layerName;
676 wxString sheetName;
677 wxString sheetPath;
678
679 if( aDxfJob->m_printMaskLayer.size() == 1 )
680 {
681 layer = aDxfJob->m_printMaskLayer.front();
682 layerName = brd->GetLayerName( layer );
683 }
684
685 if( aJob->GetVarOverrides().contains( wxT( "LAYER" ) ) )
686 layerName = aJob->GetVarOverrides().at( wxT( "LAYER" ) );
687
688 if( aJob->GetVarOverrides().contains( wxT( "SHEETNAME" ) ) )
689 sheetName = aJob->GetVarOverrides().at( wxT( "SHEETNAME" ) );
690
691 if( aJob->GetVarOverrides().contains( wxT( "SHEETPATH" ) ) )
692 sheetPath = aJob->GetVarOverrides().at( wxT( "SHEETPATH" ) );
693
694 DXF_PLOTTER* plotter = (DXF_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer, layerName, aDxfJob->GetFullOutputPath(), sheetName,
695 sheetPath );
696
697 if( plotter )
698 {
699 PlotBoardLayers( brd, plotter, aDxfJob->m_printMaskLayer, plotOpts );
700 plotter->EndPlot();
701 }
702
703 delete plotter;
704
705 return CLI::EXIT_CODES::OK;
706}
707
708
710{
711 JOB_EXPORT_PCB_PDF* aPdfJob = dynamic_cast<JOB_EXPORT_PCB_PDF*>( aJob );
712
713 if( aPdfJob == nullptr )
715
716 BOARD* brd = getBoard( aPdfJob->m_filename );
717
718 if( !brd )
720
722 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
724
725 if( aPdfJob->GetOutputPath().IsEmpty() )
726 {
727 wxFileName fn = brd->GetFileName();
728 fn.SetName( fn.GetName() );
729 fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::PDF ) );
730
731 aPdfJob->SetOutputPath( fn.GetFullName() );
732 }
733
734 PCB_PLOT_PARAMS plotOpts;
735 plotOpts.SetFormat( PLOT_FORMAT::PDF );
736
737 plotOpts.SetPlotFrameRef( aPdfJob->m_plotDrawingSheet );
738 plotOpts.SetPlotValue( aPdfJob->m_plotFootprintValues );
739 plotOpts.SetPlotReference( aPdfJob->m_plotRefDes );
740
741 plotOpts.SetLayerSelection( aPdfJob->m_printMaskLayer );
742
744 plotOpts.SetColorSettings( mgr.GetColorSettings( aPdfJob->m_colorTheme ) );
745 plotOpts.SetMirror( aPdfJob->m_mirror );
746 plotOpts.SetBlackAndWhite( aPdfJob->m_blackAndWhite );
747 plotOpts.SetNegative( aPdfJob->m_negative );
748
749 if( aPdfJob->m_sketchPadsOnFabLayers )
750 {
751 plotOpts.SetSketchPadsOnFabLayers( true );
752 plotOpts.SetPlotPadNumbers( true );
753 }
754
758
759 switch( aPdfJob->m_drillShapeOption )
760 {
761 default:
762 case 0: plotOpts.SetDrillMarksType( DRILL_MARKS::NO_DRILL_SHAPE ); break;
763 case 1: plotOpts.SetDrillMarksType( DRILL_MARKS::SMALL_DRILL_SHAPE ); break;
764 case 2: plotOpts.SetDrillMarksType( DRILL_MARKS::FULL_DRILL_SHAPE ); break;
765 }
766
768 wxString layerName;
769 wxString sheetName;
770 wxString sheetPath;
771
772 if( aPdfJob->m_printMaskLayer.size() == 1 )
773 {
774 layer = aPdfJob->m_printMaskLayer.front();
775 layerName = brd->GetLayerName( layer );
776 }
777
778 if( aPdfJob->GetVarOverrides().contains( wxT( "LAYER" ) ) )
779 layerName = aPdfJob->GetVarOverrides().at( wxT( "LAYER" ) );
780
781 if( aPdfJob->GetVarOverrides().contains( wxT( "SHEETNAME" ) ) )
782 sheetName = aPdfJob->GetVarOverrides().at( wxT( "SHEETNAME" ) );
783
784 if( aPdfJob->GetVarOverrides().contains( wxT( "SHEETPATH" ) ) )
785 sheetPath = aPdfJob->GetVarOverrides().at( wxT( "SHEETPATH" ) );
786
787 PDF_PLOTTER* plotter = (PDF_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer, layerName, aPdfJob->GetFullOutputPath(), sheetName,
788 sheetPath );
789
790 if( plotter )
791 {
792 PlotBoardLayers( brd, plotter, aPdfJob->m_printMaskLayer, plotOpts );
793 PlotInteractiveLayer( brd, plotter, plotOpts );
794 plotter->EndPlot();
795 }
796
797 delete plotter;
798
799 return CLI::EXIT_CODES::OK;
800}
801
802
804{
805 int exitCode = CLI::EXIT_CODES::OK;
806 JOB_EXPORT_PCB_GERBERS* aGerberJob = dynamic_cast<JOB_EXPORT_PCB_GERBERS*>( aJob );
807
808 if( aGerberJob == nullptr )
810
811 BOARD* brd = getBoard( aGerberJob->m_filename );
812
813 if( !brd )
815
816 loadOverrideDrawingSheet( brd, aGerberJob->m_drawingSheet );
817 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
819
820 PCB_PLOT_PARAMS boardPlotOptions = brd->GetPlotOptions();
821 LSET plotOnAllLayersSelection = boardPlotOptions.GetPlotOnAllLayersSelection();
822 GERBER_JOBFILE_WRITER jobfile_writer( brd );
823
824 wxString fileExt;
825
826 if( aGerberJob->m_useBoardPlotParams )
827 {
828 // The board plot options are saved with all copper layers enabled, even those that don't
829 // exist in the current stackup. This is done so the layers are automatically enabled in the plot
830 // dialog when the user enables them. We need to filter out these not-enabled layers here so
831 // we don't plot 32 layers when we only have 4, etc.
832 LSET plotLayers = ( boardPlotOptions.GetLayerSelection() & LSET::AllNonCuMask() )
833 | ( brd->GetEnabledLayers() & LSET::AllCuMask() );
834 aGerberJob->m_printMaskLayer = plotLayers.SeqStackupForPlotting();
835 aGerberJob->m_layersIncludeOnAll = boardPlotOptions.GetPlotOnAllLayersSelection();
836 }
837 else
838 {
839 // default to the board enabled layers
840 if( aGerberJob->m_printMaskLayer.empty() )
842
843 if( aGerberJob->m_layersIncludeOnAllSet )
844 aGerberJob->m_layersIncludeOnAll = plotOnAllLayersSelection;
845 }
846
847 // Ensure layers to plot are restricted to enabled layers of the board to plot
848 LSET layersToPlot = LSET( { aGerberJob->m_printMaskLayer } ) & brd->GetEnabledLayers();
849
850 for( PCB_LAYER_ID layer : layersToPlot.UIOrder() )
851 {
852 LSEQ plotSequence;
853
854 // Base layer always gets plotted first.
855 plotSequence.push_back( layer );
856
857 // Now all the "include on all" layers
858 for( PCB_LAYER_ID layer_all : aGerberJob->m_layersIncludeOnAll.UIOrder() )
859 {
860 // Don't plot the same layer more than once;
861 if( find( plotSequence.begin(), plotSequence.end(), layer_all ) != plotSequence.end() )
862 continue;
863
864 plotSequence.push_back( layer_all );
865 }
866
867 // Pick the basename from the board file
868 wxFileName fn( brd->GetFileName() );
869 wxString layerName = brd->GetLayerName( layer );
870 wxString sheetName;
871 wxString sheetPath;
872 PCB_PLOT_PARAMS plotOpts;
873
874 if( aGerberJob->m_useBoardPlotParams )
875 plotOpts = boardPlotOptions;
876 else
877 populateGerberPlotOptionsFromJob( plotOpts, aGerberJob );
878
879 if( plotOpts.GetUseGerberProtelExtensions() )
880 fileExt = GetGerberProtelExtension( layer );
881 else
883
884 BuildPlotFileName( &fn, aGerberJob->GetFullOutputPath(), layerName, fileExt );
885 wxString fullname = fn.GetFullName();
886
887 jobfile_writer.AddGbrFile( layer, fullname );
888
889 if( aJob->GetVarOverrides().contains( wxT( "LAYER" ) ) )
890 layerName = aJob->GetVarOverrides().at( wxT( "LAYER" ) );
891
892 if( aJob->GetVarOverrides().contains( wxT( "SHEETNAME" ) ) )
893 sheetName = aJob->GetVarOverrides().at( wxT( "SHEETNAME" ) );
894
895 if( aJob->GetVarOverrides().contains( wxT( "SHEETPATH" ) ) )
896 sheetPath = aJob->GetVarOverrides().at( wxT( "SHEETPATH" ) );
897
898 // We are feeding it one layer at the start here to silence a logic check
899 GERBER_PLOTTER* plotter = (GERBER_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer,
900 layerName, fn.GetFullPath(),
901 sheetName, sheetPath );
902
903 if( plotter )
904 {
905 m_reporter->Report( wxString::Format( _( "Plotted to '%s'.\n" ), fn.GetFullPath() ),
907 PlotBoardLayers( brd, plotter, plotSequence, plotOpts );
908 plotter->EndPlot();
909 }
910 else
911 {
912 m_reporter->Report( wxString::Format( _( "Failed to plot to '%s'.\n" ),
913 fn.GetFullPath() ),
916 }
917
918 delete plotter;
919 }
920
921 wxFileName fn( aGerberJob->m_filename );
922
923 // Build gerber job file from basename
924 BuildPlotFileName( &fn, aGerberJob->GetFullOutputPath(), wxT( "job" ),
926 jobfile_writer.CreateJobFile( fn.GetFullPath() );
927
928 return exitCode;
929}
930
932{
933 JOB_EXPORT_PCB_GENCAD* aGencadJob = dynamic_cast<JOB_EXPORT_PCB_GENCAD*>( aJob );
934
935 if( aGencadJob == nullptr )
937
938 BOARD* aBoard = LoadBoard( aGencadJob->m_filename, true ); // Ensure m_board is of type BOARD*
939
940 if( aBoard == nullptr )
942
943 GENCAD_EXPORTER exporter( aBoard );
944
945 VECTOR2I GencadOffset;
946 VECTOR2I auxOrigin = aBoard->GetDesignSettings().GetAuxOrigin();
947 GencadOffset.x = aGencadJob->m_useDrillOrigin ? auxOrigin.x : 0;
948 GencadOffset.y = aGencadJob->m_useDrillOrigin ? auxOrigin.y : 0;
949
950 exporter.FlipBottomPads( aGencadJob->m_flipBottomPads );
951 exporter.UsePinNamesUnique( aGencadJob->m_useUniquePins );
952 exporter.UseIndividualShapes( aGencadJob->m_useIndividualShapes );
953 exporter.SetPlotOffet( GencadOffset );
954 exporter.StoreOriginCoordsInFile( aGencadJob->m_storeOriginCoords );
955
956 if( aGencadJob->GetOutputPath().IsEmpty() )
957 {
958 wxFileName fn = aBoard->GetFileName();
959 fn.SetName( fn.GetName() );
960 fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::DXF ) );
961
962 aGencadJob->SetOutputPath( fn.GetFullName() );
963 }
964
965 if( !exporter.WriteFile( aGencadJob->GetFullOutputPath() ) )
966 {
967 wxString msg;
968 msg.Printf( _( "Failed to create file '%s'.\n" ), aGencadJob->GetFullOutputPath() );
969
971
973 }
974
975 m_reporter->Report( _( "Successfully created genCAD file\n" ), RPT_SEVERITY_INFO );
976
977 return CLI::EXIT_CODES::OK;
978}
979
980
983{
984 aPlotOpts.SetFormat( PLOT_FORMAT::GERBER );
985
986 aPlotOpts.SetPlotFrameRef( aJob->m_plotDrawingSheet );
987 aPlotOpts.SetPlotValue( aJob->m_plotFootprintValues );
988 aPlotOpts.SetPlotReference( aJob->m_plotRefDes );
989
991
992 // Always disable plot pad holes
993 aPlotOpts.SetDrillMarksType( DRILL_MARKS::NO_DRILL_SHAPE );
994
996 aPlotOpts.SetUseGerberX2format( aJob->m_useX2Format );
998 aPlotOpts.SetUseAuxOrigin( aJob->m_useAuxOrigin );
1000 aPlotOpts.SetGerberPrecision( aJob->m_precision );
1001}
1002
1003
1005{
1006 int exitCode = CLI::EXIT_CODES::OK;
1007 JOB_EXPORT_PCB_GERBER* aGerberJob = dynamic_cast<JOB_EXPORT_PCB_GERBER*>( aJob );
1008
1009 if( aGerberJob == nullptr )
1011
1012 BOARD* brd = getBoard( aGerberJob->m_filename );
1013
1014 if( !brd )
1016
1017 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
1018 brd->SynchronizeProperties();
1019
1020 if( aGerberJob->GetOutputPath().IsEmpty() )
1021 {
1022 wxFileName fn = brd->GetFileName();
1023 fn.SetName( fn.GetName() );
1024 fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::GERBER ) );
1025
1026 aGerberJob->SetOutputPath( fn.GetFullName() );
1027 }
1028
1029 PCB_PLOT_PARAMS plotOpts;
1030 populateGerberPlotOptionsFromJob( plotOpts, aGerberJob );
1031 plotOpts.SetLayerSelection( aGerberJob->m_printMaskLayer );
1032
1034 wxString layerName;
1035 wxString sheetName;
1036 wxString sheetPath;
1037
1038 // The first layer will be treated as the layer name for the gerber header,
1039 // the other layers will be treated equivalent to the "Plot on All Layers" option
1040 // in the GUI
1041 if( aGerberJob->m_printMaskLayer.size() >= 1 )
1042 {
1043 layer = aGerberJob->m_printMaskLayer.front();
1044 layerName = brd->GetLayerName( layer );
1045 }
1046
1047 if( aJob->GetVarOverrides().contains( wxT( "LAYER" ) ) )
1048 layerName = aJob->GetVarOverrides().at( wxT( "LAYER" ) );
1049
1050 if( aJob->GetVarOverrides().contains( wxT( "SHEETNAME" ) ) )
1051 sheetName = aJob->GetVarOverrides().at( wxT( "SHEETNAME" ) );
1052
1053 if( aJob->GetVarOverrides().contains( wxT( "SHEETPATH" ) ) )
1054 sheetPath = aJob->GetVarOverrides().at( wxT( "SHEETPATH" ) );
1055
1056 // We are feeding it one layer at the start here to silence a logic check
1057 GERBER_PLOTTER* plotter = (GERBER_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer, layerName,
1058 aGerberJob->GetFullOutputPath(),
1059 sheetName, sheetPath );
1060
1061 if( plotter )
1062 {
1063 PlotBoardLayers( brd, plotter, aGerberJob->m_printMaskLayer, plotOpts );
1064 plotter->EndPlot();
1065 }
1066 else
1067 {
1068 m_reporter->Report( wxString::Format( _( "Failed to plot to '%s'.\n" ),
1069 aGerberJob->GetFullOutputPath() ),
1072 }
1073
1074 delete plotter;
1075
1076 return exitCode;
1077}
1078
1081
1082
1084{
1085 JOB_EXPORT_PCB_DRILL* aDrillJob = dynamic_cast<JOB_EXPORT_PCB_DRILL*>( aJob );
1086
1087 if( aDrillJob == nullptr )
1089
1090 BOARD* brd = getBoard( aDrillJob->m_filename );
1091
1092 if( !brd )
1094
1095 // ensure output dir exists
1096 wxFileName fn( aDrillJob->GetFullOutputPath() + wxT( "/" ) );
1097
1098 if( !fn.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
1099 {
1100 m_reporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
1102 }
1103
1104 std::unique_ptr<GENDRILL_WRITER_BASE> drillWriter;
1105
1107 drillWriter = std::make_unique<EXCELLON_WRITER>( brd );
1108 else
1109 drillWriter = std::make_unique<GERBER_WRITER>( brd );
1110
1111 VECTOR2I offset;
1112
1114 offset = VECTOR2I( 0, 0 );
1115 else
1116 offset = brd->GetDesignSettings().GetAuxOrigin();
1117
1118 PLOT_FORMAT mapFormat = PLOT_FORMAT::PDF;
1119
1120 switch( aDrillJob->m_mapFormat )
1121 {
1122 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::POSTSCRIPT: mapFormat = PLOT_FORMAT::POST; break;
1123 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::GERBER_X2: mapFormat = PLOT_FORMAT::GERBER; break;
1124 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::DXF: mapFormat = PLOT_FORMAT::DXF; break;
1125 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::SVG: mapFormat = PLOT_FORMAT::SVG; break;
1126 default:
1127 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::PDF: mapFormat = PLOT_FORMAT::PDF; break;
1128 }
1129
1131 {
1133 switch( aDrillJob->m_zeroFormat )
1134 {
1137 break;
1140 break;
1143 break;
1145 default:
1147 break;
1148 }
1149
1150 DRILL_PRECISION precision;
1151
1153 precision = precisionListForInches;
1154 else
1155 precision = precisionListForMetric;
1156
1157 EXCELLON_WRITER* excellonWriter = dynamic_cast<EXCELLON_WRITER*>( drillWriter.get() );
1158
1159 if( excellonWriter == nullptr )
1161
1162 excellonWriter->SetFormat( aDrillJob->m_drillUnits
1164 zeroFmt, precision.m_Lhs, precision.m_Rhs );
1165 excellonWriter->SetOptions( aDrillJob->m_excellonMirrorY,
1166 aDrillJob->m_excellonMinimalHeader,
1167 offset, aDrillJob->m_excellonCombinePTHNPTH );
1168 excellonWriter->SetRouteModeForOvalHoles( aDrillJob->m_excellonOvalDrillRoute );
1169 excellonWriter->SetMapFileFormat( mapFormat );
1170
1171 if( !excellonWriter->CreateDrillandMapFilesSet( aDrillJob->GetFullOutputPath(), true,
1172 aDrillJob->m_generateMap, m_reporter ) )
1173 {
1175 }
1176 }
1178 {
1179 GERBER_WRITER* gerberWriter = dynamic_cast<GERBER_WRITER*>( drillWriter.get() );
1180
1181 if( gerberWriter == nullptr )
1183
1184 // Set gerber precision: only 5 or 6 digits for mantissa are allowed
1185 // (SetFormat() accept 5 or 6, and any other value set the precision to 5)
1186 // the integer part precision is always 4, and units always mm
1187 gerberWriter->SetFormat( aDrillJob->m_gerberPrecision );
1188 gerberWriter->SetOptions( offset );
1189 gerberWriter->SetMapFileFormat( mapFormat );
1190
1191 if( !gerberWriter->CreateDrillandMapFilesSet( aDrillJob->GetFullOutputPath(), true,
1192 aDrillJob->m_generateMap, m_reporter ) )
1193 {
1195 }
1196 }
1197
1198 return CLI::EXIT_CODES::OK;
1199}
1200
1201
1203{
1204 JOB_EXPORT_PCB_POS* aPosJob = dynamic_cast<JOB_EXPORT_PCB_POS*>( aJob );
1205
1206 if( aPosJob == nullptr )
1208
1209 BOARD* brd = getBoard( aPosJob->m_filename );
1210
1211 if( !brd )
1212 {
1214 }
1215
1216 if( aPosJob->GetOutputPath().IsEmpty() )
1217 {
1218 wxFileName fn = brd->GetFileName();
1219 fn.SetName( fn.GetName() );
1220
1223 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::CSV )
1224 fn.SetExt( FILEEXT::CsvFileExtension );
1225 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::GERBER )
1226 fn.SetExt( FILEEXT::GerberFileExtension );
1227
1228 aPosJob->SetOutputPath( fn.GetFullName() );
1229 }
1230
1233 {
1234 FILE* file = nullptr;
1235 file = wxFopen( aPosJob->GetFullOutputPath(), wxS( "wt" ) );
1236
1237 if( file == nullptr )
1239
1240 std::string data;
1241
1242 bool frontSide = aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::FRONT
1244
1245 bool backSide = aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::BACK
1247
1248 PLACE_FILE_EXPORTER exporter( brd,
1250 aPosJob->m_smdOnly, aPosJob->m_excludeFootprintsWithTh,
1251 aPosJob->m_excludeDNP,
1252 frontSide, backSide,
1255 aPosJob->m_negateBottomX );
1256 data = exporter.GenPositionData();
1257
1258 fputs( data.c_str(), file );
1259 fclose( file );
1260
1261 aPosJob->AddOutput( aPosJob->GetFullOutputPath() );
1262 }
1263 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::GERBER )
1264 {
1265 PLACEFILE_GERBER_WRITER exporter( brd );
1266
1267 PCB_LAYER_ID gbrLayer = F_Cu;
1268
1269 if( aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::BACK )
1270 gbrLayer = B_Cu;
1271
1272 if( exporter.CreatePlaceFile( aPosJob->GetFullOutputPath(), gbrLayer, aPosJob->m_gerberBoardEdge )
1273 >= 0 )
1274 {
1275 aPosJob->AddOutput( aPosJob->GetFullOutputPath() );
1276 }
1277 else
1278 {
1280 }
1281 }
1282
1283 return CLI::EXIT_CODES::OK;
1284}
1285
1286extern FOOTPRINT* try_load_footprint( const wxFileName& aFileName, PCB_IO_MGR::PCB_FILE_T aFileType,
1287 const wxString& aName );
1288
1289
1291{
1292 JOB_FP_UPGRADE* upgradeJob = dynamic_cast<JOB_FP_UPGRADE*>( aJob );
1293
1294 if( upgradeJob == nullptr )
1296
1298
1299 if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
1300 {
1301 if( wxFile::Exists( upgradeJob->m_outputLibraryPath ) ||
1302 wxDir::Exists( upgradeJob->m_outputLibraryPath) )
1303 {
1304 m_reporter->Report( _( "Output path must not conflict with existing path\n" ),
1307 }
1308 }
1309 else if( fileType != PCB_IO_MGR::KICAD_SEXP )
1310 {
1311 m_reporter->Report( _( "Output path must be specified to convert legacy and non-KiCad libraries\n" ),
1313
1315 }
1316
1318 {
1319 if( !wxDir::Exists( upgradeJob->m_libraryPath ) )
1320 {
1321 m_reporter->Report( _( "Footprint library path does not exist or is not accessible\n" ),
1324 }
1325
1326 m_reporter->Report( _( "Loading footprint library\n" ), RPT_SEVERITY_INFO );
1327
1329 FP_CACHE fpLib( &pcb_io, upgradeJob->m_libraryPath );
1330
1331 try
1332 {
1333 fpLib.Load();
1334 }
1335 catch( ... )
1336 {
1337 m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
1339 }
1340
1341 bool shouldSave = upgradeJob->m_force;
1342
1343 for( const auto& footprint : fpLib.GetFootprints() )
1344 {
1345 if( footprint.second->GetFootprint()->GetFileFormatVersionAtLoad()
1347 {
1348 shouldSave = true;
1349 }
1350 }
1351
1352 if( shouldSave )
1353 {
1354 m_reporter->Report( _( "Saving footprint library\n" ), RPT_SEVERITY_INFO );
1355
1356 try
1357 {
1358 if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
1359 {
1360 fpLib.SetPath( upgradeJob->m_outputLibraryPath );
1361 }
1362
1363 fpLib.Save();
1364 }
1365 catch( ... )
1366 {
1367 m_reporter->Report( _( "Unable to save library\n" ), RPT_SEVERITY_ERROR );
1369 }
1370 }
1371 else
1372 {
1373 m_reporter->Report( _( "Footprint library was not updated\n" ), RPT_SEVERITY_INFO );
1374 }
1375 }
1376 else
1377 {
1378 if( !PCB_IO_MGR::ConvertLibrary( nullptr, upgradeJob->m_libraryPath,
1379 upgradeJob->m_outputLibraryPath, nullptr /* REPORTER */ ) )
1380 {
1381 m_reporter->Report( ( "Unable to convert library\n" ), RPT_SEVERITY_ERROR );
1383 }
1384 }
1385
1386 return CLI::EXIT_CODES::OK;
1387}
1388
1389
1391{
1392 JOB_FP_EXPORT_SVG* svgJob = dynamic_cast<JOB_FP_EXPORT_SVG*>( aJob );
1393
1394 if( svgJob == nullptr )
1396
1397 m_reporter->Report( _( "Loading footprint library\n" ), RPT_SEVERITY_INFO );
1398
1400 FP_CACHE fpLib( &pcb_io, svgJob->m_libraryPath );
1401
1402 try
1403 {
1404 fpLib.Load();
1405 }
1406 catch( ... )
1407 {
1408 m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
1410 }
1411
1412 if( !svgJob->m_outputDirectory.IsEmpty() && !wxDir::Exists( svgJob->m_outputDirectory ) )
1413 {
1414 wxFileName::Mkdir( svgJob->m_outputDirectory );
1415 }
1416
1417 int exitCode = CLI::EXIT_CODES::OK;
1418
1419 // Just plot all the symbols we can
1420 FP_CACHE_FOOTPRINT_MAP& footprintMap = fpLib.GetFootprints();
1421
1422 bool singleFpPlotted = false;
1423 for( FP_CACHE_FOOTPRINT_MAP::iterator it = footprintMap.begin(); it != footprintMap.end();
1424 ++it )
1425 {
1426 const FOOTPRINT* fp = it->second->GetFootprint();
1427 if( !svgJob->m_footprint.IsEmpty() )
1428 {
1429 if( fp->GetFPID().GetLibItemName().wx_str() != svgJob->m_footprint )
1430 {
1431 // skip until we find the right footprint
1432 continue;
1433 }
1434 else
1435 {
1436 singleFpPlotted = true;
1437 }
1438 }
1439
1440 exitCode = doFpExportSvg( svgJob, fp );
1441 if( exitCode != CLI::EXIT_CODES::OK )
1442 break;
1443 }
1444
1445 if( !svgJob->m_footprint.IsEmpty() && !singleFpPlotted )
1446 {
1447 m_reporter->Report( _( "The given footprint could not be found to export." ) + wxS( "\n" ),
1449 }
1450
1451 return CLI::EXIT_CODES::OK;
1452}
1453
1454
1456{
1457 // the hack for now is we create fake boards containing the footprint and plot the board
1458 // until we refactor better plot api later
1459 std::unique_ptr<BOARD> brd;
1460 brd.reset( CreateEmptyBoard() );
1461 brd->GetProject()->ApplyTextVars( aSvgJob->GetVarOverrides() );
1462 brd->SynchronizeProperties();
1463
1464 FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( aFootprint->Clone() );
1465
1466 if( fp == nullptr )
1468
1469 fp->SetLink( niluuid );
1470 fp->SetFlags( IS_NEW );
1471 fp->SetParent( brd.get() );
1472
1473 for( PAD* pad : fp->Pads() )
1474 {
1475 pad->SetLocalRatsnestVisible( false );
1476 pad->SetNetCode( 0 );
1477 }
1478
1479 fp->SetOrientation( ANGLE_0 );
1480 fp->SetPosition( VECTOR2I( 0, 0 ) );
1481
1482 brd->Add( fp, ADD_MODE::INSERT, true );
1483
1484 wxFileName outputFile;
1485 outputFile.SetPath( aSvgJob->m_outputDirectory );
1486 outputFile.SetName( aFootprint->GetFPID().GetLibItemName().wx_str() );
1487 outputFile.SetExt( FILEEXT::SVGFileExtension );
1488
1489 m_reporter->Report( wxString::Format( _( "Plotting footprint '%s' to '%s'\n" ),
1490 aFootprint->GetFPID().GetLibItemName().wx_str(),
1491 outputFile.GetFullPath() ),
1493
1494
1495 PCB_PLOT_SVG_OPTIONS svgPlotOptions;
1496 svgPlotOptions.m_blackAndWhite = aSvgJob->m_blackAndWhite;
1497 svgPlotOptions.m_colorTheme = aSvgJob->m_colorTheme;
1498 svgPlotOptions.m_outputFile = outputFile.GetFullPath();
1499 svgPlotOptions.m_mirror = false;
1500 svgPlotOptions.m_pageSizeMode = 2; // board bounding box
1501 svgPlotOptions.m_printMaskLayer = aSvgJob->m_printMaskLayer;
1502 svgPlotOptions.m_sketchPadsOnFabLayers = aSvgJob->m_sketchPadsOnFabLayers;
1503 svgPlotOptions.m_hideDNPFPsOnFabLayers = aSvgJob->m_hideDNPFPsOnFabLayers;
1504 svgPlotOptions.m_sketchDNPFPsOnFabLayers = aSvgJob->m_sketchDNPFPsOnFabLayers;
1506 svgPlotOptions.m_plotFrame = false;
1507
1508 if( !EXPORT_SVG::Plot( brd.get(), svgPlotOptions ) )
1509 m_reporter->Report( _( "Error creating svg file" ) + wxS( "\n" ), RPT_SEVERITY_ERROR );
1510
1511 return CLI::EXIT_CODES::OK;
1512}
1513
1514
1516{
1517 JOB_PCB_DRC* drcJob = dynamic_cast<JOB_PCB_DRC*>( aJob );
1518
1519 if( drcJob == nullptr )
1521
1522 BOARD* brd = getBoard( drcJob->m_filename );
1523
1524 if( !brd )
1526
1527 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
1528 brd->SynchronizeProperties();
1529
1530 if( drcJob->m_outputFile.IsEmpty() )
1531 {
1532 wxFileName fn = brd->GetFileName();
1533 fn.SetName( fn.GetName() );
1534
1536 fn.SetExt( FILEEXT::JsonFileExtension );
1537 else
1538 fn.SetExt( FILEEXT::ReportFileExtension );
1539
1540 drcJob->m_outputFile = fn.GetFullName();
1541 }
1542
1543 EDA_UNITS units;
1544
1545 switch( drcJob->m_units )
1546 {
1547 case JOB_PCB_DRC::UNITS::INCHES: units = EDA_UNITS::INCHES; break;
1548 case JOB_PCB_DRC::UNITS::MILS: units = EDA_UNITS::MILS; break;
1549 case JOB_PCB_DRC::UNITS::MILLIMETERS: units = EDA_UNITS::MILLIMETRES; break;
1550 default: units = EDA_UNITS::MILLIMETRES; break;
1551 }
1552
1553 std::shared_ptr<DRC_ENGINE> drcEngine = brd->GetDesignSettings().m_DRCEngine;
1554 std::unique_ptr<NETLIST> netlist = std::make_unique<NETLIST>();
1555
1556 drcEngine->SetDrawingSheet( getDrawingSheetProxyView( brd ) );
1557
1558 // BOARD_COMMIT uses TOOL_MANAGER to grab the board internally so we must give it one
1559 TOOL_MANAGER* toolManager = new TOOL_MANAGER;
1560 toolManager->SetEnvironment( brd, nullptr, nullptr, Kiface().KifaceSettings(), nullptr );
1561
1562 BOARD_COMMIT commit( toolManager );
1563
1564 m_reporter->Report( _( "Running DRC...\n" ), RPT_SEVERITY_INFO );
1565
1566 if( drcJob->m_parity )
1567 {
1568 typedef bool (*NETLIST_FN_PTR)( const wxString&, std::string& );
1569
1571 wxFileName schematicPath( drcJob->m_filename );
1572 NETLIST_FN_PTR netlister = (NETLIST_FN_PTR) eeschema->IfaceOrAddress( KIFACE_NETLIST_SCHEMATIC );
1573 std::string netlist_str;
1574
1575 schematicPath.SetExt( FILEEXT::KiCadSchematicFileExtension );
1576
1577 if( !schematicPath.Exists() )
1578 schematicPath.SetExt( FILEEXT::LegacySchematicFileExtension );
1579
1580 if( !schematicPath.Exists() )
1581 {
1582 m_reporter->Report( _( "Failed to find schematic for parity tests.\n" ),
1584 }
1585 else
1586 {
1587 (*netlister)( schematicPath.GetFullPath(), netlist_str );
1588
1589 try
1590 {
1591 auto lineReader = new STRING_LINE_READER( netlist_str, _( "Eeschema netlist" ) );
1592 KICAD_NETLIST_READER netlistReader( lineReader, netlist.get() );
1593 netlistReader.LoadNetlist();
1594 }
1595 catch( const IO_ERROR& )
1596 {
1597 m_reporter->Report( _( "Failed to fetch schematic netlist for parity tests.\n" ),
1599 }
1600
1601 drcEngine->SetSchematicNetlist( netlist.get() );
1602 }
1603 }
1604
1605 drcEngine->SetProgressReporter( nullptr );
1606 drcEngine->SetViolationHandler(
1607 [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
1608 {
1609 PCB_MARKER* marker = new PCB_MARKER( aItem, aPos, aLayer );
1610 commit.Add( marker );
1611 } );
1612
1613 brd->RecordDRCExclusions();
1614 brd->DeleteMARKERs( true, true );
1615 drcEngine->RunTests( units, drcJob->m_reportAllTrackErrors, drcJob->m_parity );
1616 drcEngine->ClearViolationHandler();
1617
1618 commit.Push( _( "DRC" ), SKIP_UNDO | SKIP_SET_DIRTY );
1619
1620 // Update the exclusion status on any excluded markers that still exist.
1621 brd->ResolveDRCExclusions( false );
1622
1623 std::shared_ptr<DRC_ITEMS_PROVIDER> markersProvider = std::make_shared<DRC_ITEMS_PROVIDER>(
1625
1626 std::shared_ptr<DRC_ITEMS_PROVIDER> ratsnestProvider =
1627 std::make_shared<DRC_ITEMS_PROVIDER>( brd, MARKER_BASE::MARKER_RATSNEST );
1628
1629 std::shared_ptr<DRC_ITEMS_PROVIDER> fpWarningsProvider =
1630 std::make_shared<DRC_ITEMS_PROVIDER>( brd, MARKER_BASE::MARKER_PARITY );
1631
1632 markersProvider->SetSeverities( drcJob->m_severity );
1633 ratsnestProvider->SetSeverities( drcJob->m_severity );
1634 fpWarningsProvider->SetSeverities( drcJob->m_severity );
1635
1636 m_reporter->Report( wxString::Format( _( "Found %d violations\n" ),
1637 markersProvider->GetCount() ),
1639 m_reporter->Report( wxString::Format( _( "Found %d unconnected items\n" ),
1640 ratsnestProvider->GetCount() ),
1642
1643 if( drcJob->m_parity )
1644 {
1645 m_reporter->Report( wxString::Format( _( "Found %d schematic parity issues\n" ),
1646 fpWarningsProvider->GetCount() ),
1648 }
1649
1650 DRC_REPORT reportWriter( brd, units, markersProvider, ratsnestProvider, fpWarningsProvider );
1651
1652 bool wroteReport = false;
1653
1655 wroteReport = reportWriter.WriteJsonReport( drcJob->m_outputFile );
1656 else
1657 wroteReport = reportWriter.WriteTextReport( drcJob->m_outputFile );
1658
1659 if( !wroteReport )
1660 {
1661 m_reporter->Report( wxString::Format( _( "Unable to save DRC report to %s\n" ),
1662 drcJob->m_outputFile ),
1665 }
1666
1667 m_reporter->Report( wxString::Format( _( "Saved DRC Report to %s\n" ),
1668 drcJob->m_outputFile ),
1670
1671 if( drcJob->m_exitCodeViolations )
1672 {
1673 if( markersProvider->GetCount() > 0 || ratsnestProvider->GetCount() > 0
1674 || fpWarningsProvider->GetCount() > 0 )
1675 {
1677 }
1678 }
1679
1681}
1682
1683
1685{
1686 JOB_EXPORT_PCB_IPC2581* job = dynamic_cast<JOB_EXPORT_PCB_IPC2581*>( aJob );
1687
1688 if( job == nullptr )
1690
1691 BOARD* brd = getBoard( job->m_filename );
1692
1693 if( !brd )
1695
1696 if( job->OutputPathFullSpecified() )
1697 {
1698 wxFileName fn = brd->GetFileName();
1699 fn.SetName( fn.GetName() );
1700 fn.SetExt( FILEEXT::Ipc2581FileExtension );
1701
1702 job->SetOutputPath( fn.GetName() );
1703 }
1704
1705 std::map<std::string, UTF8> props;
1706 props["units"] = job->m_units == JOB_EXPORT_PCB_IPC2581::IPC2581_UNITS::MILLIMETERS ? "mm"
1707 : "inch";
1708 props["sigfig"] = wxString::Format( "%d", job->m_precision );
1709 props["version"] = job->m_version == JOB_EXPORT_PCB_IPC2581::IPC2581_VERSION::C ? "C" : "B";
1710 props["OEMRef"] = job->m_colInternalId;
1711 props["mpn"] = job->m_colMfgPn;
1712 props["mfg"] = job->m_colMfg;
1713 props["dist"] = job->m_colDist;
1714 props["distpn"] = job->m_colDistPn;
1715
1716 wxString tempFile = wxFileName::CreateTempFileName( wxS( "pcbnew_ipc" ) );
1717 try
1718 {
1720 pi->SetProgressReporter( m_progressReporter );
1721 pi->SaveBoard( tempFile, brd, &props );
1722 }
1723 catch( const IO_ERROR& ioe )
1724 {
1725 m_reporter->Report( wxString::Format( _( "Error generating IPC2581 file '%s'.\n%s" ),
1726 job->m_filename, ioe.What() ),
1728
1729 wxRemoveFile( tempFile );
1730
1732 }
1733
1734 if( job->m_compress )
1735 {
1736 wxFileName tempfn = job->GetFullOutputPath();
1737 tempfn.SetExt( FILEEXT::Ipc2581FileExtension );
1738 wxFileName zipfn = tempFile;
1739 zipfn.SetExt( "zip" );
1740
1741 wxFFileOutputStream fnout( zipfn.GetFullPath() );
1742 wxZipOutputStream zip( fnout );
1743 wxFFileInputStream fnin( tempFile );
1744
1745 zip.PutNextEntry( tempfn.GetFullName() );
1746 fnin.Read( zip );
1747 zip.Close();
1748 fnout.Close();
1749
1750 wxRemoveFile( tempFile );
1751 tempFile = zipfn.GetFullPath();
1752 }
1753
1754 // If save succeeded, replace the original with what we just wrote
1755 if( !wxRenameFile( tempFile, job->GetFullOutputPath() ) )
1756 {
1757 m_reporter->Report( wxString::Format( _( "Error generating IPC2581 file '%s'.\n"
1758 "Failed to rename temporary file '%s." )
1759 + wxS( "\n" ),
1760 job->GetFullOutputPath(), tempFile ),
1762 }
1763
1765}
1766
1767
1769{
1771 &aBrd->GetPageSettings(),
1772 aBrd->GetProject(),
1773 &aBrd->GetTitleBlock(),
1774 &aBrd->GetProperties() );
1775
1776 drawingSheet->SetSheetName( std::string() );
1777 drawingSheet->SetSheetPath( std::string() );
1778 drawingSheet->SetIsFirstPage( true );
1779
1780 drawingSheet->SetFileName( TO_UTF8( aBrd->GetFileName() ) );
1781
1782 return drawingSheet;
1783}
1784
1785
1786void PCBNEW_JOBS_HANDLER::loadOverrideDrawingSheet( BOARD* aBrd, const wxString& aSheetPath )
1787{
1788 // dont bother attempting to load a empty path, if there was one
1789 if( aSheetPath.IsEmpty() )
1790 return;
1791
1792 auto loadSheet =
1793 [&]( const wxString& path ) -> bool
1794 {
1797 resolver.SetProject( aBrd->GetProject() );
1799
1801 aBrd->GetProject()->GetProjectPath(),
1802 aBrd->GetEmbeddedFiles() );
1803 wxString msg;
1804
1805 if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( filename, &msg ) )
1806 {
1807 m_reporter->Report( wxString::Format( _( "Error loading drawing sheet '%s'." ),
1808 path )
1809 + wxS( "\n" ) + msg + wxS( "\n" ),
1811 return false;
1812 }
1813
1814 return true;
1815 };
1816
1817 if( loadSheet( aSheetPath ) )
1818 return;
1819
1820 // failed loading custom path, revert back to default
1821 loadSheet( aBrd->GetProject()->GetProjectFile().m_BoardDrawingSheetFile );
1822}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
#define RANGE_SCALE_3D
This defines the range that all coord will have to be rendered.
Definition: board_adapter.h:66
PROJECTION_TYPE
Definition: camera.h:40
static wxString m_DrawingSheetFileName
the name of the drawing sheet file, or empty to use the default drawing sheet
Definition: base_screen.h:85
Helper class to handle information needed to display 3D board.
Definition: board_adapter.h:73
double BiuTo3dUnits() const noexcept
Board integer units To 3D units.
bool m_IsPreviewer
true if we're in a 3D preview panel, false for the standard 3D viewer
void SetBoard(BOARD *aBoard) noexcept
Set current board to be rendered.
EDA_3D_VIEWER_SETTINGS * m_Cfg
std::map< int, COLOR4D > m_ColorOverrides
allows to override color scheme colors
void Set3dCacheManager(S3D_CACHE *aCacheMgr) noexcept
Update the cache manager pointer.
Definition: board_adapter.h:84
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:290
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:775
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition: board.cpp:2546
const PAGE_INFO & GetPageSettings() const
Definition: board.h:689
void RecordDRCExclusions()
Scan existing markers and record data from any that are Excluded.
Definition: board.cpp:327
TITLE_BLOCK & GetTitleBlock()
Definition: board.h:695
BOX2I ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Calculate the bounding box containing all board items (or board edge segments).
Definition: board.cpp:1670
const std::map< wxString, wxString > & GetProperties() const
Definition: board.h:362
const wxString & GetFileName() const
Definition: board.h:327
std::vector< PCB_MARKER * > ResolveDRCExclusions(bool aCreateMarkers)
Rebuild DRC markers from the serialized data in BOARD_DESIGN_SETTINGS.
Definition: board.cpp:344
const PCB_PLOT_PARAMS & GetPlotOptions() const
Definition: board.h:692
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:579
PROJECT * GetProject() const
Definition: board.h:491
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:892
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition: board.cpp:2042
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition: board.cpp:1357
constexpr const Vec GetCenter() const
Definition: box2.h:230
void SetProjection(PROJECTION_TYPE aProjection)
Definition: camera.h:206
void RotateY_T1(float aAngleInRadians)
Definition: camera.cpp:685
bool Zoom_T1(float aFactor)
Definition: camera.cpp:628
bool SetCurWindowSize(const wxSize &aSize)
Update the windows size of the camera.
Definition: camera.cpp:570
bool ViewCommand_T1(VIEW3D_TYPE aRequestedView)
Definition: camera.cpp:110
void RotateX_T1(float aAngleInRadians)
Definition: camera.cpp:679
void SetLookAtPos_T1(const SFVEC3F &aLookAtPos)
Definition: camera.h:162
const SFVEC3F & GetLookAtPos_T1() const
Definition: camera.h:167
void RotateZ_T1(float aAngleInRadians)
Definition: camera.cpp:691
bool ParametersChanged()
Definition: camera.cpp:729
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
Definition: commit.h:80
The dialog to create footprint position files and choose options (one or 2 files, units and force all...
A dialog to set the plot options and create plot files in various formats.
Definition: dialog_plot.h:41
int ShowModal() override
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.
bool LoadDrawingSheet(const wxString &aFullFileName, wxString *aMsg, bool aAppend=false)
Populates the list with a custom layout or the default layout if no custom layout is available.
static DS_DATA_MODEL & GetTheInstance()
static function: returns the instance of DS_DATA_MODEL used in the application
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:127
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:104
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)
wxString m_outputFile
Definition: exporter_step.h:53
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 aIncludeUnspecified, bool aIncludeDNP, 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:29
Provide an extensible class to resolve 3D model paths.
bool SetProject(PROJECT *aProject, bool *flgChanged=nullptr)
Set the current KiCad project directory as the first entry in the model path list.
void SetProgramBase(PGM_BASE *aBase)
Set a pointer to the application's PGM_BASE instance used to extract the local env vars.
wxString ResolvePath(const wxString &aFileName, const wxString &aWorkingPath, const EMBEDDED_FILES *aFiles)
Determines the full path of the given file name.
void SetPosition(const VECTOR2I &aPos) override
Definition: footprint.cpp:2341
void SetLink(const KIID &aLink)
Definition: footprint.h:853
void SetOrientation(const EDA_ANGLE &aNewAngle)
Definition: footprint.cpp:2411
EDA_ITEM * Clone() const override
Invoke a function on all children.
Definition: footprint.cpp:2032
std::deque< PAD * > & Pads()
Definition: footprint.h:206
const LIB_ID & GetFPID() const
Definition: footprint.h:248
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 UseIndividualShapes(bool aUnique)
Make pad shapes unique.
void UsePinNamesUnique(bool aUnique)
Make pin names unique.
void StoreOriginCoordsInFile(bool aStore)
Store coord origin in genCAD file.
void FlipBottomPads(bool aFlip)
Flip pad shapes on the bottom side.
void SetPlotOffet(VECTOR2I aOffset)
Set the coordinates offet when exporting items.
bool WriteFile(const wxString &aFullFileName)
Export a genCAD file.
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
void Register(const std::string &aJobTypeName, std::function< int(JOB *job)> aHandler, std::function< bool(JOB *job, wxWindow *aParent)> aConfigHandler)
PROGRESS_REPORTER * m_progressReporter
REPORTER * m_reporter
JOB_EXPORT_PCB_3D::FORMAT m_format
EXPORTER_STEP_PARAMS m_3dparams
Despite the name; also used for other formats.
bool m_mirror
Common Options.
wxString m_libraryPath
wxString m_outputLibraryPath
OUTPUT_FORMAT m_format
Definition: job_pcb_drc.h:58
UNITS m_units
Definition: job_pcb_drc.h:48
bool m_parity
Definition: job_pcb_drc.h:61
wxString m_filename
Definition: job_pcb_drc.h:36
int m_severity
Definition: job_pcb_drc.h:50
bool m_reportAllTrackErrors
Definition: job_pcb_drc.h:39
wxString m_outputFile
Definition: job_pcb_drc.h:37
bool m_exitCodeViolations
Definition: job_pcb_drc.h:60
BG_STYLE m_bgStyle
VECTOR3D m_rotation
wxString m_filename
VECTOR3D m_pivot
std::string m_colorPreset
wxString m_outputFile
An simple container class that lets us dispatch output jobs to kifaces.
Definition: job.h:79
void AddOutput(wxString aOutputPath)
Definition: job.h:111
wxString GetFullOutputPath() const
Definition: job.cpp:87
bool OutputPathFullSpecified() const
Definition: job.cpp:135
void SetOutputPath(const wxString &aPath)
Definition: job.cpp:129
const std::map< wxString, wxString > & GetVarOverrides() const
Definition: job.h:87
wxString GetOutputPath() const
Definition: job.h:119
Read the new s-expression based KiCad netlist format.
virtual void LoadNetlist() override
Load the contents of the netlist file into aNetlist.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:284
virtual KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=nullptr)
Return the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:406
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:291
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Definition: lseq.h:47
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:36
LSEQ UIOrder() const
Returns the copper, technical and user layers in the order shown in layer widget.
Definition: lset.cpp:799
LSEQ SeqStackupForPlotting() const
Return the sequence that is typical for a bottom-to-top stack-up.
Definition: lset.cpp:500
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
Definition: lset.cpp:687
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:676
@ MARKER_DRAWING_SHEET
Definition: marker_base.h:56
Definition: pad.h:54
void populateGerberPlotOptionsFromJob(PCB_PLOT_PARAMS &aPlotOpts, JOB_EXPORT_PCB_GERBER *aJob)
int JobExportFpUpgrade(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 JobExportGencad(JOB *aJob)
BOARD * getBoard(const wxString &aPath=wxEmptyString)
int JobExportRender(JOB *aJob)
int doFpExportSvg(JOB_FP_EXPORT_SVG *aSvgJob, const FOOTPRINT *aFootprint)
The main frame for Pcbnew.
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:69
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
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition: pcb_io_mgr.h:58
static bool ConvertLibrary(std::map< std::string, UTF8 > *aOldFileProps, const wxString &aOldFilePath, const wxString &aNewFilePath, REPORTER *aReporter)
Convert a schematic symbol library to the latest KiCad format.
Definition: pcb_io_mgr.cpp:191
static PCB_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath, int aCtl=0)
Return a plugin type given a footprint library's libPath.
Definition: pcb_io_mgr.cpp:136
Parameters and options when plotting/printing a board.
void SetDrillMarksType(DRILL_MARKS aVal)
void SetLayerSelection(LSET aSelection)
void SetPlotReference(bool aFlag)
void SetSketchPadsOnFabLayers(bool aFlag)
void SetUseGerberX2format(bool aUse)
void SetDXFPlotPolygonMode(bool aFlag)
void SetPlotFrameRef(bool aFlag)
void SetSketchDNPFPsOnFabLayers(bool aFlag)
void SetPlotPadNumbers(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 SetHideDNPFPsOnFabLayers(bool aFlag)
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 SetCrossoutDNPFPsOnFabLayers(bool aFlag)
void SetFormat(PLOT_FORMAT aFormat)
virtual bool EndPlot() override
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
Used to create Gerber drill files.
int CreatePlaceFile(const 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:159
static S3D_CACHE * Get3DCacheManager(PROJECT *aProject, bool updateProjDir=false)
Return a pointer to an instance of the 3D cache manager.
Definition: project_pcb.cpp:77
Container for project specific data.
Definition: project.h:64
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:200
bool Redraw(bool aIsMoving, REPORTER *aStatusReporter, REPORTER *aWarningReporter) override
Redraw the view.
void SetCurWindowSize(const wxSize &aSize) override
Before each render, the canvas will tell the render what is the size of its windows,...
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
T * GetAppSettings()
Returns a handle to the a given settings by type If the settings have already been loaded,...
COLOR_SETTINGS * GetColorSettings(const wxString &aName="user")
Retrieves a color settings object that applications can read colors from.
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition: richio.h:253
Master controller class:
Definition: tool_manager.h:62
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).
void Pan_T1(const SFVEC3F &aDeltaOffsetInc) override
Definition: track_ball.cpp:125
void SetT0_and_T1_current_T() override
This will set T0 and T1 with the current values.
Definition: track_ball.cpp:138
void Interpolate(float t) override
It will update the matrix to interpolate between T0 and T1 values.
Definition: track_ball.cpp:152
wxString wx_str() const
Definition: utf8.cpp:45
T y
Definition: vector3.h:64
T z
Definition: vector3.h:65
T x
Definition: vector3.h:63
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:401
#define IS_NEW
New item, just created.
EDA_UNITS
Definition: eda_units.h:46
static FILENAME_RESOLVER * resolver
Definition: export_idf.cpp:53
@ FRAME_PCB_EDITOR
Definition: frame_type.h:42
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 BrepFileExtension
static const std::string GerberJobFileExtension
static const std::string GerberFileExtension
static const std::string XaoFileExtension
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 StlFileExtension
static const std::string PlyFileExtension
static const std::string StepFileExtension
static const std::string SVGFileExtension
static const std::string VrmlFileExtension
static const std::string KiCadPcbFileExtension
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition: io_mgr.h:33
PROJECT & Prj()
Definition: kicad.cpp:595
@ KIFACE_NETLIST_SCHEMATIC
Definition: kiface_ids.h:56
KIID niluuid(0)
@ LAYER_3D_BACKGROUND_TOP
Definition: layer_ids.h:454
@ LAYER_3D_BACKGROUND_BOTTOM
Definition: layer_ids.h:453
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ B_Cu
Definition: layer_ids.h:65
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
@ F_Cu
Definition: layer_ids.h:64
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 ERR_INVALID_INPUT_FILE
Definition: exit_codes.h:33
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)
SETTINGS_MANAGER * GetSettingsManager()
BOARD * CreateEmptyBoard()
Construct a default BOARD with a temporary (no filename) project.
BOARD * LoadBoard(const wxString &aFileName, bool aSetActive, PROJECT *aProject)
Loads a board from file This function identifies the file type by extension and determines the correc...
const wxString GetGerberProtelExtension(int aLayer)
Definition: pcbplot.cpp:43
void BuildPlotFileName(wxFileName *aFilename, const wxString &aOutputDir, const wxString &aSuffix, const wxString &aExtension)
Complete a plot filename.
Definition: pcbplot.cpp:379
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.).
PLOTTER * StartPlotBoard(BOARD *aBoard, const PCB_PLOT_PARAMS *aPlotOpts, int aLayer, const wxString &aLayerName, 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...
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
see class PGM_BASE
PLOT_FORMAT
The set of supported output plot formats.
Definition: plotter.h:65
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:43
#define SKIP_UNDO
Definition: sch_commit.h:41
const int scale
MODEL3D_FORMAT_TYPE fileType(const char *aFileName)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: string_utils.h:398
constexpr double IUTomm(int iu) const
Definition: base_units.h:86
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
Implement a participant in the KIWAY alchemy.
Definition: kiway.h:151
bool m_sketchPadsOnFabLayers
Definition: export_svg.h:37
bool m_sketchDNPFPsOnFabLayers
Definition: export_svg.h:39
wxString m_colorTheme
Definition: export_svg.h:27
wxString m_outputFile
Definition: export_svg.h:26
bool m_crossoutDNPFPsOnFabLayers
Definition: export_svg.h:40
bool m_hideDNPFPsOnFabLayers
Definition: export_svg.h:38
Declaration for a track ball camera.
double DEG2RAD(double deg)
Definition: trigo.h:166
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691
Definition of file extensions used in Kicad.
glm::vec3 SFVEC3F
Definition: xv3d_types.h:44