KiCad PCB EDA Suite
dialog_plot.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) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 
25 #include <kiface_i.h>
26 #include <plotter.h>
27 #include <confirm.h>
28 #include <pcb_edit_frame.h>
29 #include <pcbnew_settings.h>
30 #include <pcbplot.h>
31 #include <gerber_jobfile_writer.h>
32 #include <reporter.h>
35 #include <locale_io.h>
36 #include <bitmaps.h>
37 #include <board.h>
38 #include <dialog_plot.h>
39 #include <dialog_gendrill.h>
40 #include <wx_html_report_panel.h>
41 #include <tool/tool_manager.h>
42 #include <tools/zone_filler_tool.h>
43 #include <tools/drc_tool.h>
44 #include <math/util.h> // for KiROUND
45 #include <macros.h>
46 
47 
49  DIALOG_PLOT_BASE( aParent ), m_parent( aParent ),
50  m_defaultPenSize( aParent, m_hpglPenLabel, m_hpglPenCtrl, m_hpglPenUnits, true ),
51  m_trackWidthCorrection( aParent, m_widthAdjustLabel, m_widthAdjustCtrl, m_widthAdjustUnits, true )
52 {
53  SetName( DLG_WINDOW_NAME );
54  m_plotOpts = aParent->GetPlotSettings();
56 
57  m_messagesPanel->SetFileName( Prj().GetProjectPath() + wxT( "report.txt" ) );
58 
59  init_Dialog();
60 
61  // We use a sdbSizer to get platform-dependent ordering of the action buttons, but
62  // that requires us to correct the button labels here.
63  m_sdbSizer1OK->SetLabel( _( "Plot" ) );
64  m_sdbSizer1Apply->SetLabel( _( "Generate Drill Files..." ) );
65  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
66  m_sizerButtons->Layout();
67 
68  m_sdbSizer1OK->SetDefault();
69 
70  GetSizer()->Fit( this );
71  GetSizer()->SetSizeHints( this );
72 }
73 
74 
76 {
77  BOARD* board = m_parent->GetBoard();
78  wxFileName fileName;
79 
80  auto cfg = m_parent->GetPcbNewSettings();
81 
82  m_XScaleAdjust = cfg->m_Plot.fine_scale_x;
83  m_YScaleAdjust = cfg->m_Plot.fine_scale_y;
84 
85  m_zoneFillCheck->SetValue( cfg->m_Plot.check_zones_before_plotting );
86 
87  m_browseButton->SetBitmap( KiBitmap( small_folder_xpm ) );
88 
89  // m_PSWidthAdjust is stored in mm in user config
90  m_PSWidthAdjust = KiROUND( cfg->m_Plot.ps_fine_width_adjust * IU_PER_MM );
91 
92  // The reasonable width correction value must be in a range of
93  // [-(MinTrackWidth-1), +(MinClearanceValue-1)] decimils.
96 
97  switch( m_plotOpts.GetFormat() )
98  {
99  default:
100  case PLOT_FORMAT::GERBER: m_plotFormatOpt->SetSelection( 0 ); break;
101  case PLOT_FORMAT::POST: m_plotFormatOpt->SetSelection( 1 ); break;
102  case PLOT_FORMAT::SVG: m_plotFormatOpt->SetSelection( 2 ); break;
103  case PLOT_FORMAT::DXF: m_plotFormatOpt->SetSelection( 3 ); break;
104  case PLOT_FORMAT::HPGL: m_plotFormatOpt->SetSelection( 4 ); break;
105  case PLOT_FORMAT::PDF: m_plotFormatOpt->SetSelection( 5 ); break;
106  }
107 
108  // Set units and value for HPGL pen size (this param is in mils).
110 
111  // Test for a reasonable scale value. Set to 1 if problem
115 
118 
119  // Test for a reasonable PS width correction value. Set to 0 if problem.
120  if( m_PSWidthAdjust < m_widthAdjustMinValue || m_PSWidthAdjust > m_widthAdjustMaxValue )
121  m_PSWidthAdjust = 0.;
122 
124 
127 
128  // Could devote a PlotOrder() function in place of UIOrder().
129  m_layerList = board->GetEnabledLayers().UIOrder();
130 
131  // Populate the check list box by all enabled layers names
132  for( LSEQ seq = m_layerList; seq; ++seq )
133  {
134  PCB_LAYER_ID layer = *seq;
135 
136  int checkIndex = m_layerCheckListBox->Append( board->GetLayerName( layer ) );
137 
138  if( m_plotOpts.GetLayerSelection()[layer] )
139  m_layerCheckListBox->Check( checkIndex );
140  }
141 
142  // Option for disabling Gerber Aperture Macro (for broken Gerber readers)
144 
145  // Option for using proper Gerber extensions. Note also Protel extensions are
146  // a broken feature. However, for now, we need to handle it.
148 
149  // Option for including Gerber attributes, from Gerber X2 format, in the output
150  // In X1 format, they will be added as comments
152 
153  // Option for including Gerber netlist info (from Gerber X2 format) in the output
155 
156  // Option to generate a Gerber job file
158 
159  // Gerber precision for coordinates
160  m_coordFormatCtrl->SetSelection( m_plotOpts.GetGerberPrecision() == 5 ? 0 : 1 );
161 
162  // SVG precision and units for coordinates
164  m_svgUnits->SetSelection( m_plotOpts.GetSvgUseInch() );
165 
166  // Option for excluding contents of "Edges Pcb" layer
168 
169  // Option to exclude pads from silkscreen layers
171 
172  // Option to tent vias
174 
175  // Option to use aux origin
177 
178  // Option to plot page references:
180 
181  // Options to plot texts on footprints
185 
186  // Options to plot pads and vias holes
187  m_drillShapeOpt->SetSelection( m_plotOpts.GetDrillMarksType() );
188 
189  // Scale option
190  m_scaleOpt->SetSelection( m_plotOpts.GetScaleSelection() );
191 
192  // Plot mode
194 
195  // DXF outline mode
197 
198  // DXF text mode
200 
201  // DXF units selection
202  m_DXF_plotUnits->SetSelection( m_plotOpts.GetDXFPlotUnits() == DXF_UNITS::INCHES ? 0 : 1);
203 
204  // Plot mirror option
205  m_plotMirrorOpt->SetValue( m_plotOpts.GetMirror() );
206 
207  // Put vias on mask layer
209 
210  // Initialize a few other parameters, which can also be modified
211  // from the drill dialog
212  reInitDialog();
213 
214  // Update options values:
215  wxCommandEvent cmd_event;
216  SetPlotFormat( cmd_event );
217  OnSetScaleOpt( cmd_event );
218 }
219 
220 
222 {
223  // after calling the Drill or DRC dialogs some parameters can be modified....
224 
225  // Output directory
227 
228  // Origin of coordinates:
230 
231  int knownViolations = 0;
232  int exclusions = 0;
233 
234  for( PCB_MARKER* marker : m_parent->GetBoard()->Markers() )
235  {
236  if( marker->IsExcluded() )
237  exclusions++;
238  else
239  knownViolations++;
240  }
241 
242  if( knownViolations || exclusions )
243  {
245  knownViolations,
246  exclusions ) );
247  m_DRCExclusionsWarning->Show();
248  }
249  else
250  {
251  m_DRCExclusionsWarning->Hide();
252  }
253 
254  BOARD* board = m_parent->GetBoard();
255  const BOARD_DESIGN_SETTINGS& brd_settings = board->GetDesignSettings();
256 
258  ( brd_settings.m_SolderMaskMargin || brd_settings.m_SolderMaskMinWidth ) )
259  {
261  }
262  else
263  {
265  }
266 }
267 
268 
269 // A helper function to show a popup menu, when the dialog is right clicked.
270 void DIALOG_PLOT::OnRightClick( wxMouseEvent& event )
271 {
272  PopupMenu( m_popMenu );
273 }
274 
275 
276 // Select or deselect groups of layers in the layers list:
277 void DIALOG_PLOT::OnPopUpLayers( wxCommandEvent& event )
278 {
279  // Build a list of layers for usual fabrication:
280  // copper layers + tech layers without courtyard
281  LSET fab_layer_set = ( LSET::AllCuMask() | LSET::AllTechMask() )
282  & ~LSET( 2, B_CrtYd, F_CrtYd );
283 
284  switch( event.GetId() )
285  {
286  case ID_LAYER_FAB: // Select layers usually needed to build a board
287  for( unsigned i = 0; i < m_layerList.size(); i++ )
288  {
289  LSET layermask( m_layerList[ i ] );
290 
291  if( ( layermask & fab_layer_set ).any() )
292  m_layerCheckListBox->Check( i, true );
293  else
294  m_layerCheckListBox->Check( i, false );
295  }
296  break;
297 
299  for( unsigned i = 0; i < m_layerList.size(); i++ )
300  {
301  if( IsCopperLayer( m_layerList[i] ) )
302  m_layerCheckListBox->Check( i, true );
303  }
304  break;
305 
307  for( unsigned i = 0; i < m_layerList.size(); i++ )
308  {
309  if( IsCopperLayer( m_layerList[i] ) )
310  m_layerCheckListBox->Check( i, false );
311  }
312  break;
313 
315  for( unsigned i = 0; i < m_layerList.size(); i++ )
316  m_layerCheckListBox->Check( i, true );
317  break;
318 
320  for( unsigned i = 0; i < m_layerList.size(); i++ )
321  m_layerCheckListBox->Check( i, false );
322  break;
323 
324  default:
325  break;
326  }
327 }
328 
329 
330 void DIALOG_PLOT::CreateDrillFile( wxCommandEvent& event )
331 {
332  // Be sure drill file use the same settings (axis option, plot directory)
333  // as plot files:
335 
336  DIALOG_GENDRILL dlg( m_parent, this );
337  dlg.ShowModal();
338 
339  // a few plot settings can be modified: take them in account
341  reInitDialog();
342 }
343 
344 
345 void DIALOG_PLOT::OnChangeDXFPlotMode( wxCommandEvent& event )
346 {
347  // m_DXF_plotTextStrokeFontOpt is disabled if m_DXF_plotModeOpt
348  // is checked (plot in DXF polygon mode)
349  m_DXF_plotTextStrokeFontOpt->Enable( !m_DXF_plotModeOpt->GetValue() );
350 
351  // if m_DXF_plotTextStrokeFontOpt option is disabled (plot DXF in polygon mode),
352  // force m_DXF_plotTextStrokeFontOpt to true to use Pcbnew stroke font
353  if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() )
354  m_DXF_plotTextStrokeFontOpt->SetValue( true );
355 }
356 
357 
358 void DIALOG_PLOT::OnSetScaleOpt( wxCommandEvent& event )
359 {
360  /* Disable sheet reference for scale != 1:1 */
361  bool scale1 = ( m_scaleOpt->GetSelection() == 1 );
362 
363  m_plotSheetRef->Enable( scale1 );
364 
365  if( !scale1 )
366  m_plotSheetRef->SetValue( false );
367 }
368 
369 
370 void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
371 {
372  // Build the absolute path of current output directory to preselect it in the file browser.
373  wxString path = ExpandEnvVarSubstitutions( m_outputDirectoryName->GetValue(), &Prj() );
374  path = Prj().AbsolutePath( path );
375 
376  wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
377 
378  if( dirDialog.ShowModal() == wxID_CANCEL )
379  return;
380 
381  wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
382 
383  wxFileName fn( Prj().AbsolutePath( m_parent->GetBoard()->GetFileName() ) );
384  wxString defaultPath = fn.GetPathWithSep();
385  wxString msg;
386  wxFileName relPathTest; // Used to test if we can make the path relative
387 
388  relPathTest.Assign( dirDialog.GetPath() );
389 
390  // Test if making the path relative is possible before asking the user if they want to do it
391  if( relPathTest.MakeRelativeTo( defaultPath ) )
392  {
393  msg.Printf( _( "Do you want to use a path relative to\n\"%s\"" ), defaultPath );
394 
395  wxMessageDialog dialog( this, msg, _( "Plot Output Directory" ),
396  wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
397 
398  if( dialog.ShowModal() == wxID_YES )
399  dirName.MakeRelativeTo( defaultPath );
400  }
401 
402  m_outputDirectoryName->SetValue( dirName.GetFullPath() );
403 }
404 
405 
407 {
408  // plot format id's are ordered like displayed in m_plotFormatOpt
411 
412  return plotFmt[m_plotFormatOpt->GetSelection()];
413 }
414 
415 
416 // Enable or disable widgets according to the plot format selected
417 // and clear also some optional values
418 void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
419 {
420  // this option exist only in DXF format:
422 
423  // The alert message about non 0 solder mask min width and margin is shown
424  // only in gerber format and if min mask width or mask margin is not 0
425  BOARD* board = m_parent->GetBoard();
426  const BOARD_DESIGN_SETTINGS& brd_settings = board->GetDesignSettings();
427 
429  ( brd_settings.m_SolderMaskMargin || brd_settings.m_SolderMaskMinWidth ) )
430  {
432  }
433  else
434  {
436  }
437 
438 
439  switch( getPlotFormat() )
440  {
441  case PLOT_FORMAT::SVG:
442  case PLOT_FORMAT::PDF:
443  m_drillShapeOpt->Enable( true );
444  m_plotModeOpt->Enable( false );
446  m_plotMirrorOpt->Enable( true );
447  m_useAuxOriginCheckBox->Enable( false );
448  m_useAuxOriginCheckBox->SetValue( false );
449  m_defaultPenSize.Enable( false );
450  m_excludeEdgeLayerOpt->Enable( true );
451  m_scaleOpt->Enable( false );
452  m_scaleOpt->SetSelection( 1 );
453  m_fineAdjustXCtrl->Enable( false );
454  m_fineAdjustYCtrl->Enable( false );
456  m_plotPSNegativeOpt->Enable( true );
457  m_forcePSA4OutputOpt->Enable( false );
458  m_forcePSA4OutputOpt->SetValue( false );
459 
462  else
464 
469  break;
470 
471  case PLOT_FORMAT::POST:
472  m_drillShapeOpt->Enable( true );
473  m_plotModeOpt->Enable( true );
474  m_plotMirrorOpt->Enable( true );
475  m_useAuxOriginCheckBox->Enable( false );
476  m_useAuxOriginCheckBox->SetValue( false );
477  m_defaultPenSize.Enable( false );
478  m_excludeEdgeLayerOpt->Enable( true );
479  m_scaleOpt->Enable( true );
480  m_fineAdjustXCtrl->Enable( true );
481  m_fineAdjustYCtrl->Enable( true );
483  m_plotPSNegativeOpt->Enable( true );
484  m_forcePSA4OutputOpt->Enable( true );
485 
491  break;
492 
493  case PLOT_FORMAT::GERBER:
494  m_drillShapeOpt->Enable( false );
495  m_drillShapeOpt->SetSelection( 0 );
496  m_plotModeOpt->Enable( false );
498  m_plotMirrorOpt->Enable( false );
499  m_plotMirrorOpt->SetValue( false );
500  m_useAuxOriginCheckBox->Enable( true );
501  m_defaultPenSize.Enable( false );
502  m_excludeEdgeLayerOpt->Enable( true );
503  m_scaleOpt->Enable( false );
504  m_scaleOpt->SetSelection( 1 );
505  m_fineAdjustXCtrl->Enable( false );
506  m_fineAdjustYCtrl->Enable( false );
508  m_plotPSNegativeOpt->Enable( false );
509  m_plotPSNegativeOpt->SetValue( false );
510  m_forcePSA4OutputOpt->Enable( false );
511  m_forcePSA4OutputOpt->SetValue( false );
512 
518  break;
519 
520  case PLOT_FORMAT::HPGL:
521  m_drillShapeOpt->Enable( true );
522  m_plotModeOpt->Enable( true );
523  m_plotMirrorOpt->Enable( true );
524  m_useAuxOriginCheckBox->Enable( false );
525  m_useAuxOriginCheckBox->SetValue( false );
526  m_defaultPenSize.Enable( true );
527  m_excludeEdgeLayerOpt->Enable( true );
528  m_scaleOpt->Enable( true );
529  m_fineAdjustXCtrl->Enable( false );
530  m_fineAdjustYCtrl->Enable( false );
532  m_plotPSNegativeOpt->SetValue( false );
533  m_plotPSNegativeOpt->Enable( false );
534  m_forcePSA4OutputOpt->Enable( true );
535 
541  break;
542 
543  case PLOT_FORMAT::DXF:
544  m_drillShapeOpt->Enable( true );
545  m_plotModeOpt->Enable( false );
547  m_plotMirrorOpt->Enable( false );
548  m_plotMirrorOpt->SetValue( false );
549  m_useAuxOriginCheckBox->Enable( true );
550  m_defaultPenSize.Enable( false );
551  m_excludeEdgeLayerOpt->Enable( true );
552  m_scaleOpt->Enable( false );
553  m_scaleOpt->SetSelection( 1 );
554  m_fineAdjustXCtrl->Enable( false );
555  m_fineAdjustYCtrl->Enable( false );
557  m_plotPSNegativeOpt->Enable( false );
558  m_plotPSNegativeOpt->SetValue( false );
559  m_forcePSA4OutputOpt->Enable( false );
560  m_forcePSA4OutputOpt->SetValue( false );
561 
567 
568  OnChangeDXFPlotMode( event );
569  break;
570 
572  break;
573  }
574 
575  /* Update the interlock between scale and frame reference
576  * (scaling would mess up the frame border...) */
577  OnSetScaleOpt( event );
578 
579  Layout();
580  m_MainSizer->SetSizeHints( this );
581 }
582 
583 
584 // A helper function to "clip" aValue between aMin and aMax
585 // and write result in * aResult
586 // return false if clipped, true if aValue is just copied into * aResult
587 static bool setDouble( double* aResult, double aValue, double aMin, double aMax )
588 {
589  if( aValue < aMin )
590  {
591  *aResult = aMin;
592  return false;
593  }
594  else if( aValue > aMax )
595  {
596  *aResult = aMax;
597  return false;
598  }
599 
600  *aResult = aValue;
601  return true;
602 }
603 
604 
605 static bool setInt( int* aResult, int aValue, int aMin, int aMax )
606 {
607  if( aValue < aMin )
608  {
609  *aResult = aMin;
610  return false;
611  }
612  else if( aValue > aMax )
613  {
614  *aResult = aMax;
615  return false;
616  }
617 
618  *aResult = aValue;
619  return true;
620 }
621 
622 
624 {
625  REPORTER& reporter = m_messagesPanel->Reporter();
626  int sel;
627  PCB_PLOT_PARAMS tempOptions;
628 
629  tempOptions.SetExcludeEdgeLayer( m_excludeEdgeLayerOpt->GetValue() );
630  tempOptions.SetSubtractMaskFromSilk( m_subtractMaskFromSilk->GetValue() );
631  tempOptions.SetPlotFrameRef( m_plotSheetRef->GetValue() );
632  tempOptions.SetSketchPadsOnFabLayers( m_sketchPadsOnFabLayers->GetValue() );
633  tempOptions.SetUseAuxOrigin( m_useAuxOriginCheckBox->GetValue() );
634  tempOptions.SetPlotValue( m_plotModuleValueOpt->GetValue() );
635  tempOptions.SetPlotReference( m_plotModuleRefOpt->GetValue() );
636  tempOptions.SetPlotInvisibleText( m_plotInvisibleText->GetValue() );
637  tempOptions.SetScaleSelection( m_scaleOpt->GetSelection() );
638 
639  sel = m_drillShapeOpt->GetSelection();
640  tempOptions.SetDrillMarksType( static_cast<PCB_PLOT_PARAMS::DrillMarksType>( sel ) );
641 
642  tempOptions.SetMirror( m_plotMirrorOpt->GetValue() );
643  tempOptions.SetPlotMode( m_plotModeOpt->GetSelection() == 1 ? SKETCH : FILLED );
644  tempOptions.SetDXFPlotPolygonMode( m_DXF_plotModeOpt->GetValue() );
645 
646  sel = m_DXF_plotUnits->GetSelection();
647  tempOptions.SetDXFPlotUnits( sel == 0 ? DXF_UNITS::INCHES : DXF_UNITS::MILLIMETERS );
648 
649  tempOptions.SetPlotViaOnMaskLayer( m_plotNoViaOnMaskOpt->GetValue() );
650 
651  if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() ) // Currently, only DXF supports this option
652  tempOptions.SetTextMode( PLOT_TEXT_MODE::DEFAULT );
653  else
656 
657  // Update settings from text fields. Rewrite values back to the fields,
658  // since the values may have been constrained by the setters.
659  wxString msg;
660 
661  // read HPLG pen size (this param is stored in mils)
662  // However, due to issues when converting this value from or to mm
663  // that can slightly change the value, update this param only if it
664  // is in use
666  {
667  if( !tempOptions.SetHPGLPenDiameter( m_defaultPenSize.GetValue() / IU_PER_MILS ) )
668  {
670  msg.Printf( _( "HPGL pen size constrained." ) );
671  reporter.Report( msg, RPT_SEVERITY_INFO );
672  }
673  }
674  else // keep the last value (initial value if no HPGL plot made)
676 
677  // X scale
678  double tmpDouble;
679  msg = m_fineAdjustXCtrl->GetValue();
680  msg.ToDouble( &tmpDouble );
681 
682  if( !setDouble( &m_XScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
683  {
684  msg.Printf( wxT( "%f" ), m_XScaleAdjust );
685  m_fineAdjustXCtrl->SetValue( msg );
686  msg.Printf( _( "X scale constrained." ) );
687  reporter.Report( msg, RPT_SEVERITY_INFO );
688  }
689 
690  // Y scale
691  msg = m_fineAdjustYCtrl->GetValue();
692  msg.ToDouble( &tmpDouble );
693 
694  if( !setDouble( &m_YScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
695  {
696  msg.Printf( wxT( "%f" ), m_YScaleAdjust );
697  m_fineAdjustYCtrl->SetValue( msg );
698  msg.Printf( _( "Y scale constrained." ) );
699  reporter.Report( msg, RPT_SEVERITY_INFO );
700  }
701 
702  auto cfg = m_parent->GetPcbNewSettings();
703 
705  cfg->m_Plot.fine_scale_y = m_YScaleAdjust;
706 
707  cfg->m_Plot.check_zones_before_plotting = m_zoneFillCheck->GetValue();
708 
709  // PS Width correction
712  {
714  msg.Printf( _( "Width correction constrained. "
715  "The reasonable width correction value must be in a range of "
716  " [%s; %s] (%s) for current design rules." ),
720  reporter.Report( msg, RPT_SEVERITY_WARNING );
721  }
722 
723  // Store m_PSWidthAdjust in mm in user config
724  cfg->m_Plot.ps_fine_width_adjust = Iu2Millimeter( m_PSWidthAdjust );
725 
726  tempOptions.SetFormat( getPlotFormat() );
727 
728  tempOptions.SetDisableGerberMacros( m_disableApertMacros->GetValue() );
729  tempOptions.SetUseGerberProtelExtensions( m_useGerberExtensions->GetValue() );
730  tempOptions.SetUseGerberX2format( m_useGerberX2Format->GetValue() );
731  tempOptions.SetIncludeGerberNetlistInfo( m_useGerberNetAttributes->GetValue() );
732  tempOptions.SetCreateGerberJobFile( m_generateGerberJobFile->GetValue() );
733 
734  tempOptions.SetGerberPrecision( m_coordFormatCtrl->GetSelection() == 0 ? 5 : 6 );
735  tempOptions.SetSvgPrecision( m_svgPrecsision->GetValue(), m_svgUnits->GetSelection() );
736 
737  LSET selectedLayers;
738  for( unsigned i = 0; i < m_layerList.size(); i++ )
739  {
740  if( m_layerCheckListBox->IsChecked( i ) )
741  selectedLayers.set( m_layerList[i] );
742  }
743  // Get a list of copper layers that aren't being used by inverting enabled layers.
744  LSET disabledCopperLayers = LSET::AllCuMask() & ~m_parent->GetBoard()->GetEnabledLayers();
745  // Enable all of the disabled copper layers.
746  // If someone enables more copper layers they will be selected by default.
747  selectedLayers = selectedLayers | disabledCopperLayers;
748  tempOptions.SetLayerSelection( selectedLayers );
749 
750  tempOptions.SetNegative( m_plotPSNegativeOpt->GetValue() );
751  tempOptions.SetA4Output( m_forcePSA4OutputOpt->GetValue() );
752 
753  // Set output directory and replace backslashes with forward ones
754  wxString dirStr;
755  dirStr = m_outputDirectoryName->GetValue();
756  dirStr.Replace( wxT( "\\" ), wxT( "/" ) );
757  tempOptions.SetOutputDirectory( dirStr );
758 
759  if( !m_plotOpts.IsSameAs( tempOptions ) )
760  {
761  m_parent->SetPlotSettings( tempOptions );
762  m_parent->OnModify();
763  m_plotOpts = tempOptions;
764  }
765 }
766 
767 
768 void DIALOG_PLOT::OnGerberX2Checked( wxCommandEvent& event )
769 {
770  // Currently: do nothing
771 }
772 
773 
774 void DIALOG_PLOT::Plot( wxCommandEvent& event )
775 {
776  BOARD* board = m_parent->GetBoard();
777 
779 
780  SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
782 
784 
786 
787  // If no layer selected, we have nothing plotted.
788  // Prompt user if it happens because he could think there is a bug in Pcbnew.
789  if( !m_plotOpts.GetLayerSelection().any() )
790  {
791  DisplayError( this, _( "No layer selected, Nothing to plot" ) );
792  return;
793  }
794 
795  // Create output directory if it does not exist (also transform it in
796  // absolute form). Bail if it fails
798  wxFileName outputDir = wxFileName::DirName( path );
799  wxString boardFilename = m_parent->GetBoard()->GetFileName();
800  REPORTER& reporter = m_messagesPanel->Reporter();
801 
802  if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) )
803  {
804  wxString msg;
805  msg.Printf( _( "Could not write plot files to folder \"%s\"." ), outputDir.GetPath() );
806  DisplayError( this, msg );
807  return;
808  }
809 
810  if( m_zoneFillCheck->GetValue() )
811  m_parent->GetToolManager()->GetTool<ZONE_FILLER_TOOL>()->CheckAllZones( this );
812 
813  m_plotOpts.SetAutoScale( false );
814 
815  switch( m_plotOpts.GetScaleSelection() )
816  {
817  default: m_plotOpts.SetScale( 1 ); break;
818  case 0: m_plotOpts.SetAutoScale( true ); break;
819  case 2: m_plotOpts.SetScale( 1.5 ); break;
820  case 3: m_plotOpts.SetScale( 2 ); break;
821  case 4: m_plotOpts.SetScale( 3 ); break;
822  }
823 
824  /* If the scale factor edit controls are disabled or the scale value
825  * is 0, don't adjust the base scale factor. This fixes a bug when
826  * the default scale adjust is initialized to 0 and saved in program
827  * settings resulting in a divide by zero fault.
828  */
830  {
831  if( m_XScaleAdjust != 0.0 )
833 
834  if( m_YScaleAdjust != 0.0 )
836 
838  }
839 
840  wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) );
841 
842  // Test for a reasonable scale value
843  // XXX could this actually happen? isn't it constrained in the apply
844  // function?
846  DisplayInfoMessage( this, _( "Warning: Scale option set to a very small value" ) );
847 
849  DisplayInfoMessage( this, _( "Warning: Scale option set to a very large value" ) );
850 
851  GERBER_JOBFILE_WRITER jobfile_writer( board, &reporter );
852 
853  // Save the current plot options in the board
855 
856  wxBusyCursor dummy;
857 
858  for( LSEQ seq = m_plotOpts.GetLayerSelection().UIOrder(); seq; ++seq )
859  {
860  PCB_LAYER_ID layer = *seq;
861 
862  // All copper layers that are disabled are actually selected
863  // This is due to wonkyness in automatically selecting copper layers
864  // for plotting when adding more than two layers to a board.
865  // If plot options become accessible to the layers setup dialog
866  // please move this functionality there!
867  // This skips a copper layer if it is actually disabled on the board.
868  if( ( LSET::AllCuMask() & ~board->GetEnabledLayers() )[layer] )
869  continue;
870 
871  // Pick the basename from the board file
872  wxFileName fn( boardFilename );
873 
874  // Use Gerber Extensions based on layer number
875  // (See http://en.wikipedia.org/wiki/Gerber_File)
877  file_ext = GetGerberProtelExtension( layer );
878 
879  BuildPlotFileName( &fn, outputDir.GetPath(), board->GetLayerName( layer ), file_ext );
880  wxString fullname = fn.GetFullName();
881  jobfile_writer.AddGbrFile( layer, fullname );
882 
883  LOCALE_IO toggle;
884 
885  PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, fn.GetFullPath(), wxEmptyString );
886 
887  // Print diags in messages box:
888  wxString msg;
889 
890  if( plotter )
891  {
892  PlotOneBoardLayer( board, plotter, layer, m_plotOpts );
893  plotter->EndPlot();
894  delete plotter->RenderSettings();
895  delete plotter;
896 
897  msg.Printf( _( "Plot file \"%s\" created." ), fn.GetFullPath() );
898  reporter.Report( msg, RPT_SEVERITY_ACTION );
899  }
900  else
901  {
902  msg.Printf( _( "Unable to create file \"%s\"." ), fn.GetFullPath() );
903  reporter.Report( msg, RPT_SEVERITY_ERROR );
904  }
905 
906  wxSafeYield(); // displays report message.
907  }
908 
910  {
911  // Pick the basename from the board file
912  wxFileName fn( boardFilename );
913  // Build gerber job file from basename
914  BuildPlotFileName( &fn, outputDir.GetPath(), "job", GerberJobFileExtension );
915  jobfile_writer.CreateJobFile( fn.GetFullPath() );
916  }
917 }
918 
919 
920 void DIALOG_PLOT::onRunDRC( wxCommandEvent& event )
921 {
922  PCB_EDIT_FRAME* parent = dynamic_cast<PCB_EDIT_FRAME*>( GetParent() );
923 
924  if( parent )
925  {
926  DRC_TOOL* drcTool = parent->GetToolManager()->GetTool<DRC_TOOL>();
927 
928  // First close an existing dialog if open
929  // (low probability, but can happen)
930  drcTool->DestroyDRCDialog();
931 
932  // Open a new drc dialod, with the right parent frame, and in Modal Mode
933  drcTool->ShowDRCDialog( this );
934 
935  // Update DRC warnings on return to this dialog
936  reInitDialog();
937  }
938 }
939 
940 
941 void DIALOG_PLOT::onBoardSetup( wxHyperlinkEvent& aEvent )
942 {
943  PCB_EDIT_FRAME* parent = dynamic_cast<PCB_EDIT_FRAME*>( GetParent() );
944 
945  if( parent )
946  {
947  parent->ShowBoardSetupDialog( _( "Solder Mask/Paste" ) );
948 
949  // Update warnings on return to this dialog
950  reInitDialog();
951  }
952 }
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:750
void SetUseGerberProtelExtensions(bool aUse)
void SetPlotReference(bool aFlag)
void SetExcludeEdgeLayer(bool aFlag)
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:252
WX_HTML_REPORT_PANEL * m_messagesPanel
OUTLINE_MODE GetPlotMode() const
wxStaticBoxSizer * m_HPGLOptionsSizer
void SetScaleSelection(int aSelection)
LSEQ m_layerList
Definition: dialog_plot.h:47
void SetIncludeGerberNetlistInfo(bool aUse)
void SetDXFPlotPolygonMode(bool aFlag)
double m_YScaleAdjust
Definition: dialog_plot.h:50
bool GetCreateGerberJobFile() const
void OnModify() override
Must be called after a board change to set the modified flag.
wxCheckBox * m_useGerberExtensions
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
void SetGerberPrecision(int aPrecision)
void OnOutputDirectoryBrowseClicked(wxCommandEvent &event) override
wxButton * m_sdbSizer1Cancel
void SetPlotViaOnMaskLayer(bool aFlag)
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:342
bool GetPlotFrameRef() const
bool CreateJobFile(const wxString &aFullFilename)
Creates a Gerber job file.
bool GetDXFPlotPolygonMode() const
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
wxString GetDefaultPlotExtension(PLOT_FORMAT aFormat)
Returns the default plot extension for a format.
void SetLayerSelection(LSET aSelection)
void OnGerberX2Checked(wxCommandEvent &event) override
void SetUseAuxOrigin(bool aAux)
This file is part of the common library.
const BITMAP_OPAQUE small_folder_xpm[1]
void SetSketchPadLineWidth(int aWidth)
static constexpr double IU_PER_MM
Mock up a conversion function.
void OnChangeDXFPlotMode(wxCommandEvent &event) override
void PlotOneBoardLayer(BOARD *aBoard, PLOTTER *aPlotter, PCB_LAYER_ID aLayer, const PCB_PLOT_PARAMS &aPlotOpt)
Function PlotOneBoardLayer main function to plot one copper or technical layer.
wxCheckBox * m_plotPSNegativeOpt
#define PLOT_MIN_SCALE
Definition: pcbplot.h:56
bool GetDisableGerberMacros() const
MARKERS & Markers()
Definition: board.h:312
wxCheckBox * m_excludeEdgeLayerOpt
void SetCreateGerberJobFile(bool aCreate)
void onRunDRC(wxCommandEvent &event) override
void SetMirror(bool aFlag)
wxButton * m_sdbSizer1OK
const wxString GetGerberProtelExtension(LAYER_NUM aLayer)
Function GetGerberProtelExtension.
Definition: pcbplot.cpp:45
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
Definition: sch_symbol.cpp:69
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:591
wxCheckBox * m_plotMirrorOpt
void SetTextMode(PLOT_TEXT_MODE aVal)
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings Returns a bit-mask of all t...
Definition: board.cpp:447
wxString GetAbbreviatedUnitsLabel(EDA_UNITS aUnit, EDA_DATA_TYPE aType)
Get the units string for a given units type.
Definition: base_units.cpp:472
void ShowDRCDialog(wxWindow *aParent)
Open a dialog and prompts the user, then if a test run button is clicked, runs the test(s) and create...
Definition: drc_tool.cpp:68
wxCheckBox * m_zoneFillCheck
void SetDrillMarksType(DrillMarksType aVal)
const wxString ExpandEnvVarSubstitutions(const wxString &aString, PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:269
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:64
wxChoice * m_plotFormatOpt
static LSET AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
Definition: lset.cpp:820
virtual const PCB_PLOT_PARAMS & GetPlotSettings() const
Return the PCB_PLOT_PARAMS for the BOARD owned by this frame.
wxChoice * m_coordFormatCtrl
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
void SetDXFPlotUnits(DXF_UNITS aUnit)
void CreateDrillFile(wxCommandEvent &event) override
const wxString & GetFileName() const
Definition: board.h:298
Classes used to generate a Gerber job file in JSON.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
wxStaticBoxSizer * m_SizerDXF_options
double GetScale() const
UNIT_BINDER m_trackWidthCorrection
Definition: dialog_plot.h:60
void SetA4Output(int aForce)
bool GetUseGerberX2format() const
double m_XScaleAdjust
Definition: dialog_plot.h:48
wxButton * m_sdbSizer1Apply
wxTextCtrl * m_fineAdjustYCtrl
wxCheckBox * m_DXF_plotModeOpt
virtual const wxString AbsolutePath(const wxString &aFileName) const
Fix up aFileName if it is relative to the project's directory to be an absolute path and filename.
This file contains miscellaneous commonly used macros and functions.
bool GetMirror() const
void SetPlotValue(bool aFlag)
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:120
wxBoxSizer * m_SizerSolderMaskAlert
Board plot function definition file.
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
wxCheckBox * m_plotSheetRef
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:82
virtual bool EndPlot()=0
void SetPlotFrameRef(bool aFlag)
void SetPlotFormat(wxCommandEvent &event) override
void Plot(wxCommandEvent &event) override
wxTextCtrl * m_fineAdjustXCtrl
Class DIALOG_PLOT_BASE.
PCB_LAYER_ID
A quick note on layer IDs:
void SetDisableGerberMacros(bool aDisable)
bool GetA4Output() const
Handle actions specific to filling copper zones.
int GetGerberPrecision() const
wxSpinCtrl * m_svgPrecsision
GERBER_JOBFILE_WRITER is a class used to create Gerber job file a Gerber job file stores info to make...
LSET is a set of PCB_LAYER_IDs.
void ShowBoardSetupDialog(const wxString &aInitialPage=wxEmptyString)
PLOT_FORMAT GetFormat() const
PCB_EDIT_FRAME * m_parent
Definition: dialog_plot.h:46
int m_widthAdjustMaxValue
Definition: dialog_plot.h:57
bool IsSameAs(const PCB_PLOT_PARAMS &aPcbPlotParams) const
Compare current settings to aPcbPlotParams, including not saved parameters in brd file.
bool GetUseGerberProtelExtensions() const
void SetColorSettings(COLOR_SETTINGS *aSettings)
PLOT_FORMAT getPlotFormat()
unsigned GetSvgPrecision() const
PLOT_FORMAT
The set of supported output plot formats.
Definition: plotter.h:67
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
void onBoardSetup(wxHyperlinkEvent &aEvent) override
static bool setDouble(double *aResult, double aValue, double aMin, double aMax)
bool EnsureFileDirectoryExists(wxFileName *aTargetFullFileName, const wxString &aBaseFilename, REPORTER *aReporter)
Make aTargetFullFileName absolute and create the path of this file if it doesn't yet exist.
Definition: common.cpp:297
#define PLOT_MAX_SCALE
Definition: pcbplot.h:57
bool GetIncludeGerberNetlistInfo() const
int m_PSWidthAdjust
Definition: dialog_plot.h:52
const std::string GerberJobFileExtension
Definition of file extensions used in Kicad.
PLOT_TEXT_MODE GetTextMode() const
wxCheckBox * m_forcePSA4OutputOpt
void OnPopUpLayers(wxCommandEvent &event) override
void SetSubtractMaskFromSilk(bool aSubtract)
void AddGbrFile(PCB_LAYER_ID aLayer, wxString &aFilename)
add a gerber file name and type in job file list
void setPlotModeChoiceSelection(OUTLINE_MODE aPlotMode)
Definition: dialog_plot.h:85
void SetUseGerberX2format(bool aUse)
virtual void SetPlotSettings(const PCB_PLOT_PARAMS &aSettings)
AppSettings * GetAppSettings(bool aLoadNow=true)
Returns a handle to the a given settings by type If the settings have already been loaded,...
void OnSetScaleOpt(wxCommandEvent &event) override
wxStaticBoxSizer * m_GerberOptionsSizer
wxCheckBox * m_useGerberNetAttributes
void SetOutputDirectory(wxString aDir)
wxCheckBox * m_disableApertMacros
wxChoice * m_DXF_plotUnits
void SetFormat(PLOT_FORMAT aFormat)
int m_widthAdjustMinValue
Definition: dialog_plot.h:56
wxCheckBox * m_generateGerberJobFile
PCB_PLOT_PARAMS handles plot parameters and options when plotting/printing a board.
wxTextCtrl * m_outputDirectoryName
void SetPlotInvisibleText(bool aFlag)
void SetScale(double aVal)
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
wxCheckBox * m_DXF_plotTextStrokeFontOpt
void SetPlotMode(OUTLINE_MODE aPlotMode)
PCB_PLOT_PARAMS m_plotOpts
Definition: dialog_plot.h:64
void SetNegative(bool aFlag)
bool GetPlotValue() const
void SetSvgPrecision(unsigned aPrecision, bool aUseInch)
wxString GetOutputDirectory() const
void SetFineScaleAdjustX(double aVal)
wxChoice * m_scaleOpt
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void BuildPlotFileName(wxFileName *aFilename, const wxString &aOutputDir, const wxString &aSuffix, const wxString &aExtension)
Function BuildPlotFileName (helper function) Complete a plot filename: forces the output directory,...
Definition: pcbplot.cpp:369
void reInitDialog()
wxCheckBox * m_plotModuleRefOpt
COLOR_SETTINGS * GetColorSettings(const wxString &aName="user")
Retrieves a color settings object that applications can read colors from.
bool SetHPGLPenDiameter(double aValue)
wxString m_DRCWarningTemplate
Definition: dialog_plot.h:62
Base plotter engine class.
Definition: plotter.h:121
wxBoxSizer * m_sizerButtons
wxCheckBox * m_subtractMaskFromSilk
bool GetSketchPadsOnFabLayers() const
void init_Dialog()
Definition: dialog_plot.cpp:75
wxCheckBox * m_plotNoViaOnMaskOpt
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:155
wxCheckBox * m_plotModuleValueOpt
bool GetPlotViaOnMaskLayer() const
wxChoice * m_drillShapeOpt
Board layer functions and definitions.
void applyPlotSettings()
void SetWidthAdjust(int aVal)
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
bool GetSubtractMaskFromSilk() const
#define _(s)
Definition: 3d_actions.cpp:33
static bool setInt(int *aResult, int aValue, int aMin, int aMax)
virtual void SetValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
wxCheckBox * m_plotInvisibleText
double GetHPGLPenDiameter() const
wxCheckBox * m_sketchPadsOnFabLayers
The main frame for Pcbnew.
PCBNEW_SETTINGS * GetPcbNewSettings() const
#define IU_PER_MILS
Definition: plotter.cpp:137
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
wxCheckBox * m_useAuxOriginCheckBox
DIALOG_PLOT m_Plot
bool GetPlotInvisibleText() const
void SetAutoScale(bool aFlag)
void SetFineScaleAdjustY(double aVal)
wxChoice * m_plotModeOpt
virtual long long int GetValue()
Return the current value in Internal Units.
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
wxString StringFromValue(EDA_UNITS aUnits, double aValue, bool aAddUnitSymbol, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:225
int GetScaleSelection() const
DXF_UNITS GetDXFPlotUnits() const
UNIT_BINDER m_defaultPenSize
Definition: dialog_plot.h:59
void OnRightClick(wxMouseEvent &event) override
bool GetSvgUseInch() const
wxBitmapButton * m_browseButton
wxBoxSizer * m_MainSizer
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
PLOTTER * StartPlotBoard(BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts, int aLayer, const wxString &aFullFileName, const wxString &aSheetDesc)
Open a new plotfile using the options (and especially the format) specified in the options and prepar...
bool GetNegative() const
wxCheckBox * m_useGerberX2Format
wxStaticBoxSizer * m_svgOptionsSizer
BOARD * GetBoard() const
bool GetUseAuxOrigin() const
wxCheckListBox * m_layerCheckListBox
void DestroyDRCDialog()
Close and free the DRC dialog.
Definition: drc_tool.cpp:119
void SetFileName(const wxString &aReportFileName)
wxStaticBoxSizer * m_PSOptionsSizer
LSET GetLayerSelection() const
LSEQ UIOrder() const
Definition: lset.cpp:895
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:280
DrillMarksType GetDrillMarksType() const
wxBoxSizer * m_PlotOptionsSizer
bool GetPlotReference() const
DIALOG_PLOT(PCB_EDIT_FRAME *parent)
Definition: dialog_plot.cpp:48
#define DLG_WINDOW_NAME
wxStaticText * m_DRCExclusionsWarning
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
bool GetExcludeEdgeLayer() const
void SetSketchPadsOnFabLayers(bool aFlag)
Container for design settings for a BOARD object.
wxString m_ColorTheme
Active color theme name.
Definition: app_settings.h:184