KiCad PCB EDA Suite
dlg_select_3dmodel.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) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
5  * Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
6  * Copyright (C) 2017-2018 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 
27 #include <set>
28 #include "dlg_select_3dmodel.h"
29 #include "project.h"
30 #include "3d_cache/3d_info.h"
31 #include "3d_cache/3d_cache.h"
32 #include "3d_cache_dialogs.h"
35 #include <filename_resolver.h>
36 #include <pcbnew/class_module.h>
37 
38 #define ID_FILE_TREE ( wxID_LAST + 1 )
39 #define ID_SET_DIR ( ID_FILE_TREE + 1 )
40 #define ID_CFG_PATHS ( ID_SET_DIR + 1 )
41 
42 
44  EVT_DIRCTRL_SELECTIONCHANGED( ID_FILE_TREE, DLG_SELECT_3DMODEL::OnSelectionChanged )
45  EVT_DIRCTRL_FILEACTIVATED( ID_FILE_TREE, DLG_SELECT_3DMODEL::OnFileActivated )
48 wxEND_EVENT_TABLE()
49 
50 
51 DLG_SELECT_3DMODEL::DLG_SELECT_3DMODEL( wxWindow* aParent, S3D_CACHE* aCacheManager,
52  MODULE_3D_SETTINGS* aModelItem, wxString& prevModelSelectDir, int& prevModelWildcard ) :
53  DIALOG_SHIM( aParent, wxID_ANY, _( "Select 3D Model" ), wxDefaultPosition,
54  wxSize( 500,200 ), wxCAPTION | wxRESIZE_BORDER | wxCLOSE_BOX
55  | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxSYSTEM_MENU ),
56  m_model( aModelItem ), m_cache( aCacheManager ), m_previousDir( prevModelSelectDir ),
57  m_previousFilterIndex( prevModelWildcard )
58 {
59  SetSizeHints( wxSize( 500,200 ), wxDefaultSize );
60 
61  if( NULL != m_cache )
62  m_resolver = m_cache->GetResolver();
63  else
64  m_resolver = NULL;
65 
66  wxBoxSizer* bSizer0 = new wxBoxSizer( wxVERTICAL );
67 
68  wxBoxSizer* bSizer1 = new wxBoxSizer( wxHORIZONTAL );
69 
70  wxBoxSizer* bSizer2 = new wxBoxSizer( wxVERTICAL );
71 
72  // set to NULL to avoid segfaults when m_FileTree is instantiated
73  // and wxGenericDirCtrl events are posted
74  m_modelViewer = NULL;
75  dirChoices = NULL;
76 
77  m_FileTree = new wxGenericDirCtrl( this, ID_FILE_TREE, prevModelSelectDir, wxDefaultPosition,
78  wxSize( 300,100 ), wxDIRCTRL_3D_INTERNAL | wxDIRCTRL_EDIT_LABELS
79  | wxDIRCTRL_SELECT_FIRST | wxDIRCTRL_SHOW_FILTERS | wxBORDER_SIMPLE, wxEmptyString, 0 );
80 
81 
82  m_FileTree->ShowHidden( false );
83  m_FileTree->SetMinSize( wxSize( 300, 400 ) );
84  m_FileTree->SetLabel( wxT( "3D_MODEL_SELECTOR" ) );
85 
86  bSizer2->Add( m_FileTree, 1, wxEXPAND | wxALL, 5 );
87  bSizer1->Add( bSizer2, 3, wxEXPAND, 5 );
88 
89  m_modelViewer = new C3D_MODEL_VIEWER( this, COGL_ATT_LIST::GetAttributesList( true ), m_cache );
90  m_modelViewer->SetMinSize( wxSize( 500, 400 ) );
91 
92  bSizer1->Add( m_modelViewer, 5, wxEXPAND | wxALL | wxCENTER, 5 );
93 
94  // create the filter list
95  if( NULL != m_cache )
96  {
97  std::list< wxString > const* fl = m_cache->GetFileFilters();
98  std::list< wxString >::const_iterator sL = fl->begin();
99  std::list< wxString >::const_iterator eL = fl->end();
100  wxString filter;
101 
102  while( sL != eL )
103  {
104  filter.Append( *sL );
105 
106  ++sL;
107 
108  if( sL != eL )
109  filter.Append( wxT( "|" ) );
110  }
111 
112  if( !filter.empty() )
113  m_FileTree->SetFilter( filter );
114  else
115  m_FileTree->SetFilter( wxFileSelectorDefaultWildcardStr );
116 
117  if( prevModelWildcard >= 0 && prevModelWildcard < (int)fl->size() )
118  m_FileTree->SetFilterIndex( prevModelWildcard );
119  else
120  {
121  prevModelWildcard = 0;
122  m_FileTree->SetFilterIndex( 0 );
123  }
124  }
125  else
126  {
127  m_FileTree->SetFilter( wxFileSelectorDefaultWildcardStr );
128  prevModelWildcard = 0;
129  m_FileTree->SetFilterIndex( 0 );
130  }
131 
132  // Add the path choice box and config button
133  wxBoxSizer* hboxDirChoice = new wxBoxSizer( wxHORIZONTAL );
134  dirChoices = new wxChoice( this, ID_SET_DIR, wxDefaultPosition, wxSize( 320, 20 ) );
135  dirChoices->SetMinSize( wxSize( 320, 12 ) );
136 
137  wxStaticText* stDirChoice = new wxStaticText( this, -1, _( "Paths:" ) );
138  wxButton* cfgPaths = new wxButton( this, ID_CFG_PATHS, _( "Configure Paths" ) );
139  hboxDirChoice->Add( stDirChoice, 0, wxALL | wxCENTER, 5 );
140  hboxDirChoice->Add( dirChoices, 1, wxEXPAND | wxALL, 5 );
141  hboxDirChoice->Add( cfgPaths, 0, wxALL, 5 );
142 
143  wxButton* btn_OK = new wxButton( this, wxID_OK, _( "OK" ) );
144  wxButton* btn_Cancel = new wxButton( this, wxID_CANCEL, _( "Cancel" ) );
145 
146  wxStdDialogButtonSizer* hSizer1 = new wxStdDialogButtonSizer();
147  hSizer1->AddButton( btn_OK );
148  hSizer1->AddButton( btn_Cancel );
149  hSizer1->Realize();
150 
151  bSizer0->Add( bSizer1, 1, wxALL | wxEXPAND, 5 );
152  bSizer0->Add( hboxDirChoice, 0, wxALL | wxEXPAND, 5 );
153  bSizer0->Add( hSizer1, 0, wxALL | wxEXPAND, 5 );
154 
155  updateDirChoiceList();
156 
157  SetSizerAndFit( bSizer0 );
158  Layout();
159  Centre( wxBOTH );
160 
161  m_modelViewer->Refresh();
162  m_modelViewer->SetFocus();
163 }
164 
165 
167 {
168  if( NULL == m_model || NULL == m_FileTree )
169  return true;
170 
171  m_model->m_Scale.x = 1.0;
172  m_model->m_Scale.y = 1.0;
173  m_model->m_Scale.z = 1.0;
174 
175  m_model->m_Rotation.x = 0.0;
176  m_model->m_Rotation.y = 0.0;
177  m_model->m_Rotation.z = 0.0;
178 
180  m_model->m_Filename.clear();
181 
182  wxString name = m_FileTree->GetFilePath();
183 
184  if( name.empty() )
185  return true;
186 
187  m_previousDir = m_FileTree->GetPath();
188  m_previousFilterIndex = m_FileTree->GetFilterIndex();
189 
190  // file selection mode: retrieve the filename and specify a
191  // path relative to one of the config paths
192  wxFileName fname = m_FileTree->GetFilePath();
193  fname.Normalize();
194  m_model->m_Filename = m_resolver->ShortenPath( fname.GetFullPath() );
195 
196  return true;
197 }
198 
199 
200 void DLG_SELECT_3DMODEL::OnSelectionChanged( wxTreeEvent& event )
201 {
202  if( m_modelViewer )
203  m_modelViewer->Set3DModel( m_FileTree->GetFilePath() );
204 
205  event.Skip();
206  return;
207 }
208 
209 
210 void DLG_SELECT_3DMODEL::OnFileActivated( wxTreeEvent& event )
211 {
212  if( m_modelViewer )
213  m_modelViewer->Set3DModel( m_FileTree->GetFilePath() );
214 
215  event.Skip();
216  SetEscapeId( wxID_OK );
217  Close();
218 
219  return;
220 }
221 
222 
223 void DLG_SELECT_3DMODEL::SetRootDir( wxCommandEvent& event )
224 {
225  if( m_FileTree && dirChoices->GetSelection() > 0 )
226  m_FileTree->SetPath( dirChoices->GetString( dirChoices->GetSelection() ) );
227 
228  return;
229 }
230 
231 
232 void DLG_SELECT_3DMODEL::Cfg3DPaths( wxCommandEvent& event )
233 {
234  if( S3D::Configure3DPaths( this, m_resolver ) )
236 }
237 
238 
240 {
241  if( NULL == m_FileTree || NULL == m_resolver || NULL == dirChoices )
242  return;
243 
244  std::list< SEARCH_PATH > const* md = m_resolver->GetPaths();
245  std::list< SEARCH_PATH >::const_iterator sL = md->begin();
246  std::list< SEARCH_PATH >::const_iterator eL = md->end();
247  std::set< wxString > cl;
248  wxString prjDir;
249 
250  // extract the current project dir
251  if( sL != eL )
252  {
253  prjDir = sL->m_pathexp;
254  ++sL;
255  }
256 
257  while( sL != eL )
258  {
259  if( !sL->m_pathexp.empty() && sL->m_pathexp.compare( prjDir ) )
260  cl.insert( sL->m_pathexp );
261 
262  ++sL;
263  }
264 
265  if( !cl.empty() )
266  {
267  unsigned int choice = 0;
268  dirChoices->Clear();
269  dirChoices->Append( "" ); //Insert a blank string at the beginning to allow selection
270 
271  if( !prjDir.empty() )
272  {
273  dirChoices->Append( prjDir );
274 
275  if( prjDir == m_FileTree->GetPath() )
276  choice = 1;
277  }
278 
279  std::set< wxString >::const_iterator sI = cl.begin();
280  std::set< wxString >::const_iterator eI = cl.end();
281 
282  while( sI != eI )
283  {
284  if( *sI == m_FileTree->GetPath() )
285  choice = dirChoices->GetCount();
286 
287  dirChoices->Append( *sI );
288  ++sI;
289  }
290 
291  dirChoices->Select( choice );
292  }
293 
294  return;
295 }
bool TransferDataFromWindow() override
static const int * GetAttributesList(bool aUseAntiAliasing)
Get a list of attributes to pass to wxGLCanvas.
C3D_MODEL_VIEWER * m_modelViewer
#define ID_FILE_TREE
provides an extensible class to resolve 3D model paths.
void Cfg3DPaths(wxCommandEvent &event)
void OnFileActivated(wxTreeEvent &event)
const std::list< SEARCH_PATH > * GetPaths(void)
Function GetPaths returns a pointer to the internal path list; the items in:load.
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
Definition: dialog_shim.h:84
S3D_CACHE.
Definition: 3d_cache.h:54
Class C3D_MODEL_VIEWER Implement a canvas based on a wxGLCanvas.
defines the basic data associated with a single 3D model.
VECTOR3D m_Offset
3D model offset (mm)
Definition: class_module.h:99
#define ID_CFG_PATHS
#define NULL
Implements a model viewer canvas.
wxString ShortenPath(const wxString &aFullPathName)
Function ShortenPath produces a relative path based on the existing search directories or returns the...
void Set3DModel(const S3DMODEL &a3DModel)
Set3DModel - Set this model to be displayed.
wxGenericDirCtrl * m_FileTree
Declaration of the cogl_att_list class.
#define ID_SET_DIR
wxString m_Filename
The 3D shape filename in 3D library.
Definition: class_module.h:100
void SetRootDir(wxCommandEvent &event)
void OnSelectionChanged(wxTreeEvent &event)
#define D(x)
Definition: ptree.cpp:41
bool Configure3DPaths(wxWindow *aParent, FILENAME_RESOLVER *aResolver)
const char * name
Definition: DXF_plotter.cpp:60
VECTOR3D m_Rotation
3D model rotation (degrees)
Definition: class_module.h:98
#define _(s)
Definition: 3d_actions.cpp:33
creates a dialog to select 3D model files
FILENAME_RESOLVER * m_resolver
defines the display data cache manager for 3D models
VECTOR3D m_Scale
3D model scaling factor (dimensionless)
Definition: class_module.h:97
Module description (excepted pads)
wxBEGIN_EVENT_TABLE(DLG_SELECT_3DMODEL, DIALOG_SHIM) wxEND_EVENT_TABLE() DLG_SELECT_3DMODEL
MODULE_3D_SETTINGS * m_model