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>
42#include <jobs/job_pcb_render.h>
43#include <jobs/job_pcb_drc.h>
44#include <lset.h>
45#include <cli/exit_codes.h>
51#include <tool/tool_manager.h>
52#include <tools/drc_tool.h>
53#include <filename_resolver.h>
58#include <kiface_base.h>
59#include <macros.h>
60#include <pad.h>
61#include <pcb_marker.h>
65#include <kiface_ids.h>
68#include <pcbnew_settings.h>
69#include <pcbplot.h>
70#include <pgm_base.h>
73#include <project_pcb.h>
75#include <reporter.h>
77#include <export_vrml.h>
78#include <wx/wfstream.h>
79#include <wx/zipstrm.h>
87#include <dialogs/dialog_plot.h>
88
90
91
92#ifdef _WIN32
93#ifdef TRANSPARENT
94#undef TRANSPARENT
95#endif
96#endif
97
98
100 JOB_DISPATCHER( aKiway ),
101 m_cliBoard( nullptr )
102{
103 Register( "3d", std::bind( &PCBNEW_JOBS_HANDLER::JobExportStep, this, std::placeholders::_1 ),
104 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
105 {
106 JOB_EXPORT_PCB_3D* svgJob = dynamic_cast<JOB_EXPORT_PCB_3D*>( job );
107
108 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>(
109 aKiway->Player( FRAME_PCB_EDITOR, false ) );
110 DIALOG_EXPORT_STEP dlg( editFrame, aParent, "", svgJob );
111 dlg.ShowModal();
112
113 return dlg.GetReturnCode() == wxID_OK;
114 } );
115 Register( "render",
116 std::bind( &PCBNEW_JOBS_HANDLER::JobExportRender, this, std::placeholders::_1 ),
117 []( JOB* job, wxWindow* aParent ) -> bool
118 {
119 return false;
120 } );
121 Register( "svg", std::bind( &PCBNEW_JOBS_HANDLER::JobExportSvg, this, std::placeholders::_1 ),
122 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
123 {
124 JOB_EXPORT_PCB_SVG* svgJob = dynamic_cast<JOB_EXPORT_PCB_SVG*>( job );
125
126 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>(
127 aKiway->Player( FRAME_PCB_EDITOR, false ) );
128
129 DIALOG_PLOT dlg( editFrame, aParent, svgJob );
130 dlg.ShowModal();
131
132 return dlg.GetReturnCode() == wxID_OK;
133 } );
134 Register( "gencad",
135 std::bind( &PCBNEW_JOBS_HANDLER::JobExportGencad, this, std::placeholders::_1 ),
136 []( JOB* job, wxWindow* aParent ) -> bool
137 {
138 return false;
139 } );
140 Register( "dxf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDxf, this, std::placeholders::_1 ),
141 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
142 {
143 JOB_EXPORT_PCB_DXF* dxfJob = dynamic_cast<JOB_EXPORT_PCB_DXF*>( job );
144
145 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>(
146 aKiway->Player( FRAME_PCB_EDITOR, false ) );
147
148 DIALOG_PLOT dlg( editFrame, aParent, dxfJob );
149 dlg.ShowModal();
150
151 return dlg.GetReturnCode() == wxID_OK;
152 } );
153 Register( "pdf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPdf, this, std::placeholders::_1 ),
154 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
155 {
156 JOB_EXPORT_PCB_PDF* pdfJob = dynamic_cast<JOB_EXPORT_PCB_PDF*>( job );
157
158 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>(
159 aKiway->Player( FRAME_PCB_EDITOR, false ) );
160
161 DIALOG_PLOT dlg( editFrame, aParent, pdfJob );
162 dlg.ShowModal();
163
164 return dlg.GetReturnCode() == wxID_OK;
165 } );
166 Register( "gerber",
167 std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerber, this, std::placeholders::_1 ),
168 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
169 {
170 JOB_EXPORT_PCB_GERBER* gJob = dynamic_cast<JOB_EXPORT_PCB_GERBER*>( job );
171
172 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>(
173 aKiway->Player( FRAME_PCB_EDITOR, false ) );
174
175 DIALOG_PLOT dlg( editFrame, aParent, gJob );
176 dlg.ShowModal();
177
178 return dlg.GetReturnCode() == wxID_OK;
179 } );
180 Register( "gerbers",
181 std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerbers, this, std::placeholders::_1 ),
182 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
183 {
184 JOB_EXPORT_PCB_GERBERS* gJob = dynamic_cast<JOB_EXPORT_PCB_GERBERS*>( job );
185
186 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>(
187 aKiway->Player( FRAME_PCB_EDITOR, false ) );
188
189 DIALOG_PLOT dlg( editFrame, aParent, gJob );
190 dlg.ShowModal();
191
192 return dlg.GetReturnCode() == wxID_OK;
193 } );
194 Register( "drill",
195 std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrill, this, std::placeholders::_1 ),
196 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
197 {
198 JOB_EXPORT_PCB_DRILL* drillJob = dynamic_cast<JOB_EXPORT_PCB_DRILL*>( job );
199
200 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( aKiway->Player( FRAME_PCB_EDITOR, false ) );
201 DIALOG_GENDRILL dlg( editFrame, drillJob, aParent );
202 dlg.ShowModal();
203 return dlg.GetReturnCode() == wxID_OK;
204 } );
205 Register( "pos", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPos, this, std::placeholders::_1 ),
206 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
207 {
208 JOB_EXPORT_PCB_POS* posJob = dynamic_cast<JOB_EXPORT_PCB_POS*>( job );
209
210 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( aKiway->Player( FRAME_PCB_EDITOR, false ) );
211 DIALOG_GEN_FOOTPRINT_POSITION dlg( posJob, editFrame, aParent );
212 dlg.ShowModal();
213 return dlg.GetReturnCode() == wxID_OK;
214 } );
215 Register( "fpupgrade",
216 std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpUpgrade, this, std::placeholders::_1 ),
217 []( JOB* job, wxWindow* aParent ) -> bool
218 {
219 return false;
220 } );
221 Register( "fpsvg",
222 std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpSvg, this, std::placeholders::_1 ),
223 []( JOB* job, wxWindow* aParent ) -> bool
224 {
225 return false;
226 } );
227 Register( "drc", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrc, this, std::placeholders::_1 ),
228 []( JOB* job, wxWindow* aParent ) -> bool
229 {
230 return false;
231 } );
232 Register( "ipc2581",
233 std::bind( &PCBNEW_JOBS_HANDLER::JobExportIpc2581, this, std::placeholders::_1 ),
234 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
235 {
236 JOB_EXPORT_PCB_IPC2581* ipcJob = dynamic_cast<JOB_EXPORT_PCB_IPC2581*>( job );
237
238 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( aKiway->Player( FRAME_PCB_EDITOR, false ) );
239 wxCHECK( ipcJob && editFrame, false );
240
241 DIALOG_EXPORT_2581 dlg( ipcJob, editFrame, aParent );
242 dlg.ShowModal();
243
244 return dlg.GetReturnCode() == wxID_OK;
245 } );
246 Register( "odb",
247 std::bind( &PCBNEW_JOBS_HANDLER::JobExportOdb, this, std::placeholders::_1 ),
248 [aKiway]( JOB* job, wxWindow* aParent ) -> bool
249 {
250 JOB_EXPORT_PCB_ODB* odbJob = dynamic_cast<JOB_EXPORT_PCB_ODB*>( job );
251 wxCHECK( odbJob, false );
252
253 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( aKiway->Player( FRAME_PCB_EDITOR, false ) );
254
255 DIALOG_EXPORT_ODBPP dlg( odbJob, editFrame, aParent );
256 dlg.ShowModal();
257
258 return dlg.GetReturnCode() == wxID_OK;
259 } );
260}
261
262
263BOARD* PCBNEW_JOBS_HANDLER::getBoard( const wxString& aPath )
264{
265 BOARD* brd = nullptr;
266
267 if( !Pgm().IsGUI() &&
268 Pgm().GetSettingsManager().IsProjectOpen() )
269 {
270 wxString pcbPath = aPath;
271
272 if( pcbPath.IsEmpty() )
273 {
274 wxFileName path = Pgm().GetSettingsManager().Prj().GetProjectFullName();
276 path.MakeAbsolute();
277 pcbPath = path.GetFullPath();
278 }
279
280 if( !m_cliBoard )
281 {
282 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
283 m_cliBoard = LoadBoard( pcbPath, true );
284 }
285
286 brd = m_cliBoard;
287 }
288 else if( Pgm().IsGUI() && Pgm().GetSettingsManager().IsProjectOpen() )
289 {
290 PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_kiway->Player( FRAME_PCB_EDITOR, false ) );
291
292 if( editFrame )
293 {
294 brd = editFrame->GetBoard();
295 }
296 }
297 else
298 {
299 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
300 brd = LoadBoard( aPath, true );
301 }
302
303 if ( !brd )
304 {
305 m_reporter->Report( _( "Failed to load board\n" ), RPT_SEVERITY_ERROR );
306 }
307
308 return brd;
309}
310
311
313{
314 JOB_EXPORT_PCB_3D* aStepJob = dynamic_cast<JOB_EXPORT_PCB_3D*>( aJob );
315
316 if( aStepJob == nullptr )
318
319 BOARD* brd = getBoard( aStepJob->m_filename );
320
321 if( !brd )
323
324 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
326
327 if( aStepJob->GetOutputPath().IsEmpty() )
328 {
329 wxFileName fn = brd->GetFileName();
330 fn.SetName( fn.GetName() );
331
332 switch( aStepJob->m_format )
333 {
335 break;
337 break;
339 break;
341 break;
343 break;
345 break;
347 break;
348 default:
349 return CLI::EXIT_CODES::ERR_UNKNOWN; // shouldnt have gotten here
350 }
351
352 aStepJob->SetOutputPath( fn.GetFullName() );
353 }
354
356 {
357
358 double scale = 0.0;
359 switch ( aStepJob->m_vrmlUnits )
360 {
362 case JOB_EXPORT_PCB_3D::VRML_UNITS::METERS: scale = 0.001; break;
363 case JOB_EXPORT_PCB_3D::VRML_UNITS::TENTHS: scale = 10.0 / 25.4; break;
364 case JOB_EXPORT_PCB_3D::VRML_UNITS::INCHES: scale = 1.0 / 25.4; break;
365 }
366
367 EXPORTER_VRML vrmlExporter( brd );
368 wxString messages;
369
370 double originX = pcbIUScale.IUTomm( aStepJob->m_3dparams.m_Origin.x );
371 double originY = pcbIUScale.IUTomm( aStepJob->m_3dparams.m_Origin.y );
372
373 if( !aStepJob->m_hasUserOrigin )
374 {
375 BOX2I bbox = brd->ComputeBoundingBox( true );
376 originX = pcbIUScale.IUTomm( bbox.GetCenter().x );
377 originY = pcbIUScale.IUTomm( bbox.GetCenter().y );
378 }
379
380 bool success = vrmlExporter.ExportVRML_File(
381 brd->GetProject(), &messages, aStepJob->GetFullOutputPath(), scale,
383 !aStepJob->m_vrmlModelDir.IsEmpty(), aStepJob->m_vrmlRelativePaths,
384 aStepJob->m_vrmlModelDir, originX, originY );
385
386 if ( success )
387 {
388 m_reporter->Report( wxString::Format( _( "Successfully exported VRML to %s" ),
389 aStepJob->GetFullOutputPath() ),
391 }
392 else
393 {
394 m_reporter->Report( _( "Error exporting VRML" ), RPT_SEVERITY_ERROR );
396 }
397 }
398 else
399 {
400 EXPORTER_STEP_PARAMS params = aStepJob->m_3dparams;
401
402 switch( aStepJob->m_format )
403 {
406 break;
409 break;
412 break;
415 break;
418 break;
421 break;
422 default:
423 return CLI::EXIT_CODES::ERR_UNKNOWN; // shouldnt have gotten here
424 }
425
426 EXPORTER_STEP stepExporter( brd, params );
427 stepExporter.m_outputFile = aStepJob->GetFullOutputPath();
428
429 if( !stepExporter.Export() )
431 }
432
433 return CLI::EXIT_CODES::OK;
434}
435
436
438{
439 JOB_PCB_RENDER* aRenderJob = dynamic_cast<JOB_PCB_RENDER*>( aJob );
440
441 if( aRenderJob == nullptr )
443
444 BOARD* brd = getBoard( aRenderJob->m_filename );
445
446 if( !brd )
448
449 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
451
452 BOARD_ADAPTER boardAdapter;
453
454 boardAdapter.SetBoard( brd );
455 boardAdapter.m_IsBoardView = false;
456 boardAdapter.m_IsPreviewer = true; // Force display 3D models, regardless of 3D viewer options
457
460
461 if( aRenderJob->m_quality == JOB_PCB_RENDER::QUALITY::BASIC )
462 {
463 // Silkscreen is pixelated without antialiasing
465
466 cfg->m_Render.raytrace_backfloor = false;
468
470 cfg->m_Render.raytrace_reflections = false;
471 cfg->m_Render.raytrace_shadows = false;
472
473 // Better colors
475
476 // Tracks below soldermask are not visible without refractions
477 cfg->m_Render.raytrace_refractions = true;
479 }
480 else if( aRenderJob->m_quality == JOB_PCB_RENDER::QUALITY::HIGH )
481 {
483 cfg->m_Render.raytrace_backfloor = true;
486 cfg->m_Render.raytrace_reflections = true;
487 cfg->m_Render.raytrace_shadows = true;
488 cfg->m_Render.raytrace_refractions = true;
490 }
491
492 if( aRenderJob->m_floor )
493 {
494 cfg->m_Render.raytrace_backfloor = true;
495 cfg->m_Render.raytrace_shadows = true;
497 }
498
499 cfg->m_CurrentPreset = aRenderJob->m_colorPreset;
500 boardAdapter.m_Cfg = cfg;
501
504 && aRenderJob->m_format == JOB_PCB_RENDER::FORMAT::PNG ) )
505 {
506 boardAdapter.m_ColorOverrides[LAYER_3D_BACKGROUND_TOP] = COLOR4D( 1.0, 1.0, 1.0, 0.0 );
507 boardAdapter.m_ColorOverrides[LAYER_3D_BACKGROUND_BOTTOM] = COLOR4D( 1.0, 1.0, 1.0, 0.0 );
508 }
509
511
512 static std::map<JOB_PCB_RENDER::SIDE, VIEW3D_TYPE> s_viewCmdMap = {
513 { JOB_PCB_RENDER::SIDE::TOP, VIEW3D_TYPE::VIEW3D_TOP },
514 { JOB_PCB_RENDER::SIDE::BOTTOM, VIEW3D_TYPE::VIEW3D_BOTTOM },
515 { JOB_PCB_RENDER::SIDE::LEFT, VIEW3D_TYPE::VIEW3D_LEFT },
516 { JOB_PCB_RENDER::SIDE::RIGHT, VIEW3D_TYPE::VIEW3D_RIGHT },
517 { JOB_PCB_RENDER::SIDE::FRONT, VIEW3D_TYPE::VIEW3D_FRONT },
518 { JOB_PCB_RENDER::SIDE::BACK, VIEW3D_TYPE::VIEW3D_BACK },
519 };
520
521 PROJECTION_TYPE projection =
522 aRenderJob->m_perspective ? PROJECTION_TYPE::PERSPECTIVE : PROJECTION_TYPE::ORTHO;
523
524 wxSize windowSize( aRenderJob->m_width, aRenderJob->m_height );
525 TRACK_BALL camera( 2 * RANGE_SCALE_3D );
526
527 camera.SetProjection( projection );
528 camera.SetCurWindowSize( windowSize );
529
530 RENDER_3D_RAYTRACE_RAM raytrace( boardAdapter, camera );
531 raytrace.SetCurWindowSize( windowSize );
532
533 for( bool first = true; raytrace.Redraw( false, m_reporter, m_reporter ); first = false )
534 {
535 if( first )
536 {
537 const float cmTo3D = boardAdapter.BiuTo3dUnits() * pcbIUScale.mmToIU( 10.0 );
538
539 // First redraw resets lookat point to the board center, so set up the camera here
540 camera.ViewCommand_T1( s_viewCmdMap[aRenderJob->m_side] );
541
542 camera.SetLookAtPos_T1(
543 camera.GetLookAtPos_T1()
544 + SFVEC3F( aRenderJob->m_pivot.x, aRenderJob->m_pivot.y, aRenderJob->m_pivot.z )
545 * cmTo3D );
546
547 camera.Pan_T1(
548 SFVEC3F( aRenderJob->m_pan.x, aRenderJob->m_pan.y, aRenderJob->m_pan.z ) );
549
550 camera.Zoom_T1( aRenderJob->m_zoom );
551
552 camera.RotateX_T1( DEG2RAD( aRenderJob->m_rotation.x ) );
553 camera.RotateY_T1( DEG2RAD( aRenderJob->m_rotation.y ) );
554 camera.RotateZ_T1( DEG2RAD( aRenderJob->m_rotation.z ) );
555
556 camera.Interpolate( 1.0f );
557 camera.SetT0_and_T1_current_T();
558 camera.ParametersChanged();
559 }
560 }
561
562 uint8_t* rgbaBuffer = raytrace.GetBuffer();
563 wxSize realSize = raytrace.GetRealBufferSize();
564 bool success = !!rgbaBuffer;
565
566 if( rgbaBuffer )
567 {
568 const unsigned int wxh = realSize.x * realSize.y;
569
570 unsigned char* rgbBuffer = (unsigned char*) malloc( wxh * 3 );
571 unsigned char* alphaBuffer = (unsigned char*) malloc( wxh );
572
573 unsigned char* rgbaPtr = rgbaBuffer;
574 unsigned char* rgbPtr = rgbBuffer;
575 unsigned char* alphaPtr = alphaBuffer;
576
577 for( int y = 0; y < realSize.y; y++ )
578 {
579 for( int x = 0; x < realSize.x; x++ )
580 {
581 rgbPtr[0] = rgbaPtr[0];
582 rgbPtr[1] = rgbaPtr[1];
583 rgbPtr[2] = rgbaPtr[2];
584 alphaPtr[0] = rgbaPtr[3];
585
586 rgbaPtr += 4;
587 rgbPtr += 3;
588 alphaPtr += 1;
589 }
590 }
591
592 wxImage image( realSize );
593 image.SetData( rgbBuffer );
594 image.SetAlpha( alphaBuffer );
595 image = image.Mirror( false );
596
597 image.SetOption( wxIMAGE_OPTION_QUALITY, 90 );
598 image.SaveFile( aRenderJob->m_outputFile,
599 aRenderJob->m_format == JOB_PCB_RENDER::FORMAT::PNG ? wxBITMAP_TYPE_PNG
600 : wxBITMAP_TYPE_JPEG );
601 }
602
603 m_reporter->Report( wxString::Format( _( "Actual image size: %dx%d" ), realSize.x, realSize.y )
604 + wxS( "\n" ),
606
607 if( success )
608 m_reporter->Report( _( "Successfully created 3D render image" ) + wxS( "\n" ),
610 else
611 m_reporter->Report( _( "Error creating 3D render image" ) + wxS( "\n" ),
613
614 return CLI::EXIT_CODES::OK;
615}
616
617
619{
620 JOB_EXPORT_PCB_SVG* aSvgJob = dynamic_cast<JOB_EXPORT_PCB_SVG*>( aJob );
621
622 if( aSvgJob == nullptr )
624
625 PCB_PLOT_SVG_OPTIONS svgPlotOptions;
626 svgPlotOptions.m_blackAndWhite = aSvgJob->m_blackAndWhite;
627 svgPlotOptions.m_colorTheme = aSvgJob->m_colorTheme;
628 svgPlotOptions.m_outputFile = aSvgJob->GetFullOutputPath();
629 svgPlotOptions.m_mirror = aSvgJob->m_mirror;
630 svgPlotOptions.m_negative = aSvgJob->m_negative;
631 svgPlotOptions.m_pageSizeMode = aSvgJob->m_pageSizeMode;
632 svgPlotOptions.m_printMaskLayer = aSvgJob->m_printMaskLayer;
633 svgPlotOptions.m_plotFrame = aSvgJob->m_plotDrawingSheet;
634 svgPlotOptions.m_sketchPadsOnFabLayers = aSvgJob->m_sketchPadsOnFabLayers;
635 svgPlotOptions.m_hideDNPFPsOnFabLayers = aSvgJob->m_hideDNPFPsOnFabLayers;
638 svgPlotOptions.m_drillShapeOption = aSvgJob->m_drillShapeOption;
639 svgPlotOptions.m_precision = aSvgJob->m_precision;
640
641 BOARD* brd = getBoard( aSvgJob->m_filename );
642
643 if( !brd )
645
647 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
649
650 if( EXPORT_SVG::Plot( brd, svgPlotOptions ) )
651 m_reporter->Report( _( "Successfully created svg file" ) + wxS( "\n" ), RPT_SEVERITY_INFO );
652 else
653 m_reporter->Report( _( "Error creating svg file" ) + wxS( "\n" ), RPT_SEVERITY_ERROR );
654
655 return CLI::EXIT_CODES::OK;
656}
657
658
660{
661 JOB_EXPORT_PCB_DXF* aDxfJob = dynamic_cast<JOB_EXPORT_PCB_DXF*>( aJob );
662
663 if( aDxfJob == nullptr )
665
666 BOARD* brd = getBoard( aDxfJob->m_filename );
667
668 if( !brd )
670
672 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
674
675 if( aDxfJob->GetOutputPath().IsEmpty() )
676 {
677 wxFileName fn = brd->GetFileName();
678 fn.SetName( fn.GetName() );
679 fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::DXF ) );
680
681 aDxfJob->SetOutputPath( fn.GetFullName() );
682 }
683
684 PCB_PLOT_PARAMS plotOpts;
685 plotOpts.SetFormat( PLOT_FORMAT::DXF );
686
688 plotOpts.SetUseAuxOrigin( aDxfJob->m_useDrillOrigin );
689
691 plotOpts.SetDXFPlotUnits( DXF_UNITS::MILLIMETERS );
692 else
693 plotOpts.SetDXFPlotUnits( DXF_UNITS::INCHES );
694
695 plotOpts.SetPlotFrameRef( aDxfJob->m_plotDrawingSheet );
696 plotOpts.SetPlotValue( aDxfJob->m_plotFootprintValues );
697 plotOpts.SetPlotReference( aDxfJob->m_plotRefDes );
698 plotOpts.SetLayerSelection( aDxfJob->m_printMaskLayer );
700
702 wxString layerName;
703 wxString sheetName;
704 wxString sheetPath;
705
706 if( aDxfJob->m_printMaskLayer.size() == 1 )
707 {
708 layer = aDxfJob->m_printMaskLayer.front();
709 layerName = brd->GetLayerName( layer );
710 }
711
712 if( aJob->GetVarOverrides().contains( wxT( "LAYER" ) ) )
713 layerName = aJob->GetVarOverrides().at( wxT( "LAYER" ) );
714
715 if( aJob->GetVarOverrides().contains( wxT( "SHEETNAME" ) ) )
716 sheetName = aJob->GetVarOverrides().at( wxT( "SHEETNAME" ) );
717
718 if( aJob->GetVarOverrides().contains( wxT( "SHEETPATH" ) ) )
719 sheetPath = aJob->GetVarOverrides().at( wxT( "SHEETPATH" ) );
720
721 DXF_PLOTTER* plotter = (DXF_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer, layerName, aDxfJob->GetFullOutputPath(), sheetName,
722 sheetPath );
723
724 if( plotter )
725 {
726 PlotBoardLayers( brd, plotter, aDxfJob->m_printMaskLayer, plotOpts );
727 plotter->EndPlot();
728 }
729
730 delete plotter;
731
732 return CLI::EXIT_CODES::OK;
733}
734
735
737{
738 JOB_EXPORT_PCB_PDF* aPdfJob = dynamic_cast<JOB_EXPORT_PCB_PDF*>( aJob );
739
740 if( aPdfJob == nullptr )
742
743 BOARD* brd = getBoard( aPdfJob->m_filename );
744
745 if( !brd )
747
749 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
751
752 if( aPdfJob->GetOutputPath().IsEmpty() )
753 {
754 wxFileName fn = brd->GetFileName();
755 fn.SetName( fn.GetName() );
756 fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::PDF ) );
757
758 aPdfJob->SetOutputPath( fn.GetFullName() );
759 }
760
761 PCB_PLOT_PARAMS plotOpts;
762 plotOpts.SetFormat( PLOT_FORMAT::PDF );
763
764 plotOpts.SetPlotFrameRef( aPdfJob->m_plotDrawingSheet );
765 plotOpts.SetPlotValue( aPdfJob->m_plotFootprintValues );
766 plotOpts.SetPlotReference( aPdfJob->m_plotRefDes );
767
768 plotOpts.SetLayerSelection( aPdfJob->m_printMaskLayer );
770
772 plotOpts.SetColorSettings( mgr.GetColorSettings( aPdfJob->m_colorTheme ) );
773 plotOpts.SetMirror( aPdfJob->m_mirror );
774 plotOpts.SetBlackAndWhite( aPdfJob->m_blackAndWhite );
775 plotOpts.SetNegative( aPdfJob->m_negative );
776
777 if( aPdfJob->m_sketchPadsOnFabLayers )
778 {
779 plotOpts.SetSketchPadsOnFabLayers( true );
780 plotOpts.SetPlotPadNumbers( true );
781 }
782
786
787 switch( aPdfJob->m_drillShapeOption )
788 {
789 default:
790 case 0: plotOpts.SetDrillMarksType( DRILL_MARKS::NO_DRILL_SHAPE ); break;
791 case 1: plotOpts.SetDrillMarksType( DRILL_MARKS::SMALL_DRILL_SHAPE ); break;
792 case 2: plotOpts.SetDrillMarksType( DRILL_MARKS::FULL_DRILL_SHAPE ); break;
793 }
794
796 wxString layerName;
797 wxString sheetName;
798 wxString sheetPath;
799
800 if( aPdfJob->m_printMaskLayer.size() == 1 )
801 {
802 layer = aPdfJob->m_printMaskLayer.front();
803 layerName = brd->GetLayerName( layer );
804 }
805
806 if( aPdfJob->GetVarOverrides().contains( wxT( "LAYER" ) ) )
807 layerName = aPdfJob->GetVarOverrides().at( wxT( "LAYER" ) );
808
809 if( aPdfJob->GetVarOverrides().contains( wxT( "SHEETNAME" ) ) )
810 sheetName = aPdfJob->GetVarOverrides().at( wxT( "SHEETNAME" ) );
811
812 if( aPdfJob->GetVarOverrides().contains( wxT( "SHEETPATH" ) ) )
813 sheetPath = aPdfJob->GetVarOverrides().at( wxT( "SHEETPATH" ) );
814
815 PDF_PLOTTER* plotter = (PDF_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer, layerName, aPdfJob->GetFullOutputPath(), sheetName,
816 sheetPath );
817
818 if( plotter )
819 {
820 PlotBoardLayers( brd, plotter, aPdfJob->m_printMaskLayer, plotOpts );
821 PlotInteractiveLayer( brd, plotter, plotOpts );
822 plotter->EndPlot();
823 }
824
825 delete plotter;
826
827 return CLI::EXIT_CODES::OK;
828}
829
830
832{
833 int exitCode = CLI::EXIT_CODES::OK;
834 JOB_EXPORT_PCB_GERBERS* aGerberJob = dynamic_cast<JOB_EXPORT_PCB_GERBERS*>( aJob );
835
836 if( aGerberJob == nullptr )
838
839 BOARD* brd = getBoard( aGerberJob->m_filename );
840
841 if( !brd )
843
844 loadOverrideDrawingSheet( brd, aGerberJob->m_drawingSheet );
845 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
847
848 PCB_PLOT_PARAMS boardPlotOptions = brd->GetPlotOptions();
849 LSET plotOnAllLayersSelection = boardPlotOptions.GetPlotOnAllLayersSelection();
850 GERBER_JOBFILE_WRITER jobfile_writer( brd );
851
852 wxString fileExt;
853
854 if( aGerberJob->m_useBoardPlotParams )
855 {
856 // The board plot options are saved with all copper layers enabled, even those that don't
857 // exist in the current stackup. This is done so the layers are automatically enabled in the plot
858 // dialog when the user enables them. We need to filter out these not-enabled layers here so
859 // we don't plot 32 layers when we only have 4, etc.
860 LSET plotLayers = ( boardPlotOptions.GetLayerSelection() & LSET::AllNonCuMask() )
861 | ( brd->GetEnabledLayers() & LSET::AllCuMask() );
862 aGerberJob->m_printMaskLayer = plotLayers.SeqStackupForPlotting();
863 aGerberJob->m_layersIncludeOnAll = boardPlotOptions.GetPlotOnAllLayersSelection();
864 }
865 else
866 {
867 // default to the board enabled layers
868 if( aGerberJob->m_printMaskLayer.empty() )
870
871 if( aGerberJob->m_layersIncludeOnAllSet )
872 aGerberJob->m_layersIncludeOnAll = plotOnAllLayersSelection;
873 }
874
875 // Ensure layers to plot are restricted to enabled layers of the board to plot
876 LSET layersToPlot = LSET( { aGerberJob->m_printMaskLayer } ) & brd->GetEnabledLayers();
877
878 for( PCB_LAYER_ID layer : layersToPlot.UIOrder() )
879 {
880 LSEQ plotSequence;
881
882 // Base layer always gets plotted first.
883 plotSequence.push_back( layer );
884
885 // Now all the "include on all" layers
886 for( PCB_LAYER_ID layer_all : aGerberJob->m_layersIncludeOnAll.UIOrder() )
887 {
888 // Don't plot the same layer more than once;
889 if( find( plotSequence.begin(), plotSequence.end(), layer_all ) != plotSequence.end() )
890 continue;
891
892 plotSequence.push_back( layer_all );
893 }
894
895 // Pick the basename from the board file
896 wxFileName fn( brd->GetFileName() );
897 wxString layerName = brd->GetLayerName( layer );
898 wxString sheetName;
899 wxString sheetPath;
900 PCB_PLOT_PARAMS plotOpts;
901
902 if( aGerberJob->m_useBoardPlotParams )
903 plotOpts = boardPlotOptions;
904 else
905 populateGerberPlotOptionsFromJob( plotOpts, aGerberJob );
906
907 if( plotOpts.GetUseGerberProtelExtensions() )
908 fileExt = GetGerberProtelExtension( layer );
909 else
911
912 BuildPlotFileName( &fn, aGerberJob->GetFullOutputPath(), layerName, fileExt );
913 wxString fullname = fn.GetFullName();
914
915 jobfile_writer.AddGbrFile( layer, fullname );
916
917 if( aJob->GetVarOverrides().contains( wxT( "LAYER" ) ) )
918 layerName = aJob->GetVarOverrides().at( wxT( "LAYER" ) );
919
920 if( aJob->GetVarOverrides().contains( wxT( "SHEETNAME" ) ) )
921 sheetName = aJob->GetVarOverrides().at( wxT( "SHEETNAME" ) );
922
923 if( aJob->GetVarOverrides().contains( wxT( "SHEETPATH" ) ) )
924 sheetPath = aJob->GetVarOverrides().at( wxT( "SHEETPATH" ) );
925
926 // We are feeding it one layer at the start here to silence a logic check
927 GERBER_PLOTTER* plotter = (GERBER_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer,
928 layerName, fn.GetFullPath(),
929 sheetName, sheetPath );
930
931 if( plotter )
932 {
933 m_reporter->Report( wxString::Format( _( "Plotted to '%s'.\n" ), fn.GetFullPath() ),
935 PlotBoardLayers( brd, plotter, plotSequence, plotOpts );
936 plotter->EndPlot();
937 }
938 else
939 {
940 m_reporter->Report( wxString::Format( _( "Failed to plot to '%s'.\n" ),
941 fn.GetFullPath() ),
944 }
945
946 delete plotter;
947 }
948
949 wxFileName fn( aGerberJob->m_filename );
950
951 // Build gerber job file from basename
952 BuildPlotFileName( &fn, aGerberJob->GetFullOutputPath(), wxT( "job" ),
954 jobfile_writer.CreateJobFile( fn.GetFullPath() );
955
956 return exitCode;
957}
958
960{
961 JOB_EXPORT_PCB_GENCAD* aGencadJob = dynamic_cast<JOB_EXPORT_PCB_GENCAD*>( aJob );
962
963 if( aGencadJob == nullptr )
965
966 BOARD* aBoard = LoadBoard( aGencadJob->m_filename, true ); // Ensure m_board is of type BOARD*
967
968 if( aBoard == nullptr )
970
971 GENCAD_EXPORTER exporter( aBoard );
972
973 VECTOR2I GencadOffset;
974 VECTOR2I auxOrigin = aBoard->GetDesignSettings().GetAuxOrigin();
975 GencadOffset.x = aGencadJob->m_useDrillOrigin ? auxOrigin.x : 0;
976 GencadOffset.y = aGencadJob->m_useDrillOrigin ? auxOrigin.y : 0;
977
978 exporter.FlipBottomPads( aGencadJob->m_flipBottomPads );
979 exporter.UsePinNamesUnique( aGencadJob->m_useUniquePins );
980 exporter.UseIndividualShapes( aGencadJob->m_useIndividualShapes );
981 exporter.SetPlotOffet( GencadOffset );
982 exporter.StoreOriginCoordsInFile( aGencadJob->m_storeOriginCoords );
983
984 if( aGencadJob->GetOutputPath().IsEmpty() )
985 {
986 wxFileName fn = aBoard->GetFileName();
987 fn.SetName( fn.GetName() );
988 fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::DXF ) );
989
990 aGencadJob->SetOutputPath( fn.GetFullName() );
991 }
992
993 if( !exporter.WriteFile( aGencadJob->GetFullOutputPath() ) )
994 {
995 wxString msg;
996 msg.Printf( _( "Failed to create file '%s'.\n" ), aGencadJob->GetFullOutputPath() );
997
999
1001 }
1002
1003 m_reporter->Report( _( "Successfully created genCAD file\n" ), RPT_SEVERITY_INFO );
1004
1005 return CLI::EXIT_CODES::OK;
1006}
1007
1008
1010 JOB_EXPORT_PCB_GERBER* aJob )
1011{
1012 aPlotOpts.SetFormat( PLOT_FORMAT::GERBER );
1013
1014 aPlotOpts.SetPlotFrameRef( aJob->m_plotDrawingSheet );
1015 aPlotOpts.SetPlotValue( aJob->m_plotFootprintValues );
1016 aPlotOpts.SetPlotReference( aJob->m_plotRefDes );
1017
1019
1020 // Always disable plot pad holes
1021 aPlotOpts.SetDrillMarksType( DRILL_MARKS::NO_DRILL_SHAPE );
1022
1024 aPlotOpts.SetUseGerberX2format( aJob->m_useX2Format );
1026 aPlotOpts.SetUseAuxOrigin( aJob->m_useAuxOrigin );
1028 aPlotOpts.SetGerberPrecision( aJob->m_precision );
1029}
1030
1031
1033{
1034 int exitCode = CLI::EXIT_CODES::OK;
1035 JOB_EXPORT_PCB_GERBER* aGerberJob = dynamic_cast<JOB_EXPORT_PCB_GERBER*>( aJob );
1036
1037 if( aGerberJob == nullptr )
1039
1040 BOARD* brd = getBoard( aGerberJob->m_filename );
1041
1042 if( !brd )
1044
1045 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
1046 brd->SynchronizeProperties();
1047
1048 if( aGerberJob->GetOutputPath().IsEmpty() )
1049 {
1050 wxFileName fn = brd->GetFileName();
1051 fn.SetName( fn.GetName() );
1052 fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::GERBER ) );
1053
1054 aGerberJob->SetOutputPath( fn.GetFullName() );
1055 }
1056
1057 PCB_PLOT_PARAMS plotOpts;
1058 populateGerberPlotOptionsFromJob( plotOpts, aGerberJob );
1059 plotOpts.SetLayerSelection( aGerberJob->m_printMaskLayer );
1061
1063 wxString layerName;
1064 wxString sheetName;
1065 wxString sheetPath;
1066
1067 // The first layer will be treated as the layer name for the gerber header,
1068 // the other layers will be treated equivalent to the "Plot on All Layers" option
1069 // in the GUI
1070 if( aGerberJob->m_printMaskLayer.size() >= 1 )
1071 {
1072 layer = aGerberJob->m_printMaskLayer.front();
1073 layerName = brd->GetLayerName( layer );
1074 }
1075
1076 if( aJob->GetVarOverrides().contains( wxT( "LAYER" ) ) )
1077 layerName = aJob->GetVarOverrides().at( wxT( "LAYER" ) );
1078
1079 if( aJob->GetVarOverrides().contains( wxT( "SHEETNAME" ) ) )
1080 sheetName = aJob->GetVarOverrides().at( wxT( "SHEETNAME" ) );
1081
1082 if( aJob->GetVarOverrides().contains( wxT( "SHEETPATH" ) ) )
1083 sheetPath = aJob->GetVarOverrides().at( wxT( "SHEETPATH" ) );
1084
1085 // We are feeding it one layer at the start here to silence a logic check
1086 GERBER_PLOTTER* plotter = (GERBER_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer, layerName,
1087 aGerberJob->GetFullOutputPath(),
1088 sheetName, sheetPath );
1089
1090 if( plotter )
1091 {
1092 PlotBoardLayers( brd, plotter, aGerberJob->m_printMaskLayer, plotOpts );
1093 plotter->EndPlot();
1094 }
1095 else
1096 {
1097 m_reporter->Report( wxString::Format( _( "Failed to plot to '%s'.\n" ),
1098 aGerberJob->GetFullOutputPath() ),
1101 }
1102
1103 delete plotter;
1104
1105 return exitCode;
1106}
1107
1110
1111
1113{
1114 JOB_EXPORT_PCB_DRILL* aDrillJob = dynamic_cast<JOB_EXPORT_PCB_DRILL*>( aJob );
1115
1116 if( aDrillJob == nullptr )
1118
1119 BOARD* brd = getBoard( aDrillJob->m_filename );
1120
1121 if( !brd )
1123
1124 // ensure output dir exists
1125 wxFileName fn( aDrillJob->GetFullOutputPath() + wxT( "/" ) );
1126
1127 if( !fn.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
1128 {
1129 m_reporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
1131 }
1132
1133 std::unique_ptr<GENDRILL_WRITER_BASE> drillWriter;
1134
1136 drillWriter = std::make_unique<EXCELLON_WRITER>( brd );
1137 else
1138 drillWriter = std::make_unique<GERBER_WRITER>( brd );
1139
1140 VECTOR2I offset;
1141
1143 offset = VECTOR2I( 0, 0 );
1144 else
1145 offset = brd->GetDesignSettings().GetAuxOrigin();
1146
1147 PLOT_FORMAT mapFormat = PLOT_FORMAT::PDF;
1148
1149 switch( aDrillJob->m_mapFormat )
1150 {
1151 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::POSTSCRIPT: mapFormat = PLOT_FORMAT::POST; break;
1152 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::GERBER_X2: mapFormat = PLOT_FORMAT::GERBER; break;
1153 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::DXF: mapFormat = PLOT_FORMAT::DXF; break;
1154 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::SVG: mapFormat = PLOT_FORMAT::SVG; break;
1155 default:
1156 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::PDF: mapFormat = PLOT_FORMAT::PDF; break;
1157 }
1158
1160 {
1162 switch( aDrillJob->m_zeroFormat )
1163 {
1166 break;
1169 break;
1172 break;
1174 default:
1176 break;
1177 }
1178
1179 DRILL_PRECISION precision;
1180
1182 precision = precisionListForInches;
1183 else
1184 precision = precisionListForMetric;
1185
1186 EXCELLON_WRITER* excellonWriter = dynamic_cast<EXCELLON_WRITER*>( drillWriter.get() );
1187
1188 if( excellonWriter == nullptr )
1190
1191 excellonWriter->SetFormat( aDrillJob->m_drillUnits
1193 zeroFmt, precision.m_Lhs, precision.m_Rhs );
1194 excellonWriter->SetOptions( aDrillJob->m_excellonMirrorY,
1195 aDrillJob->m_excellonMinimalHeader,
1196 offset, aDrillJob->m_excellonCombinePTHNPTH );
1197 excellonWriter->SetRouteModeForOvalHoles( aDrillJob->m_excellonOvalDrillRoute );
1198 excellonWriter->SetMapFileFormat( mapFormat );
1199
1200 if( !excellonWriter->CreateDrillandMapFilesSet( aDrillJob->GetFullOutputPath(), true,
1201 aDrillJob->m_generateMap, m_reporter ) )
1202 {
1204 }
1205 }
1207 {
1208 GERBER_WRITER* gerberWriter = dynamic_cast<GERBER_WRITER*>( drillWriter.get() );
1209
1210 if( gerberWriter == nullptr )
1212
1213 // Set gerber precision: only 5 or 6 digits for mantissa are allowed
1214 // (SetFormat() accept 5 or 6, and any other value set the precision to 5)
1215 // the integer part precision is always 4, and units always mm
1216 gerberWriter->SetFormat( aDrillJob->m_gerberPrecision );
1217 gerberWriter->SetOptions( offset );
1218 gerberWriter->SetMapFileFormat( mapFormat );
1219
1220 if( !gerberWriter->CreateDrillandMapFilesSet( aDrillJob->GetFullOutputPath(), true,
1221 aDrillJob->m_generateMap, m_reporter ) )
1222 {
1224 }
1225 }
1226
1227 return CLI::EXIT_CODES::OK;
1228}
1229
1230
1232{
1233 JOB_EXPORT_PCB_POS* aPosJob = dynamic_cast<JOB_EXPORT_PCB_POS*>( aJob );
1234
1235 if( aPosJob == nullptr )
1237
1238 BOARD* brd = getBoard( aPosJob->m_filename );
1239
1240 if( !brd )
1241 {
1243 }
1244
1245 if( aPosJob->GetOutputPath().IsEmpty() )
1246 {
1247 wxFileName fn = brd->GetFileName();
1248 fn.SetName( fn.GetName() );
1249
1252 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::CSV )
1253 fn.SetExt( FILEEXT::CsvFileExtension );
1254 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::GERBER )
1255 fn.SetExt( FILEEXT::GerberFileExtension );
1256
1257 aPosJob->SetOutputPath( fn.GetFullName() );
1258 }
1259
1262 {
1263 FILE* file = nullptr;
1264 file = wxFopen( aPosJob->GetFullOutputPath(), wxS( "wt" ) );
1265
1266 if( file == nullptr )
1268
1269 std::string data;
1270
1271 bool frontSide = aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::FRONT
1273
1274 bool backSide = aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::BACK
1276
1277 PLACE_FILE_EXPORTER exporter( brd,
1279 aPosJob->m_smdOnly, aPosJob->m_excludeFootprintsWithTh,
1280 aPosJob->m_excludeDNP,
1281 frontSide, backSide,
1284 aPosJob->m_negateBottomX );
1285 data = exporter.GenPositionData();
1286
1287 fputs( data.c_str(), file );
1288 fclose( file );
1289
1290 aPosJob->AddOutput( aPosJob->GetFullOutputPath() );
1291 }
1292 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::GERBER )
1293 {
1294 PLACEFILE_GERBER_WRITER exporter( brd );
1295
1296 PCB_LAYER_ID gbrLayer = F_Cu;
1297
1298 if( aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::BACK )
1299 gbrLayer = B_Cu;
1300
1301 if( exporter.CreatePlaceFile( aPosJob->GetFullOutputPath(), gbrLayer, aPosJob->m_gerberBoardEdge )
1302 >= 0 )
1303 {
1304 aPosJob->AddOutput( aPosJob->GetFullOutputPath() );
1305 }
1306 else
1307 {
1309 }
1310 }
1311
1312 return CLI::EXIT_CODES::OK;
1313}
1314
1315extern FOOTPRINT* try_load_footprint( const wxFileName& aFileName, PCB_IO_MGR::PCB_FILE_T aFileType,
1316 const wxString& aName );
1317
1318
1320{
1321 JOB_FP_UPGRADE* upgradeJob = dynamic_cast<JOB_FP_UPGRADE*>( aJob );
1322
1323 if( upgradeJob == nullptr )
1325
1327
1328 if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
1329 {
1330 if( wxFile::Exists( upgradeJob->m_outputLibraryPath ) ||
1331 wxDir::Exists( upgradeJob->m_outputLibraryPath) )
1332 {
1333 m_reporter->Report( _( "Output path must not conflict with existing path\n" ),
1336 }
1337 }
1338 else if( fileType != PCB_IO_MGR::KICAD_SEXP )
1339 {
1340 m_reporter->Report( _( "Output path must be specified to convert legacy and non-KiCad libraries\n" ),
1342
1344 }
1345
1347 {
1348 if( !wxDir::Exists( upgradeJob->m_libraryPath ) )
1349 {
1350 m_reporter->Report( _( "Footprint library path does not exist or is not accessible\n" ),
1353 }
1354
1355 m_reporter->Report( _( "Loading footprint library\n" ), RPT_SEVERITY_INFO );
1356
1358 FP_CACHE fpLib( &pcb_io, upgradeJob->m_libraryPath );
1359
1360 try
1361 {
1362 fpLib.Load();
1363 }
1364 catch( ... )
1365 {
1366 m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
1368 }
1369
1370 bool shouldSave = upgradeJob->m_force;
1371
1372 for( const auto& footprint : fpLib.GetFootprints() )
1373 {
1374 if( footprint.second->GetFootprint()->GetFileFormatVersionAtLoad()
1376 {
1377 shouldSave = true;
1378 }
1379 }
1380
1381 if( shouldSave )
1382 {
1383 m_reporter->Report( _( "Saving footprint library\n" ), RPT_SEVERITY_INFO );
1384
1385 try
1386 {
1387 if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
1388 {
1389 fpLib.SetPath( upgradeJob->m_outputLibraryPath );
1390 }
1391
1392 fpLib.Save();
1393 }
1394 catch( ... )
1395 {
1396 m_reporter->Report( _( "Unable to save library\n" ), RPT_SEVERITY_ERROR );
1398 }
1399 }
1400 else
1401 {
1402 m_reporter->Report( _( "Footprint library was not updated\n" ), RPT_SEVERITY_INFO );
1403 }
1404 }
1405 else
1406 {
1407 if( !PCB_IO_MGR::ConvertLibrary( nullptr, upgradeJob->m_libraryPath,
1408 upgradeJob->m_outputLibraryPath, nullptr /* REPORTER */ ) )
1409 {
1410 m_reporter->Report( ( "Unable to convert library\n" ), RPT_SEVERITY_ERROR );
1412 }
1413 }
1414
1415 return CLI::EXIT_CODES::OK;
1416}
1417
1418
1420{
1421 JOB_FP_EXPORT_SVG* svgJob = dynamic_cast<JOB_FP_EXPORT_SVG*>( aJob );
1422
1423 if( svgJob == nullptr )
1425
1426 m_reporter->Report( _( "Loading footprint library\n" ), RPT_SEVERITY_INFO );
1427
1429 FP_CACHE fpLib( &pcb_io, svgJob->m_libraryPath );
1430
1431 try
1432 {
1433 fpLib.Load();
1434 }
1435 catch( ... )
1436 {
1437 m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
1439 }
1440
1441 if( !svgJob->m_outputDirectory.IsEmpty() && !wxDir::Exists( svgJob->m_outputDirectory ) )
1442 {
1443 wxFileName::Mkdir( svgJob->m_outputDirectory );
1444 }
1445
1446 int exitCode = CLI::EXIT_CODES::OK;
1447
1448 // Just plot all the symbols we can
1449 FP_CACHE_FOOTPRINT_MAP& footprintMap = fpLib.GetFootprints();
1450
1451 bool singleFpPlotted = false;
1452 for( FP_CACHE_FOOTPRINT_MAP::iterator it = footprintMap.begin(); it != footprintMap.end();
1453 ++it )
1454 {
1455 const FOOTPRINT* fp = it->second->GetFootprint();
1456 if( !svgJob->m_footprint.IsEmpty() )
1457 {
1458 if( fp->GetFPID().GetLibItemName().wx_str() != svgJob->m_footprint )
1459 {
1460 // skip until we find the right footprint
1461 continue;
1462 }
1463 else
1464 {
1465 singleFpPlotted = true;
1466 }
1467 }
1468
1469 exitCode = doFpExportSvg( svgJob, fp );
1470 if( exitCode != CLI::EXIT_CODES::OK )
1471 break;
1472 }
1473
1474 if( !svgJob->m_footprint.IsEmpty() && !singleFpPlotted )
1475 {
1476 m_reporter->Report( _( "The given footprint could not be found to export." ) + wxS( "\n" ),
1478 }
1479
1480 return CLI::EXIT_CODES::OK;
1481}
1482
1483
1485{
1486 // the hack for now is we create fake boards containing the footprint and plot the board
1487 // until we refactor better plot api later
1488 std::unique_ptr<BOARD> brd;
1489 brd.reset( CreateEmptyBoard() );
1490 brd->GetProject()->ApplyTextVars( aSvgJob->GetVarOverrides() );
1491 brd->SynchronizeProperties();
1492
1493 FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( aFootprint->Clone() );
1494
1495 if( fp == nullptr )
1497
1498 fp->SetLink( niluuid );
1499 fp->SetFlags( IS_NEW );
1500 fp->SetParent( brd.get() );
1501
1502 for( PAD* pad : fp->Pads() )
1503 {
1504 pad->SetLocalRatsnestVisible( false );
1505 pad->SetNetCode( 0 );
1506 }
1507
1508 fp->SetOrientation( ANGLE_0 );
1509 fp->SetPosition( VECTOR2I( 0, 0 ) );
1510
1511 brd->Add( fp, ADD_MODE::INSERT, true );
1512
1513 wxFileName outputFile;
1514 outputFile.SetPath( aSvgJob->m_outputDirectory );
1515 outputFile.SetName( aFootprint->GetFPID().GetLibItemName().wx_str() );
1516 outputFile.SetExt( FILEEXT::SVGFileExtension );
1517
1518 m_reporter->Report( wxString::Format( _( "Plotting footprint '%s' to '%s'\n" ),
1519 aFootprint->GetFPID().GetLibItemName().wx_str(),
1520 outputFile.GetFullPath() ),
1522
1523
1524 PCB_PLOT_SVG_OPTIONS svgPlotOptions;
1525 svgPlotOptions.m_blackAndWhite = aSvgJob->m_blackAndWhite;
1526 svgPlotOptions.m_colorTheme = aSvgJob->m_colorTheme;
1527 svgPlotOptions.m_outputFile = outputFile.GetFullPath();
1528 svgPlotOptions.m_mirror = false;
1529 svgPlotOptions.m_pageSizeMode = 2; // board bounding box
1530 svgPlotOptions.m_printMaskLayer = aSvgJob->m_printMaskLayer;
1531 svgPlotOptions.m_sketchPadsOnFabLayers = aSvgJob->m_sketchPadsOnFabLayers;
1532 svgPlotOptions.m_hideDNPFPsOnFabLayers = aSvgJob->m_hideDNPFPsOnFabLayers;
1533 svgPlotOptions.m_sketchDNPFPsOnFabLayers = aSvgJob->m_sketchDNPFPsOnFabLayers;
1535 svgPlotOptions.m_plotFrame = false;
1536
1537 if( !EXPORT_SVG::Plot( brd.get(), svgPlotOptions ) )
1538 m_reporter->Report( _( "Error creating svg file" ) + wxS( "\n" ), RPT_SEVERITY_ERROR );
1539
1540 return CLI::EXIT_CODES::OK;
1541}
1542
1543
1545{
1546 JOB_PCB_DRC* drcJob = dynamic_cast<JOB_PCB_DRC*>( aJob );
1547
1548 if( drcJob == nullptr )
1550
1551 BOARD* brd = getBoard( drcJob->m_filename );
1552
1553 if( !brd )
1555
1556 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
1557 brd->SynchronizeProperties();
1558
1559 if( drcJob->m_outputFile.IsEmpty() )
1560 {
1561 wxFileName fn = brd->GetFileName();
1562 fn.SetName( fn.GetName() );
1563
1565 fn.SetExt( FILEEXT::JsonFileExtension );
1566 else
1567 fn.SetExt( FILEEXT::ReportFileExtension );
1568
1569 drcJob->m_outputFile = fn.GetFullName();
1570 }
1571
1572 EDA_UNITS units;
1573
1574 switch( drcJob->m_units )
1575 {
1576 case JOB_PCB_DRC::UNITS::INCHES: units = EDA_UNITS::INCHES; break;
1577 case JOB_PCB_DRC::UNITS::MILS: units = EDA_UNITS::MILS; break;
1578 case JOB_PCB_DRC::UNITS::MILLIMETERS: units = EDA_UNITS::MILLIMETRES; break;
1579 default: units = EDA_UNITS::MILLIMETRES; break;
1580 }
1581
1582 std::shared_ptr<DRC_ENGINE> drcEngine = brd->GetDesignSettings().m_DRCEngine;
1583 std::unique_ptr<NETLIST> netlist = std::make_unique<NETLIST>();
1584
1585 drcEngine->SetDrawingSheet( getDrawingSheetProxyView( brd ) );
1586
1587 // BOARD_COMMIT uses TOOL_MANAGER to grab the board internally so we must give it one
1588 TOOL_MANAGER* toolManager = new TOOL_MANAGER;
1589 toolManager->SetEnvironment( brd, nullptr, nullptr, Kiface().KifaceSettings(), nullptr );
1590
1591 BOARD_COMMIT commit( toolManager );
1592
1593 m_reporter->Report( _( "Running DRC...\n" ), RPT_SEVERITY_INFO );
1594
1595 if( drcJob->m_parity )
1596 {
1597 typedef bool (*NETLIST_FN_PTR)( const wxString&, std::string& );
1598
1600 wxFileName schematicPath( drcJob->m_filename );
1601 NETLIST_FN_PTR netlister = (NETLIST_FN_PTR) eeschema->IfaceOrAddress( KIFACE_NETLIST_SCHEMATIC );
1602 std::string netlist_str;
1603
1604 schematicPath.SetExt( FILEEXT::KiCadSchematicFileExtension );
1605
1606 if( !schematicPath.Exists() )
1607 schematicPath.SetExt( FILEEXT::LegacySchematicFileExtension );
1608
1609 if( !schematicPath.Exists() )
1610 {
1611 m_reporter->Report( _( "Failed to find schematic for parity tests.\n" ),
1613 }
1614 else
1615 {
1616 (*netlister)( schematicPath.GetFullPath(), netlist_str );
1617
1618 try
1619 {
1620 auto lineReader = new STRING_LINE_READER( netlist_str, _( "Eeschema netlist" ) );
1621 KICAD_NETLIST_READER netlistReader( lineReader, netlist.get() );
1622 netlistReader.LoadNetlist();
1623 }
1624 catch( const IO_ERROR& )
1625 {
1626 m_reporter->Report( _( "Failed to fetch schematic netlist for parity tests.\n" ),
1628 }
1629
1630 drcEngine->SetSchematicNetlist( netlist.get() );
1631 }
1632 }
1633
1634 drcEngine->SetProgressReporter( nullptr );
1635 drcEngine->SetViolationHandler(
1636 [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
1637 {
1638 PCB_MARKER* marker = new PCB_MARKER( aItem, aPos, aLayer );
1639 commit.Add( marker );
1640 } );
1641
1642 brd->RecordDRCExclusions();
1643 brd->DeleteMARKERs( true, true );
1644 drcEngine->RunTests( units, drcJob->m_reportAllTrackErrors, drcJob->m_parity );
1645 drcEngine->ClearViolationHandler();
1646
1647 commit.Push( _( "DRC" ), SKIP_UNDO | SKIP_SET_DIRTY );
1648
1649 // Update the exclusion status on any excluded markers that still exist.
1650 brd->ResolveDRCExclusions( false );
1651
1652 std::shared_ptr<DRC_ITEMS_PROVIDER> markersProvider = std::make_shared<DRC_ITEMS_PROVIDER>(
1654
1655 std::shared_ptr<DRC_ITEMS_PROVIDER> ratsnestProvider =
1656 std::make_shared<DRC_ITEMS_PROVIDER>( brd, MARKER_BASE::MARKER_RATSNEST );
1657
1658 std::shared_ptr<DRC_ITEMS_PROVIDER> fpWarningsProvider =
1659 std::make_shared<DRC_ITEMS_PROVIDER>( brd, MARKER_BASE::MARKER_PARITY );
1660
1661 markersProvider->SetSeverities( drcJob->m_severity );
1662 ratsnestProvider->SetSeverities( drcJob->m_severity );
1663 fpWarningsProvider->SetSeverities( drcJob->m_severity );
1664
1665 m_reporter->Report( wxString::Format( _( "Found %d violations\n" ),
1666 markersProvider->GetCount() ),
1668 m_reporter->Report( wxString::Format( _( "Found %d unconnected items\n" ),
1669 ratsnestProvider->GetCount() ),
1671
1672 if( drcJob->m_parity )
1673 {
1674 m_reporter->Report( wxString::Format( _( "Found %d schematic parity issues\n" ),
1675 fpWarningsProvider->GetCount() ),
1677 }
1678
1679 DRC_REPORT reportWriter( brd, units, markersProvider, ratsnestProvider, fpWarningsProvider );
1680
1681 bool wroteReport = false;
1682
1684 wroteReport = reportWriter.WriteJsonReport( drcJob->m_outputFile );
1685 else
1686 wroteReport = reportWriter.WriteTextReport( drcJob->m_outputFile );
1687
1688 if( !wroteReport )
1689 {
1690 m_reporter->Report( wxString::Format( _( "Unable to save DRC report to %s\n" ),
1691 drcJob->m_outputFile ),
1694 }
1695
1696 m_reporter->Report( wxString::Format( _( "Saved DRC Report to %s\n" ),
1697 drcJob->m_outputFile ),
1699
1700 if( drcJob->m_exitCodeViolations )
1701 {
1702 if( markersProvider->GetCount() > 0 || ratsnestProvider->GetCount() > 0
1703 || fpWarningsProvider->GetCount() > 0 )
1704 {
1706 }
1707 }
1708
1710}
1711
1712
1714{
1715 JOB_EXPORT_PCB_IPC2581* job = dynamic_cast<JOB_EXPORT_PCB_IPC2581*>( aJob );
1716
1717 if( job == nullptr )
1719
1720 BOARD* brd = getBoard( job->m_filename );
1721
1722 if( !brd )
1724
1725 if( job->OutputPathFullSpecified() )
1726 {
1727 wxFileName fn = brd->GetFileName();
1728 fn.SetName( fn.GetName() );
1729 fn.SetExt( FILEEXT::Ipc2581FileExtension );
1730
1731 job->SetOutputPath( fn.GetName() );
1732 }
1733
1734 std::map<std::string, UTF8> props;
1735 props["units"] = job->m_units == JOB_EXPORT_PCB_IPC2581::IPC2581_UNITS::MILLIMETERS ? "mm"
1736 : "inch";
1737 props["sigfig"] = wxString::Format( "%d", job->m_precision );
1738 props["version"] = job->m_version == JOB_EXPORT_PCB_IPC2581::IPC2581_VERSION::C ? "C" : "B";
1739 props["OEMRef"] = job->m_colInternalId;
1740 props["mpn"] = job->m_colMfgPn;
1741 props["mfg"] = job->m_colMfg;
1742 props["dist"] = job->m_colDist;
1743 props["distpn"] = job->m_colDistPn;
1744
1745 wxString tempFile = wxFileName::CreateTempFileName( wxS( "pcbnew_ipc" ) );
1746 try
1747 {
1749 pi->SetProgressReporter( m_progressReporter );
1750 pi->SaveBoard( tempFile, brd, &props );
1751 }
1752 catch( const IO_ERROR& ioe )
1753 {
1754 m_reporter->Report( wxString::Format( _( "Error generating IPC2581 file '%s'.\n%s" ),
1755 job->m_filename, ioe.What() ),
1757
1758 wxRemoveFile( tempFile );
1759
1761 }
1762
1763 if( job->m_compress )
1764 {
1765 wxFileName tempfn = job->GetFullOutputPath();
1766 tempfn.SetExt( FILEEXT::Ipc2581FileExtension );
1767 wxFileName zipfn = tempFile;
1768 zipfn.SetExt( "zip" );
1769
1770 wxFFileOutputStream fnout( zipfn.GetFullPath() );
1771 wxZipOutputStream zip( fnout );
1772 wxFFileInputStream fnin( tempFile );
1773
1774 zip.PutNextEntry( tempfn.GetFullName() );
1775 fnin.Read( zip );
1776 zip.Close();
1777 fnout.Close();
1778
1779 wxRemoveFile( tempFile );
1780 tempFile = zipfn.GetFullPath();
1781 }
1782
1783 // If save succeeded, replace the original with what we just wrote
1784 if( !wxRenameFile( tempFile, job->GetFullOutputPath() ) )
1785 {
1786 m_reporter->Report( wxString::Format( _( "Error generating IPC2581 file '%s'.\n"
1787 "Failed to rename temporary file '%s." )
1788 + wxS( "\n" ),
1789 job->GetFullOutputPath(), tempFile ),
1791 }
1792
1794}
1795
1796
1798{
1799 JOB_EXPORT_PCB_ODB* job = dynamic_cast<JOB_EXPORT_PCB_ODB*>( aJob );
1800
1801 if( job == nullptr )
1803
1804 BOARD* brd = getBoard( job->m_filename );
1805
1806 if( !brd )
1808
1809 if( job->OutputPathFullSpecified() )
1810 {
1811 wxFileName fn = brd->GetFileName();
1812 fn.SetName( fn.GetName() );
1813 fn.SetExt( "zip" );
1814
1815 job->SetOutputPath( fn.GetName() );
1816 }
1817
1819
1821}
1822
1823
1825{
1827 &aBrd->GetPageSettings(),
1828 aBrd->GetProject(),
1829 &aBrd->GetTitleBlock(),
1830 &aBrd->GetProperties() );
1831
1832 drawingSheet->SetSheetName( std::string() );
1833 drawingSheet->SetSheetPath( std::string() );
1834 drawingSheet->SetIsFirstPage( true );
1835
1836 drawingSheet->SetFileName( TO_UTF8( aBrd->GetFileName() ) );
1837
1838 return drawingSheet;
1839}
1840
1841
1842void PCBNEW_JOBS_HANDLER::loadOverrideDrawingSheet( BOARD* aBrd, const wxString& aSheetPath )
1843{
1844 // dont bother attempting to load a empty path, if there was one
1845 if( aSheetPath.IsEmpty() )
1846 return;
1847
1848 auto loadSheet =
1849 [&]( const wxString& path ) -> bool
1850 {
1853 resolver.SetProject( aBrd->GetProject() );
1855
1857 aBrd->GetProject()->GetProjectPath(),
1858 aBrd->GetEmbeddedFiles() );
1859 wxString msg;
1860
1861 if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( filename, &msg ) )
1862 {
1863 m_reporter->Report( wxString::Format( _( "Error loading drawing sheet '%s'." ),
1864 path )
1865 + wxS( "\n" ) + msg + wxS( "\n" ),
1867 return false;
1868 }
1869
1870 return true;
1871 };
1872
1873 if( loadSheet( aSheetPath ) )
1874 return;
1875
1876 // failed loading custom path, revert back to default
1877 loadSheet( aBrd->GetProject()->GetProjectFile().m_BoardDrawingSheetFile );
1878}
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:778
EMBEDDED_FILES * GetEmbeddedFiles() override
Definition: board.cpp:2550
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:1674
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:574
PROJECT * GetProject() const
Definition: board.h:491
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:895
void SynchronizeProperties()
Copy the current project's text variables into the boards property cache.
Definition: board.cpp:2046
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition: board.cpp:1361
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
static void GenerateODBPPFiles(const JOB_EXPORT_PCB_ODB &aJob, BOARD *aBoard, PCB_EDIT_FRAME *aParentFrame=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr, REPORTER *aErrorReporter=nullptr)
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:2388
void SetLink(const KIID &aLink)
Definition: footprint.h:871
void SetOrientation(const EDA_ANGLE &aNewAngle)
Definition: footprint.cpp:2458
EDA_ITEM * Clone() const override
Invoke a function on all children.
Definition: footprint.cpp:2075
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.
LSEQ m_printMaskLayer
Layers to include on all individual layer prints.
bool m_mirror
Common Options.
unsigned int m_precision
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:809
LSEQ SeqStackupForPlotting() const
Return the sequence that is typical for a bottom-to-top stack-up.
Definition: lset.cpp:510
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
Definition: lset.cpp:697
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:686
@ 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)
BOARD * GetBoard() const
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
void SetPlotOnAllLayersSelection(LSET aSelection)
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
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition: project.cpp:129
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.
COLOR_SETTINGS * GetColorSettings(const wxString &aName="user")
Retrieves a color settings object that applications can read colors from.
T * GetAppSettings(const wxString &aFilename)
Returns a handle to the a given settings by type If the settings have already been loaded,...
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
@ 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)
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
unsigned int m_precision
Definition: export_svg.h:48
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