KiCad PCB EDA Suite
dialog_export_step.cpp
Go to the documentation of this file.
1 
5 /*
6  * This program source code file is part of KiCad, a free EDA CAD application.
7  *
8  * Copyright (C) 2016 Cirilo Bernardo
9  * Copyright (C) 2016-2017 KiCad Developers, see AUTHORS.txt for contributors.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, you may find one here:
23  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
24  * or you may search the http://www.gnu.org website for the version 2 license,
25  * or you may write to the Free Software Foundation, Inc.,
26  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
27  */
28 
29 #include <wx/choicdlg.h>
30 #include <wx/stdpaths.h>
31 
32 #include "wxPcbStruct.h"
33 #include "kiface_i.h"
34 #include "confirm.h"
35 
36 #include "pcbnew.h"
37 #include "class_board.h"
39 
40 #define OPTKEY_STEP_ORIGIN_OPT "STEP_Origin_Opt"
41 #define OPTKEY_STEP_UORG_UNITS "STEP_UserOriginUnits"
42 #define OPTKEY_STEP_UORG_X "STEP_UserOriginX"
43 #define OPTKEY_STEP_UORG_Y "STEP_UserOriginY"
44 #define OPTKEY_STEP_NOVIRT "STEP_NoVirtual"
45 
46 
48 {
49 public:
51  {
52  STEP_ORG_0, // absolute coordinates
53  STEP_ORG_PLOT_AXIS, // origin is plot/drill axis origin
54  STEP_ORG_GRID_AXIS, // origin is grid origin
55  STEP_ORG_BOARD_CENTER, // origin is board center
56  STEP_ORG_USER, // origin is entered by user
57  };
58 
59 private:
61  wxConfigBase* m_config;
62  // The last preference for STEP Origin:
64  bool m_noVirtual; // remember last preference for No Virtual Component
65  int m_OrgUnits; // remember last units for User Origin
66  double m_XOrg; // remember last User Origin X value
67  double m_YOrg; // remember last User Origin Y value
68 
69 public:
71 
73  {
74  GetOriginOption(); // Update m_STEP_org_opt member.
75  m_config->Write( OPTKEY_STEP_ORIGIN_OPT, (int)m_STEP_org_opt );
76 
77  m_config->Write( OPTKEY_STEP_NOVIRT, m_cbRemoveVirtual->GetValue() );
78 
79  m_config->Write( OPTKEY_STEP_UORG_UNITS, m_STEP_OrgUnitChoice->GetSelection() );
80  m_config->Write( OPTKEY_STEP_UORG_X, m_STEP_Xorg->GetValue() );
81  m_config->Write( OPTKEY_STEP_UORG_Y, m_STEP_Yorg->GetValue() );
82  }
83 
84  wxFilePickerCtrl* FilePicker()
85  {
86  return m_filePickerSTEP;
87  }
88 
90  {
91  return m_STEP_OrgUnitChoice->GetSelection();
92  }
93 
94  double GetXOrg()
95  {
96  return DoubleValueFromString( UNSCALED_UNITS, m_STEP_Xorg->GetValue() );
97  }
98 
99  double GetYOrg()
100  {
101  return DoubleValueFromString( UNSCALED_UNITS, m_STEP_Yorg->GetValue() );
102  }
103 
105 
107  {
108  return m_cbRemoveVirtual->GetValue();
109  }
110 
111  bool TransferDataFromWindow() override;
112  void onSelectOrigin( wxCommandEvent& event ) override;
113 };
114 
116  DIALOG_EXPORT_STEP_BASE( parent )
117 {
118  m_parent = parent;
120  SetFocus();
121 
123  int tmp = STEP_ORG_0;
124 
125  if( m_config->Read( OPTKEY_STEP_ORIGIN_OPT, &tmp ) )
127 
128  switch( m_STEP_org_opt )
129  {
130  default: break;
131  case STEP_ORG_PLOT_AXIS: m_cbPlotOrigin->SetValue( true ); break;
132  case STEP_ORG_GRID_AXIS: m_cbGridOrigin->SetValue( true ); break;
133  case STEP_ORG_USER: m_cbUserOrigin->SetValue( true ); break;
134  case STEP_ORG_BOARD_CENTER: m_cbBoardCenter->SetValue( true ); break;
135  }
136 
138  m_config->Read( OPTKEY_STEP_UORG_X, &m_XOrg, 0.0 );
139  m_config->Read( OPTKEY_STEP_UORG_Y, &m_YOrg, 0.0 );
141  m_cbRemoveVirtual->SetValue( m_noVirtual );
142 
143  m_STEP_OrgUnitChoice->SetSelection( m_OrgUnits );
144  wxString tmpStr;
145  tmpStr << m_XOrg;
146  m_STEP_Xorg->SetValue( tmpStr );
147  tmpStr = "";
148  tmpStr << m_YOrg;
149  m_STEP_Yorg->SetValue( tmpStr );
150 
151  m_STEP_OrgUnitChoice->Enable( m_cbUserOrigin->IsChecked() );
152  m_STEP_Xorg->Enable( m_cbUserOrigin->IsChecked() );
153  m_STEP_Yorg->Enable( m_cbUserOrigin->IsChecked() );
154 
155  m_sdbSizerOK->SetDefault();
156 
157  // Now all widgets have the size fixed, call FinishDialogSettings
159 }
160 
161 
163 {
164  if( !wxDialog::TransferDataFromWindow() )
165  return false;
166 
167  wxFileName fn = m_filePickerSTEP->GetFileName();
168 
169  if( fn.FileExists() )
170  {
171  wxString msg;
172  msg.Printf( _( "File: %s\n"
173  "already exists. Do you want overwrite this file?" ),
174  fn.GetFullPath().GetData() );
175 
176  if( wxMessageBox( msg, _( "STEP Export" ), wxYES_NO | wxICON_QUESTION, this ) == wxNO )
177  return false;
178  }
179 
180  return true;
181 }
182 
183 
184 void DIALOG_EXPORT_STEP::onSelectOrigin( wxCommandEvent& event )
185 {
186  // If a new checkbox was checked: ensure other options are disabled
187  wxCheckBox* cbList[]
188  {
190  };
191 
192  if( event.IsChecked() )
193  {
194  for( int ii = 0; cbList[ii]; ii++ )
195  {
196  if( cbList[ii] != event.GetEventObject() )
197  cbList[ii]->SetValue( false );
198  }
199  }
200 
201  // Enable/disable the user origin widgets:
202  m_STEP_OrgUnitChoice->Enable( m_cbUserOrigin->IsChecked() );
203  m_STEP_Xorg->Enable( m_cbUserOrigin->IsChecked() );
204  m_STEP_Yorg->Enable( m_cbUserOrigin->IsChecked() );
205 }
206 
207 
209 {
211 
212  if( m_cbPlotOrigin->IsChecked() )
214  else if( m_cbGridOrigin->IsChecked() )
216  else if( m_cbUserOrigin->IsChecked() )
218  else if( m_cbBoardCenter->IsChecked() )
220 
221  return m_STEP_org_opt;
222 }
223 
224 
225 void PCB_EDIT_FRAME::OnExportSTEP( wxCommandEvent& event )
226 {
227 
228  wxFileName brdFile = GetBoard()->GetFileName();
229  wxString brdName;
230 
231  if( GetScreen()->IsModify() || brdFile.GetFullPath().empty() )
232  {
233  if( !doAutoSave() )
234  {
235  DisplayErrorMessage( this,
236  _( "STEP export failed! Please save the PCB and try again" ) );
237  return;
238  }
239 
240  brdFile = GetBoard()->GetFileName();
241  brdName = GetAutoSaveFilePrefix();
242  brdName.append( brdFile.GetName() );
243  brdFile.SetName( brdName );
244  }
245 
246  brdName = "\"";
247  brdName.Append( brdFile.GetFullPath() );
248  brdName.Append( "\"" );
249 
250  // Build default output file name
251  brdFile = GetBoard()->GetFileName();
252  wxString brdExt = brdFile.GetExt();
253  brdFile.SetExt( "stp" );
254 
255  DIALOG_EXPORT_STEP dlg( this );
256  dlg.FilePicker()->SetPath( brdFile.GetFullPath() );
257 
258  if ( dlg.ShowModal() != wxID_OK )
259  return;
260 
261  wxString outputFile = dlg.FilePicker()->GetPath();
262  brdFile.SetExt( brdExt );
263  outputFile.Prepend( "\"" );
264  outputFile.Append( "\"" );
265 
267  double xOrg = 0.0;
268  double yOrg = 0.0;
269 
270  wxFileName appK2S( wxStandardPaths::Get().GetExecutablePath() );
271  appK2S.SetName( "kicad2step" );
272 
273  wxString cmdK2S = "\"";
274  cmdK2S.Append( appK2S.GetFullPath() );
275  cmdK2S.Append( "\"" );
276 
277  if( dlg.GetNoVirtOption() )
278  cmdK2S.Append( " --no-virtual" );
279 
280  switch( orgOpt )
281  {
283  break;
284 
286  cmdK2S.Append( " --drill-origin" );
287  break;
288 
290  cmdK2S.Append( " --grid-origin" );
291  break;
292 
294  {
295  xOrg = dlg.GetXOrg();
296  yOrg = dlg.GetYOrg();
297 
298  if( dlg.GetOrgUnitsChoice() == 1 )
299  {
300  // selected reference unit is in inches, and STEP units are mm
301  xOrg *= 25.4;
302  yOrg *= 25.4;
303  }
304 
306  cmdK2S.Append( wxString::Format( " --user-origin %.6fx%.6f", xOrg, yOrg ) );
307  }
308  break;
309 
311  {
312  EDA_RECT bbox = GetBoard()->ComputeBoundingBox( true );
313  xOrg = Iu2Millimeter( bbox.GetCenter().x );
314  yOrg = Iu2Millimeter( bbox.GetCenter().y );
316  cmdK2S.Append( wxString::Format( " --user-origin %.6fx%.6f", xOrg, yOrg ) );
317  }
318  break;
319  }
320 
321  cmdK2S.Append( " -f -o " );
322  cmdK2S.Append( outputFile );
323 
324  cmdK2S.Append( " " );
325  cmdK2S.Append( brdName );
326 
327  int result = 0;
328 
329  do
330  {
331  wxBusyCursor dummy;
332  result = wxExecute( cmdK2S, wxEXEC_SYNC | wxEXEC_HIDE_CONSOLE );
333  } while( 0 );
334 
335  if( result )
336  {
337  DisplayErrorMessage( this, _( "Unable to create STEP file. Check that the board has a "
338  "valid outline and models." ), cmdK2S );
339  }
340 }
bool TransferDataFromWindow() override
#define OPTKEY_STEP_UORG_X
static wxString GetAutoSaveFilePrefix()
Function GetAutoSaveFilePrefix.
Class LOCALE_IO is a class that can be instantiated within a scope in which you are expecting excepti...
Definition: common.h:165
#define OPTKEY_STEP_NOVIRT
This file is part of the common library.
EDA_RECT ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Function ComputeBoundingBox calculates the bounding box containing all board items (or board edge seg...
virtual bool doAutoSave() override
Function doAutoSave performs auto save when the board has been modified and not saved within the auto...
Class BOARD to handle a board.
void OnExportSTEP(wxCommandEvent &event)
Function OnExportSTEP Exports the current BOARD to a STEP assembly.
PCB_EDIT_FRAME * m_parent
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
#define OPTKEY_STEP_UORG_UNITS
BOARD * GetBoard() const
#define OPTKEY_STEP_ORIGIN_OPT
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
STEP_ORG_OPT GetOriginOption()
wxFilePickerCtrl * m_filePickerSTEP
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString aExtraInfo)
Function DisplayErrorMessage displays an error message with aMessage.
Definition: confirm.cpp:87
const wxString & GetFileName() const
Definition: class_board.h:234
void onSelectOrigin(wxCommandEvent &event) override
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
wxFilePickerCtrl * FilePicker()
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
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 DIALOG_EXPORT_STEP_BASE.
Class EDA_RECT handles the component boundary box.
PCB_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
#define OPTKEY_STEP_UORG_Y
DIALOG_EXPORT_STEP(PCB_EDIT_FRAME *parent)
double DoubleValueFromString(EDA_UNITS_T aUnits, const wxString &aTextValue)
Function DoubleValueFromString converts aTextValue to a double.
Definition: base_units.cpp:301
const wxPoint GetCenter() const