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>
34 #include <bitmaps.h>
35 #include <class_board.h>
36 #include <dialog_plot.h>
37 #include <dialog_gendrill.h>
38 #include <wx_html_report_panel.h>
39 #include <tool/tool_manager.h>
40 #include <tools/drc.h>
41 #include <tools/zone_filler_tool.h>
42 #include <math/util.h> // for KiROUND
43 
44 
46  DIALOG_PLOT_BASE( aParent ), m_parent( aParent ),
47  m_defaultLineWidth( aParent, m_lineWidthLabel, m_lineWidthCtrl, m_lineWidthUnits, true ),
48  m_defaultPenSize( aParent, m_hpglPenLabel, m_hpglPenCtrl, m_hpglPenUnits, true ),
49  m_trackWidthCorrection( aParent, m_widthAdjustLabel, m_widthAdjustCtrl, m_widthAdjustUnits, true )
50 {
51  SetName( DLG_WINDOW_NAME );
53  m_plotOpts = aParent->GetPlotSettings();
54  init_Dialog();
55 
56  // We use a sdbSizer to get platform-dependent ordering of the action buttons, but
57  // that requires us to correct the button labels here.
58  m_sdbSizer1OK->SetLabel( _( "Plot" ) );
59  m_sdbSizer1Apply->SetLabel( _( "Generate Drill Files..." ) );
60  m_sdbSizer1Cancel->SetLabel( _( "Close" ) );
61  m_sizerButtons->Layout();
62 
63  m_sdbSizer1OK->SetDefault();
64 
65  GetSizer()->Fit( this );
66  GetSizer()->SetSizeHints( this );
67 }
68 
69 
71 {
72  BOARD* board = m_parent->GetBoard();
73  wxFileName fileName;
74 
77 
78  bool checkZones;
79  m_config->Read( OPTKEY_PLOT_CHECK_ZONES, &checkZones, true );
80  m_zoneFillCheck->SetValue( checkZones );
81 
82  m_browseButton->SetBitmap( KiBitmap( folder_xpm ) );
83 
84  // m_PSWidthAdjust is stored in mm in user config
85  double dtmp;
86  m_config->Read( CONFIG_PS_FINEWIDTH_ADJ, &dtmp, 0 );
87  m_PSWidthAdjust = KiROUND( dtmp * 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:
98  m_plotFormatOpt->SetSelection( 0 );
99  break;
100  case PLOT_FORMAT::POST:
101  m_plotFormatOpt->SetSelection( 1 );
102  break;
103  case PLOT_FORMAT::SVG:
104  m_plotFormatOpt->SetSelection( 2 );
105  break;
106  case PLOT_FORMAT::DXF:
107  m_plotFormatOpt->SetSelection( 3 );
108  break;
109  case PLOT_FORMAT::HPGL:
110  m_plotFormatOpt->SetSelection( 4 );
111  break;
112  case PLOT_FORMAT::PDF:
113  m_plotFormatOpt->SetSelection( 5 );
114  break;
115  }
116 
117  // Set units and value for HPGL pen size (this param is in mils).
119 
121 
122  // Test for a reasonable scale value. Set to 1 if problem
126 
129 
130  // Test for a reasonable PS width correction value. Set to 0 if problem.
131  if( m_PSWidthAdjust < m_widthAdjustMinValue || m_PSWidthAdjust > m_widthAdjustMaxValue )
132  m_PSWidthAdjust = 0.;
133 
135 
138 
139  // Could devote a PlotOrder() function in place of UIOrder().
140  m_layerList = board->GetEnabledLayers().UIOrder();
141 
142  // Populate the check list box by all enabled layers names
143  for( LSEQ seq = m_layerList; seq; ++seq )
144  {
145  PCB_LAYER_ID layer = *seq;
146 
147  int checkIndex = m_layerCheckListBox->Append( board->GetLayerName( layer ) );
148 
149  if( m_plotOpts.GetLayerSelection()[layer] )
150  m_layerCheckListBox->Check( checkIndex );
151  }
152 
153  // Option for using proper Gerber extensions. Note also Protel extensions are
154  // a broken feature. However, for now, we need to handle it.
156 
157  // Option for including Gerber attributes, from Gerber X2 format, in the output
158  // In X1 format, they will be added as comments
160 
161  // Option for including Gerber netlist info (from Gerber X2 format) in the output
163 
164  // Option to generate a Gerber job file
166 
167  // Gerber precision for coordinates
168  m_coordFormatCtrl->SetSelection( m_plotOpts.GetGerberPrecision() == 5 ? 0 : 1 );
169 
170  // Option for excluding contents of "Edges Pcb" layer
172 
173  // Option to exclude pads from silkscreen layers
175 
176  // Option to tent vias
178 
179  // Option to use aux origin
181 
182  // Option to plot page references:
184 
185  // Options to plot texts on footprints
189 
190  // Options to plot pads and vias holes
191  m_drillShapeOpt->SetSelection( m_plotOpts.GetDrillMarksType() );
192 
193  // Scale option
194  m_scaleOpt->SetSelection( m_plotOpts.GetScaleSelection() );
195 
196  // Plot mode
198 
199  // DXF outline mode
201 
202  // DXF text mode
204 
205  // DXF units selection
206  m_DXF_plotUnits->SetSelection( static_cast<int>( m_plotOpts.GetDXFPlotUnits() ) );
207 
208  // Plot mirror option
209  m_plotMirrorOpt->SetValue( m_plotOpts.GetMirror() );
210 
211  // Put vias on mask layer
213 
214  // Initialize a few other parameters, which can also be modified
215  // from the drill dialog
216  reInitDialog();
217 
218  // Update options values:
219  wxCommandEvent cmd_event;
220  SetPlotFormat( cmd_event );
221  OnSetScaleOpt( cmd_event );
222 }
223 
224 
226 {
227  // after calling drill dialog, some parameters can be modified.
228  // update them
229 
230  // Output directory
232 
233  // Origin of coordinates:
235 }
236 
237 
238 // A helper function to show a popup menu, when the dialog is right clicked.
239 void DIALOG_PLOT::OnRightClick( wxMouseEvent& event )
240 {
241  PopupMenu( m_popMenu );
242 }
243 
244 
245 // Select or deselect groups of layers in the layers list:
246 void DIALOG_PLOT::OnPopUpLayers( wxCommandEvent& event )
247 {
248  // Build a list of layers for usual fabrication:
249  // copper layers + tech layers without courtyard
250  LSET fab_layer_set = ( LSET::AllCuMask() | LSET::AllTechMask() )
251  & ~LSET( 2, B_CrtYd, F_CrtYd );
252 
253  switch( event.GetId() )
254  {
255  case ID_LAYER_FAB: // Select layers usually needed to build a board
256  for( unsigned i = 0; i < m_layerList.size(); i++ )
257  {
258  LSET layermask( m_layerList[ i ] );
259 
260  if( ( layermask & fab_layer_set ).any() )
261  m_layerCheckListBox->Check( i, true );
262  else
263  m_layerCheckListBox->Check( i, false );
264  }
265  break;
266 
268  for( unsigned i = 0; i < m_layerList.size(); i++ )
269  {
270  if( IsCopperLayer( m_layerList[i] ) )
271  m_layerCheckListBox->Check( i, true );
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, false );
280  }
281  break;
282 
284  for( unsigned i = 0; i < m_layerList.size(); i++ )
285  m_layerCheckListBox->Check( i, true );
286  break;
287 
289  for( unsigned i = 0; i < m_layerList.size(); i++ )
290  m_layerCheckListBox->Check( i, false );
291  break;
292 
293  default:
294  break;
295  }
296 }
297 
298 
299 void DIALOG_PLOT::CreateDrillFile( wxCommandEvent& event )
300 {
301  // Be sure drill file use the same settings (axis option, plot directory)
302  // as plot files:
304 
305  DIALOG_GENDRILL dlg( m_parent, this );
306  dlg.ShowModal();
307 
308  // a few plot settings can be modified: take them in account
310  reInitDialog();
311 }
312 
313 
314 void DIALOG_PLOT::OnChangeDXFPlotMode( wxCommandEvent& event )
315 {
316  // m_DXF_plotTextStrokeFontOpt is disabled if m_DXF_plotModeOpt
317  // is checked (plot in DXF polygon mode)
318  m_DXF_plotTextStrokeFontOpt->Enable( !m_DXF_plotModeOpt->GetValue() );
319 
320  // if m_DXF_plotTextStrokeFontOpt option is disabled (plot DXF in polygon mode),
321  // force m_DXF_plotTextStrokeFontOpt to true to use Pcbnew stroke font
322  if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() )
323  m_DXF_plotTextStrokeFontOpt->SetValue( true );
324 }
325 
326 
327 void DIALOG_PLOT::OnSetScaleOpt( wxCommandEvent& event )
328 {
329  /* Disable sheet reference for scale != 1:1 */
330  bool scale1 = ( m_scaleOpt->GetSelection() == 1 );
331 
332  m_plotSheetRef->Enable( scale1 );
333 
334  if( !scale1 )
335  m_plotSheetRef->SetValue( false );
336 }
337 
338 
339 void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
340 {
341  // Build the absolute path of current output plot directory
342  // to preselect it when opening the dialog.
343  wxFileName fn( m_outputDirectoryName->GetValue() );
344  wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() );
345 
346  wxDirDialog dirDialog( this, _( "Select Output Directory" ), path );
347 
348  if( dirDialog.ShowModal() == wxID_CANCEL )
349  return;
350 
351  wxFileName dirName = wxFileName::DirName( dirDialog.GetPath() );
352 
353  fn = Prj().AbsolutePath( m_parent->GetBoard()->GetFileName() );
354  wxString defaultPath = fn.GetPathWithSep();
355  wxString msg;
356  msg.Printf( _( "Do you want to use a path relative to\n\"%s\"" ),
357  GetChars( defaultPath ) );
358 
359  wxMessageDialog dialog( this, msg, _( "Plot Output Directory" ),
360  wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
361 
362  if( dialog.ShowModal() == wxID_YES )
363  {
364  if( !dirName.MakeRelativeTo( defaultPath ) )
365  wxMessageBox( _( "Cannot make path relative (target volume different from file volume)!" ),
366  _( "Plot Output Directory" ), wxOK | wxICON_ERROR );
367  }
368 
369  m_outputDirectoryName->SetValue( dirName.GetFullPath() );
370 }
371 
372 
374 {
375  // plot format id's are ordered like displayed in m_plotFormatOpt
378 
379  return plotFmt[m_plotFormatOpt->GetSelection()];
380 }
381 
382 
383 // Enable or disable widgets according to the plot format selected
384 // and clear also some optional values
385 void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
386 {
387  // this option exist only in DXF format:
389 
390  switch( getPlotFormat() )
391  {
392  case PLOT_FORMAT::PDF:
393  case PLOT_FORMAT::SVG:
394  m_drillShapeOpt->Enable( true );
395  m_plotModeOpt->Enable( false );
397  m_plotMirrorOpt->Enable( true );
398  m_useAuxOriginCheckBox->Enable( false );
399  m_useAuxOriginCheckBox->SetValue( false );
400  m_defaultLineWidth.Enable( true );
401  m_defaultPenSize.Enable( false );
402  m_excludeEdgeLayerOpt->Enable( true );
403  m_scaleOpt->Enable( false );
404  m_scaleOpt->SetSelection( 1 );
405  m_fineAdjustXCtrl->Enable( false );
406  m_fineAdjustYCtrl->Enable( false );
408  m_plotPSNegativeOpt->Enable( true );
409  m_forcePSA4OutputOpt->Enable( false );
410  m_forcePSA4OutputOpt->SetValue( false );
411 
416  break;
417 
418  case PLOT_FORMAT::POST:
419  m_drillShapeOpt->Enable( true );
420  m_plotModeOpt->Enable( true );
421  m_plotMirrorOpt->Enable( true );
422  m_useAuxOriginCheckBox->Enable( false );
423  m_useAuxOriginCheckBox->SetValue( false );
424  m_defaultLineWidth.Enable( true );
425  m_defaultPenSize.Enable( false );
426  m_excludeEdgeLayerOpt->Enable( true );
427  m_scaleOpt->Enable( true );
428  m_fineAdjustXCtrl->Enable( true );
429  m_fineAdjustYCtrl->Enable( true );
431  m_plotPSNegativeOpt->Enable( true );
432  m_forcePSA4OutputOpt->Enable( true );
433 
438  break;
439 
440  case PLOT_FORMAT::GERBER:
441  m_drillShapeOpt->Enable( false );
442  m_drillShapeOpt->SetSelection( 0 );
443  m_plotModeOpt->Enable( false );
445  m_plotMirrorOpt->Enable( false );
446  m_plotMirrorOpt->SetValue( false );
447  m_useAuxOriginCheckBox->Enable( true );
448  m_defaultLineWidth.Enable( true );
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( false );
457  m_plotPSNegativeOpt->SetValue( false );
458  m_forcePSA4OutputOpt->Enable( false );
459  m_forcePSA4OutputOpt->SetValue( false );
460 
465  break;
466 
467  case PLOT_FORMAT::HPGL:
468  m_drillShapeOpt->Enable( true );
469  m_plotModeOpt->Enable( true );
470  m_plotMirrorOpt->Enable( true );
471  m_useAuxOriginCheckBox->Enable( false );
472  m_useAuxOriginCheckBox->SetValue( false );
473  m_defaultLineWidth.Enable( false );
474  m_defaultPenSize.Enable( true );
475  m_excludeEdgeLayerOpt->Enable( true );
476  m_scaleOpt->Enable( true );
477  m_fineAdjustXCtrl->Enable( false );
478  m_fineAdjustYCtrl->Enable( false );
480  m_plotPSNegativeOpt->SetValue( false );
481  m_plotPSNegativeOpt->Enable( false );
482  m_forcePSA4OutputOpt->Enable( true );
483 
488  break;
489 
490  case PLOT_FORMAT::DXF:
491  m_drillShapeOpt->Enable( true );
492  m_plotModeOpt->Enable( false );
494  m_plotMirrorOpt->Enable( false );
495  m_plotMirrorOpt->SetValue( false );
496  m_useAuxOriginCheckBox->Enable( true );
497  m_defaultLineWidth.Enable( false );
498  m_defaultPenSize.Enable( false );
499  m_excludeEdgeLayerOpt->Enable( true );
500  m_scaleOpt->Enable( false );
501  m_scaleOpt->SetSelection( 1 );
502  m_fineAdjustXCtrl->Enable( false );
503  m_fineAdjustYCtrl->Enable( false );
505  m_plotPSNegativeOpt->Enable( false );
506  m_plotPSNegativeOpt->SetValue( false );
507  m_forcePSA4OutputOpt->Enable( false );
508  m_forcePSA4OutputOpt->SetValue( false );
509 
514 
515  OnChangeDXFPlotMode( event );
516  break;
517 
519  break;
520  }
521 
522  /* Update the interlock between scale and frame reference
523  * (scaling would mess up the frame border...) */
524  OnSetScaleOpt( event );
525 
526  Layout();
527  m_MainSizer->SetSizeHints( this );
528 }
529 
530 
531 // A helper function to "clip" aValue between aMin and aMax
532 // and write result in * aResult
533 // return false if clipped, true if aValue is just copied into * aResult
534 static bool setDouble( double* aResult, double aValue, double aMin, double aMax )
535 {
536  if( aValue < aMin )
537  {
538  *aResult = aMin;
539  return false;
540  }
541  else if( aValue > aMax )
542  {
543  *aResult = aMax;
544  return false;
545  }
546 
547  *aResult = aValue;
548  return true;
549 }
550 
551 
552 static bool setInt( int* aResult, int aValue, int aMin, int aMax )
553 {
554  if( aValue < aMin )
555  {
556  *aResult = aMin;
557  return false;
558  }
559  else if( aValue > aMax )
560  {
561  *aResult = aMax;
562  return false;
563  }
564 
565  *aResult = aValue;
566  return true;
567 }
568 
569 
571 {
572  REPORTER& reporter = m_messagesPanel->Reporter();
573  int sel;
574  PCB_PLOT_PARAMS tempOptions;
575 
576  tempOptions.SetExcludeEdgeLayer( m_excludeEdgeLayerOpt->GetValue() );
577  tempOptions.SetSubtractMaskFromSilk( m_subtractMaskFromSilk->GetValue() );
578  tempOptions.SetPlotFrameRef( m_plotSheetRef->GetValue() );
579  tempOptions.SetPlotPadsOnSilkLayer( !m_excludePadsFromSilkscreen->GetValue() );
580  tempOptions.SetUseAuxOrigin( m_useAuxOriginCheckBox->GetValue() );
581  tempOptions.SetPlotValue( m_plotModuleValueOpt->GetValue() );
582  tempOptions.SetPlotReference( m_plotModuleRefOpt->GetValue() );
583  tempOptions.SetPlotInvisibleText( m_plotInvisibleText->GetValue() );
584  tempOptions.SetScaleSelection( m_scaleOpt->GetSelection() );
585 
586  sel = m_drillShapeOpt->GetSelection();
587  tempOptions.SetDrillMarksType( static_cast<PCB_PLOT_PARAMS::DrillMarksType>( sel ) );
588 
589  tempOptions.SetMirror( m_plotMirrorOpt->GetValue() );
590  tempOptions.SetPlotMode( m_plotModeOpt->GetSelection() == 1 ? SKETCH : FILLED );
591  tempOptions.SetDXFPlotPolygonMode( m_DXF_plotModeOpt->GetValue() );
592 
593  sel = m_DXF_plotUnits->GetSelection();
594  tempOptions.SetDXFPlotUnits( static_cast<DXF_PLOTTER::DXF_UNITS>( sel ) );
595 
596  tempOptions.SetPlotViaOnMaskLayer( m_plotNoViaOnMaskOpt->GetValue() );
597 
598  if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() ) // Currently, only DXF supports this option
599  tempOptions.SetTextMode( PLOT_TEXT_MODE::DEFAULT );
600  else
603 
604  // Update settings from text fields. Rewrite values back to the fields,
605  // since the values may have been constrained by the setters.
606  wxString msg;
607 
608  // read HPLG pen size (this param is stored in mils)
609  // However, due to issues when converting this value from or to mm
610  // that can slightly change the value, update this param only if it
611  // is in use
613  {
614  if( !tempOptions.SetHPGLPenDiameter( m_defaultPenSize.GetValue() / IU_PER_MILS ) )
615  {
617  msg.Printf( _( "HPGL pen size constrained." ) );
618  reporter.Report( msg, REPORTER::RPT_INFO );
619  }
620  }
621  else // keep the last value (initial value if no HPGL plot made)
623 
624  // Default linewidth
625  if( !tempOptions.SetLineWidth( m_defaultLineWidth.GetValue() ) )
626  {
627  m_defaultLineWidth.SetValue( tempOptions.GetLineWidth() );
628  msg.Printf( _( "Default line width constrained." ) );
629  reporter.Report( msg, REPORTER::RPT_INFO );
630  }
631 
632  // X scale
633  double tmpDouble;
634  msg = m_fineAdjustXCtrl->GetValue();
635  msg.ToDouble( &tmpDouble );
636 
637  if( !setDouble( &m_XScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
638  {
639  msg.Printf( wxT( "%f" ), m_XScaleAdjust );
640  m_fineAdjustXCtrl->SetValue( msg );
641  msg.Printf( _( "X scale constrained." ) );
642  reporter.Report( msg, REPORTER::RPT_INFO );
643  }
644 
646 
647  // Y scale
648  msg = m_fineAdjustYCtrl->GetValue();
649  msg.ToDouble( &tmpDouble );
650 
651  if( !setDouble( &m_YScaleAdjust, tmpDouble, PLOT_MIN_SCALE, PLOT_MAX_SCALE ) )
652  {
653  msg.Printf( wxT( "%f" ), m_YScaleAdjust );
654  m_fineAdjustYCtrl->SetValue( msg );
655  msg.Printf( _( "Y scale constrained." ) );
656  reporter.Report( msg, REPORTER::RPT_INFO );
657  }
658 
660 
661  m_config->Write( OPTKEY_PLOT_CHECK_ZONES, m_zoneFillCheck->GetValue() );
662 
663  // PS Width correction
666  {
668  msg.Printf( _( "Width correction constrained. "
669  "The reasonable width correction value must be in a range of "
670  " [%s; %s] (%s) for current design rules." ),
674  reporter.Report( msg, REPORTER::RPT_WARNING );
675  }
676 
677  // Store m_PSWidthAdjust in mm in user config
679  (double)m_PSWidthAdjust / IU_PER_MM );
680 
681  tempOptions.SetFormat( getPlotFormat() );
682 
683  tempOptions.SetUseGerberProtelExtensions( m_useGerberExtensions->GetValue() );
684  tempOptions.SetUseGerberX2format( m_useGerberX2Format->GetValue() );
685  tempOptions.SetIncludeGerberNetlistInfo( m_useGerberNetAttributes->GetValue() );
686  tempOptions.SetCreateGerberJobFile( m_generateGerberJobFile->GetValue() );
687 
688  tempOptions.SetGerberPrecision( m_coordFormatCtrl->GetSelection() == 0 ? 5 : 6 );
689 
690  LSET selectedLayers;
691  for( unsigned i = 0; i < m_layerList.size(); i++ )
692  {
693  if( m_layerCheckListBox->IsChecked( i ) )
694  selectedLayers.set( m_layerList[i] );
695  }
696  // Get a list of copper layers that aren't being used by inverting enabled layers.
697  LSET disabledCopperLayers = LSET::AllCuMask() & ~m_parent->GetBoard()->GetEnabledLayers();
698  // Enable all of the disabled copper layers.
699  // If someone enables more copper layers they will be selected by default.
700  selectedLayers = selectedLayers | disabledCopperLayers;
701  tempOptions.SetLayerSelection( selectedLayers );
702 
703  tempOptions.SetNegative( m_plotPSNegativeOpt->GetValue() );
704  tempOptions.SetA4Output( m_forcePSA4OutputOpt->GetValue() );
705 
706  // Set output directory and replace backslashes with forward ones
707  wxString dirStr;
708  dirStr = m_outputDirectoryName->GetValue();
709  dirStr.Replace( wxT( "\\" ), wxT( "/" ) );
710  tempOptions.SetOutputDirectory( dirStr );
711 
712  if( !m_plotOpts.IsSameAs( tempOptions, false ) )
713  {
714  // First, mark board as modified only for parameters saved in file
715  if( !m_plotOpts.IsSameAs( tempOptions, true ) )
716  m_parent->OnModify();
717 
718  // Now, save any change, for the session
719  m_parent->SetPlotSettings( tempOptions );
720  m_plotOpts = tempOptions;
721  }
722 }
723 
724 
725 void DIALOG_PLOT::OnGerberX2Checked( wxCommandEvent& event )
726 {
727  // Currently: do nothing
728 }
729 
730 
731 void DIALOG_PLOT::Plot( wxCommandEvent& event )
732 {
733  BOARD* board = m_parent->GetBoard();
734 
736 
737  // If no layer selected, we have nothing plotted.
738  // Prompt user if it happens because he could think there is a bug in Pcbnew.
739  if( !m_plotOpts.GetLayerSelection().any() )
740  {
741  DisplayError( this, _( "No layer selected, Nothing to plot" ) );
742  return;
743  }
744 
745  // Create output directory if it does not exist (also transform it in
746  // absolute form). Bail if it fails
747  wxFileName outputDir = wxFileName::DirName( m_plotOpts.GetOutputDirectory() );
748  wxString boardFilename = m_parent->GetBoard()->GetFileName();
749  REPORTER& reporter = m_messagesPanel->Reporter();
750 
751  if( !EnsureFileDirectoryExists( &outputDir, boardFilename, &reporter ) )
752  {
753  wxString msg;
754  msg.Printf( _( "Could not write plot files to folder \"%s\"." ),
755  GetChars( outputDir.GetPath() ) );
756  DisplayError( this, msg );
757  return;
758  }
759 
760  if( m_zoneFillCheck->GetValue() )
761  m_parent->GetToolManager()->GetTool<ZONE_FILLER_TOOL>()->CheckAllZones( this );
762 
763  m_plotOpts.SetAutoScale( false );
764  m_plotOpts.SetScale( 1 );
765 
766  switch( m_plotOpts.GetScaleSelection() )
767  {
768  default:
769  break;
770 
771  case 0: // Autoscale option
772  m_plotOpts.SetAutoScale( true );
773  break;
774 
775  case 2: // 3:2 option
776  m_plotOpts.SetScale( 1.5 );
777  break;
778 
779  case 3: // 2:1 option
780  m_plotOpts.SetScale( 2 );
781  break;
782 
783  case 4: // 3:1 option
784  m_plotOpts.SetScale( 3 );
785  break;
786  }
787 
788  /* If the scale factor edit controls are disabled or the scale value
789  * is 0, don't adjust the base scale factor. This fixes a bug when
790  * the default scale adjust is initialized to 0 and saved in program
791  * settings resulting in a divide by zero fault.
792  */
794  {
795  if( m_XScaleAdjust != 0.0 )
797 
798  if( m_YScaleAdjust != 0.0 )
800 
802  }
803 
804  wxString file_ext( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) );
805 
806  // Test for a reasonable scale value
807  // XXX could this actually happen? isn't it constrained in the apply
808  // function?
810  DisplayInfoMessage( this, _( "Warning: Scale option set to a very small value" ) );
811 
813  DisplayInfoMessage( this, _( "Warning: Scale option set to a very large value" ) );
814 
815  GERBER_JOBFILE_WRITER jobfile_writer( board, &reporter );
816 
817  // Save the current plot options in the board
819 
820  wxBusyCursor dummy;
821 
822  for( LSEQ seq = m_plotOpts.GetLayerSelection().UIOrder(); seq; ++seq )
823  {
824  PCB_LAYER_ID layer = *seq;
825 
826  // All copper layers that are disabled are actually selected
827  // This is due to wonkyness in automatically selecting copper layers
828  // for plotting when adding more than two layers to a board.
829  // If plot options become accessible to the layers setup dialog
830  // please move this functionality there!
831  // This skips a copper layer if it is actually disabled on the board.
832  if( ( LSET::AllCuMask() & ~board->GetEnabledLayers() )[layer] )
833  continue;
834 
835  // Pick the basename from the board file
836  wxFileName fn( boardFilename );
837 
838  // Use Gerber Extensions based on layer number
839  // (See http://en.wikipedia.org/wiki/Gerber_File)
841  file_ext = GetGerberProtelExtension( layer );
842 
843  BuildPlotFileName( &fn, outputDir.GetPath(), board->GetLayerName( layer ), file_ext );
844  wxString fullname = fn.GetFullName();
845  jobfile_writer.AddGbrFile( layer, fullname );
846 
847  LOCALE_IO toggle;
848 
849  PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, fn.GetFullPath(), wxEmptyString );
850 
851  // Print diags in messages box:
852  wxString msg;
853 
854  if( plotter )
855  {
856  PlotOneBoardLayer( board, plotter, layer, m_plotOpts );
857  plotter->EndPlot();
858  delete plotter;
859 
860  msg.Printf( _( "Plot file \"%s\" created." ), fn.GetFullPath() );
861  reporter.Report( msg, REPORTER::RPT_ACTION );
862  }
863  else
864  {
865  msg.Printf( _( "Unable to create file \"%s\"." ), fn.GetFullPath() );
866  reporter.Report( msg, REPORTER::RPT_ERROR );
867  }
868 
869  wxSafeYield(); // displays report message.
870  }
871 
873  {
874  // Pick the basename from the board file
875  wxFileName fn( boardFilename );
876  // Build gerber job file from basename
877  BuildPlotFileName( &fn, outputDir.GetPath(), "job", GerberJobFileExtension );
878  jobfile_writer.CreateJobFile( fn.GetFullPath() );
879  }
880 }
881 
882 
883 void DIALOG_PLOT::onRunDRC( wxCommandEvent& event )
884 {
885  PCB_EDIT_FRAME* parent = dynamic_cast<PCB_EDIT_FRAME*>( GetParent() );
886 
887  if( parent )
888  {
889  DRC* drcTool = parent->GetToolManager()->GetTool<DRC>();
890 
891  // First close an existing dialog if open
892  // (low probability, but can happen)
893  drcTool->DestroyDRCDialog( wxID_OK );
894 
895  // Open a new drc dialod, with the right parent frame, and in Modal Mode
896  drcTool->ShowDRCDialog( this );
897  }
898 }
899 
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:236
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)
const BITMAP_OPAQUE folder_xpm[1]
Definition: folder.cpp:20
void SetDXFPlotPolygonMode(bool aFlag)
double m_YScaleAdjust
Definition: dialog_plot.h:51
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:90
#define OPTKEY_PLOT_Y_FINESCALE_ADJ
Definition: pcbplot.h:62
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:69
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
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:219
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:530
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: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:756
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:215
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
wxString GetAbbreviatedUnitsLabel(EDA_UNITS aUnit, bool aUseMils)
Get the units string for a given units type.
Definition: base_units.cpp:452
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:386
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: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
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
#define OPTKEY_PLOT_X_FINESCALE_ADJ
Definition: pcbplot.h:61
PCB_EDIT_FRAME * m_parent
Definition: dialog_plot.h:46
int m_widthAdjustMaxValue
Definition: dialog_plot.h:58
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:50
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:456
REPORTER & Reporter()
returns the reporter object that reports to this panel
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
#define PLOT_MAX_SCALE
Definition: pcbplot.h:70
bool GetIncludeGerberNetlistInfo() const
int m_PSWidthAdjust
Definition: dialog_plot.h:53
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
#define CONFIG_PS_FINEWIDTH_ADJ
Definition: pcbplot.h:63
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)
wxChoice * m_DXF_plotUnits
void SetFormat(PLOT_FORMAT aFormat)
int m_widthAdjustMinValue
Definition: dialog_plot.h:57
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: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:373
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:103
wxBoxSizer * m_sizerButtons
wxCheckBox * m_subtractMaskFromSilk
void init_Dialog()
Definition: dialog_plot.cpp:70
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 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:160
bool GetSubtractMaskFromSilk() const
#define _(s)
Definition: 3d_actions.cpp:31
Design Rule Checker object that performs all the DRC tests.
Definition: drc.h:186
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
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.
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
#define OPTKEY_PLOT_CHECK_ZONES
Definition: pcbplot.h:64
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
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:264
DrillMarksType GetDrillMarksType() const
wxBoxSizer * m_PlotOptionsSizer
bool GetPlotReference() const
DIALOG_PLOT(PCB_EDIT_FRAME *parent)
Definition: dialog_plot.cpp:45
#define DLG_WINDOW_NAME
void Enable(bool aEnable)
Function Enable Enables/diasables the label, widget and units label.
bool GetExcludeEdgeLayer() const
EDA_DRAW_MODE_T GetPlotMode() const