KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcbnew_jobs_handler.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2022 Mark Roszko <[email protected]>
5 * Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <wx/dir.h>
22#include "pcbnew_jobs_handler.h"
23#include <board_commit.h>
25#include <drc/drc_item.h>
26#include <drc/drc_report.h>
30#include <jobs/job_fp_upgrade.h>
40#include <jobs/job_pcb_render.h>
41#include <jobs/job_pcb_drc.h>
42#include <cli/exit_codes.h>
48#include <tool/tool_manager.h>
49#include <tools/drc_tool.h>
54#include <kiface_base.h>
55#include <macros.h>
56#include <pad.h>
57#include <pcb_marker.h>
60#include <kiface_ids.h>
63#include <pcbnew_settings.h>
64#include <pcbplot.h>
65#include <pgm_base.h>
68#include <project_pcb.h>
70#include <reporter.h>
71#include <string_utf8_map.h>
73#include <export_vrml.h>
74#include <wx/wfstream.h>
75#include <wx/zipstrm.h>
76
78
79
80#ifdef _WIN32
81#ifdef TRANSPARENT
82#undef TRANSPARENT
83#endif
84#endif
85
86
88 JOB_DISPATCHER( aKiway )
89{
90 Register( "3d", std::bind( &PCBNEW_JOBS_HANDLER::JobExportStep, this, std::placeholders::_1 ) );
91 Register( "render", std::bind( &PCBNEW_JOBS_HANDLER::JobExportRender, this, std::placeholders::_1 ) );
92 Register( "svg", std::bind( &PCBNEW_JOBS_HANDLER::JobExportSvg, this, std::placeholders::_1 ) );
93 Register( "dxf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDxf, this, std::placeholders::_1 ) );
94 Register( "pdf", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPdf, this, std::placeholders::_1 ) );
95 Register( "gerber",
96 std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerber, this, std::placeholders::_1 ) );
97 Register( "gerbers",
98 std::bind( &PCBNEW_JOBS_HANDLER::JobExportGerbers, this, std::placeholders::_1 ) );
99 Register( "drill",
100 std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrill, this, std::placeholders::_1 ) );
101 Register( "pos", std::bind( &PCBNEW_JOBS_HANDLER::JobExportPos, this, std::placeholders::_1 ) );
102 Register( "fpupgrade",
103 std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpUpgrade, this, std::placeholders::_1 ) );
104 Register( "fpsvg",
105 std::bind( &PCBNEW_JOBS_HANDLER::JobExportFpSvg, this, std::placeholders::_1 ) );
106 Register( "drc", std::bind( &PCBNEW_JOBS_HANDLER::JobExportDrc, this, std::placeholders::_1 ) );
107 Register( "ipc2581",
108 std::bind( &PCBNEW_JOBS_HANDLER::JobExportIpc2581, this, std::placeholders::_1 ) );
109}
110
111
113{
114 JOB_EXPORT_PCB_3D* aStepJob = dynamic_cast<JOB_EXPORT_PCB_3D*>( aJob );
115
116 if( aStepJob == nullptr )
118
119 if( aJob->IsCli() )
120 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
121
122 BOARD* brd = LoadBoard( aStepJob->m_filename, true );
123 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
124
125 if( aStepJob->m_outputFile.IsEmpty() )
126 {
127 wxFileName fn = brd->GetFileName();
128 fn.SetName( fn.GetName() );
129
130 switch( aStepJob->m_format )
131 {
133 break;
135 break;
137 break;
139 break;
141 break;
142 default:
143 return CLI::EXIT_CODES::ERR_UNKNOWN; // shouldnt have gotten here
144 }
145
146 aStepJob->m_outputFile = fn.GetFullName();
147 }
148
150 {
151
152 double scale = 0.0;
153 switch ( aStepJob->m_vrmlUnits )
154 {
156 case JOB_EXPORT_PCB_3D::VRML_UNITS::METERS: scale = 0.001; break;
157 case JOB_EXPORT_PCB_3D::VRML_UNITS::TENTHS: scale = 10.0 / 25.4; break;
158 case JOB_EXPORT_PCB_3D::VRML_UNITS::INCHES: scale = 1.0 / 25.4; break;
159 }
160
161 EXPORTER_VRML vrmlExporter( brd );
162 wxString messages;
163
164 double originX = pcbIUScale.IUTomm( aStepJob->m_xOrigin );
165 double originY = pcbIUScale.IUTomm( aStepJob->m_yOrigin );
166
167 if( !aStepJob->m_hasUserOrigin )
168 {
169 BOX2I bbox = brd->ComputeBoundingBox( true, false );
170 originX = pcbIUScale.IUTomm( bbox.GetCenter().x );
171 originY = pcbIUScale.IUTomm( bbox.GetCenter().y );
172 }
173
174 bool success = vrmlExporter.ExportVRML_File(
175 brd->GetProject(), &messages, aStepJob->m_outputFile, scale,
176 aStepJob->m_includeUnspecified, aStepJob->m_includeDNP,
177 !aStepJob->m_vrmlModelDir.IsEmpty(), aStepJob->m_vrmlRelativePaths,
178 aStepJob->m_vrmlModelDir, originX, originY );
179
180 if ( success )
181 {
182 m_reporter->Report( wxString::Format( _( "Successfully exported VRML to %s" ),
183 aStepJob->m_outputFile ),
185 }
186 else
187 {
188 m_reporter->Report( _( "Error exporting VRML" ), RPT_SEVERITY_ERROR );
190 }
191 }
192 else
193 {
195 params.m_exportBoardBody = aStepJob->m_exportBoardBody;
196 params.m_exportComponents = aStepJob->m_exportComponents;
197 params.m_exportTracksVias = aStepJob->m_exportTracks;
198 params.m_exportZones = aStepJob->m_exportZones;
199 params.m_exportInnerCopper = aStepJob->m_exportInnerCopper;
200 params.m_fuseShapes = aStepJob->m_fuseShapes;
202 params.m_includeDNP = aStepJob->m_includeDNP;
204 params.m_overwrite = aStepJob->m_overwrite;
205 params.m_substModels = aStepJob->m_substModels;
206 params.m_origin = VECTOR2D( aStepJob->m_xOrigin, aStepJob->m_yOrigin );
207 params.m_useDrillOrigin = aStepJob->m_useDrillOrigin;
208 params.m_useGridOrigin = aStepJob->m_useGridOrigin;
209 params.m_boardOnly = aStepJob->m_boardOnly;
210 params.m_optimizeStep = aStepJob->m_optimizeStep;
211 params.m_netFilter = aStepJob->m_netFilter;
212
213 switch( aStepJob->m_format )
214 {
217 break;
220 break;
223 break;
226 break;
227 default:
228 return CLI::EXIT_CODES::ERR_UNKNOWN; // shouldnt have gotten here
229 }
230
231 EXPORTER_STEP stepExporter( brd, params );
232 stepExporter.m_outputFile = aStepJob->m_outputFile;
233
234 if( !stepExporter.Export() )
236 }
237
238 return CLI::EXIT_CODES::OK;
239}
240
241
243{
244 JOB_PCB_RENDER* aRenderJob = dynamic_cast<JOB_PCB_RENDER*>( aJob );
245
246 if( aRenderJob == nullptr )
248
249 if( aJob->IsCli() )
250 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
251
252 BOARD* brd = LoadBoard( aRenderJob->m_filename, true );
253 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
254
255 BOARD_ADAPTER boardAdapter;
256
257 boardAdapter.SetBoard( brd );
258 boardAdapter.m_IsBoardView = false;
259 boardAdapter.m_IsPreviewer =
260 true; // Force display 3D models, regardless the 3D viewer options
261
264
265 if( aRenderJob->m_quality == JOB_PCB_RENDER::QUALITY::BASIC )
266 {
267 // Silkscreen is pixelated without antialiasing
269
270 cfg->m_Render.raytrace_backfloor = false;
272
274 cfg->m_Render.raytrace_reflections = false;
275 cfg->m_Render.raytrace_shadows = false;
276
277 // Better colors
279
280 // Tracks below soldermask are not visible without refractions
281 cfg->m_Render.raytrace_refractions = true;
283 }
284 else if( aRenderJob->m_quality == JOB_PCB_RENDER::QUALITY::HIGH )
285 {
287 cfg->m_Render.raytrace_backfloor = true;
290 cfg->m_Render.raytrace_reflections = true;
291 cfg->m_Render.raytrace_shadows = true;
292 cfg->m_Render.raytrace_refractions = true;
294 }
295
296 if( aRenderJob->m_floor )
297 {
298 cfg->m_Render.raytrace_backfloor = true;
299 cfg->m_Render.raytrace_shadows = true;
301 }
302
303 cfg->m_CurrentPreset = aRenderJob->m_colorPreset;
304 boardAdapter.m_Cfg = cfg;
305
308 && aRenderJob->m_format == JOB_PCB_RENDER::FORMAT::PNG ) )
309 {
310 boardAdapter.m_ColorOverrides[LAYER_3D_BACKGROUND_TOP] = COLOR4D( 1.0, 1.0, 1.0, 0.0 );
311 boardAdapter.m_ColorOverrides[LAYER_3D_BACKGROUND_BOTTOM] = COLOR4D( 1.0, 1.0, 1.0, 0.0 );
312 }
313
315
316 static std::map<JOB_PCB_RENDER::SIDE, VIEW3D_TYPE> s_viewCmdMap = {
317 { JOB_PCB_RENDER::SIDE::TOP, VIEW3D_TYPE::VIEW3D_TOP },
318 { JOB_PCB_RENDER::SIDE::BOTTOM, VIEW3D_TYPE::VIEW3D_BOTTOM },
319 { JOB_PCB_RENDER::SIDE::LEFT, VIEW3D_TYPE::VIEW3D_LEFT },
320 { JOB_PCB_RENDER::SIDE::RIGHT, VIEW3D_TYPE::VIEW3D_RIGHT },
321 { JOB_PCB_RENDER::SIDE::FRONT, VIEW3D_TYPE::VIEW3D_FRONT },
322 { JOB_PCB_RENDER::SIDE::BACK, VIEW3D_TYPE::VIEW3D_BACK },
323 };
324
325 PROJECTION_TYPE projection =
326 aRenderJob->m_perspective ? PROJECTION_TYPE::PERSPECTIVE : PROJECTION_TYPE::ORTHO;
327
328 wxSize windowSize( aRenderJob->m_width, aRenderJob->m_height );
329 TRACK_BALL camera( 2 * RANGE_SCALE_3D );
330
331 camera.SetProjection( projection );
332 camera.SetCurWindowSize( windowSize );
333
334 RENDER_3D_RAYTRACE_RAM raytrace( boardAdapter, camera );
335 raytrace.SetCurWindowSize( windowSize );
336
337 for( bool first = true; raytrace.Redraw( false, m_reporter, m_reporter ); first = false )
338 {
339 if( first )
340 {
341 const float cmTo3D = boardAdapter.BiuTo3dUnits() * pcbIUScale.mmToIU( 10.0 );
342
343 // First redraw resets lookat point to the board center, so set up the camera here
344 camera.ViewCommand_T1( s_viewCmdMap[aRenderJob->m_side] );
345
346 camera.SetLookAtPos_T1(
347 camera.GetLookAtPos_T1()
348 + SFVEC3F( aRenderJob->m_pivot.x, aRenderJob->m_pivot.y, aRenderJob->m_pivot.z )
349 * cmTo3D );
350
351 camera.Pan_T1(
352 SFVEC3F( aRenderJob->m_pan.x, aRenderJob->m_pan.y, aRenderJob->m_pan.z ) );
353
354 camera.Zoom_T1( aRenderJob->m_zoom );
355
356 camera.RotateX_T1( DEG2RAD( aRenderJob->m_rotation.x ) );
357 camera.RotateY_T1( DEG2RAD( aRenderJob->m_rotation.y ) );
358 camera.RotateZ_T1( DEG2RAD( aRenderJob->m_rotation.z ) );
359
360 camera.Interpolate( 1.0f );
361 camera.SetT0_and_T1_current_T();
362 camera.ParametersChanged();
363 }
364 }
365
366 GLubyte* rgbaBuffer = raytrace.GetBuffer();
367 wxSize realSize = raytrace.GetRealBufferSize();
368 bool success = !!rgbaBuffer;
369
370 if( rgbaBuffer )
371 {
372 const unsigned int wxh = realSize.x * realSize.y;
373
374 unsigned char* rgbBuffer = (unsigned char*) malloc( wxh * 3 );
375 unsigned char* alphaBuffer = (unsigned char*) malloc( wxh );
376
377 unsigned char* rgbaPtr = rgbaBuffer;
378 unsigned char* rgbPtr = rgbBuffer;
379 unsigned char* alphaPtr = alphaBuffer;
380
381 for( int y = 0; y < realSize.y; y++ )
382 {
383 for( int x = 0; x < realSize.x; x++ )
384 {
385 rgbPtr[0] = rgbaPtr[0];
386 rgbPtr[1] = rgbaPtr[1];
387 rgbPtr[2] = rgbaPtr[2];
388 alphaPtr[0] = rgbaPtr[3];
389
390 rgbaPtr += 4;
391 rgbPtr += 3;
392 alphaPtr += 1;
393 }
394 }
395
396 wxImage image( realSize );
397 image.SetData( rgbBuffer );
398 image.SetAlpha( alphaBuffer );
399 image = image.Mirror( false );
400
401 image.SetOption( wxIMAGE_OPTION_QUALITY, 90 );
402 image.SaveFile( aRenderJob->m_outputFile,
403 aRenderJob->m_format == JOB_PCB_RENDER::FORMAT::PNG ? wxBITMAP_TYPE_PNG
404 : wxBITMAP_TYPE_JPEG );
405 }
406
407 m_reporter->Report( wxString::Format( _( "Actual image size: %dx%d" ), realSize.x, realSize.y )
408 + wxS( "\n" ),
410
411 if( success )
412 m_reporter->Report( _( "Successfully created 3D render image" ) + wxS( "\n" ),
414 else
415 m_reporter->Report( _( "Error creating 3D render image" ) + wxS( "\n" ),
417
418 return CLI::EXIT_CODES::OK;
419}
420
421
423{
424 JOB_EXPORT_PCB_SVG* aSvgJob = dynamic_cast<JOB_EXPORT_PCB_SVG*>( aJob );
425
426 if( aSvgJob == nullptr )
428
429 PCB_PLOT_SVG_OPTIONS svgPlotOptions;
430 svgPlotOptions.m_blackAndWhite = aSvgJob->m_blackAndWhite;
431 svgPlotOptions.m_colorTheme = aSvgJob->m_colorTheme;
432 svgPlotOptions.m_outputFile = aSvgJob->m_outputFile;
433 svgPlotOptions.m_mirror = aSvgJob->m_mirror;
434 svgPlotOptions.m_negative = aSvgJob->m_negative;
435 svgPlotOptions.m_pageSizeMode = aSvgJob->m_pageSizeMode;
436 svgPlotOptions.m_printMaskLayer = aSvgJob->m_printMaskLayer;
437 svgPlotOptions.m_plotFrame = aSvgJob->m_plotDrawingSheet;
438 svgPlotOptions.m_drillShapeOption = aSvgJob->m_drillShapeOption;
439
440 if( aJob->IsCli() )
441 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
442
443 BOARD* brd = LoadBoard( aSvgJob->m_filename, true );
445 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
446
447 if( aJob->IsCli() )
448 {
449 if( EXPORT_SVG::Plot( brd, svgPlotOptions ) )
450 m_reporter->Report( _( "Successfully created svg file" ) + wxS( "\n" ), RPT_SEVERITY_INFO );
451 else
452 m_reporter->Report( _( "Error creating svg file" ) + wxS( "\n" ), RPT_SEVERITY_ERROR );
453 }
454
455 return CLI::EXIT_CODES::OK;
456}
457
458
460{
461 JOB_EXPORT_PCB_DXF* aDxfJob = dynamic_cast<JOB_EXPORT_PCB_DXF*>( aJob );
462
463 if( aDxfJob == nullptr )
465
466 if( aJob->IsCli() )
467 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
468
469 BOARD* brd = LoadBoard( aDxfJob->m_filename, true );
471 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
472
473 if( aDxfJob->m_outputFile.IsEmpty() )
474 {
475 wxFileName fn = brd->GetFileName();
476 fn.SetName( fn.GetName() );
477 fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::DXF ) );
478
479 aDxfJob->m_outputFile = fn.GetFullName();
480 }
481
482 PCB_PLOT_PARAMS plotOpts;
483 plotOpts.SetFormat( PLOT_FORMAT::DXF );
484
486
488 plotOpts.SetDXFPlotUnits( DXF_UNITS::MILLIMETERS );
489 else
490 plotOpts.SetDXFPlotUnits( DXF_UNITS::INCHES );
491
492 plotOpts.SetPlotFrameRef( aDxfJob->m_plotBorderTitleBlocks );
493 plotOpts.SetPlotValue( aDxfJob->m_plotFootprintValues );
494 plotOpts.SetPlotReference( aDxfJob->m_plotRefDes );
495 plotOpts.SetLayerSelection( aDxfJob->m_printMaskLayer );
496
498 wxString layerName;
499 wxString sheetName;
500 wxString sheetPath;
501
502 if( aDxfJob->m_printMaskLayer.size() == 1 )
503 {
504 layer = aDxfJob->m_printMaskLayer.front();
505 layerName = brd->GetLayerName( layer );
506 }
507
508 if( aJob->GetVarOverrides().contains( wxT( "LAYER" ) ) )
509 layerName = aJob->GetVarOverrides().at( wxT( "LAYER" ) );
510
511 if( aJob->GetVarOverrides().contains( wxT( "SHEETNAME" ) ) )
512 sheetName = aJob->GetVarOverrides().at( wxT( "SHEETNAME" ) );
513
514 if( aJob->GetVarOverrides().contains( wxT( "SHEETPATH" ) ) )
515 sheetPath = aJob->GetVarOverrides().at( wxT( "SHEETPATH" ) );
516
517 DXF_PLOTTER* plotter = (DXF_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer, layerName,
518 aDxfJob->m_outputFile, sheetName,
519 sheetPath );
520
521 if( plotter )
522 {
523 PlotBoardLayers( brd, plotter, aDxfJob->m_printMaskLayer, plotOpts );
524 plotter->EndPlot();
525 }
526
527 delete plotter;
528
529 return CLI::EXIT_CODES::OK;
530}
531
532
534{
535 JOB_EXPORT_PCB_PDF* aPdfJob = dynamic_cast<JOB_EXPORT_PCB_PDF*>( aJob );
536
537 if( aPdfJob == nullptr )
539
540 if( aJob->IsCli() )
541 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
542
543 BOARD* brd = LoadBoard( aPdfJob->m_filename, true );
545 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
546
547 if( aPdfJob->m_outputFile.IsEmpty() )
548 {
549 wxFileName fn = brd->GetFileName();
550 fn.SetName( fn.GetName() );
551 fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::PDF ) );
552
553 aPdfJob->m_outputFile = fn.GetFullName();
554 }
555
556 PCB_PLOT_PARAMS plotOpts;
557 plotOpts.SetFormat( PLOT_FORMAT::PDF );
558
559 plotOpts.SetPlotFrameRef( aPdfJob->m_plotBorderTitleBlocks );
560 plotOpts.SetPlotValue( aPdfJob->m_plotFootprintValues );
561 plotOpts.SetPlotReference( aPdfJob->m_plotRefDes );
562
563 plotOpts.SetLayerSelection( aPdfJob->m_printMaskLayer );
564
566 plotOpts.SetColorSettings( mgr.GetColorSettings( aPdfJob->m_colorTheme ) );
567 plotOpts.SetMirror( aPdfJob->m_mirror );
568 plotOpts.SetBlackAndWhite( aPdfJob->m_blackAndWhite );
569 plotOpts.SetNegative( aPdfJob->m_negative );
570
571 switch( aPdfJob->m_drillShapeOption )
572 {
573 default:
574 case 0: plotOpts.SetDrillMarksType( DRILL_MARKS::NO_DRILL_SHAPE ); break;
575 case 1: plotOpts.SetDrillMarksType( DRILL_MARKS::SMALL_DRILL_SHAPE ); break;
576 case 2: plotOpts.SetDrillMarksType( DRILL_MARKS::FULL_DRILL_SHAPE ); break;
577 }
578
580 wxString layerName;
581 wxString sheetName;
582 wxString sheetPath;
583
584 if( aPdfJob->m_printMaskLayer.size() == 1 )
585 {
586 layer = aPdfJob->m_printMaskLayer.front();
587 layerName = brd->GetLayerName( layer );
588 }
589
590 if( aPdfJob->GetVarOverrides().contains( wxT( "LAYER" ) ) )
591 layerName = aPdfJob->GetVarOverrides().at( wxT( "LAYER" ) );
592
593 if( aPdfJob->GetVarOverrides().contains( wxT( "SHEETNAME" ) ) )
594 sheetName = aPdfJob->GetVarOverrides().at( wxT( "SHEETNAME" ) );
595
596 if( aPdfJob->GetVarOverrides().contains( wxT( "SHEETPATH" ) ) )
597 sheetPath = aPdfJob->GetVarOverrides().at( wxT( "SHEETPATH" ) );
598
599 PDF_PLOTTER* plotter = (PDF_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer, layerName,
600 aPdfJob->m_outputFile, sheetName,
601 sheetPath );
602
603 if( plotter )
604 {
605 PlotBoardLayers( brd, plotter, aPdfJob->m_printMaskLayer, plotOpts );
606 PlotInteractiveLayer( brd, plotter, plotOpts );
607 plotter->EndPlot();
608 }
609
610 delete plotter;
611
612 return CLI::EXIT_CODES::OK;
613}
614
615
617{
618 int exitCode = CLI::EXIT_CODES::OK;
619 JOB_EXPORT_PCB_GERBERS* aGerberJob = dynamic_cast<JOB_EXPORT_PCB_GERBERS*>( aJob );
620
621 if( aGerberJob == nullptr )
623
624 if( aJob->IsCli() )
625 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
626
627 BOARD* brd = LoadBoard( aGerberJob->m_filename, true );
628 loadOverrideDrawingSheet( brd, aGerberJob->m_drawingSheet );
629 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
630
631 PCB_PLOT_PARAMS boardPlotOptions = brd->GetPlotOptions();
632 LSET plotOnAllLayersSelection = boardPlotOptions.GetPlotOnAllLayersSelection();
633 GERBER_JOBFILE_WRITER jobfile_writer( brd );
634
635 wxString fileExt;
636
637 if( aGerberJob->m_useBoardPlotParams )
638 {
639 // The board plot options are saved with all copper layers enabled, even those that don't
640 // exist in the current stackup. This is done so the layers are automatically enabled in the plot
641 // dialog when the user enables them. We need to filter out these not-enabled layers here so
642 // we don't plot 32 layers when we only have 4, etc.
643 LSET plotLayers = ( boardPlotOptions.GetLayerSelection() & LSET::AllNonCuMask() )
644 | ( brd->GetEnabledLayers() & LSET::AllCuMask() );
645 aGerberJob->m_printMaskLayer = plotLayers.SeqStackupForPlotting();
646 aGerberJob->m_layersIncludeOnAll = boardPlotOptions.GetPlotOnAllLayersSelection();
647 }
648 else
649 {
650 // default to the board enabled layers
651 if( aGerberJob->m_printMaskLayer == 0 )
653
654 if( aGerberJob->m_layersIncludeOnAllSet )
655 aGerberJob->m_layersIncludeOnAll = plotOnAllLayersSelection;
656 }
657
658 for( LSEQ seq = LSET( aGerberJob->m_printMaskLayer ).UIOrder(); seq; ++seq )
659 {
660 LSEQ plotSequence;
661
662 // Base layer always gets plotted first.
663 plotSequence.push_back( *seq );
664
665 // Now all the "include on all" layers
666 for( LSEQ seqAll = aGerberJob->m_layersIncludeOnAll.UIOrder(); seqAll; ++seqAll )
667 {
668 // Don't plot the same layer more than once;
669 if( find( plotSequence.begin(), plotSequence.end(), *seqAll ) != plotSequence.end() )
670 continue;
671
672 plotSequence.push_back( *seqAll );
673 }
674
675 // Pick the basename from the board file
676 wxFileName fn( brd->GetFileName() );
677 PCB_LAYER_ID layer = *seq;
678 wxString layerName = brd->GetLayerName( layer );
679 wxString sheetName;
680 wxString sheetPath;
681 PCB_PLOT_PARAMS plotOpts;
682
683 if( aGerberJob->m_useBoardPlotParams )
684 plotOpts = boardPlotOptions;
685 else
686 populateGerberPlotOptionsFromJob( plotOpts, aGerberJob );
687
688 if( plotOpts.GetUseGerberProtelExtensions() )
689 fileExt = GetGerberProtelExtension( layer );
690 else
692
693 BuildPlotFileName( &fn, aGerberJob->m_outputFile, layerName, fileExt );
694 wxString fullname = fn.GetFullName();
695
696 jobfile_writer.AddGbrFile( layer, fullname );
697
698 if( aJob->GetVarOverrides().contains( wxT( "LAYER" ) ) )
699 layerName = aJob->GetVarOverrides().at( wxT( "LAYER" ) );
700
701 if( aJob->GetVarOverrides().contains( wxT( "SHEETNAME" ) ) )
702 sheetName = aJob->GetVarOverrides().at( wxT( "SHEETNAME" ) );
703
704 if( aJob->GetVarOverrides().contains( wxT( "SHEETPATH" ) ) )
705 sheetPath = aJob->GetVarOverrides().at( wxT( "SHEETPATH" ) );
706
707 // We are feeding it one layer at the start here to silence a logic check
708 GERBER_PLOTTER* plotter = (GERBER_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer,
709 layerName, fn.GetFullPath(),
710 sheetName, sheetPath );
711
712 if( plotter )
713 {
714 m_reporter->Report( wxString::Format( _( "Plotted to '%s'.\n" ), fn.GetFullPath() ),
716 PlotBoardLayers( brd, plotter, plotSequence, plotOpts );
717 plotter->EndPlot();
718 }
719 else
720 {
721 m_reporter->Report( wxString::Format( _( "Failed to plot to '%s'.\n" ),
722 fn.GetFullPath() ),
725 }
726
727 delete plotter;
728 }
729
730 wxFileName fn( aGerberJob->m_filename );
731
732 // Build gerber job file from basename
733 BuildPlotFileName( &fn, aGerberJob->m_outputFile, wxT( "job" ),
735 jobfile_writer.CreateJobFile( fn.GetFullPath() );
736
737 return exitCode;
738}
739
740
743{
744 aPlotOpts.SetFormat( PLOT_FORMAT::GERBER );
745
746 aPlotOpts.SetPlotFrameRef( aJob->m_plotBorderTitleBlocks );
747 aPlotOpts.SetPlotValue( aJob->m_plotFootprintValues );
748 aPlotOpts.SetPlotReference( aJob->m_plotRefDes );
749
751
752 // Always disable plot pad holes
753 aPlotOpts.SetDrillMarksType( DRILL_MARKS::NO_DRILL_SHAPE );
754
756 aPlotOpts.SetUseGerberX2format( aJob->m_useX2Format );
758 aPlotOpts.SetUseAuxOrigin( aJob->m_useAuxOrigin );
760 aPlotOpts.SetGerberPrecision( aJob->m_precision );
761}
762
763
765{
766 int exitCode = CLI::EXIT_CODES::OK;
767 JOB_EXPORT_PCB_GERBER* aGerberJob = dynamic_cast<JOB_EXPORT_PCB_GERBER*>( aJob );
768
769 if( aGerberJob == nullptr )
771
772 if( aJob->IsCli() )
773 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
774
775 BOARD* brd = LoadBoard( aGerberJob->m_filename, true );
776 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
777
778 if( aGerberJob->m_outputFile.IsEmpty() )
779 {
780 wxFileName fn = brd->GetFileName();
781 fn.SetName( fn.GetName() );
782 fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::GERBER ) );
783
784 aGerberJob->m_outputFile = fn.GetFullName();
785 }
786
787 PCB_PLOT_PARAMS plotOpts;
788 populateGerberPlotOptionsFromJob( plotOpts, aGerberJob );
789 plotOpts.SetLayerSelection( aGerberJob->m_printMaskLayer );
790
792 wxString layerName;
793 wxString sheetName;
794 wxString sheetPath;
795
796 if( aGerberJob->m_printMaskLayer.size() == 1 )
797 {
798 layer = aGerberJob->m_printMaskLayer.front();
799 layerName = brd->GetLayerName( layer );
800 }
801
802 if( aJob->GetVarOverrides().contains( wxT( "LAYER" ) ) )
803 layerName = aJob->GetVarOverrides().at( wxT( "LAYER" ) );
804
805 if( aJob->GetVarOverrides().contains( wxT( "SHEETNAME" ) ) )
806 sheetName = aJob->GetVarOverrides().at( wxT( "SHEETNAME" ) );
807
808 if( aJob->GetVarOverrides().contains( wxT( "SHEETPATH" ) ) )
809 sheetPath = aJob->GetVarOverrides().at( wxT( "SHEETPATH" ) );
810
811 // We are feeding it one layer at the start here to silence a logic check
812 GERBER_PLOTTER* plotter = (GERBER_PLOTTER*) StartPlotBoard( brd, &plotOpts, layer, layerName,
813 aGerberJob->m_outputFile,
814 sheetName, sheetPath );
815
816 if( plotter )
817 {
818 PlotBoardLayers( brd, plotter, aGerberJob->m_printMaskLayer, plotOpts );
819 plotter->EndPlot();
820 }
821 else
822 {
823 m_reporter->Report( wxString::Format( _( "Failed to plot to '%s'.\n" ),
824 aGerberJob->m_outputFile ),
827 }
828
829 delete plotter;
830
831 return exitCode;
832}
833
836
837
839{
840 JOB_EXPORT_PCB_DRILL* aDrillJob = dynamic_cast<JOB_EXPORT_PCB_DRILL*>( aJob );
841
842 if( aDrillJob == nullptr )
844
845 if( aJob->IsCli() )
846 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
847
848 BOARD* brd = LoadBoard( aDrillJob->m_filename, true );
849
850 // ensure output dir exists
851 wxFileName fn( aDrillJob->m_outputDir + wxT( "/" ) );
852
853 if( !fn.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
854 {
855 m_reporter->Report( _( "Failed to create output directory\n" ), RPT_SEVERITY_ERROR );
857 }
858
859 std::unique_ptr<GENDRILL_WRITER_BASE> drillWriter;
860
862 drillWriter = std::make_unique<EXCELLON_WRITER>( brd );
863 else
864 drillWriter = std::make_unique<GERBER_WRITER>( brd );
865
866 VECTOR2I offset;
867
869 offset = VECTOR2I( 0, 0 );
870 else
871 offset = brd->GetDesignSettings().GetAuxOrigin();
872
873 PLOT_FORMAT mapFormat = PLOT_FORMAT::PDF;
874
875 switch( aDrillJob->m_mapFormat )
876 {
877 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::POSTSCRIPT: mapFormat = PLOT_FORMAT::POST; break;
878 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::GERBER_X2: mapFormat = PLOT_FORMAT::GERBER; break;
879 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::DXF: mapFormat = PLOT_FORMAT::DXF; break;
880 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::SVG: mapFormat = PLOT_FORMAT::SVG; break;
881 default:
882 case JOB_EXPORT_PCB_DRILL::MAP_FORMAT::PDF: mapFormat = PLOT_FORMAT::PDF; break;
883 }
884
886 {
888 switch( aDrillJob->m_zeroFormat )
889 {
892 break;
895 break;
898 break;
900 default:
902 break;
903 }
904
905 DRILL_PRECISION precision;
906
908 precision = precisionListForInches;
909 else
910 precision = precisionListForMetric;
911
912 EXCELLON_WRITER* excellonWriter = dynamic_cast<EXCELLON_WRITER*>( drillWriter.get() );
913
914 if( excellonWriter == nullptr )
916
917 excellonWriter->SetFormat( aDrillJob->m_drillUnits
919 zeroFmt, precision.m_Lhs, precision.m_Rhs );
920 excellonWriter->SetOptions( aDrillJob->m_excellonMirrorY,
921 aDrillJob->m_excellonMinimalHeader,
922 offset, aDrillJob->m_excellonCombinePTHNPTH );
923 excellonWriter->SetRouteModeForOvalHoles( aDrillJob->m_excellonOvalDrillRoute );
924 excellonWriter->SetMapFileFormat( mapFormat );
925
926 if( !excellonWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true,
927 aDrillJob->m_generateMap, m_reporter ) )
928 {
930 }
931 }
933 {
934 GERBER_WRITER* gerberWriter = dynamic_cast<GERBER_WRITER*>( drillWriter.get() );
935
936 if( gerberWriter == nullptr )
938
939 // Set gerber precision: only 5 or 6 digits for mantissa are allowed
940 // (SetFormat() accept 5 or 6, and any other value set the precision to 5)
941 // the integer part precision is always 4, and units always mm
942 gerberWriter->SetFormat( aDrillJob->m_gerberPrecision );
943 gerberWriter->SetOptions( offset );
944 gerberWriter->SetMapFileFormat( mapFormat );
945
946 if( !gerberWriter->CreateDrillandMapFilesSet( aDrillJob->m_outputDir, true,
947 aDrillJob->m_generateMap, m_reporter ) )
948 {
950 }
951 }
952
953 return CLI::EXIT_CODES::OK;
954}
955
956
958{
959 JOB_EXPORT_PCB_POS* aPosJob = dynamic_cast<JOB_EXPORT_PCB_POS*>( aJob );
960
961 if( aPosJob == nullptr )
963
964 if( aJob->IsCli() )
965 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
966
967 BOARD* brd = LoadBoard( aPosJob->m_filename, true );
968
969 if( aPosJob->m_outputFile.IsEmpty() )
970 {
971 wxFileName fn = brd->GetFileName();
972 fn.SetName( fn.GetName() );
973
976 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::CSV )
977 fn.SetExt( FILEEXT::CsvFileExtension );
978 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::GERBER )
979 fn.SetExt( FILEEXT::GerberFileExtension );
980
981 aPosJob->m_outputFile = fn.GetFullName();
982 }
983
986 {
987 FILE* file = nullptr;
988 file = wxFopen( aPosJob->m_outputFile, wxS( "wt" ) );
989
990 if( file == nullptr )
992
993 std::string data;
994
995 bool frontSide = aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::FRONT
997
998 bool backSide = aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::BACK
1000
1001 PLACE_FILE_EXPORTER exporter( brd,
1003 aPosJob->m_smdOnly, aPosJob->m_excludeFootprintsWithTh,
1004 aPosJob->m_excludeDNP,
1005 frontSide, backSide,
1008 aPosJob->m_negateBottomX );
1009 data = exporter.GenPositionData();
1010
1011 fputs( data.c_str(), file );
1012 fclose( file );
1013 }
1014 else if( aPosJob->m_format == JOB_EXPORT_PCB_POS::FORMAT::GERBER )
1015 {
1016 PLACEFILE_GERBER_WRITER exporter( brd );
1017
1018 PCB_LAYER_ID gbrLayer = F_Cu;
1019
1020 if( aPosJob->m_side == JOB_EXPORT_PCB_POS::SIDE::BACK )
1021 gbrLayer = B_Cu;
1022
1023 exporter.CreatePlaceFile( aPosJob->m_outputFile, gbrLayer, aPosJob->m_gerberBoardEdge );
1024 }
1025
1026 return CLI::EXIT_CODES::OK;
1027}
1028
1029extern FOOTPRINT* try_load_footprint( const wxFileName& aFileName, PCB_IO_MGR::PCB_FILE_T aFileType,
1030 const wxString& aName );
1031
1032
1034{
1035 JOB_FP_UPGRADE* upgradeJob = dynamic_cast<JOB_FP_UPGRADE*>( aJob );
1036
1037 if( upgradeJob == nullptr )
1039
1041
1042 if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
1043 {
1044 if( wxFile::Exists( upgradeJob->m_outputLibraryPath ) ||
1045 wxDir::Exists( upgradeJob->m_outputLibraryPath) )
1046 {
1047 m_reporter->Report( _( "Output path must not conflict with existing path\n" ),
1050 }
1051 }
1052 else if( fileType != PCB_IO_MGR::KICAD_SEXP )
1053 {
1054 m_reporter->Report( _( "Output path must be specified to convert legacy and non-KiCad libraries\n" ),
1056
1058 }
1059
1061 {
1062 if( !wxDir::Exists( upgradeJob->m_libraryPath ) )
1063 {
1064 m_reporter->Report( _( "Footprint library path does not exist or is not accessible\n" ),
1067 }
1068
1069
1070 if( aJob->IsCli() )
1071 m_reporter->Report( _( "Loading footprint library\n" ), RPT_SEVERITY_INFO );
1072
1074 FP_CACHE fpLib( &pcb_io, upgradeJob->m_libraryPath );
1075
1076 try
1077 {
1078 fpLib.Load();
1079 }
1080 catch( ... )
1081 {
1082 m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
1084 }
1085
1086 bool shouldSave = upgradeJob->m_force;
1087
1088 for( const auto& footprint : fpLib.GetFootprints() )
1089 {
1090 if( footprint.second->GetFootprint()->GetFileFormatVersionAtLoad()
1092 {
1093 shouldSave = true;
1094 }
1095 }
1096
1097 if( shouldSave )
1098 {
1099 m_reporter->Report( _( "Saving footprint library\n" ), RPT_SEVERITY_INFO );
1100
1101 try
1102 {
1103 if( !upgradeJob->m_outputLibraryPath.IsEmpty() )
1104 {
1105 fpLib.SetPath( upgradeJob->m_outputLibraryPath );
1106 }
1107
1108 fpLib.Save();
1109 }
1110 catch( ... )
1111 {
1112 m_reporter->Report( _( "Unable to save library\n" ), RPT_SEVERITY_ERROR );
1114 }
1115 }
1116 else
1117 {
1118 m_reporter->Report( _( "Footprint library was not updated\n" ), RPT_SEVERITY_INFO );
1119 }
1120 }
1121 else
1122 {
1123 if( !PCB_IO_MGR::ConvertLibrary( nullptr, upgradeJob->m_libraryPath, upgradeJob->m_outputLibraryPath ) )
1124 {
1125 m_reporter->Report( ( "Unable to convert library\n" ), RPT_SEVERITY_ERROR );
1127 }
1128 }
1129
1130 return CLI::EXIT_CODES::OK;
1131}
1132
1133
1135{
1136 JOB_FP_EXPORT_SVG* svgJob = dynamic_cast<JOB_FP_EXPORT_SVG*>( aJob );
1137
1138 if( svgJob == nullptr )
1140
1141 if( aJob->IsCli() )
1142 m_reporter->Report( _( "Loading footprint library\n" ), RPT_SEVERITY_INFO );
1143
1145 FP_CACHE fpLib( &pcb_io, svgJob->m_libraryPath );
1146
1147 try
1148 {
1149 fpLib.Load();
1150 }
1151 catch( ... )
1152 {
1153 m_reporter->Report( _( "Unable to load library\n" ), RPT_SEVERITY_ERROR );
1155 }
1156
1157 if( !svgJob->m_outputDirectory.IsEmpty() && !wxDir::Exists( svgJob->m_outputDirectory ) )
1158 {
1159 wxFileName::Mkdir( svgJob->m_outputDirectory );
1160 }
1161
1162 int exitCode = CLI::EXIT_CODES::OK;
1163
1164 // Just plot all the symbols we can
1165 FP_CACHE_FOOTPRINT_MAP& footprintMap = fpLib.GetFootprints();
1166
1167 bool singleFpPlotted = false;
1168 for( FP_CACHE_FOOTPRINT_MAP::iterator it = footprintMap.begin(); it != footprintMap.end();
1169 ++it )
1170 {
1171 const FOOTPRINT* fp = it->second->GetFootprint();
1172 if( !svgJob->m_footprint.IsEmpty() )
1173 {
1174 if( fp->GetFPID().GetLibItemName().wx_str() != svgJob->m_footprint )
1175 {
1176 // skip until we find the right footprint
1177 continue;
1178 }
1179 else
1180 {
1181 singleFpPlotted = true;
1182 }
1183 }
1184
1185 exitCode = doFpExportSvg( svgJob, fp );
1186 if( exitCode != CLI::EXIT_CODES::OK )
1187 break;
1188 }
1189
1190 if( !svgJob->m_footprint.IsEmpty() && !singleFpPlotted )
1191 {
1192 m_reporter->Report( _( "The given footprint could not be found to export." ) + wxS( "\n" ),
1194 }
1195
1196 return CLI::EXIT_CODES::OK;
1197}
1198
1199
1201{
1202 // the hack for now is we create fake boards containing the footprint and plot the board
1203 // until we refactor better plot api later
1204 std::unique_ptr<BOARD> brd;
1205 brd.reset( CreateEmptyBoard() );
1206 brd->GetProject()->ApplyTextVars( aSvgJob->GetVarOverrides() );
1207
1208 FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( aFootprint->Clone() );
1209
1210 if( fp == nullptr )
1212
1213 fp->SetLink( niluuid );
1214 fp->SetFlags( IS_NEW );
1215 fp->SetParent( brd.get() );
1216
1217 for( PAD* pad : fp->Pads() )
1218 {
1219 pad->SetLocalRatsnestVisible( false );
1220 pad->SetNetCode( 0 );
1221 }
1222
1223 fp->SetOrientation( ANGLE_0 );
1224 fp->SetPosition( VECTOR2I( 0, 0 ) );
1225
1226 brd->Add( fp, ADD_MODE::INSERT, true );
1227
1228 wxFileName outputFile;
1229 outputFile.SetPath( aSvgJob->m_outputDirectory );
1230 outputFile.SetName( aFootprint->GetFPID().GetLibItemName().wx_str() );
1231 outputFile.SetExt( FILEEXT::SVGFileExtension );
1232
1233 m_reporter->Report( wxString::Format( _( "Plotting footprint '%s' to '%s'\n" ),
1234 aFootprint->GetFPID().GetLibItemName().wx_str(),
1235 outputFile.GetFullPath() ),
1237
1238
1239 PCB_PLOT_SVG_OPTIONS svgPlotOptions;
1240 svgPlotOptions.m_blackAndWhite = aSvgJob->m_blackAndWhite;
1241 svgPlotOptions.m_colorTheme = aSvgJob->m_colorTheme;
1242 svgPlotOptions.m_outputFile = outputFile.GetFullPath();
1243 svgPlotOptions.m_mirror = false;
1244 svgPlotOptions.m_pageSizeMode = 2; // board bounding box
1245 svgPlotOptions.m_printMaskLayer = aSvgJob->m_printMaskLayer;
1246 svgPlotOptions.m_plotFrame = false;
1247
1248 if( !EXPORT_SVG::Plot( brd.get(), svgPlotOptions ) )
1249 m_reporter->Report( _( "Error creating svg file" ) + wxS( "\n" ), RPT_SEVERITY_ERROR );
1250
1251
1252 return CLI::EXIT_CODES::OK;
1253}
1254
1255
1257{
1258 JOB_PCB_DRC* drcJob = dynamic_cast<JOB_PCB_DRC*>( aJob );
1259
1260 if( drcJob == nullptr )
1262
1263 if( aJob->IsCli() )
1264 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
1265
1266 BOARD* brd = LoadBoard( drcJob->m_filename, true );
1267 brd->GetProject()->ApplyTextVars( aJob->GetVarOverrides() );
1268
1269 if( drcJob->m_outputFile.IsEmpty() )
1270 {
1271 wxFileName fn = brd->GetFileName();
1272 fn.SetName( fn.GetName() );
1273
1275 fn.SetExt( FILEEXT::JsonFileExtension );
1276 else
1277 fn.SetExt( FILEEXT::ReportFileExtension );
1278
1279 drcJob->m_outputFile = fn.GetFullName();
1280 }
1281
1282 EDA_UNITS units;
1283
1284 switch( drcJob->m_units )
1285 {
1286 case JOB_PCB_DRC::UNITS::INCHES: units = EDA_UNITS::INCHES; break;
1287 case JOB_PCB_DRC::UNITS::MILS: units = EDA_UNITS::MILS; break;
1288 case JOB_PCB_DRC::UNITS::MILLIMETERS: units = EDA_UNITS::MILLIMETRES; break;
1289 default: units = EDA_UNITS::MILLIMETRES; break;
1290 }
1291
1292 std::shared_ptr<DRC_ENGINE> drcEngine = brd->GetDesignSettings().m_DRCEngine;
1293 std::unique_ptr<NETLIST> netlist = std::make_unique<NETLIST>();
1294
1295 drcEngine->SetDrawingSheet( getDrawingSheetProxyView( brd ) );
1296
1297 // BOARD_COMMIT uses TOOL_MANAGER to grab the board internally so we must give it one
1298 TOOL_MANAGER* toolManager = new TOOL_MANAGER;
1299 toolManager->SetEnvironment( brd, nullptr, nullptr, Kiface().KifaceSettings(), nullptr );
1300
1301 BOARD_COMMIT commit( toolManager );
1302
1303 m_reporter->Report( _( "Running DRC...\n" ), RPT_SEVERITY_INFO );
1304
1305 if( drcJob->m_parity )
1306 {
1307 typedef bool (*NETLIST_FN_PTR)( const wxString&, std::string& );
1308
1310 wxFileName schematicPath( drcJob->m_filename );
1311 NETLIST_FN_PTR netlister = (NETLIST_FN_PTR) eeschema->IfaceOrAddress( KIFACE_NETLIST_SCHEMATIC );
1312 std::string netlist_str;
1313
1314 schematicPath.SetExt( FILEEXT::KiCadSchematicFileExtension );
1315
1316 if( !schematicPath.Exists() )
1317 schematicPath.SetExt( FILEEXT::LegacySchematicFileExtension );
1318
1319 if( !schematicPath.Exists() )
1320 {
1321 m_reporter->Report( _( "Failed to find schematic for parity tests.\n" ),
1323 }
1324 else
1325 {
1326 (*netlister)( schematicPath.GetFullPath(), netlist_str );
1327
1328 try
1329 {
1330 auto lineReader = new STRING_LINE_READER( netlist_str, _( "Eeschema netlist" ) );
1331 KICAD_NETLIST_READER netlistReader( lineReader, netlist.get() );
1332 netlistReader.LoadNetlist();
1333 }
1334 catch( const IO_ERROR& )
1335 {
1336 m_reporter->Report( _( "Failed to fetch schematic netlist for parity tests.\n" ),
1338 }
1339
1340 drcEngine->SetSchematicNetlist( netlist.get() );
1341 }
1342 }
1343
1344 drcEngine->SetProgressReporter( nullptr );
1345 drcEngine->SetViolationHandler(
1346 [&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
1347 {
1348 PCB_MARKER* marker = new PCB_MARKER( aItem, aPos, aLayer );
1349 commit.Add( marker );
1350 } );
1351
1352 brd->RecordDRCExclusions();
1353 brd->DeleteMARKERs( true, true );
1354 drcEngine->RunTests( units, drcJob->m_reportAllTrackErrors, drcJob->m_parity );
1355 drcEngine->ClearViolationHandler();
1356
1357 commit.Push( _( "DRC" ), SKIP_UNDO | SKIP_SET_DIRTY );
1358
1359 // Update the exclusion status on any excluded markers that still exist.
1360 brd->ResolveDRCExclusions( false );
1361
1362 std::shared_ptr<DRC_ITEMS_PROVIDER> markersProvider = std::make_shared<DRC_ITEMS_PROVIDER>(
1364
1365 std::shared_ptr<DRC_ITEMS_PROVIDER> ratsnestProvider =
1366 std::make_shared<DRC_ITEMS_PROVIDER>( brd, MARKER_BASE::MARKER_RATSNEST );
1367
1368 std::shared_ptr<DRC_ITEMS_PROVIDER> fpWarningsProvider =
1369 std::make_shared<DRC_ITEMS_PROVIDER>( brd, MARKER_BASE::MARKER_PARITY );
1370
1371 markersProvider->SetSeverities( drcJob->m_severity );
1372 ratsnestProvider->SetSeverities( drcJob->m_severity );
1373 fpWarningsProvider->SetSeverities( drcJob->m_severity );
1374
1375 m_reporter->Report( wxString::Format( _( "Found %d violations\n" ),
1376 markersProvider->GetCount() ),
1378 m_reporter->Report( wxString::Format( _( "Found %d unconnected items\n" ),
1379 ratsnestProvider->GetCount() ),
1381
1382 if( drcJob->m_parity )
1383 {
1384 m_reporter->Report( wxString::Format( _( "Found %d schematic parity issues\n" ),
1385 fpWarningsProvider->GetCount() ),
1387 }
1388
1389 DRC_REPORT reportWriter( brd, units, markersProvider, ratsnestProvider, fpWarningsProvider );
1390
1391 bool wroteReport = false;
1392
1394 wroteReport = reportWriter.WriteJsonReport( drcJob->m_outputFile );
1395 else
1396 wroteReport = reportWriter.WriteTextReport( drcJob->m_outputFile );
1397
1398 if( !wroteReport )
1399 {
1400 m_reporter->Report( wxString::Format( _( "Unable to save DRC report to %s\n" ),
1401 drcJob->m_outputFile ),
1404 }
1405
1406 m_reporter->Report( wxString::Format( _( "Saved DRC Report to %s\n" ),
1407 drcJob->m_outputFile ),
1409
1410 if( drcJob->m_exitCodeViolations )
1411 {
1412 if( markersProvider->GetCount() > 0 || ratsnestProvider->GetCount() > 0
1413 || fpWarningsProvider->GetCount() > 0 )
1414 {
1416 }
1417 }
1418
1420}
1421
1422
1424{
1425 JOB_EXPORT_PCB_IPC2581* job = dynamic_cast<JOB_EXPORT_PCB_IPC2581*>( aJob );
1426
1427 if( job == nullptr )
1429
1430 if( job->IsCli() )
1431 m_reporter->Report( _( "Loading board\n" ), RPT_SEVERITY_INFO );
1432
1433 BOARD* brd = LoadBoard( job->m_filename, true );
1434
1435 if( job->m_outputFile.IsEmpty() )
1436 {
1437 wxFileName fn = brd->GetFileName();
1438 fn.SetName( fn.GetName() );
1439 fn.SetExt( FILEEXT::Ipc2581FileExtension );
1440
1441 job->m_outputFile = fn.GetFullName();
1442 }
1443
1444 STRING_UTF8_MAP props;
1445 props["units"] = job->m_units == JOB_EXPORT_PCB_IPC2581::IPC2581_UNITS::MILLIMETERS ? "mm"
1446 : "inch";
1447 props["sigfig"] = wxString::Format( "%d", job->m_units );
1448 props["version"] = job->m_version == JOB_EXPORT_PCB_IPC2581::IPC2581_VERSION::C ? "C" : "B";
1449 props["OEMRef"] = job->m_colInternalId;
1450 props["mpn"] = job->m_colMfgPn;
1451 props["mfg"] = job->m_colMfg;
1452 props["dist"] = job->m_colDist;
1453 props["distpn"] = job->m_colDistPn;
1454
1455 wxString tempFile = wxFileName::CreateTempFileName( wxS( "pcbnew_ipc" ) );
1456 try
1457 {
1459 pi->SetProgressReporter( m_progressReporter );
1460 pi->SaveBoard( tempFile, brd, &props );
1461 }
1462 catch( const IO_ERROR& ioe )
1463 {
1464 m_reporter->Report( wxString::Format( _( "Error generating IPC2581 file '%s'.\n%s" ),
1465 job->m_filename, ioe.What() ),
1467
1468 wxRemoveFile( tempFile );
1469
1471 }
1472
1473 if( job->m_compress )
1474 {
1475 wxFileName tempfn = job->m_outputFile;
1476 tempfn.SetExt( FILEEXT::Ipc2581FileExtension );
1477 wxFileName zipfn = tempFile;
1478 zipfn.SetExt( "zip" );
1479
1480 wxFFileOutputStream fnout( zipfn.GetFullPath() );
1481 wxZipOutputStream zip( fnout );
1482 wxFFileInputStream fnin( tempFile );
1483
1484 zip.PutNextEntry( tempfn.GetFullName() );
1485 fnin.Read( zip );
1486 zip.Close();
1487 fnout.Close();
1488
1489 wxRemoveFile( tempFile );
1490 tempFile = zipfn.GetFullPath();
1491 }
1492
1493 // If save succeeded, replace the original with what we just wrote
1494 if( !wxRenameFile( tempFile, job->m_outputFile ) )
1495 {
1496 m_reporter->Report( wxString::Format( _( "Error generating IPC2581 file '%s'.\n"
1497 "Failed to rename temporary file '%s." )
1498 + wxS( "\n" ),
1499 job->m_outputFile, tempFile ),
1501 }
1502
1504}
1505
1506
1508{
1510 &aBrd->GetPageSettings(),
1511 aBrd->GetProject(),
1512 &aBrd->GetTitleBlock(),
1513 &aBrd->GetProperties() );
1514
1515 drawingSheet->SetSheetName( std::string() );
1516 drawingSheet->SetSheetPath( std::string() );
1517 drawingSheet->SetIsFirstPage( true );
1518
1519 drawingSheet->SetFileName( TO_UTF8( aBrd->GetFileName() ) );
1520
1521 return drawingSheet;
1522}
1523
1524
1525void PCBNEW_JOBS_HANDLER::loadOverrideDrawingSheet( BOARD* aBrd, const wxString& aSheetPath )
1526{
1527 // dont bother attempting to load a empty path, if there was one
1528 if( aSheetPath.IsEmpty() )
1529 return;
1530
1531 auto loadSheet =
1532 [&]( const wxString& path ) -> bool
1533 {
1536 aBrd->GetProject()->GetProjectPath() );
1537
1538 if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( filename ) )
1539 {
1540 m_reporter->Report( wxString::Format( _( "Error loading drawing sheet '%s'." ) + wxS( "\n" ),
1541 path ),
1543 return false;
1544 }
1545
1546 return true;
1547 };
1548
1549 if( loadSheet( aSheetPath ) )
1550 return;
1551
1552 // failed loading custom path, revert back to default
1553 loadSheet( aBrd->GetProject()->GetProjectFile().m_BoardDrawingSheetFile );
1554}
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:282
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:677
const PAGE_INFO & GetPageSettings() const
Definition: board.h:671
BOX2I ComputeBoundingBox(bool aBoardEdgesOnly=false, bool aIncludeHiddenText=false) const
Calculate the bounding box containing all board items (or board edge segments).
Definition: board.cpp:1552
void RecordDRCExclusions()
Scan existing markers and record data from any that are Excluded.
Definition: board.cpp:317
TITLE_BLOCK & GetTitleBlock()
Definition: board.h:677
const std::map< wxString, wxString > & GetProperties() const
Definition: board.h:354
const wxString & GetFileName() const
Definition: board.h:319
std::vector< PCB_MARKER * > ResolveDRCExclusions(bool aCreateMarkers)
Rebuild DRC markers from the serialized data in BOARD_DESIGN_SETTINGS.
Definition: board.cpp:334
const PCB_PLOT_PARAMS & GetPlotOptions() const
Definition: board.h:674
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:564
PROJECT * GetProject() const
Definition: board.h:476
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:794
void DeleteMARKERs()
Delete all MARKERS from the board.
Definition: board.cpp:1239
const Vec GetCenter() const
Definition: box2.h:220
void SetProjection(PROJECTION_TYPE aProjection)
Definition: camera.h:206
void RotateY_T1(float aAngleInRadians)
Definition: camera.cpp:677
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:671
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:683
bool ParametersChanged()
Definition: camera.cpp:721
COMMIT & Add(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
Definition: commit.h:80
bool WriteJsonReport(const wxString &aFullFileName)
Definition: drc_report.cpp:114
bool WriteTextReport(const wxString &aFullFileName)
Definition: drc_report.cpp:47
Helper to handle drill precision format in excellon files.
static DS_DATA_MODEL & GetTheInstance()
static function: returns the instance of DS_DATA_MODEL used in the application
static const wxString ResolvePath(const wxString &aPath, const wxString &aProjectPath)
Resolve a path which might be project-relative or contain env variable references.
void SetSheetPath(const std::string &aSheetPath)
Set the sheet path displayed in the title block.
void SetSheetName(const std::string &aSheetName)
Set the sheet name displayed in the title block.
void SetIsFirstPage(bool aIsFirstPage)
Change if this is first page.
void SetFileName(const std::string &aFileName)
Set the file name displayed in the title block.
virtual bool EndPlot() override
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:126
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:103
Create Excellon drill, drill map, and drill report files.
void SetFormat(bool aMetric, ZEROS_FMT aZerosFmt=DECIMAL_FORMAT, int aLeftDigits=0, int aRightDigits=0)
Initialize internal parameters to match the given format.
bool CreateDrillandMapFilesSet(const wxString &aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER *aReporter=nullptr)
Create the full set of Excellon drill file for the board.
void SetOptions(bool aMirror, bool aMinimalHeader, const VECTOR2I &aOffset, bool aMerge_PTH_NPTH)
Initialize internal parameters to match drill options.
void SetRouteModeForOvalHoles(bool aUseRouteModeForOvalHoles)
double m_BoardOutlinesChainingEpsilon
Definition: exporter_step.h:87
wxString m_outputFile
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:30
void SetPosition(const VECTOR2I &aPos) override
Definition: footprint.cpp:2315
void SetLink(const KIID &aLink)
Definition: footprint.h:839
void SetOrientation(const EDA_ANGLE &aNewAngle)
Definition: footprint.cpp:2387
EDA_ITEM * Clone() const override
Invoke a function on all children.
Definition: footprint.cpp:2004
PADS & Pads()
Definition: footprint.h:191
const LIB_ID & GetFPID() const
Definition: footprint.h:233
FP_CACHE_FOOTPRINT_MAP & GetFootprints()
void Save(FOOTPRINT *aFootprint=nullptr)
Save the footprint cache or a single footprint from it to disk.
void SetPath(const wxString &aPath)
void SetMapFileFormat(PLOT_FORMAT aMapFmt)
Initialize the format for the drill map file.
GERBER_JOBFILE_WRITER is a class used to create Gerber job file a Gerber job file stores info to make...
bool CreateJobFile(const wxString &aFullFilename)
Creates a Gerber job file.
void AddGbrFile(PCB_LAYER_ID aLayer, wxString &aFilename)
add a gerber file name and type in job file list
virtual bool EndPlot() override
Used to create Gerber drill files.
bool CreateDrillandMapFilesSet(const wxString &aPlotDirectory, bool aGenDrill, bool aGenMap, REPORTER *aReporter=nullptr)
Create the full set of Excellon drill file for the board filenames are computed from the board name,...
void SetOptions(const VECTOR2I &aOffset)
Initialize internal parameters to match drill options.
void SetFormat(int aRightDigits=6)
Initialize internal parameters to match the given format.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
PROGRESS_REPORTER * m_progressReporter
void Register(const std::string &aJobTypeName, std::function< int(JOB *job)> aHandler)
REPORTER * m_reporter
double m_BoardOutlinesChainingEpsilon
JOB_EXPORT_PCB_3D::FORMAT m_format
wxString m_libraryPath
wxString m_outputLibraryPath
OUTPUT_FORMAT m_format
Definition: job_pcb_drc.h:57
UNITS m_units
Definition: job_pcb_drc.h:47
bool m_parity
Definition: job_pcb_drc.h:60
wxString m_filename
Definition: job_pcb_drc.h:35
int m_severity
Definition: job_pcb_drc.h:49
bool m_reportAllTrackErrors
Definition: job_pcb_drc.h:38
wxString m_outputFile
Definition: job_pcb_drc.h:36
bool m_exitCodeViolations
Definition: job_pcb_drc.h:59
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:32
bool IsCli() const
Definition: job.h:39
const std::map< wxString, wxString > & GetVarOverrides() const
Definition: job.h:41
Read the new s-expression based KiCad netlist format.
virtual void LoadNetlist() override
Load the contents of the netlist file into aNetlist.
A 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:279
virtual KIFACE * KiFACE(FACE_T aFaceId, bool doLoad=true)
Return the KIFACE* given a FACE_T.
Definition: kiway.cpp:202
@ FACE_SCH
eeschema DSO
Definition: kiway.h:286
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Definition: layer_ids.h:521
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:575
LSEQ UIOrder() const
Definition: lset.cpp:1012
LSEQ SeqStackupForPlotting() const
Return the sequence that is typical for a bottom-to-top stack-up.
Definition: lset.cpp:563
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
Definition: lset.cpp:884
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:863
@ MARKER_DRAWING_SHEET
Definition: marker_base.h:56
Definition: pad.h:53
void populateGerberPlotOptionsFromJob(PCB_PLOT_PARAMS &aPlotOpts, JOB_EXPORT_PCB_GERBER *aJob)
int JobExportFpUpgrade(JOB *aJob)
int JobExportGerber(JOB *aJob)
DS_PROXY_VIEW_ITEM * getDrawingSheetProxyView(BOARD *aBrd)
void loadOverrideDrawingSheet(BOARD *brd, const wxString &aSheetPath)
PCBNEW_JOBS_HANDLER(KIWAY *aKiway)
int JobExportGerbers(JOB *aJob)
int JobExportRender(JOB *aJob)
int doFpExportSvg(JOB_FP_EXPORT_SVG *aSvgJob, const FOOTPRINT *aFootprint)
A #PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
static PCB_IO * PluginFind(PCB_FILE_T aFileType)
Return a #PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: pcb_io_mgr.cpp:65
static bool ConvertLibrary(STRING_UTF8_MAP *aOldFileProps, const wxString &aOldFilePath, const wxString &aNewFilePath)
Convert a schematic symbol library to the latest KiCad format.
Definition: pcb_io_mgr.cpp:187
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 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:132
Parameters and options when plotting/printing a board.
void SetDrillMarksType(DRILL_MARKS aVal)
void SetLayerSelection(LSET aSelection)
void SetPlotReference(bool aFlag)
void SetUseGerberX2format(bool aUse)
void SetDXFPlotPolygonMode(bool aFlag)
void SetPlotFrameRef(bool aFlag)
LSET GetLayerSelection() const
LSET GetPlotOnAllLayersSelection() const
void SetDisableGerberMacros(bool aDisable)
void SetMirror(bool aFlag)
void SetBlackAndWhite(bool blackAndWhite)
void SetGerberPrecision(int aPrecision)
void SetSubtractMaskFromSilk(bool aSubtract)
void SetPlotValue(bool aFlag)
void SetUseGerberProtelExtensions(bool aUse)
void SetDXFPlotUnits(DXF_UNITS aUnit)
void SetColorSettings(COLOR_SETTINGS *aSettings)
void SetIncludeGerberNetlistInfo(bool aUse)
void SetNegative(bool aFlag)
void SetUseAuxOrigin(bool aAux)
bool GetUseGerberProtelExtensions() const
void SetFormat(PLOT_FORMAT aFormat)
virtual bool EndPlot() override
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
Used to create Gerber drill files.
int CreatePlaceFile(wxString &aFullFilename, PCB_LAYER_ID aLayer, bool aIncludeBrdEdges)
Create an pnp gerber file.
The ASCII format of the kicad place file is:
std::string GenPositionData()
build a string filled with the position data
wxString m_BoardDrawingSheetFile
PcbNew params.
Definition: project_file.h:154
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 GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:135
virtual void ApplyTextVars(const std::map< wxString, wxString > &aVarsMap)
Applies the given var map, it will create or update existing vars.
Definition: project.cpp:90
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:166
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.
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition: richio.h:253
A name/value tuple with unique names and optional values.
Master controller class:
Definition: tool_manager.h: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:63
T z
Definition: vector3.h:64
T x
Definition: vector3.h:62
wxString GetDefaultPlotExtension(PLOT_FORMAT aFormat)
Returns the default plot extension for a format.
static DRILL_PRECISION precisionListForInches(2, 4)
static DRILL_PRECISION precisionListForMetric(3, 3)
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition: eda_angle.h:435
#define IS_NEW
New item, just created.
EDA_UNITS
Definition: eda_units.h:46
Classes used in drill files, map files and report files generation.
Classes used in drill files, map files and report files generation.
Classes used to generate a Gerber job file in JSON.
Classes used in place file generation.
static const std::string LegacySchematicFileExtension
static const std::string 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 StepFileExtension
static const std::string SVGFileExtension
static const std::string VrmlFileExtension
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition: io_mgr.h:33
@ KIFACE_NETLIST_SCHEMATIC
Definition: kiface_ids.h:56
KIID niluuid(0)
@ LAYER_3D_BACKGROUND_TOP
Definition: layer_ids.h:452
@ LAYER_3D_BACKGROUND_BOTTOM
Definition: layer_ids.h:451
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ B_Cu
Definition: layer_ids.h:95
@ 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)
BOARD * LoadBoard(wxString &aFileName, bool aSetActive)
Loads a board from file This function identifies the file type by extension and determines the correc...
BOARD * CreateEmptyBoard()
Construct a default BOARD with a temporary (no filename) project.
const wxString GetGerberProtelExtension(int aLayer)
Definition: pcbplot.cpp:42
void BuildPlotFileName(wxFileName *aFilename, const wxString &aOutputDir, const wxString &aSuffix, const wxString &aExtension)
Complete a plot filename.
Definition: pcbplot.cpp:361
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:1059
see class PGM_BASE
PLOT_FORMAT
The set of supported output plot formats.
Definition: plotter.h:64
Plotting engines similar to ps (PostScript, Gerber, svg)
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_INFO
@ RPT_SEVERITY_ACTION
#define SKIP_SET_DIRTY
Definition: sch_commit.h: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:391
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
wxString m_colorTheme
Definition: export_svg.h:27
wxString m_outputFile
Definition: export_svg.h:26
Declaration for a track ball camera.
double DEG2RAD(double deg)
Definition: trigo.h:200
VECTOR2< double > VECTOR2D
Definition: vector2d.h:601
VECTOR2< int > VECTOR2I
Definition: vector2d.h:602
Definition of file extensions used in Kicad.
glm::vec3 SFVEC3F
Definition: xv3d_types.h:44