KiCad PCB EDA Suite
dialog_export_vrml.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) 2009-2013 Lorenzo Mercantonio
9  * Copyright (C) 2013 Jean-Pierre Charras jp.charras at wanadoo.fr
10  * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, you may find one here:
24  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
25  * or you may search the http://www.gnu.org website for the version 2 license,
26  * or you may write to the Free Software Foundation, Inc.,
27  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28  */
29 #include <wx/dir.h>
30 
31 #include <class_board.h>
32 #include <confirm.h>
33 #include <fctsys.h>
34 #include <kiface_i.h>
35 #include <pcb_edit_frame.h>
36 #include <pcbnew_settings.h>
37 #include <pcbnew.h>
38 #include <project/project_file.h> // LAST_PATH_TYPE
39 
40 
41 /* the dialog to create VRML files, derived from DIALOG_EXPORT_3DFILE_BASE,
42  * created by wxFormBuilder
43  */
44 #include <dialog_export_vrml_base.h> // the wxFormBuilder header file
45 
46 
48 {
49 private:
51  int m_unitsOpt; // Remember last units option
52  bool m_copy3DFilesOpt; // Remember last copy model files option
53  bool m_useRelativePathsOpt; // Remember last use absolute paths option
54  bool m_usePlainPCBOpt; // Remember last Plain Board option
55  int m_RefUnits; // Remember last units for Reference Point
56  double m_XRef; // Remember last X Reference Point
57  double m_YRef; // Remember last Y Reference Point
58 
59 public:
61  DIALOG_EXPORT_3DFILE_BASE( parent ), m_parent( parent )
62  {
63  m_filePicker->SetFocus();
64 
65  auto cfg = m_parent->GetPcbNewSettings();
66 
67  m_unitsOpt = cfg->m_ExportVrml.units;
68  m_copy3DFilesOpt = cfg->m_ExportVrml.copy_3d_models;
69  m_useRelativePathsOpt = cfg->m_ExportVrml.use_relative_paths;
70  m_usePlainPCBOpt = cfg->m_ExportVrml.use_plain_pcb;
71  m_RefUnits = cfg->m_ExportVrml.ref_units;
72  m_XRef = cfg->m_ExportVrml.ref_x;
73  m_YRef = cfg->m_ExportVrml.ref_y;
74 
75  m_rbSelectUnits->SetSelection( m_unitsOpt );
76  m_cbCopyFiles->SetValue( m_copy3DFilesOpt );
78  m_cbPlainPCB->SetValue( m_usePlainPCBOpt );
79  m_VRML_RefUnitChoice->SetSelection( m_RefUnits );
80  wxString tmpStr;
81  tmpStr << m_XRef;
82  m_VRML_Xref->SetValue( tmpStr );
83  tmpStr = wxT( "" );
84  tmpStr << m_YRef;
85  m_VRML_Yref->SetValue( tmpStr );
86  m_sdbSizer1OK->SetDefault();
87 
88  // Now all widgets have the size fixed, call FinishDialogSettings
90 
91  Connect( ID_USE_ABS_PATH, wxEVT_UPDATE_UI,
92  wxUpdateUIEventHandler( DIALOG_EXPORT_3DFILE::OnUpdateUseRelativePath ) );
93  }
94 
96  {
97  m_unitsOpt = GetUnits();
99 
100  auto cfg = m_parent->GetPcbNewSettings();
101 
103  cfg->m_ExportVrml.copy_3d_models = m_copy3DFilesOpt;
104  cfg->m_ExportVrml.use_relative_paths = m_useRelativePathsOpt;
105  cfg->m_ExportVrml.use_plain_pcb = m_usePlainPCBOpt;
106  cfg->m_ExportVrml.ref_units = m_VRML_RefUnitChoice->GetSelection();
107 
108  double val = 0.0;
109  m_VRML_Xref->GetValue().ToDouble( &val );
110  cfg->m_ExportVrml.ref_x = val;
111 
112  m_VRML_Yref->GetValue().ToDouble( &val );
113  cfg->m_ExportVrml.ref_y = val;
114  };
115 
116  void SetSubdir( const wxString & aDir )
117  {
118  m_SubdirNameCtrl->SetValue( aDir );
119  }
120 
121  wxString GetSubdir3Dshapes()
122  {
123  return m_SubdirNameCtrl->GetValue();
124  }
125 
126  wxFilePickerCtrl* FilePicker()
127  {
128  return m_filePicker;
129  }
130 
132  {
133  return m_VRML_RefUnitChoice->GetSelection();
134  }
135 
136  double GetXRef()
137  {
139  }
140 
141  double GetYRef()
142  {
144  }
145 
146  int GetUnits()
147  {
148  return m_unitsOpt = m_rbSelectUnits->GetSelection();
149  }
150 
152  {
153  return m_copy3DFilesOpt = m_cbCopyFiles->GetValue();
154  }
155 
157  {
158  return m_useRelativePathsOpt = m_cbUseRelativePaths->GetValue();
159  }
160 
162  {
163  return m_usePlainPCBOpt = m_cbPlainPCB->GetValue();
164  }
165 
166  void OnUpdateUseRelativePath( wxUpdateUIEvent& event )
167  {
168  // Making path relative or absolute has no meaning when VRML files are not copied.
169  event.Enable( m_cbCopyFiles->GetValue() );
170  }
171 
172  bool TransferDataFromWindow() override;
173 };
174 
175 
177 {
178  wxFileName fn = m_filePicker->GetPath();
179 
180  if( fn.Exists() )
181  {
182  if( wxMessageBox( _( "Are you sure you want to overwrite the existing file?" ),
183  _( "Warning" ), wxYES_NO | wxCENTER | wxICON_QUESTION, this ) == wxNO )
184  return false;
185  }
186 
187  return true;
188 }
189 
190 
191 void PCB_EDIT_FRAME::OnExportVRML( wxCommandEvent& event )
192 {
193  // These variables are static to keep info during the session.
194  static wxString subDirFor3Dshapes;
195 
196  // Build default output file name
197  wxString path = GetLastPath( LAST_PATH_VRML );
198 
199  if( path.IsEmpty() )
200  {
201  wxFileName brdFile = GetBoard()->GetFileName();
202  brdFile.SetExt( "wrl" );
203  path = brdFile.GetFullPath();
204  }
205 
206  if( subDirFor3Dshapes.IsEmpty() )
207  subDirFor3Dshapes = wxT( "shapes3D" );
208 
209  // The general VRML scale factor
210  // Assuming the VRML default unit is the mm
211  // this is the mm to VRML scaling factor for mm, 0.1 inch, and inch
212  double scaleList[4] = { 1.0, 0.001, 10.0/25.4, 1.0/25.4 };
213 
214  DIALOG_EXPORT_3DFILE dlg( this );
215  dlg.FilePicker()->SetPath( path );
216  dlg.SetSubdir( subDirFor3Dshapes );
217 
218  if( dlg.ShowModal() != wxID_OK )
219  return;
220 
221  double aXRef = dlg.GetXRef();
222  double aYRef = dlg.GetYRef();
223 
224  if( dlg.GetRefUnitsChoice() == 1 )
225  {
226  // selected reference unit is in inches
227  aXRef *= 25.4;
228  aYRef *= 25.4;
229  }
230 
231  double scale = scaleList[dlg.GetUnits()]; // final scale export
232  bool export3DFiles = dlg.GetCopyFilesOption();
233  bool useRelativePaths = dlg.GetUseRelativePathsOption();
234  bool usePlainPCB = dlg.GetUsePlainPCBOption();
235 
236  path = dlg.FilePicker()->GetPath();
237  SetLastPath( LAST_PATH_VRML, path );
238  wxFileName modelPath = path;
239 
240  wxBusyCursor dummy;
241 
242  subDirFor3Dshapes = dlg.GetSubdir3Dshapes();
243  modelPath.AppendDir( subDirFor3Dshapes );
244 
245  if( export3DFiles && !modelPath.DirExists() )
246  {
247  if( !modelPath.Mkdir() )
248  {
249  wxString msg = wxString::Format(
250  _( "Unable to create directory \"%s\"" ), modelPath.GetPath() );
251  DisplayErrorMessage( this, msg );
252  return;
253  }
254  }
255 
256  if( !ExportVRML_File( path, scale, export3DFiles, useRelativePaths,
257  usePlainPCB, modelPath.GetPath(), aXRef, aYRef ) )
258  {
259  wxString msg = wxString::Format( _( "Unable to create file \"%s\"" ), path );
260  DisplayErrorMessage( this, msg );
261  return;
262  }
263 }
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:252
This file is part of the common library.
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
double DoubleValueFromString(EDA_UNITS aUnits, const wxString &aTextValue, bool aUseMils, EDA_DATA_TYPE aType)
Function DoubleValueFromString converts aTextValue to a double.
Definition: base_units.cpp:346
wxFilePickerCtrl * FilePicker()
PCBNEW_SETTINGS * GetPcbNewSettings()
DIALOG_EXPORT_VRML m_ExportVrml
const wxString & GetFileName() const
Definition: class_board.h:255
wxString GetLastPath(LAST_PATH_TYPE aType)
Get the last path for a particular type.
DIALOG_EXPORT_3DFILE(PCB_EDIT_FRAME *parent)
PCB_EDIT_FRAME * m_parent
void OnUpdateUseRelativePath(wxUpdateUIEvent &event)
Class DIALOG_EXPORT_3DFILE_BASE.
void SetSubdir(const wxString &aDir)
const int scale
bool ExportVRML_File(const wxString &aFullFileName, double aMMtoWRMLunit, bool aExport3DFiles, bool aUseRelativePaths, bool aUsePlainPCB, const wxString &a3D_Subdir, double aXRef, double aYRef)
Function ExportVRML_File Creates the file(s) exporting current BOARD to a VRML file.
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 to draw a dummy shape when a LIB_PART is not found in library.
#define _(s)
Definition: 3d_actions.cpp:33
void OnExportVRML(wxCommandEvent &event)
Function OnExportVRML will export the current BOARD to a VRML file.
PCB_EDIT_FRAME is the main frame for Pcbnew.
bool TransferDataFromWindow() override
BOARD * GetBoard() const
void SetLastPath(LAST_PATH_TYPE aType, const wxString &aLastPath)
Set the path of the last file successfully read.