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-2018 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 "pcb_edit_frame.h"
33 #include "kiface_i.h"
34 #include "confirm.h"
35 
36 #include "pcbnew.h"
37 #include "class_board.h"
39 #include <widgets/text_ctrl_eval.h>
40 
41 #define OPTKEY_STEP_ORIGIN_OPT "STEP_Origin_Opt"
42 #define OPTKEY_STEP_UORG_UNITS "STEP_UserOriginUnits"
43 #define OPTKEY_STEP_UORG_X "STEP_UserOriginX"
44 #define OPTKEY_STEP_UORG_Y "STEP_UserOriginY"
45 #define OPTKEY_STEP_NOVIRT "STEP_NoVirtual"
46 
47 
49 {
50 public:
52  {
53  STEP_ORG_0, // absolute coordinates
54  STEP_ORG_PLOT_AXIS, // origin is plot/drill axis origin
55  STEP_ORG_GRID_AXIS, // origin is grid origin
56  STEP_ORG_BOARD_CENTER, // origin is board center
57  STEP_ORG_USER, // origin is entered by user
58  };
59 
60 private:
62  wxConfigBase* m_config;
63  // The last preference for STEP Origin:
65  bool m_noVirtual; // remember last preference for No Virtual Component
66  int m_OrgUnits; // remember last units for User Origin
67  double m_XOrg; // remember last User Origin X value
68  double m_YOrg; // remember last User Origin Y value
69 
70 protected:
71  void onUpdateUnits( wxUpdateUIEvent& aEvent ) override;
72  void onUpdateXPos( wxUpdateUIEvent& aEvent ) override;
73  void onUpdateYPos( wxUpdateUIEvent& aEvent ) override;
74 
75 public:
77 
79  {
80  GetOriginOption(); // Update m_STEP_org_opt member.
81  m_config->Write( OPTKEY_STEP_ORIGIN_OPT, (int)m_STEP_org_opt );
82 
83  m_config->Write( OPTKEY_STEP_NOVIRT, m_cbRemoveVirtual->GetValue() );
84 
85  m_config->Write( OPTKEY_STEP_UORG_UNITS, m_STEP_OrgUnitChoice->GetSelection() );
86  m_config->Write( OPTKEY_STEP_UORG_X, m_STEP_Xorg->GetValue() );
87  m_config->Write( OPTKEY_STEP_UORG_Y, m_STEP_Yorg->GetValue() );
88  }
89 
90  wxFilePickerCtrl* FilePicker()
91  {
92  return m_filePickerSTEP;
93  }
94 
96  {
97  return m_STEP_OrgUnitChoice->GetSelection();
98  }
99 
100  double GetXOrg()
101  {
102  return DoubleValueFromString( UNSCALED_UNITS, m_STEP_Xorg->GetValue() );
103  }
104 
105  double GetYOrg()
106  {
107  return DoubleValueFromString( UNSCALED_UNITS, m_STEP_Yorg->GetValue() );
108  }
109 
111 
113  {
114  return m_cbRemoveVirtual->GetValue();
115  }
116 
117  bool TransferDataFromWindow() override;
118 };
119 
120 
122  DIALOG_EXPORT_STEP_BASE( parent )
123 {
124  m_parent = parent;
126  SetFocus();
127 
129  int tmp = STEP_ORG_0;
130 
131  if( m_config->Read( OPTKEY_STEP_ORIGIN_OPT, &tmp ) )
133 
134  switch( m_STEP_org_opt )
135  {
136  default: break;
137  case STEP_ORG_PLOT_AXIS: m_rbDrillAndPlotOrigin->SetValue( true ); break;
138  case STEP_ORG_GRID_AXIS: m_rbGridOrigin->SetValue( true ); break;
139  case STEP_ORG_USER: m_rbUserDefinedOrigin->SetValue( true ); break;
140  case STEP_ORG_BOARD_CENTER: m_rbBoardCenterOrigin->SetValue( true ); break;
141  }
142 
144  m_config->Read( OPTKEY_STEP_UORG_X, &m_XOrg, 0.0 );
145  m_config->Read( OPTKEY_STEP_UORG_Y, &m_YOrg, 0.0 );
147  m_cbRemoveVirtual->SetValue( m_noVirtual );
148 
149  m_STEP_OrgUnitChoice->SetSelection( m_OrgUnits );
150  wxString tmpStr;
151  tmpStr << m_XOrg;
152  m_STEP_Xorg->SetValue( tmpStr );
153  tmpStr = "";
154  tmpStr << m_YOrg;
155  m_STEP_Yorg->SetValue( tmpStr );
156 
157  m_sdbSizerOK->SetDefault();
158 
159  // Now all widgets have the size fixed, call FinishDialogSettings
161 }
162 
163 
165 {
166  if( !wxDialog::TransferDataFromWindow() )
167  return false;
168 
169  wxFileName fn = m_filePickerSTEP->GetFileName();
170 
171  if( fn.FileExists() )
172  {
173  wxString msg;
174  msg.Printf( _( "File: %s\n"
175  "already exists. Do you want overwrite this file?" ),
176  fn.GetFullPath().GetData() );
177 
178  if( wxMessageBox( msg, _( "STEP Export" ), wxYES_NO | wxICON_QUESTION, this ) == wxNO )
179  return false;
180  }
181 
182  return true;
183 }
184 
185 
187 {
189 
190  if( m_rbDrillAndPlotOrigin->GetValue() )
192  else if( m_rbGridOrigin->GetValue() )
194  else if( m_rbUserDefinedOrigin->GetValue() )
196  else if( m_rbBoardCenterOrigin->GetValue() )
198 
199  return m_STEP_org_opt;
200 }
201 
202 
203 void PCB_EDIT_FRAME::OnExportSTEP( wxCommandEvent& event )
204 {
205 
206  wxFileName brdFile = GetBoard()->GetFileName();
207  wxString brdName;
208 
209  if( GetScreen()->IsModify() || brdFile.GetFullPath().empty() )
210  {
211  if( !doAutoSave() )
212  {
213  DisplayErrorMessage( this,
214  _( "STEP export failed! Please save the PCB and try again" ) );
215  return;
216  }
217 
218  brdFile = GetBoard()->GetFileName();
219  brdName = GetAutoSaveFilePrefix();
220  brdName.append( brdFile.GetName() );
221  brdFile.SetName( brdName );
222  }
223 
224  brdName = "\"";
225  brdName.Append( brdFile.GetFullPath() );
226  brdName.Append( "\"" );
227 
228  // Build default output file name
229  brdFile = GetBoard()->GetFileName();
230  wxString brdExt = brdFile.GetExt();
231  brdFile.SetExt( "stp" );
232 
233  DIALOG_EXPORT_STEP dlg( this );
234  dlg.FilePicker()->SetPath( brdFile.GetFullPath() );
235 
236  if ( dlg.ShowModal() != wxID_OK )
237  return;
238 
239  wxString outputFile = dlg.FilePicker()->GetPath();
240  brdFile.SetExt( brdExt );
241  outputFile.Prepend( "\"" );
242  outputFile.Append( "\"" );
243 
245  double xOrg = 0.0;
246  double yOrg = 0.0;
247 
248  wxFileName appK2S( wxStandardPaths::Get().GetExecutablePath() );
249  appK2S.SetName( "kicad2step" );
250 
251  wxString cmdK2S = "\"";
252  cmdK2S.Append( appK2S.GetFullPath() );
253  cmdK2S.Append( "\"" );
254 
255  if( dlg.GetNoVirtOption() )
256  cmdK2S.Append( " --no-virtual" );
257 
258  switch( orgOpt )
259  {
261  break;
262 
264  cmdK2S.Append( " --drill-origin" );
265  break;
266 
268  cmdK2S.Append( " --grid-origin" );
269  break;
270 
272  {
273  xOrg = dlg.GetXOrg();
274  yOrg = dlg.GetYOrg();
275 
276  if( dlg.GetOrgUnitsChoice() == 1 )
277  {
278  // selected reference unit is in inches, and STEP units are mm
279  xOrg *= 25.4;
280  yOrg *= 25.4;
281  }
282 
284  cmdK2S.Append( wxString::Format( " --user-origin %.6fx%.6f", xOrg, yOrg ) );
285  }
286  break;
287 
289  {
290  EDA_RECT bbox = GetBoard()->ComputeBoundingBox( true );
291  xOrg = Iu2Millimeter( bbox.GetCenter().x );
292  yOrg = Iu2Millimeter( bbox.GetCenter().y );
294  cmdK2S.Append( wxString::Format( " --user-origin %.6fx%.6f", xOrg, yOrg ) );
295  }
296  break;
297  }
298 
299  cmdK2S.Append( " -f -o " );
300  cmdK2S.Append( outputFile );
301 
302  cmdK2S.Append( " " );
303  cmdK2S.Append( brdName );
304 
305  int result = 0;
306 
307  do
308  {
309  wxBusyCursor dummy;
310  result = wxExecute( cmdK2S, wxEXEC_SYNC | wxEXEC_HIDE_CONSOLE );
311  } while( 0 );
312 
313  if( result )
314  {
315  DisplayErrorMessage( this, _( "Unable to create STEP file. Check that the board has a "
316  "valid outline and models." ), cmdK2S );
317  }
318 }
319 
320 
321 void DIALOG_EXPORT_STEP::onUpdateUnits( wxUpdateUIEvent& aEvent )
322 {
323  aEvent.Enable( m_rbUserDefinedOrigin->GetValue() );
324 }
325 
326 
327 void DIALOG_EXPORT_STEP::onUpdateXPos( wxUpdateUIEvent& aEvent )
328 {
329  aEvent.Enable( m_rbUserDefinedOrigin->GetValue() );
330 }
331 
332 
333 void DIALOG_EXPORT_STEP::onUpdateYPos( wxUpdateUIEvent& aEvent )
334 {
335  aEvent.Enable( m_rbUserDefinedOrigin->GetValue() );
336 }
bool TransferDataFromWindow() override
#define OPTKEY_STEP_UORG_X
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Function DisplayErrorMessage displays an error message with aMessage.
Definition: confirm.cpp:88
void onUpdateXPos(wxUpdateUIEvent &aEvent) override
Class LOCALE_IO is a class that can be instantiated within a scope in which you are expecting excepti...
Definition: common.h:166
#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...
Class BOARD to handle a board.
void OnExportSTEP(wxCommandEvent &event)
Function OnExportSTEP Exports the current BOARD to a STEP assembly.
wxRadioButton * m_rbDrillAndPlotOrigin
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
#define OPTKEY_STEP_ORIGIN_OPT
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
STEP_ORG_OPT GetOriginOption()
wxFilePickerCtrl * m_filePickerSTEP
const wxString & GetFileName() const
Definition: class_board.h:234
void onUpdateUnits(wxUpdateUIEvent &aEvent) override
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
BOARD * GetBoard()
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.
Definition: eda_rect.h:44
void onUpdateYPos(wxUpdateUIEvent &aEvent) override
#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:302
const wxPoint GetCenter() const
Definition: eda_rect.h:115