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