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 <pcbplot.h>
30 #include <gerber_jobfile_writer.h>
31 #include <reporter.h>
33 #include <bitmaps.h>
34 #include <class_board.h>
35 #include <dialog_plot.h>
36 #include <dialog_gendrill.h>
37 #include <wx_html_report_panel.h>
38 #include <drc.h>
39 
40 
42  DIALOG_PLOT_BASE( aParent ), m_parent( aParent ),
43  m_defaultLineWidth( aParent, m_lineWidthLabel, m_lineWidthCtrl, m_lineWidthUnits, true ),
44  m_defaultPenSize( aParent, m_hpglPenLabel, m_hpglPenCtrl, m_hpglPenUnits, true ),
45  m_trackWidthCorrection( aParent, m_widthAdjustLabel, m_widthAdjustCtrl, m_widthAdjustUnits, true )
46 {
47  SetName( DLG_WINDOW_NAME );
49  m_plotOpts = aParent->GetPlotSettings();
50  init_Dialog();
51 
52  // We use a sdbSizer to get platform-dependent ordering of the action buttons, but
53  // that requires us to correct the button labels here.
54  m_sdbSizer1OK->SetLabel( _( "Plot" ) );
55  m_sdbSizer1Apply->SetLabel( _( "Generate Drill Files..." ) );
56  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
57  m_sizerButtons->Layout();
58 
59  m_sdbSizer1OK->SetDefault();
60 
61  GetSizer()->Fit( this );
62  GetSizer()->SetSizeHints( this );
63 }
64 
65 
67 {
68  BOARD* board = m_parent->GetBoard();
69  wxFileName fileName;
70 
73 
74  bool checkZones;
75  m_config->Read( OPTKEY_PLOT_CHECK_ZONES, &checkZones, true );
76  m_zoneFillCheck->SetValue( checkZones );
77 
78  m_browseButton->SetBitmap( KiBitmap( folder_xpm ) );
79 
80  // m_PSWidthAdjust is stored in mm in user config
81  double dtmp;
82  m_config->Read( CONFIG_PS_FINEWIDTH_ADJ, &dtmp, 0 );
83  m_PSWidthAdjust = KiROUND( dtmp * IU_PER_MM );
84 
85  // The reasonable width correction value must be in a range of
86  // [-(MinTrackWidth-1), +(MinClearanceValue-1)] decimils.
89 
90  switch( m_plotOpts.GetFormat() )
91  {
92  default:
93  case PLOT_FORMAT_GERBER: m_plotFormatOpt->SetSelection( 0 ); break;
94  case PLOT_FORMAT_POST: m_plotFormatOpt->SetSelection( 1 ); break;
95  case PLOT_FORMAT_SVG: m_plotFormatOpt->SetSelection( 2 ); break;
96  case PLOT_FORMAT_DXF: m_plotFormatOpt->SetSelection( 3 ); break;
97  case PLOT_FORMAT_HPGL: m_plotFormatOpt->SetSelection( 4 ); break;
98  case PLOT_FORMAT_PDF: m_plotFormatOpt->SetSelection( 5 ); break;
99  }
100 
101  // Set units and value for HPGL pen size (this param is in mils).
103 
105 
106  // Test for a reasonable scale value. Set to 1 if problem
110 
113 
114  // Test for a reasonable PS width correction value. Set to 0 if problem.
115  if( m_PSWidthAdjust < m_widthAdjustMinValue || m_PSWidthAdjust > m_widthAdjustMaxValue )
116  m_PSWidthAdjust = 0.;
117 
119 
122 
123  // Could devote a PlotOrder() function in place of UIOrder().
124  m_layerList = board->GetEnabledLayers().UIOrder();
125 
126  // Populate the check list box by all enabled layers names
127  for( LSEQ seq = m_layerList; seq; ++seq )
128  {
129  PCB_LAYER_ID layer = *seq;
130 
131  int checkIndex = m_layerCheckListBox->Append( board->GetLayerName( layer ) );
132 
133  if( m_plotOpts.GetLayerSelection()[layer] )
134  m_layerCheckListBox->Check( checkIndex );
135  }
136 
137  // Option for using proper Gerber extensions. Note also Protel extensions are
138  // a broken feature. However, for now, we need to handle it.
140 
141  // Option for including Gerber attributes, from Gerber X2 format, in the output
142  // In X1 format, they will be added as comments
144 
145  // Option for including Gerber netlist info (from Gerber X2 format) in the output
147 
148  // Option to generate a Gerber job file
150 
151  // Gerber precision for coordinates
152  m_coordFormatCtrl->SetSelection( m_plotOpts.GetGerberPrecision() == 5 ? 0 : 1 );
153 
154  // Option for excluding contents of "Edges Pcb" layer
156 
157  // Option to exclude pads from silkscreen layers
159 
161 
162  // Option to plot page references:
164 
165  // Options to plot texts on footprints
169 
170  // Options to plot pads and vias holes
171  m_drillShapeOpt->SetSelection( m_plotOpts.GetDrillMarksType() );
172 
173  // Scale option
174  m_scaleOpt->SetSelection( m_plotOpts.GetScaleSelection() );
175 
176  // Plot mode
178 
179  // Plot outline mode
181 
182  // Plot text mode
184 
185  // Plot mirror option
186  m_plotMirrorOpt->SetValue( m_plotOpts.GetMirror() );
187 
188  // Put vias on mask layer
190 
191  // Initialize a few other parameters, which can also be modified
192  // from the drill dialog
193  reInitDialog();
194 
195  // Update options values:
196  wxCommandEvent cmd_event;
197  SetPlotFormat( cmd_event );
198  OnSetScaleOpt( cmd_event );
199 }
200 
201 
203 {
204  // after calling drill dialog, some parameters can be modified.
205  // update them
206 
207  // Output directory
209 
210  // Origin of coordinates:
212 }
213 
214 
215 // A helper function to show a popup menu, when the dialog is right clicked.
216 void DIALOG_PLOT::OnRightClick( wxMouseEvent& event )
217 {
218  PopupMenu( m_popMenu );
219 }
220 
221 
222 // Select or deselect groups of layers in the layers list:
224 void DIALOG_PLOT::OnPopUpLayers( wxCommandEvent& event )
225 {
226  // Build a list of layers for usual fabrication:
227  // copper layers + tech layers without courtyard
228  LSET fab_layer_set = ( LSET::AllCuMask() | LSET::AllTechMask() )
229  & ~LSET( 2, B_CrtYd, F_CrtYd );
230 
231  switch( event.GetId() )
232  {
233  case ID_LAYER_FAB: // Select layers usually needed to build a board
234  for( unsigned i = 0; i < m_layerList.size(); i++ )
235  {
236  LSET layermask( m_layerList[ i ] );
237 
238  if( ( layermask & fab_layer_set ).any() )
239  m_layerCheckListBox->Check( i, true );
240  else
241  m_layerCheckListBox->Check( i, false );
242  }
243  break;
244 
246  for( unsigned i = 0; i < m_layerList.size(); i++ )
247  {
248  if( IsCopperLayer( m_layerList[i] ) )
249  m_layerCheckListBox->Check( i, true );
250  }
251  break;
252 
254  for( unsigned i = 0; i < m_layerList.size(); i++ )
255  {
256  if( IsCopperLayer( m_layerList[i] ) )
257  m_layerCheckListBox->Check( i, false );
258  }
259  break;
260 
262  for( unsigned i = 0; i < m_layerList.size(); i++ )
263  m_layerCheckListBox->Check( i, true );
264  break;
265 
267  for( unsigned i = 0; i < m_layerList.size(); i++ )
268  m_layerCheckListBox->Check( i, false );
269  break;
270 
271  default:
272  break;
273  }
274 }
275 
276 
277 void DIALOG_PLOT::CreateDrillFile( wxCommandEvent& event )
278 {
279  // Be sure drill file use the same settings (axis option, plot directory)
280  // as plot files:
282 
283  DIALOG_GENDRILL dlg( m_parent, this );
284  dlg.ShowModal();
285 
286  // a few plot settings can be modified: take them in account
288  reInitDialog();
289 }
290 
291 
292 void DIALOG_PLOT::OnChangeDXFPlotMode( wxCommandEvent& event )
293 {
294  // m_DXF_plotTextStrokeFontOpt is disabled if m_DXF_plotModeOpt
295  // is checked (plot in DXF polygon mode)
296  m_DXF_plotTextStrokeFontOpt->Enable( !m_DXF_plotModeOpt->GetValue() );
297 
298  // if m_DXF_plotTextStrokeFontOpt option is disabled (plot DXF in polygon mode),
299  // force m_DXF_plotTextStrokeFontOpt to true to use Pcbnew stroke font
300  if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() )
301  m_DXF_plotTextStrokeFontOpt->SetValue( true );
302 }
303 
304 
305 void DIALOG_PLOT::OnSetScaleOpt( wxCommandEvent& event )
306 {
307  /* Disable sheet reference for scale != 1:1 */
308  bool scale1 = ( m_scaleOpt->GetSelection() == 1 );
309 
310  m_plotSheetRef->Enable( scale1 );
311 
312  if( !scale1 )
313  m_plotSheetRef->SetValue( false );
314 }
315 
316 
317 void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
318 {
319  // Build the absolute path of current output plot directory
320  // to preselect it when opening the dialog.
321  wxFileName fn( m_outputDirectoryName->GetValue() );
322  wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() );
323 
324  wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
325 
326  if( dirDialog.ShowModal() == wxID_CANCEL )
327  return;
328 
329  wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
330 
331  fn = Prj().AbsolutePath( m_parent->GetBoard()->GetFileName() );
332  wxString defaultPath = fn.GetPathWithSep();
333  wxString msg;
334  msg.Printf( _( "Do you want to use a path relative to\n\"%s\"" ),
335  GetChars( defaultPath ) );
336 
337  wxMessageDialog dialog( this, msg, _( "Plot Output Directory" ),
338  wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
339 
340  if( dialog.ShowModal() == wxID_YES )
341  {
342  if( !dirName.MakeRelativeTo( defaultPath ) )
343  wxMessageBox( _( "Cannot make path relative (target volume different from file volume)!" ),
344  _( "Plot Output Directory" ), wxOK | wxICON_ERROR );
345  }
346 
347  m_outputDirectoryName->SetValue( dirName.GetFullPath() );
348 }
349 
350 
352 {
353  // plot format id's are ordered like displayed in m_plotFormatOpt
354  static const PlotFormat plotFmt[] =
355  {
362  };
363 
364  return plotFmt[ m_plotFormatOpt->GetSelection() ];
365 }
366 
367 
368 // Enable or disable widgets according to the plot format selected
369 // and clear also some optional values
370 void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
371 {
372  // this option exist only in DXF format:
374 
375  switch( getPlotFormat() )
376  {
377  case PLOT_FORMAT_PDF:
378  case PLOT_FORMAT_SVG:
379  m_drillShapeOpt->Enable( true );
380  m_plotModeOpt->Enable( false );
382  m_plotMirrorOpt->Enable( true );
383  m_useAuxOriginCheckBox->Enable( false );
384  m_useAuxOriginCheckBox->SetValue( false );
385  m_defaultLineWidth.Enable( true );
386  m_defaultPenSize.Enable( false );
387  m_excludeEdgeLayerOpt->Enable( true );
388  m_scaleOpt->Enable( false );
389  m_scaleOpt->SetSelection( 1 );
390  m_fineAdjustXCtrl->Enable( false );
391  m_fineAdjustYCtrl->Enable( false );
393  m_plotPSNegativeOpt->Enable( true );
394  m_forcePSA4OutputOpt->Enable( false );
395  m_forcePSA4OutputOpt->SetValue( false );
396 
401  break;
402 
403  case PLOT_FORMAT_POST:
404  m_drillShapeOpt->Enable( true );
405  m_plotModeOpt->Enable( true );
406  m_plotMirrorOpt->Enable( true );
407  m_useAuxOriginCheckBox->Enable( false );
408  m_useAuxOriginCheckBox->SetValue( false );
409  m_defaultLineWidth.Enable( true );
410  m_defaultPenSize.Enable( false );
411  m_excludeEdgeLayerOpt->Enable( true );
412  m_scaleOpt->Enable( true );
413  m_fineAdjustXCtrl->Enable( true );
414  m_fineAdjustYCtrl->Enable( true );
416  m_plotPSNegativeOpt->Enable( true );
417  m_forcePSA4OutputOpt->Enable( true );
418 
423  break;
424 
425  case PLOT_FORMAT_GERBER:
426  m_drillShapeOpt->Enable( false );
427  m_drillShapeOpt->SetSelection( 0 );
428  m_plotModeOpt->Enable( false );
430  m_plotMirrorOpt->Enable( false );
431  m_plotMirrorOpt->SetValue( false );
432  m_useAuxOriginCheckBox->Enable( true );
433  m_defaultLineWidth.Enable( true );
434  m_defaultPenSize.Enable( false );
435  m_excludeEdgeLayerOpt->Enable( true );
436  m_scaleOpt->Enable( false );
437  m_scaleOpt->SetSelection( 1 );
438  m_fineAdjustXCtrl->Enable( false );
439  m_fineAdjustYCtrl->Enable( false );
441  m_plotPSNegativeOpt->Enable( false );
442  m_plotPSNegativeOpt->SetValue( false );
443  m_forcePSA4OutputOpt->Enable( false );
444  m_forcePSA4OutputOpt->SetValue( false );
445 
450  break;
451 
452  case PLOT_FORMAT_HPGL:
453  m_drillShapeOpt->Enable( true );
454  m_plotModeOpt->Enable( true );
455  m_plotMirrorOpt->Enable( true );
456  m_useAuxOriginCheckBox->Enable( false );
457  m_useAuxOriginCheckBox->SetValue( false );
458  m_defaultLineWidth.Enable( false );
459  m_defaultPenSize.Enable( true );
460  m_excludeEdgeLayerOpt->Enable( true );
461  m_scaleOpt->Enable( true );
462  m_fineAdjustXCtrl->Enable( false );
463  m_fineAdjustYCtrl->Enable( false );
465  m_plotPSNegativeOpt->SetValue( false );
466  m_plotPSNegativeOpt->Enable( false );
467  m_forcePSA4OutputOpt->Enable( true );
468 
473  break;
474 
475  case PLOT_FORMAT_DXF:
476  m_drillShapeOpt->Enable( true );
477  m_plotModeOpt->Enable( false );
479  m_plotMirrorOpt->Enable( false );
480  m_plotMirrorOpt->SetValue( false );
481  m_useAuxOriginCheckBox->Enable( true );
482  m_defaultLineWidth.Enable( false );
483  m_defaultPenSize.Enable( false );
484  m_excludeEdgeLayerOpt->Enable( true );
485  m_scaleOpt->Enable( false );
486  m_scaleOpt->SetSelection( 1 );
487  m_fineAdjustXCtrl->Enable( false );
488  m_fineAdjustYCtrl->Enable( false );
490  m_plotPSNegativeOpt->Enable( false );
491  m_plotPSNegativeOpt->SetValue( false );
492  m_forcePSA4OutputOpt->Enable( false );
493  m_forcePSA4OutputOpt->SetValue( false );
494 
499 
500  OnChangeDXFPlotMode( event );
501  break;
502 
504  break;
505  }
506 
507  /* Update the interlock between scale and frame reference
508  * (scaling would mess up the frame border...) */
509  OnSetScaleOpt( event );
510 
511  Layout();
512  m_MainSizer->SetSizeHints( this );
513 }
514 
515 
516 // A helper function to "clip" aValue between aMin and aMax
517 // and write result in * aResult
518 // return false if clipped, true if aValue is just copied into * aResult
519 static bool setDouble( double* aResult, double aValue, double aMin, double aMax )
520 {
521  if( aValue < aMin )
522  {
523  *aResult = aMin;
524  return false;
525  }
526  else if( aValue > aMax )
527  {
528  *aResult = aMax;
529  return false;
530  }
531 
532  *aResult = aValue;
533  return true;
534 }
535 
536 
537 static bool setInt( int* aResult, int aValue, int aMin, int aMax )
538 {
539  if( aValue < aMin )
540  {
541  *aResult = aMin;
542  return false;
543  }
544  else if( aValue > aMax )
545  {
546  *aResult = aMax;
547  return false;
548  }
549 
550  *aResult = aValue;
551  return true;
552 }
553 
554 
556 {
557  REPORTER& reporter = m_messagesPanel->Reporter();
558 
559  PCB_PLOT_PARAMS tempOptions;
560 
561  tempOptions.SetExcludeEdgeLayer( m_excludeEdgeLayerOpt->GetValue() );
562  tempOptions.SetSubtractMaskFromSilk( m_subtractMaskFromSilk->GetValue() );
563  tempOptions.SetPlotFrameRef( m_plotSheetRef->GetValue() );
564  tempOptions.SetPlotPadsOnSilkLayer( !m_excludePadsFromSilkscreen->GetValue() );
565  tempOptions.SetUseAuxOrigin( m_useAuxOriginCheckBox->GetValue() );
566  tempOptions.SetPlotValue( m_plotModuleValueOpt->GetValue() );
567  tempOptions.SetPlotReference( m_plotModuleRefOpt->GetValue() );
568  tempOptions.SetPlotInvisibleText( m_plotInvisibleText->GetValue() );
569  tempOptions.SetScaleSelection( m_scaleOpt->GetSelection() );
570  tempOptions.SetDrillMarksType( static_cast<PCB_PLOT_PARAMS::DrillMarksType>
571  ( m_drillShapeOpt->GetSelection() ) );
572  tempOptions.SetMirror( m_plotMirrorOpt->GetValue() );
573  tempOptions.SetPlotMode( m_plotModeOpt->GetSelection() == 1 ? SKETCH : FILLED );
574  tempOptions.SetDXFPlotPolygonMode( m_DXF_plotModeOpt->GetValue() );
575  tempOptions.SetPlotViaOnMaskLayer( m_plotNoViaOnMaskOpt->GetValue() );
576 
577  if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() ) // Currently, only DXF supports this option
578  tempOptions.SetTextMode( PLOTTEXTMODE_DEFAULT );
579  else
580  tempOptions.SetTextMode( m_DXF_plotTextStrokeFontOpt->GetValue() ?
582 
583  // Update settings from text fields. Rewrite values back to the fields,
584  // since the values may have been constrained by the setters.
585  wxString msg;
586 
587  // read HPLG pen size (this param is stored in mils)
588  // However, due to issues when converting this value from or to mm
589  // that can slightly change the value, update this param only if it
590  // is in use
592  {
593  if( !tempOptions.SetHPGLPenDiameter( m_defaultPenSize.GetValue() / IU_PER_MILS ) )
594  {
596  msg.Printf( _( "HPGL pen size constrained." ) );
597  reporter.Report( msg, REPORTER::RPT_INFO );
598  }
599  }
600  else // keep the last value (initial value if no HPGL plot made)
602 
603  // Default linewidth
604  if( !tempOptions.SetLineWidth( m_defaultLineWidth.GetValue() ) )
605  {
606  m_defaultLineWidth.SetValue( tempOptions.GetLineWidth() );
607  msg.Printf( _( "Default line width constrained." ) );
608  reporter.Report( msg, REPORTER::RPT_INFO );
609  }
610 
611  // X scale
612  double tmpDouble;
613  msg = m_fineAdjustXCtrl->GetValue();
614  msg.ToDouble( &tmpDouble );
615 
616  if( !setDouble( &m_XScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
617  {
618  msg.Printf( wxT( "%f" ), m_XScaleAdjust );
619  m_fineAdjustXCtrl->SetValue( msg );
620  msg.Printf( _( "X scale constrained." ) );
621  reporter.Report( msg, REPORTER::RPT_INFO );
622  }
623 
625 
626  // Y scale
627  msg = m_fineAdjustYCtrl->GetValue();
628  msg.ToDouble( &tmpDouble );
629 
630  if( !setDouble( &m_YScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
631  {
632  msg.Printf( wxT( "%f" ), m_YScaleAdjust );
633  m_fineAdjustYCtrl->SetValue( msg );
634  msg.Printf( _( "Y scale constrained." ) );
635  reporter.Report( msg, REPORTER::RPT_INFO );
636  }
637 
639 
640  m_config->Write( OPTKEY_PLOT_CHECK_ZONES, m_zoneFillCheck->GetValue() );
641 
642  // PS Width correction
645  {
647  msg.Printf( _( "Width correction constrained. "
648  "The reasonable width correction value must be in a range of "
649  " [%s; %s] (%s) for current design rules." ),
653  reporter.Report( msg, REPORTER::RPT_WARNING );
654  }
655 
656  // Store m_PSWidthAdjust in mm in user config
658  (double)m_PSWidthAdjust / IU_PER_MM );
659 
660  tempOptions.SetFormat( getPlotFormat() );
661 
662  tempOptions.SetUseGerberProtelExtensions( m_useGerberExtensions->GetValue() );
663  tempOptions.SetUseGerberX2format( m_useGerberX2Format->GetValue() );
664  tempOptions.SetIncludeGerberNetlistInfo( m_useGerberNetAttributes->GetValue() );
665  tempOptions.SetCreateGerberJobFile( m_generateGerberJobFile->GetValue() );
666 
667  tempOptions.SetGerberPrecision( m_coordFormatCtrl->GetSelection() == 0 ? 5 : 6 );
668 
669  LSET selectedLayers;
670  for( unsigned i = 0; i < m_layerList.size(); i++ )
671  {
672  if( m_layerCheckListBox->IsChecked( i ) )
673  selectedLayers.set( m_layerList[i] );
674  }
675  // Get a list of copper layers that aren't being used by inverting enabled layers.
676  LSET disabledCopperLayers = LSET::AllCuMask() & ~m_parent->GetBoard()->GetEnabledLayers();
677  // Enable all of the disabled copper layers.
678  // If someone enables more copper layers they will be selected by default.
679  selectedLayers = selectedLayers | disabledCopperLayers;
680  tempOptions.SetLayerSelection( selectedLayers );
681 
682  tempOptions.SetNegative( m_plotPSNegativeOpt->GetValue() );
683  tempOptions.SetA4Output( m_forcePSA4OutputOpt->GetValue() );
684 
685  // Set output directory and replace backslashes with forward ones
686  wxString dirStr;
687  dirStr = m_outputDirectoryName->GetValue();
688  dirStr.Replace( wxT( "\\" ), wxT( "/" ) );
689  tempOptions.SetOutputDirectory( dirStr );
690 
691  if( !m_plotOpts.IsSameAs( tempOptions, false ) )
692  {
693  // First, mark board as modified only for parameters saved in file
694  if( !m_plotOpts.IsSameAs( tempOptions, true ) )
695  m_parent->OnModify();
696 
697  // Now, save any change, for the session
698  m_parent->SetPlotSettings( tempOptions );
699  m_plotOpts = tempOptions;
700  }
701 }
702 
703 
704 void DIALOG_PLOT::OnGerberX2Checked( wxCommandEvent& event )
705 {
706  // Currently: do nothing
707 }
708 
709 
710 void DIALOG_PLOT::Plot( wxCommandEvent& event )
711 {
712  BOARD* board = m_parent->GetBoard();
713 
715 
716  // If no layer selected, we have nothing plotted.
717  // Prompt user if it happens because he could think there is a bug in Pcbnew.
718  if( !m_plotOpts.GetLayerSelection().any() )
719  {
720  DisplayError( this, _( "No layer selected, Nothing to plot" ) );
721  return;
722  }
723 
724  // Create output directory if it does not exist (also transform it in
725  // absolute form). Bail if it fails
726  wxFileName outputDir = wxFileName::DirName( m_plotOpts.GetOutputDirectory() );
727  wxString boardFilename = m_parent->GetBoard()->GetFileName();
728  REPORTER& reporter = m_messagesPanel->Reporter();
729 
730  if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) )
731  {
732  wxString msg;
733  msg.Printf( _( "Could not write plot files to folder \"%s\"." ),
734  GetChars( outputDir.GetPath() ) );
735  DisplayError( this, msg );
736  return;
737  }
738 
739  if( m_zoneFillCheck->GetValue() )
740  m_parent->Check_All_Zones( this );
741 
742  m_plotOpts.SetAutoScale( false );
743  m_plotOpts.SetScale( 1 );
744 
745  switch( m_plotOpts.GetScaleSelection() )
746  {
747  default:
748  break;
749 
750  case 0: // Autoscale option
751  m_plotOpts.SetAutoScale( true );
752  break;
753 
754  case 2: // 3:2 option
755  m_plotOpts.SetScale( 1.5 );
756  break;
757 
758  case 3: // 2:1 option
759  m_plotOpts.SetScale( 2 );
760  break;
761 
762  case 4: // 3:1 option
763  m_plotOpts.SetScale( 3 );
764  break;
765  }
766 
767  /* If the scale factor edit controls are disabled or the scale value
768  * is 0, don't adjust the base scale factor. This fixes a bug when
769  * the default scale adjust is initialized to 0 and saved in program
770  * settings resulting in a divide by zero fault.
771  */
773  {
774  if( m_XScaleAdjust != 0.0 )
776 
777  if( m_YScaleAdjust != 0.0 )
779 
781  }
782 
783  wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) );
784 
785  // Test for a reasonable scale value
786  // XXX could this actually happen? isn't it constrained in the apply
787  // function?
789  DisplayInfoMessage( this, _( "Warning: Scale option set to a very small value" ) );
790 
792  DisplayInfoMessage( this, _( "Warning: Scale option set to a very large value" ) );
793 
794  GERBER_JOBFILE_WRITER jobfile_writer( board, &reporter );
795 
796  // Save the current plot options in the board
798 
799  wxBusyCursor dummy;
800 
801  for( LSEQ seq = m_plotOpts.GetLayerSelection().UIOrder(); seq; ++seq )
802  {
803  PCB_LAYER_ID layer = *seq;
804 
805  // All copper layers that are disabled are actually selected
806  // This is due to wonkyness in automatically selecting copper layers
807  // for plotting when adding more than two layers to a board.
808  // If plot options become accessible to the layers setup dialog
809  // please move this functionality there!
810  // This skips a copper layer if it is actually disabled on the board.
811  if( ( LSET::AllCuMask() & ~board->GetEnabledLayers() )[layer] )
812  continue;
813 
814  // Pick the basename from the board file
815  wxFileName fn( boardFilename );
816 
817  // Use Gerber Extensions based on layer number
818  // (See http://en.wikipedia.org/wiki/Gerber_File)
820  file_ext = GetGerberProtelExtension( layer );
821 
822  BuildPlotFileName( &fn, outputDir.GetPath(), board->GetLayerName( layer ), file_ext );
823  wxString fullname = fn.GetFullName();
824  jobfile_writer.AddGbrFile( layer, fullname );
825 
826  LOCALE_IO toggle;
827 
828  PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, fn.GetFullPath(), wxEmptyString );
829 
830  // Print diags in messages box:
831  wxString msg;
832 
833  if( plotter )
834  {
835  PlotOneBoardLayer( board, plotter, layer, m_plotOpts );
836  plotter->EndPlot();
837  delete plotter;
838 
839  msg.Printf( _( "Plot file \"%s\" created." ), GetChars( fn.GetFullPath() ) );
840  reporter.Report( msg, REPORTER::RPT_ACTION );
841  }
842  else
843  {
844  msg.Printf( _( "Unable to create file \"%s\"." ), GetChars( fn.GetFullPath() ) );
845  reporter.Report( msg, REPORTER::RPT_ERROR );
846  }
847  }
848 
850  {
851  // Pick the basename from the board file
852  wxFileName fn( boardFilename );
853  // Build gerber job file from basename
854  BuildPlotFileName( &fn, outputDir.GetPath(), "job", GerberJobFileExtension );
855  jobfile_writer.CreateJobFile( fn.GetFullPath() );
856  }
857 }
858 
859 
860 void DIALOG_PLOT::onRunDRC( wxCommandEvent& event )
861 {
862  PCB_EDIT_FRAME* parent = dynamic_cast<PCB_EDIT_FRAME*>( GetParent() );
863 
864  if( parent )
865  {
866  // First close an existing dialog if open
867  // (low probability, but can happen)
868  parent->GetDrcController()->DestroyDRCDialog( wxID_OK );
869 
870  // Open a new drc dialod, with the right parent frame, and in Modal Mode
871  parent->GetDrcController()->ShowDRCDialog( this );
872  }
873 }
874 
void SetTextMode(PlotTextMode aVal)
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:676
void SetUseGerberProtelExtensions(bool aUse)
void SetPlotReference(bool aFlag)
void SetExcludeEdgeLayer(bool aFlag)
WX_HTML_REPORT_PANEL * m_messagesPanel
wxStaticBoxSizer * m_HPGLOptionsSizer
void SetScaleSelection(int aSelection)
LSEQ m_layerList
Definition: dialog_plot.h:48
void SetIncludeGerberNetlistInfo(bool aUse)
void SetDXFPlotPolygonMode(bool aFlag)
double m_YScaleAdjust
Definition: dialog_plot.h:51
bool GetCreateGerberJobFile() const
virtual 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.
Definition: drc.cpp:123
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
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:118
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: common.h:177
#define OPTKEY_PLOT_Y_FINESCALE_ADJ
Definition: pcbplot.h:61
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:68
Class BOARD to handle a board.
void SetFormat(PlotFormat aFormat)
PlotFormat getPlotFormat()
wxString GetDefaultPlotExtension(PlotFormat aFormat)
Returns the default plot extension for a format.
void Check_All_Zones(wxWindow *aActiveWindow)
Function Check_All_Zones Checks for out-of-date fills and fills them if requested by the user.
PlotFormat GetFormat() const
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
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
PlotFormat
Enum PlotFormat is the set of supported output plot formats.
Definition: plotter.h:50
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:534
wxCheckBox * m_plotMirrorOpt
LSET GetEnabledLayers() const
Function GetEnabledLayers is a proxy function that calls the corresponding function in m_BoardSetting...
wxCheckBox * m_zoneFillCheck
void SetDrillMarksType(DrillMarksType aVal)
Class REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:61
wxChoice * m_plotFormatOpt
static LSET AllTechMask()
Function AllTechMask returns a mask holding all technical layers (no CU layer) on both side.
Definition: lset.cpp:746
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:237
Classes used to generate a Gerber job file in JSON.
wxStaticBoxSizer * m_SizerDXF_options
double GetScale() const
UNIT_BINDER m_trackWidthCorrection
Definition: dialog_plot.h:62
void SetA4Output(int aForce)
bool GetUseGerberX2format() const
double m_XScaleAdjust
Definition: dialog_plot.h:49
wxButton * m_sdbSizer1Apply
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
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:385
bool SetLineWidth(int aValue)
bool GetMirror() const
void SetPlotValue(bool aFlag)
Board plot function definition file.
virtual int GetValue()
Function GetValue Returns the current value in Internal Units.
wxCheckBox * m_plotSheetRef
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:79
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
int GetGerberPrecision() const
GERBER_JOBFILE_WRITER is a class used to create Gerber job file a Gerber job file stores info to make...
Class LSET is a set of PCB_LAYER_IDs.
#define OPTKEY_PLOT_X_FINESCALE_ADJ
Definition: pcbplot.h:60
PCB_EDIT_FRAME * m_parent
Definition: dialog_plot.h:46
int m_widthAdjustMaxValue
Definition: dialog_plot.h:58
bool GetUseGerberProtelExtensions() const
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
int m_TrackMinWidth
track min value for width ((min copper size value
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:485
REPORTER & Reporter()
returns the reporter object that reports to this panel
#define PLOT_MAX_SCALE
Definition: pcbplot.h:69
bool GetIncludeGerberNetlistInfo() const
int m_PSWidthAdjust
Definition: dialog_plot.h:53
const std::string GerberJobFileExtension
Definition of file extensions used in Kicad.
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
#define CONFIG_PS_FINEWIDTH_ADJ
Definition: pcbplot.h:62
void setPlotModeChoiceSelection(EDA_DRAW_MODE_T aPlotMode)
Definition: dialog_plot.h:84
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)
int m_widthAdjustMinValue
Definition: dialog_plot.h:57
wxCheckBox * m_generateGerberJobFile
Class PCB_PLOT_PARAMS handles plot parameters and options when plotting/printing a board.
wxTextCtrl * m_outputDirectoryName
void SetPlotInvisibleText(bool aFlag)
void SetScale(double aVal)
Class 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:64
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:371
void reInitDialog()
wxCheckBox * m_plotModuleRefOpt
void ConfigBaseWriteDouble(wxConfigBase *aConfig, const wxString &aKey, double aValue)
Function ConfigBaseWriteDouble This is a helper function to write doubles in config We cannot use wxC...
void SetPlotPadsOnSilkLayer(bool aFlag)
void SetPlotMode(EDA_DRAW_MODE_T aPlotMode)
UNIT_BINDER m_defaultLineWidth
Definition: dialog_plot.h:60
bool SetHPGLPenDiameter(double aValue)
Base plotter engine class.
Definition: plotter.h:97
wxBoxSizer * m_sizerButtons
wxCheckBox * m_subtractMaskFromSilk
void init_Dialog()
Definition: dialog_plot.cpp:66
wxCheckBox * m_plotNoViaOnMaskOpt
wxCheckBox * m_plotModuleValueOpt
bool GetPlotViaOnMaskLayer() const
void ShowDRCDialog(wxWindow *aParent=NULL)
Open a dialog and prompts the user, then if a test run button is clicked, runs the test(s) and create...
Definition: drc.cpp:65
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:100
wxChoice * m_drillShapeOpt
Board layer functions and definitions.
void applyPlotSettings()
void SetWidthAdjust(int aVal)
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:170
bool GetSubtractMaskFromSilk() const
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...
size_t i
Definition: json11.cpp:597
wxCheckBox * m_plotInvisibleText
double GetHPGLPenDiameter() const
Class 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:134
wxCheckBox * m_useAuxOriginCheckBox
PlotTextMode GetTextMode() const
bool GetPlotInvisibleText() const
void SetAutoScale(bool aFlag)
void SetFineScaleAdjustY(double aVal)
wxChoice * m_plotModeOpt
wxConfigBase * m_config
Definition: dialog_plot.h:47
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
wxString StringFromValue(EDA_UNITS_T aUnits, int aValue, bool aAddUnitSymbol, bool aUseMils)
Function StringFromValue returns the string from aValue according to units (inch, mm ....
Definition: base_units.cpp:210
int GetScaleSelection() const
wxCheckBox * m_excludePadsFromSilkscreen
bool GetPlotPadsOnSilkLayer() const
#define OPTKEY_PLOT_CHECK_ZONES
Definition: pcbplot.h:63
UNIT_BINDER m_defaultPenSize
Definition: dialog_plot.h:61
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
#define DLG_WINDOW_NAME
Definition: dialog_plot.h:34
wxCheckBox * m_useGerberX2Format
BOARD * GetBoard() const
bool GetUseAuxOrigin() const
wxCheckListBox * m_layerCheckListBox
DRC * GetDrcController()
Function GetDrcController.
wxStaticBoxSizer * m_PSOptionsSizer
LSET GetLayerSelection() const
LSEQ UIOrder() const
Definition: lset.cpp:803
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Function DisplayInfoMessage displays an informational message box with aMessage.
Definition: confirm.cpp:276
DrillMarksType GetDrillMarksType() const
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:244
wxBoxSizer * m_PlotOptionsSizer
bool GetPlotReference() const
DIALOG_PLOT(PCB_EDIT_FRAME *parent)
Definition: dialog_plot.cpp:41
void Enable(bool aEnable)
Function Enable Enables/diasables the label, widget and units label.
bool GetExcludeEdgeLayer() const
wxString GetAbbreviatedUnitsLabel(EDA_UNITS_T aUnit, bool aUseMils)
Get the units string for a given units type.
Definition: base_units.cpp:432
EDA_DRAW_MODE_T GetPlotMode() const
EDA_UNITS_T GetUserUnits() const override
Definition: dialog_shim.h:133