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 <bitmaps.h>
36 #include <class_board.h>
37 #include <dialog_plot.h>
38 #include <dialog_gendrill.h>
39 #include <wx_html_report_panel.h>
40 #include <drc/drc.h>
41 #include <tool/tool_manager.h>
42 #include <tools/zone_filler_tool.h>
43 #include <math/util.h> // for KiROUND
44 
45 
47  DIALOG_PLOT_BASE( aParent ), m_parent( aParent ),
48  m_defaultLineWidth( aParent, m_lineWidthLabel, m_lineWidthCtrl, m_lineWidthUnits, true ),
49  m_defaultPenSize( aParent, m_hpglPenLabel, m_hpglPenCtrl, m_hpglPenUnits, true ),
50  m_trackWidthCorrection( aParent, m_widthAdjustLabel, m_widthAdjustCtrl, m_widthAdjustUnits, true )
51 {
52  SetName( DLG_WINDOW_NAME );
53  m_plotOpts = aParent->GetPlotSettings();
55 
56  init_Dialog();
57 
58  // We use a sdbSizer to get platform-dependent ordering of the action buttons, but
59  // that requires us to correct the button labels here.
60  m_sdbSizer1OK->SetLabel( _( "Plot" ) );
61  m_sdbSizer1Apply->SetLabel( _( "Generate Drill Files..." ) );
62  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
63  m_sizerButtons->Layout();
64 
65  m_sdbSizer1OK->SetDefault();
66 
67  GetSizer()->Fit( this );
68  GetSizer()->SetSizeHints( this );
69 }
70 
71 
73 {
74  BOARD* board = m_parent->GetBoard();
75  wxFileName fileName;
76 
77  auto cfg = m_parent->GetSettings();
78 
79  m_XScaleAdjust = cfg->m_Plot.fine_scale_x;
80  m_YScaleAdjust = cfg->m_Plot.fine_scale_y;
81 
82  m_zoneFillCheck->SetValue( cfg->m_Plot.check_zones_before_plotting );
83 
84  m_browseButton->SetBitmap( KiBitmap( folder_xpm ) );
85 
86  // m_PSWidthAdjust is stored in mm in user config
87  m_PSWidthAdjust = KiROUND( cfg->m_Plot.ps_fine_width_adjust * IU_PER_MM );
88 
89  // The reasonable width correction value must be in a range of
90  // [-(MinTrackWidth-1), +(MinClearanceValue-1)] decimils.
93 
94  switch( m_plotOpts.GetFormat() )
95  {
96  default:
97  case PLOT_FORMAT::GERBER: m_plotFormatOpt->SetSelection( 0 ); break;
98  case PLOT_FORMAT::POST: m_plotFormatOpt->SetSelection( 1 ); break;
99  case PLOT_FORMAT::SVG: m_plotFormatOpt->SetSelection( 2 ); break;
100  case PLOT_FORMAT::DXF: m_plotFormatOpt->SetSelection( 3 ); break;
101  case PLOT_FORMAT::HPGL: m_plotFormatOpt->SetSelection( 4 ); break;
102  case PLOT_FORMAT::PDF: m_plotFormatOpt->SetSelection( 5 ); break;
103  }
104 
105  // Set units and value for HPGL pen size (this param is in mils).
107 
109 
110  // Test for a reasonable scale value. Set to 1 if problem
114 
117 
118  // Test for a reasonable PS width correction value. Set to 0 if problem.
119  if( m_PSWidthAdjust < m_widthAdjustMinValue || m_PSWidthAdjust > m_widthAdjustMaxValue )
120  m_PSWidthAdjust = 0.;
121 
123 
126 
127  // Could devote a PlotOrder() function in place of UIOrder().
128  m_layerList = board->GetEnabledLayers().UIOrder();
129 
130  // Populate the check list box by all enabled layers names
131  for( LSEQ seq = m_layerList; seq; ++seq )
132  {
133  PCB_LAYER_ID layer = *seq;
134 
135  int checkIndex = m_layerCheckListBox->Append( board->GetLayerName( layer ) );
136 
137  if( m_plotOpts.GetLayerSelection()[layer] )
138  m_layerCheckListBox->Check( checkIndex );
139  }
140 
141  // Option for using proper Gerber extensions. Note also Protel extensions are
142  // a broken feature. However, for now, we need to handle it.
144 
145  // Option for including Gerber attributes, from Gerber X2 format, in the output
146  // In X1 format, they will be added as comments
148 
149  // Option for including Gerber netlist info (from Gerber X2 format) in the output
151 
152  // Option to generate a Gerber job file
154 
155  // Gerber precision for coordinates
156  m_coordFormatCtrl->SetSelection( m_plotOpts.GetGerberPrecision() == 5 ? 0 : 1 );
157 
158  // Option for excluding contents of "Edges Pcb" layer
160 
161  // Option to exclude pads from silkscreen layers
163 
164  // Option to tent vias
166 
167  // Option to use aux origin
169 
170  // Option to plot page references:
172 
173  // Options to plot texts on footprints
177 
178  // Options to plot pads and vias holes
179  m_drillShapeOpt->SetSelection( m_plotOpts.GetDrillMarksType() );
180 
181  // Scale option
182  m_scaleOpt->SetSelection( m_plotOpts.GetScaleSelection() );
183 
184  // Plot mode
186 
187  // DXF outline mode
189 
190  // DXF text mode
192 
193  // DXF units selection
194  m_DXF_plotUnits->SetSelection( static_cast<int>( m_plotOpts.GetDXFPlotUnits() ) );
195 
196  // Plot mirror option
197  m_plotMirrorOpt->SetValue( m_plotOpts.GetMirror() );
198 
199  // Put vias on mask layer
201 
202  // Initialize a few other parameters, which can also be modified
203  // from the drill dialog
204  reInitDialog();
205 
206  // Update options values:
207  wxCommandEvent cmd_event;
208  SetPlotFormat( cmd_event );
209  OnSetScaleOpt( cmd_event );
210 }
211 
212 
214 {
215  // after calling the Drill or DRC dialogs some parameters can be modified....
216 
217  // Output directory
219 
220  // Origin of coordinates:
222 
223  int knownViolations = 0;
224  int exclusions = 0;
225 
226  for( MARKER_PCB* marker : m_parent->GetBoard()->Markers() )
227  {
228  if( marker->IsExcluded() )
229  exclusions++;
230  else
231  knownViolations++;
232  }
233 
234  if( knownViolations || exclusions )
235  {
237  knownViolations,
238  exclusions ) );
239  m_DRCExclusionsWarning->Show();
240  }
241  else
242  m_DRCExclusionsWarning->Hide();
243 }
244 
245 
246 // A helper function to show a popup menu, when the dialog is right clicked.
247 void DIALOG_PLOT::OnRightClick( wxMouseEvent& event )
248 {
249  PopupMenu( m_popMenu );
250 }
251 
252 
253 // Select or deselect groups of layers in the layers list:
254 void DIALOG_PLOT::OnPopUpLayers( wxCommandEvent& event )
255 {
256  // Build a list of layers for usual fabrication:
257  // copper layers + tech layers without courtyard
258  LSET fab_layer_set = ( LSET::AllCuMask() | LSET::AllTechMask() )
259  & ~LSET( 2, B_CrtYd, F_CrtYd );
260 
261  switch( event.GetId() )
262  {
263  case ID_LAYER_FAB: // Select layers usually needed to build a board
264  for( unsigned i = 0; i < m_layerList.size(); i++ )
265  {
266  LSET layermask( m_layerList[ i ] );
267 
268  if( ( layermask & fab_layer_set ).any() )
269  m_layerCheckListBox->Check( i, true );
270  else
271  m_layerCheckListBox->Check( i, false );
272  }
273  break;
274 
276  for( unsigned i = 0; i < m_layerList.size(); i++ )
277  {
278  if( IsCopperLayer( m_layerList[i] ) )
279  m_layerCheckListBox->Check( i, true );
280  }
281  break;
282 
284  for( unsigned i = 0; i < m_layerList.size(); i++ )
285  {
286  if( IsCopperLayer( m_layerList[i] ) )
287  m_layerCheckListBox->Check( i, false );
288  }
289  break;
290 
292  for( unsigned i = 0; i < m_layerList.size(); i++ )
293  m_layerCheckListBox->Check( i, true );
294  break;
295 
297  for( unsigned i = 0; i < m_layerList.size(); i++ )
298  m_layerCheckListBox->Check( i, false );
299  break;
300 
301  default:
302  break;
303  }
304 }
305 
306 
307 void DIALOG_PLOT::CreateDrillFile( wxCommandEvent& event )
308 {
309  // Be sure drill file use the same settings (axis option, plot directory)
310  // as plot files:
312 
313  DIALOG_GENDRILL dlg( m_parent, this );
314  dlg.ShowModal();
315 
316  // a few plot settings can be modified: take them in account
318  reInitDialog();
319 }
320 
321 
322 void DIALOG_PLOT::OnChangeDXFPlotMode( wxCommandEvent& event )
323 {
324  // m_DXF_plotTextStrokeFontOpt is disabled if m_DXF_plotModeOpt
325  // is checked (plot in DXF polygon mode)
326  m_DXF_plotTextStrokeFontOpt->Enable( !m_DXF_plotModeOpt->GetValue() );
327 
328  // if m_DXF_plotTextStrokeFontOpt option is disabled (plot DXF in polygon mode),
329  // force m_DXF_plotTextStrokeFontOpt to true to use Pcbnew stroke font
330  if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() )
331  m_DXF_plotTextStrokeFontOpt->SetValue( true );
332 }
333 
334 
335 void DIALOG_PLOT::OnSetScaleOpt( wxCommandEvent& event )
336 {
337  /* Disable sheet reference for scale != 1:1 */
338  bool scale1 = ( m_scaleOpt->GetSelection() == 1 );
339 
340  m_plotSheetRef->Enable( scale1 );
341 
342  if( !scale1 )
343  m_plotSheetRef->SetValue( false );
344 }
345 
346 
347 void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
348 {
349  // Build the absolute path of current output plot directory
350  // to preselect it when opening the dialog.
351  wxFileName fn( m_outputDirectoryName->GetValue() );
352  wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() );
353 
354  wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
355 
356  if( dirDialog.ShowModal() == wxID_CANCEL )
357  return;
358 
359  wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
360 
361  fn = Prj().AbsolutePath( m_parent->GetBoard()->GetFileName() );
362  wxString defaultPath = fn.GetPathWithSep();
363  wxString msg;
364  msg.Printf( _( "Do you want to use a path relative to\n\"%s\"" ),
365  GetChars( defaultPath ) );
366 
367  wxMessageDialog dialog( this, msg, _( "Plot Output Directory" ),
368  wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
369 
370  if( dialog.ShowModal() == wxID_YES )
371  {
372  if( !dirName.MakeRelativeTo( defaultPath ) )
373  wxMessageBox( _( "Cannot make path relative (target volume different from file volume)!" ),
374  _( "Plot Output Directory" ), wxOK | wxICON_ERROR );
375  }
376 
377  m_outputDirectoryName->SetValue( dirName.GetFullPath() );
378 }
379 
380 
382 {
383  // plot format id's are ordered like displayed in m_plotFormatOpt
386 
387  return plotFmt[m_plotFormatOpt->GetSelection()];
388 }
389 
390 
391 // Enable or disable widgets according to the plot format selected
392 // and clear also some optional values
393 void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
394 {
395  // this option exist only in DXF format:
397 
398  switch( getPlotFormat() )
399  {
400  case PLOT_FORMAT::PDF:
401  case PLOT_FORMAT::SVG:
402  m_drillShapeOpt->Enable( true );
403  m_plotModeOpt->Enable( false );
405  m_plotMirrorOpt->Enable( true );
406  m_useAuxOriginCheckBox->Enable( false );
407  m_useAuxOriginCheckBox->SetValue( false );
408  m_defaultLineWidth.Enable( true );
409  m_defaultPenSize.Enable( false );
410  m_excludeEdgeLayerOpt->Enable( true );
411  m_scaleOpt->Enable( false );
412  m_scaleOpt->SetSelection( 1 );
413  m_fineAdjustXCtrl->Enable( false );
414  m_fineAdjustYCtrl->Enable( false );
416  m_plotPSNegativeOpt->Enable( true );
417  m_forcePSA4OutputOpt->Enable( false );
418  m_forcePSA4OutputOpt->SetValue( false );
419 
424  break;
425 
426  case PLOT_FORMAT::POST:
427  m_drillShapeOpt->Enable( true );
428  m_plotModeOpt->Enable( true );
429  m_plotMirrorOpt->Enable( true );
430  m_useAuxOriginCheckBox->Enable( false );
431  m_useAuxOriginCheckBox->SetValue( false );
432  m_defaultLineWidth.Enable( true );
433  m_defaultPenSize.Enable( false );
434  m_excludeEdgeLayerOpt->Enable( true );
435  m_scaleOpt->Enable( true );
436  m_fineAdjustXCtrl->Enable( true );
437  m_fineAdjustYCtrl->Enable( true );
439  m_plotPSNegativeOpt->Enable( true );
440  m_forcePSA4OutputOpt->Enable( true );
441 
446  break;
447 
448  case PLOT_FORMAT::GERBER:
449  m_drillShapeOpt->Enable( false );
450  m_drillShapeOpt->SetSelection( 0 );
451  m_plotModeOpt->Enable( false );
453  m_plotMirrorOpt->Enable( false );
454  m_plotMirrorOpt->SetValue( false );
455  m_useAuxOriginCheckBox->Enable( true );
456  m_defaultLineWidth.Enable( true );
457  m_defaultPenSize.Enable( false );
458  m_excludeEdgeLayerOpt->Enable( true );
459  m_scaleOpt->Enable( false );
460  m_scaleOpt->SetSelection( 1 );
461  m_fineAdjustXCtrl->Enable( false );
462  m_fineAdjustYCtrl->Enable( false );
464  m_plotPSNegativeOpt->Enable( false );
465  m_plotPSNegativeOpt->SetValue( false );
466  m_forcePSA4OutputOpt->Enable( false );
467  m_forcePSA4OutputOpt->SetValue( false );
468 
473  break;
474 
475  case PLOT_FORMAT::HPGL:
476  m_drillShapeOpt->Enable( true );
477  m_plotModeOpt->Enable( true );
478  m_plotMirrorOpt->Enable( true );
479  m_useAuxOriginCheckBox->Enable( false );
480  m_useAuxOriginCheckBox->SetValue( false );
481  m_defaultLineWidth.Enable( false );
482  m_defaultPenSize.Enable( true );
483  m_excludeEdgeLayerOpt->Enable( true );
484  m_scaleOpt->Enable( true );
485  m_fineAdjustXCtrl->Enable( false );
486  m_fineAdjustYCtrl->Enable( false );
488  m_plotPSNegativeOpt->SetValue( false );
489  m_plotPSNegativeOpt->Enable( false );
490  m_forcePSA4OutputOpt->Enable( true );
491 
496  break;
497 
498  case PLOT_FORMAT::DXF:
499  m_drillShapeOpt->Enable( true );
500  m_plotModeOpt->Enable( false );
502  m_plotMirrorOpt->Enable( false );
503  m_plotMirrorOpt->SetValue( false );
504  m_useAuxOriginCheckBox->Enable( true );
505  m_defaultLineWidth.Enable( false );
506  m_defaultPenSize.Enable( false );
507  m_excludeEdgeLayerOpt->Enable( true );
508  m_scaleOpt->Enable( false );
509  m_scaleOpt->SetSelection( 1 );
510  m_fineAdjustXCtrl->Enable( false );
511  m_fineAdjustYCtrl->Enable( false );
513  m_plotPSNegativeOpt->Enable( false );
514  m_plotPSNegativeOpt->SetValue( false );
515  m_forcePSA4OutputOpt->Enable( false );
516  m_forcePSA4OutputOpt->SetValue( false );
517 
522 
523  OnChangeDXFPlotMode( event );
524  break;
525 
527  break;
528  }
529 
530  /* Update the interlock between scale and frame reference
531  * (scaling would mess up the frame border...) */
532  OnSetScaleOpt( event );
533 
534  Layout();
535  m_MainSizer->SetSizeHints( this );
536 }
537 
538 
539 // A helper function to "clip" aValue between aMin and aMax
540 // and write result in * aResult
541 // return false if clipped, true if aValue is just copied into * aResult
542 static bool setDouble( double* aResult, double aValue, double aMin, double aMax )
543 {
544  if( aValue < aMin )
545  {
546  *aResult = aMin;
547  return false;
548  }
549  else if( aValue > aMax )
550  {
551  *aResult = aMax;
552  return false;
553  }
554 
555  *aResult = aValue;
556  return true;
557 }
558 
559 
560 static bool setInt( int* aResult, int aValue, int aMin, int aMax )
561 {
562  if( aValue < aMin )
563  {
564  *aResult = aMin;
565  return false;
566  }
567  else if( aValue > aMax )
568  {
569  *aResult = aMax;
570  return false;
571  }
572 
573  *aResult = aValue;
574  return true;
575 }
576 
577 
579 {
580  REPORTER& reporter = m_messagesPanel->Reporter();
581  int sel;
582  PCB_PLOT_PARAMS tempOptions;
583 
584  tempOptions.SetExcludeEdgeLayer( m_excludeEdgeLayerOpt->GetValue() );
585  tempOptions.SetSubtractMaskFromSilk( m_subtractMaskFromSilk->GetValue() );
586  tempOptions.SetPlotFrameRef( m_plotSheetRef->GetValue() );
587  tempOptions.SetPlotPadsOnSilkLayer( !m_excludePadsFromSilkscreen->GetValue() );
588  tempOptions.SetUseAuxOrigin( m_useAuxOriginCheckBox->GetValue() );
589  tempOptions.SetPlotValue( m_plotModuleValueOpt->GetValue() );
590  tempOptions.SetPlotReference( m_plotModuleRefOpt->GetValue() );
591  tempOptions.SetPlotInvisibleText( m_plotInvisibleText->GetValue() );
592  tempOptions.SetScaleSelection( m_scaleOpt->GetSelection() );
593 
594  sel = m_drillShapeOpt->GetSelection();
595  tempOptions.SetDrillMarksType( static_cast<PCB_PLOT_PARAMS::DrillMarksType>( sel ) );
596 
597  tempOptions.SetMirror( m_plotMirrorOpt->GetValue() );
598  tempOptions.SetPlotMode( m_plotModeOpt->GetSelection() == 1 ? SKETCH : FILLED );
599  tempOptions.SetDXFPlotPolygonMode( m_DXF_plotModeOpt->GetValue() );
600 
601  sel = m_DXF_plotUnits->GetSelection();
602  tempOptions.SetDXFPlotUnits( static_cast<DXF_PLOTTER::DXF_UNITS>( sel ) );
603 
604  tempOptions.SetPlotViaOnMaskLayer( m_plotNoViaOnMaskOpt->GetValue() );
605 
606  if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() ) // Currently, only DXF supports this option
607  tempOptions.SetTextMode( PLOT_TEXT_MODE::DEFAULT );
608  else
611 
612  // Update settings from text fields. Rewrite values back to the fields,
613  // since the values may have been constrained by the setters.
614  wxString msg;
615 
616  // read HPLG pen size (this param is stored in mils)
617  // However, due to issues when converting this value from or to mm
618  // that can slightly change the value, update this param only if it
619  // is in use
621  {
622  if( !tempOptions.SetHPGLPenDiameter( m_defaultPenSize.GetValue() / IU_PER_MILS ) )
623  {
625  msg.Printf( _( "HPGL pen size constrained." ) );
626  reporter.Report( msg, RPT_SEVERITY_INFO );
627  }
628  }
629  else // keep the last value (initial value if no HPGL plot made)
631 
632  // Default linewidth
633  if( !tempOptions.SetLineWidth( m_defaultLineWidth.GetValue() ) )
634  {
635  m_defaultLineWidth.SetValue( tempOptions.GetLineWidth() );
636  msg.Printf( _( "Default line width constrained." ) );
637  reporter.Report( msg, RPT_SEVERITY_INFO );
638  }
639 
640  // X scale
641  double tmpDouble;
642  msg = m_fineAdjustXCtrl->GetValue();
643  msg.ToDouble( &tmpDouble );
644 
645  if( !setDouble( &m_XScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
646  {
647  msg.Printf( wxT( "%f" ), m_XScaleAdjust );
648  m_fineAdjustXCtrl->SetValue( msg );
649  msg.Printf( _( "X scale constrained." ) );
650  reporter.Report( msg, RPT_SEVERITY_INFO );
651  }
652 
653  // Y scale
654  msg = m_fineAdjustYCtrl->GetValue();
655  msg.ToDouble( &tmpDouble );
656 
657  if( !setDouble( &m_YScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
658  {
659  msg.Printf( wxT( "%f" ), m_YScaleAdjust );
660  m_fineAdjustYCtrl->SetValue( msg );
661  msg.Printf( _( "Y scale constrained." ) );
662  reporter.Report( msg, RPT_SEVERITY_INFO );
663  }
664 
665  auto cfg = m_parent->GetSettings();
666 
668  cfg->m_Plot.fine_scale_y = m_YScaleAdjust;
669 
670  cfg->m_Plot.check_zones_before_plotting = m_zoneFillCheck->GetValue();
671 
672  // PS Width correction
675  {
677  msg.Printf( _( "Width correction constrained. "
678  "The reasonable width correction value must be in a range of "
679  " [%s; %s] (%s) for current design rules." ),
683  reporter.Report( msg, RPT_SEVERITY_WARNING );
684  }
685 
686  // Store m_PSWidthAdjust in mm in user config
687  cfg->m_Plot.ps_fine_width_adjust = Iu2Millimeter( m_PSWidthAdjust );
688 
689  tempOptions.SetFormat( getPlotFormat() );
690 
691  tempOptions.SetUseGerberProtelExtensions( m_useGerberExtensions->GetValue() );
692  tempOptions.SetUseGerberX2format( m_useGerberX2Format->GetValue() );
693  tempOptions.SetIncludeGerberNetlistInfo( m_useGerberNetAttributes->GetValue() );
694  tempOptions.SetCreateGerberJobFile( m_generateGerberJobFile->GetValue() );
695 
696  tempOptions.SetGerberPrecision( m_coordFormatCtrl->GetSelection() == 0 ? 5 : 6 );
697 
698  LSET selectedLayers;
699  for( unsigned i = 0; i < m_layerList.size(); i++ )
700  {
701  if( m_layerCheckListBox->IsChecked( i ) )
702  selectedLayers.set( m_layerList[i] );
703  }
704  // Get a list of copper layers that aren't being used by inverting enabled layers.
705  LSET disabledCopperLayers = LSET::AllCuMask() & ~m_parent->GetBoard()->GetEnabledLayers();
706  // Enable all of the disabled copper layers.
707  // If someone enables more copper layers they will be selected by default.
708  selectedLayers = selectedLayers | disabledCopperLayers;
709  tempOptions.SetLayerSelection( selectedLayers );
710 
711  tempOptions.SetNegative( m_plotPSNegativeOpt->GetValue() );
712  tempOptions.SetA4Output( m_forcePSA4OutputOpt->GetValue() );
713 
714  // Set output directory and replace backslashes with forward ones
715  wxString dirStr;
716  dirStr = m_outputDirectoryName->GetValue();
717  dirStr.Replace( wxT( "\\" ), wxT( "/" ) );
718  tempOptions.SetOutputDirectory( dirStr );
719 
720  if( !m_plotOpts.IsSameAs( tempOptions, false ) )
721  {
722  // First, mark board as modified only for parameters saved in file
723  if( !m_plotOpts.IsSameAs( tempOptions, true ) )
724  m_parent->OnModify();
725 
726  // Now, save any change, for the session
727  m_parent->SetPlotSettings( tempOptions );
728  m_plotOpts = tempOptions;
729  }
730 }
731 
732 
733 void DIALOG_PLOT::OnGerberX2Checked( wxCommandEvent& event )
734 {
735  // Currently: do nothing
736 }
737 
738 
739 void DIALOG_PLOT::Plot( wxCommandEvent& event )
740 {
741  BOARD* board = m_parent->GetBoard();
742 
744 
745  // If no layer selected, we have nothing plotted.
746  // Prompt user if it happens because he could think there is a bug in Pcbnew.
747  if( !m_plotOpts.GetLayerSelection().any() )
748  {
749  DisplayError( this, _( "No layer selected, Nothing to plot" ) );
750  return;
751  }
752 
753  // Create output directory if it does not exist (also transform it in
754  // absolute form). Bail if it fails
755  wxFileName outputDir = wxFileName::DirName( m_plotOpts.GetOutputDirectory() );
756  wxString boardFilename = m_parent->GetBoard()->GetFileName();
757  REPORTER& reporter = m_messagesPanel->Reporter();
758 
759  if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) )
760  {
761  wxString msg;
762  msg.Printf( _( "Could not write plot files to folder \"%s\"." ),
763  GetChars( outputDir.GetPath() ) );
764  DisplayError( this, msg );
765  return;
766  }
767 
768  if( m_zoneFillCheck->GetValue() )
769  m_parent->GetToolManager()->GetTool<ZONE_FILLER_TOOL>()->CheckAllZones( this );
770 
771  m_plotOpts.SetAutoScale( false );
772 
773  switch( m_plotOpts.GetScaleSelection() )
774  {
775  default: m_plotOpts.SetScale( 1 ); break;
776  case 0: m_plotOpts.SetAutoScale( true ); break;
777  case 2: m_plotOpts.SetScale( 1.5 ); break;
778  case 3: m_plotOpts.SetScale( 2 ); break;
779  case 4: m_plotOpts.SetScale( 3 ); break;
780  }
781 
782  /* If the scale factor edit controls are disabled or the scale value
783  * is 0, don't adjust the base scale factor. This fixes a bug when
784  * the default scale adjust is initialized to 0 and saved in program
785  * settings resulting in a divide by zero fault.
786  */
788  {
789  if( m_XScaleAdjust != 0.0 )
791 
792  if( m_YScaleAdjust != 0.0 )
794 
796  }
797 
798  wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) );
799 
800  // Test for a reasonable scale value
801  // XXX could this actually happen? isn't it constrained in the apply
802  // function?
804  DisplayInfoMessage( this, _( "Warning: Scale option set to a very small value" ) );
805 
807  DisplayInfoMessage( this, _( "Warning: Scale option set to a very large value" ) );
808 
809  GERBER_JOBFILE_WRITER jobfile_writer( board, &reporter );
810 
811  // Save the current plot options in the board
813 
814  wxBusyCursor dummy;
815 
816  for( LSEQ seq = m_plotOpts.GetLayerSelection().UIOrder(); seq; ++seq )
817  {
818  PCB_LAYER_ID layer = *seq;
819 
820  // All copper layers that are disabled are actually selected
821  // This is due to wonkyness in automatically selecting copper layers
822  // for plotting when adding more than two layers to a board.
823  // If plot options become accessible to the layers setup dialog
824  // please move this functionality there!
825  // This skips a copper layer if it is actually disabled on the board.
826  if( ( LSET::AllCuMask() & ~board->GetEnabledLayers() )[layer] )
827  continue;
828 
829  // Pick the basename from the board file
830  wxFileName fn( boardFilename );
831 
832  // Use Gerber Extensions based on layer number
833  // (See http://en.wikipedia.org/wiki/Gerber_File)
835  file_ext = GetGerberProtelExtension( layer );
836 
837  BuildPlotFileName( &fn, outputDir.GetPath(), board->GetLayerName( layer ), file_ext );
838  wxString fullname = fn.GetFullName();
839  jobfile_writer.AddGbrFile( layer, fullname );
840 
841  LOCALE_IO toggle;
842 
843  PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, fn.GetFullPath(), wxEmptyString );
844 
845  // Print diags in messages box:
846  wxString msg;
847 
848  if( plotter )
849  {
850  PlotOneBoardLayer( board, plotter, layer, m_plotOpts );
851  plotter->EndPlot();
852  delete plotter;
853 
854  msg.Printf( _( "Plot file \"%s\" created." ), fn.GetFullPath() );
855  reporter.Report( msg, RPT_SEVERITY_ACTION );
856  }
857  else
858  {
859  msg.Printf( _( "Unable to create file \"%s\"." ), fn.GetFullPath() );
860  reporter.Report( msg, RPT_SEVERITY_ERROR );
861  }
862 
863  wxSafeYield(); // displays report message.
864  }
865 
867  {
868  // Pick the basename from the board file
869  wxFileName fn( boardFilename );
870  // Build gerber job file from basename
871  BuildPlotFileName( &fn, outputDir.GetPath(), "job", GerberJobFileExtension );
872  jobfile_writer.CreateJobFile( fn.GetFullPath() );
873  }
874 }
875 
876 
877 void DIALOG_PLOT::onRunDRC( wxCommandEvent& event )
878 {
879  PCB_EDIT_FRAME* parent = dynamic_cast<PCB_EDIT_FRAME*>( GetParent() );
880 
881  if( parent )
882  {
883  DRC* drcTool = parent->GetToolManager()->GetTool<DRC>();
884 
885  // First close an existing dialog if open
886  // (low probability, but can happen)
887  drcTool->DestroyDRCDialog( wxID_OK );
888 
889  // Open a new drc dialod, with the right parent frame, and in Modal Mode
890  drcTool->ShowDRCDialog( this );
891 
892  // Update DRC warnings on return to this dialog
893  reInitDialog();
894  }
895 }
896 
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:686
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:239
WX_HTML_REPORT_PANEL * m_messagesPanel
wxStaticBoxSizer * m_HPGLOptionsSizer
void SetScaleSelection(int aSelection)
LSEQ m_layerList
Definition: dialog_plot.h:47
void SetIncludeGerberNetlistInfo(bool aUse)
const BITMAP_OPAQUE folder_xpm[1]
Definition: folder.cpp:20
void SetDXFPlotPolygonMode(bool aFlag)
double m_YScaleAdjust
Definition: dialog_plot.h:50
bool GetCreateGerberJobFile() const
void OnModify() override
Function OnModify must be called after a board change to set the modified flag.
wxCheckBox * m_useGerberExtensions
void DestroyDRCDialog(int aReason)
Deletes this ui dialog box and zeros out its pointer to remember the state of the dialog's existence.
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
void SetGerberPrecision(int aPrecision)
void OnOutputDirectoryBrowseClicked(wxCommandEvent &event) override
wxButton * m_sdbSizer1Cancel
void SetPlotViaOnMaskLayer(bool aFlag)
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
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: common.h:202
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.
int GetSmallestClearanceValue()
Function GetSmallestClearanceValue.
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
MARKERS & Markers()
Definition: class_board.h:248
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:48
wxString StringFromValue(EDA_UNITS aUnits, double aValue, bool aAddUnitSymbol, bool aUseMils)
Function StringFromValue returns the string from aValue according to units (inch, mm ....
Definition: base_units.cpp:234
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:512
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...
wxCheckBox * m_plotMirrorOpt
void SetTextMode(PLOT_TEXT_MODE aVal)
LSET GetEnabledLayers() const
Function GetEnabledLayers is a proxy function that calls the corresponding function in m_BoardSetting...
wxCheckBox * m_zoneFillCheck
void SetDrillMarksType(DrillMarksType aVal)
REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:62
wxChoice * m_plotFormatOpt
static LSET AllTechMask()
Function AllTechMask returns a mask holding all technical layers (no CU layer) on both side.
Definition: lset.cpp:756
wxString GetAbbreviatedUnitsLabel(EDA_UNITS aUnit, bool aUseMils, EDA_DATA_TYPE aType)
Get the units string for a given units type.
Definition: base_units.cpp:467
virtual const PCB_PLOT_PARAMS & GetPlotSettings() const
Function GetPlotSettings returns the PCB_PLOT_PARAMS for the BOARD owned by this frame.
wxChoice * m_coordFormatCtrl
void CreateDrillFile(wxCommandEvent &event) override
const wxString & GetFileName() const
Definition: class_board.h:218
Classes used to generate a Gerber job file in JSON.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
wxStaticBoxSizer * m_SizerDXF_options
double GetScale() const
UNIT_BINDER m_trackWidthCorrection
Definition: dialog_plot.h:61
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
VTBL_ENTRY const wxString AbsolutePath(const wxString &aFileName) const
Function AbsolutePath fixes up aFileName if it is relative to the project's directory to be an absolu...
Definition: project.cpp:413
bool SetLineWidth(int aValue)
bool GetMirror() const
void SetPlotValue(bool aFlag)
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:132
Board plot function definition file.
wxCheckBox * m_plotSheetRef
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:80
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:
bool GetA4Output() const
ZONE_FILLER_TOOL.
int GetGerberPrecision() const
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.
PLOT_FORMAT GetFormat() const
PCB_EDIT_FRAME * m_parent
Definition: dialog_plot.h:46
int m_widthAdjustMaxValue
Definition: dialog_plot.h:57
bool GetUseGerberProtelExtensions() const
void SetDXFPlotUnits(DXF_PLOTTER::DXF_UNITS aUnit)
PLOT_FORMAT getPlotFormat()
PLOT_FORMAT
Enum PlotFormat is the set of supported output plot formats.
Definition: plotter.h:51
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
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:552
REPORTER & Reporter()
returns the reporter object that reports to this panel
#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(EDA_DRAW_MODE_T aPlotMode)
Definition: dialog_plot.h:85
void SetUseGerberX2format(bool aUse)
virtual void SetPlotSettings(const PCB_PLOT_PARAMS &aSettings)
void OnSetScaleOpt(wxCommandEvent &event) override
wxStaticBoxSizer * m_GerberOptionsSizer
wxCheckBox * m_useGerberNetAttributes
void SetOutputDirectory(wxString aDir)
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
PCB_PLOT_PARAMS m_plotOpts
Definition: dialog_plot.h:65
void SetNegative(bool aFlag)
bool GetPlotValue() const
wxString GetOutputDirectory() const
void SetFineScaleAdjustX(double aVal)
wxChoice * m_scaleOpt
int GetLineWidth() const
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:373
void reInitDialog()
wxCheckBox * m_plotModuleRefOpt
void SetPlotPadsOnSilkLayer(bool aFlag)
void SetPlotMode(EDA_DRAW_MODE_T aPlotMode)
UNIT_BINDER m_defaultLineWidth
Definition: dialog_plot.h:59
bool SetHPGLPenDiameter(double aValue)
wxString m_DRCWarningTemplate
Definition: dialog_plot.h:63
Base plotter engine class.
Definition: plotter.h:104
wxBoxSizer * m_sizerButtons
wxCheckBox * m_subtractMaskFromSilk
void init_Dialog()
Definition: dialog_plot.cpp:72
wxCheckBox * m_plotNoViaOnMaskOpt
wxCheckBox * m_plotModuleValueOpt
bool GetPlotViaOnMaskLayer() const
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:101
wxChoice * m_drillShapeOpt
Board layer functions and definitions.
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
void applyPlotSettings()
void SetWidthAdjust(int aVal)
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:163
bool GetSubtractMaskFromSilk() const
#define _(s)
Definition: 3d_actions.cpp:33
Design Rule Checker object that performs all the DRC tests.
Definition: drc.h:133
static bool setInt(int *aResult, int aValue, int aMin, int aMax)
virtual void SetValue(int aValue)
Function SetValue Sets new value (in Internal Units) for the text field, taking care of units convers...
wxCheckBox * m_plotInvisibleText
double GetHPGLPenDiameter() const
PCB_EDIT_FRAME is the main frame for Pcbnew.
bool IsSameAs(const PCB_PLOT_PARAMS &aPcbPlotParams, bool aCompareOnlySavedPrms) const
Compare current settings to aPcbPlotParams, including not saved parameters in brd file.
#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:61
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()
Function GetValue Returns the current value in Internal Units.
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
int GetScaleSelection() const
wxCheckBox * m_excludePadsFromSilkscreen
bool GetPlotPadsOnSilkLayer() const
UNIT_BINDER m_defaultPenSize
Definition: dialog_plot.h:60
void OnRightClick(wxMouseEvent &event) override
wxBitmapButton * m_browseButton
wxBoxSizer * m_MainSizer
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
BOARD * GetBoard() const
bool GetUseAuxOrigin() const
wxCheckListBox * m_layerCheckListBox
wxStaticBoxSizer * m_PSOptionsSizer
LSET GetLayerSelection() const
DXF_PLOTTER::DXF_UNITS GetDXFPlotUnits() const
LSEQ UIOrder() const
Definition: lset.cpp:813
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:267
DrillMarksType GetDrillMarksType() const
wxBoxSizer * m_PlotOptionsSizer
bool GetPlotReference() const
DIALOG_PLOT(PCB_EDIT_FRAME *parent)
Definition: dialog_plot.cpp:46
#define DLG_WINDOW_NAME
wxStaticText * m_DRCExclusionsWarning
void Enable(bool aEnable)
Function Enable Enables/diasables the label, widget and units label.
bool GetExcludeEdgeLayer() const
EDA_DRAW_MODE_T GetPlotMode() const
PCBNEW_SETTINGS * GetSettings()