KiCad PCB EDA Suite
panel_prev_model.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) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
6  * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
7  * Copyright (C) 2015-2017 KiCad Developers, see AUTHORS.txt for contributors.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
33 #include <cstdlib>
34 #include <limits.h>
35 #include <bitmaps.h>
36 
37 #include <wx/valnum.h>
38 #include <wx/tglbtn.h>
39 
40 #include "project.h"
41 #include "panel_prev_model.h"
42 #include <class_board.h>
43 
44 
45 PANEL_PREV_3D::PANEL_PREV_3D( wxWindow* aParent, S3D_CACHE* aCacheManager,
46  MODULE* aModuleCopy,
47  std::vector<S3D_INFO> *aParentInfoList ):
48  PANEL_PREV_3D_BASE( aParent, wxID_ANY )
49  {
50  initPanel();
51 
52  if( NULL != aCacheManager )
53  m_resolver = aCacheManager->GetResolver();
54 
55  m_parentInfoList = aParentInfoList;
56 
57  m_dummyBoard->Add( (MODULE*)aModuleCopy );
58  m_copyModule = aModuleCopy;
59 
60  // Set 3d viewer configuration for preview
62 
63  // Create the 3D canvas
64  m_previewPane = new EDA_3D_CANVAS( this,
68  aCacheManager );
69 
70  m_SizerPanelView->Add( m_previewPane, 1, wxEXPAND );
71 
72  m_previewPane->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler(
74  }
75 
76 
78 {
79  m_previewPane->Disconnect( wxEVT_ENTER_WINDOW,
80  wxMouseEventHandler( PANEL_PREV_3D::onEnterPreviewCanvas ), NULL, this );
81 
82  delete m_settings3Dviewer;
83  delete m_dummyBoard;
84  delete m_previewPane;
85 }
86 
87 
89 {
90  m_resolver = NULL;
91  currentModelFile.clear();
92  m_dummyBoard = new BOARD();
94 
95  // Set the bitmap of 3D view buttons:
96  m_bpvTop->SetBitmap( KiBitmap( axis3d_top_xpm ) );
97  m_bpvFront->SetBitmap( KiBitmap( axis3d_front_xpm ) );
98  m_bpvBack->SetBitmap( KiBitmap( axis3d_back_xpm ) );
99  m_bpvLeft->SetBitmap( KiBitmap( axis3d_left_xpm ) );
100  m_bpvRight->SetBitmap( KiBitmap( axis3d_right_xpm ) );
101  m_bpvBottom->SetBitmap( KiBitmap( axis3d_bottom_xpm ) );
102  m_bpvISO->SetBitmap( KiBitmap( ortho_xpm ) );
103  m_bpUpdate->SetBitmap( KiBitmap( reload_xpm ) );
104 
105  // Set the min and max values of spin buttons (mandatory on Linux)
106  // They are not used, so they are set to min and max 32 bits int values
107  // (the min and max values supported by a wxSpinButton)
108  // It avoids blocking the up or down arrows when reaching this limit after
109  // a few clicks.
110  wxSpinButton* spinButtonList[] =
111  {
115  };
116 
117  for( int ii = 0; ii < 9; ii++ )
118  spinButtonList[ii]->SetRange( INT_MIN, INT_MAX );
119 }
120 
121 
122 
123 
130 static void checkRotation( double& aRotation )
131 {
132  if( aRotation > MAX_ROTATION )
133  {
134  int n = aRotation / MAX_ROTATION;
135  aRotation -= MAX_ROTATION * n;
136  }
137  else if( aRotation < -MAX_ROTATION )
138  {
139  int n = -aRotation / MAX_ROTATION;
140  aRotation += MAX_ROTATION * n;
141  }
142 }
143 
144 static bool validateFloatTextCtrl( wxTextCtrl* aTextCtrl )
145  {
146  if( aTextCtrl == NULL )
147  return false;
148 
149  if( aTextCtrl->GetLineLength(0) == 0 ) // This will skip the got and event with empty field
150  return false;
151 
152  if( aTextCtrl->GetLineLength(0) == 1 )
153  {
154  if( (aTextCtrl->GetLineText(0).compare( "." ) == 0) ||
155  (aTextCtrl->GetLineText(0).compare( "," ) == 0) )
156  return false;
157  }
158 
159  return true;
160 }
161 
162 
163 static void incrementTextCtrl( wxTextCtrl* aTextCtrl, double aInc, double aMinval, double aMaxval )
164 {
165  if( !validateFloatTextCtrl( aTextCtrl ) )
166  return;
167 
168  double curr_value = 0;
169 
170  aTextCtrl->GetValue().ToDouble( &curr_value );
171  curr_value += aInc;
172 
173  if( curr_value > aMaxval )
174  curr_value = aMaxval;
175 
176  if( curr_value < aMinval )
177  curr_value = aMinval;
178 
179  aTextCtrl->SetValue( wxString::Format( "%.4f", curr_value ) );
180 }
181 
182 
183 void PANEL_PREV_3D::SetModelDataIdx( int idx, bool aReloadPreviewModule )
184 {
185  wxASSERT( m_parentInfoList != NULL );
186 
187  if( m_parentInfoList && (idx >= 0) )
188  {
189  wxASSERT( (unsigned int)idx < (*m_parentInfoList).size() );
190 
191  if( (unsigned int)idx < (*m_parentInfoList).size() )
192  {
193  m_currentSelectedIdx = -1; // In case that we receive events on the
194  // next updates, it will set first an
195  // invalid selection
196 
197  const S3D_INFO *aModel = (const S3D_INFO *)&((*m_parentInfoList)[idx]);
198 
199  xscale->SetValue( wxString::Format( "%.4f", aModel->m_Scale.x ) );
200  yscale->SetValue( wxString::Format( "%.4f", aModel->m_Scale.y ) );
201  zscale->SetValue( wxString::Format( "%.4f", aModel->m_Scale.z ) );
202 
203  xrot->SetValue( wxString::Format( "%.2f", aModel->m_Rotation.x ) );
204  yrot->SetValue( wxString::Format( "%.2f", aModel->m_Rotation.y ) );
205  zrot->SetValue( wxString::Format( "%.2f", aModel->m_Rotation.z ) );
206 
207  switch( g_UserUnit )
208  {
209  case MILLIMETRES:
210  xoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.x * 25.4 ) );
211  yoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.y * 25.4 ) );
212  zoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.z * 25.4 ) );
213  break;
214 
215  case INCHES:
216  xoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.x ) );
217  yoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.y ) );
218  zoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.z ) );
219  break;
220 
221  case DEGREES:
222  case UNSCALED_UNITS:
223  default:
224  wxASSERT(0);
225  }
226 
227  UpdateModelName( aModel->m_Filename );
228 
229  if( aReloadPreviewModule && m_previewPane )
230  {
232 
235  }
236 
237  m_currentSelectedIdx = idx;
238  }
239  }
240 
241  if( m_previewPane )
242  m_previewPane->SetFocus();
243 
244  return;
245 }
246 
247 
248 void PANEL_PREV_3D::ResetModelData( bool aReloadPreviewModule )
249 {
251 
252  xscale->SetValue( wxString::FromDouble( 1.0 ) );
253  yscale->SetValue( wxString::FromDouble( 1.0 ) );
254  zscale->SetValue( wxString::FromDouble( 1.0 ) );
255 
256  xrot->SetValue( wxString::FromDouble( 0.0 ) );
257  yrot->SetValue( wxString::FromDouble( 0.0 ) );
258  zrot->SetValue( wxString::FromDouble( 0.0 ) );
259 
260  xoff->SetValue( wxString::FromDouble( 0.0 ) );
261  yoff->SetValue( wxString::FromDouble( 0.0 ) );
262  zoff->SetValue( wxString::FromDouble( 0.0 ) );
263 
264  // This will update the model on the preview board with the current list of 3d shapes
265  if( aReloadPreviewModule )
266  {
268 
269  if( m_previewPane )
270  {
273  }
274  }
275 
276  if( m_previewPane )
277  m_previewPane->SetFocus();
278 }
279 
280 
281 void PANEL_PREV_3D::UpdateModelName( wxString const& aModelName )
282 {
283  bool newModel = false;
284 
285  m_modelInfo.m_Filename = aModelName;
286 
287  // if the model name is a directory simply clear the current model
288  if( aModelName.empty() || wxFileName::DirExists( aModelName ) )
289  {
290  currentModelFile.clear();
291  m_modelInfo.m_Filename.clear();
292  }
293  else
294  {
295  wxString newModelFile;
296 
297  if( m_resolver )
298  newModelFile = m_resolver->ResolvePath( aModelName );
299 
300  if( !newModelFile.empty() && newModelFile.Cmp( currentModelFile ) )
301  newModel = true;
302 
303  currentModelFile = newModelFile;
304  }
305 
306  if( currentModelFile.empty() || newModel )
307  {
309 
310  if( m_previewPane )
311  {
313  m_previewPane->Refresh();
314  }
315 
316  if( currentModelFile.empty() )
317  return;
318  }
319  else
320  {
321  if( m_previewPane )
322  m_previewPane->Refresh();
323  }
324 
325  if( m_previewPane )
326  m_previewPane->SetFocus();
327 
328  return;
329 }
330 
331 
332 void PANEL_PREV_3D::updateOrientation( wxCommandEvent &event )
333 {
334  wxTextCtrl *textCtrl = (wxTextCtrl *)event.GetEventObject();
335 
336  if( textCtrl == NULL )
337  return;
338 
339  if( textCtrl->GetLineLength(0) == 0 ) // This will skip the got and event with empty field
340  return;
341 
342  if( textCtrl->GetLineLength(0) == 1 )
343  if( (textCtrl->GetLineText(0).compare( "." ) == 0) ||
344  (textCtrl->GetLineText(0).compare( "," ) == 0) )
345  return;
346 
347  SGPOINT scale;
348  SGPOINT rotation;
349  SGPOINT offset;
350 
351  getOrientationVars( scale, rotation, offset );
352 
354  m_modelInfo.m_Offset = offset;
355  m_modelInfo.m_Rotation = rotation;
356 
357  if( m_currentSelectedIdx >= 0 )
358  {
359  // This will update the parent list with the new data
360  (*m_parentInfoList)[m_currentSelectedIdx] = m_modelInfo;
361 
362  // It will update the copy model in the preview board
364 
365  // Since the OpenGL render does not need to be reloaded to update the
366  // shapes position, we just request to redraw again the canvas
367  if( m_previewPane )
368  m_previewPane->Refresh();
369  }
370 }
371 
372 
373 void PANEL_PREV_3D::onIncrementRot( wxSpinEvent& event )
374 {
375  wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
376 
377  wxTextCtrl * textCtrl = xrot;
378 
379  if( spinCtrl == m_spinYrot )
380  textCtrl = yrot;
381  else if( spinCtrl == m_spinZrot )
382  textCtrl = zrot;
383 
385 }
386 
387 
388 void PANEL_PREV_3D::onDecrementRot( wxSpinEvent& event )
389 {
390  wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
391 
392  wxTextCtrl * textCtrl = xrot;
393 
394  if( spinCtrl == m_spinYrot )
395  textCtrl = yrot;
396  else if( spinCtrl == m_spinZrot )
397  textCtrl = zrot;
398 
400 }
401 
402 
403 void PANEL_PREV_3D::onIncrementScale( wxSpinEvent& event )
404 {
405  wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
406 
407  wxTextCtrl * textCtrl = xscale;
408 
409  if( spinCtrl == m_spinYscale )
410  textCtrl = yscale;
411  else if( spinCtrl == m_spinZscale )
412  textCtrl = zscale;
413 
415 }
416 
417 
418 void PANEL_PREV_3D::onDecrementScale( wxSpinEvent& event )
419 {
420  wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
421 
422  wxTextCtrl * textCtrl = xscale;
423 
424  if( spinCtrl == m_spinYscale )
425  textCtrl = yscale;
426  else if( spinCtrl == m_spinZscale )
427  textCtrl = zscale;
428 
430 }
431 
432 
433 void PANEL_PREV_3D::onIncrementOffset( wxSpinEvent& event )
434 {
435  wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
436 
437  wxTextCtrl * textCtrl = xoff;
438 
439  if( spinCtrl == m_spinYoffset )
440  textCtrl = yoff;
441  else if( spinCtrl == m_spinZoffset )
442  textCtrl = zoff;
443 
444  double step = OFFSET_INCREMENT_MM;
445 
446  if( g_UserUnit == INCHES )
447  step = OFFSET_INCREMENT_MIL/1000.0;
448 
449  incrementTextCtrl( textCtrl, step, -MAX_OFFSET, MAX_OFFSET );
450 }
451 
452 
453 void PANEL_PREV_3D::onDecrementOffset( wxSpinEvent& event )
454 {
455  wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
456 
457  wxTextCtrl * textCtrl = xoff;
458 
459  if( spinCtrl == m_spinYoffset )
460  textCtrl = yoff;
461  else if( spinCtrl == m_spinZoffset )
462  textCtrl = zoff;
463 
464  double step = OFFSET_INCREMENT_MM;
465 
466  if( g_UserUnit == INCHES )
467  step = OFFSET_INCREMENT_MIL/1000.0;
468 
469  incrementTextCtrl( textCtrl, -step, -MAX_OFFSET, MAX_OFFSET );
470 }
471 
472 
473 void PANEL_PREV_3D::onMouseWheelScale( wxMouseEvent& event )
474 {
475  wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
476 
477  double step = SCALE_INCREMENT;
478 
479  if( event.ShiftDown( ) )
480  step = SCALE_INCREMENT_FINE;
481 
482  if( event.GetWheelRotation() >= 0 )
483  step = -step;
484 
485  incrementTextCtrl( textCtrl, step, 1/MAX_SCALE, MAX_SCALE );
486 }
487 
488 
489 void PANEL_PREV_3D::onMouseWheelRot( wxMouseEvent& event )
490 {
491  wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
492 
493  wxKeyboardState kbdState;
494 
495  double step = ROTATION_INCREMENT_WHEEL;
496 
497  if( event.ShiftDown( ) )
499 
500  if( event.GetWheelRotation() >= 0 )
501  step = -step;
502 
503  incrementTextCtrl( textCtrl, step, -MAX_ROTATION, MAX_ROTATION );
504 }
505 
506 void PANEL_PREV_3D::onMouseWheelOffset( wxMouseEvent& event )
507 {
508  wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
509 
510  double step = OFFSET_INCREMENT_MM;
511  if( event.ShiftDown( ) )
513 
514  if( g_UserUnit == INCHES )
515  {
516  step = OFFSET_INCREMENT_MIL/1000.0;
517  if( event.ShiftDown( ) )
518  step = OFFSET_INCREMENT_MIL_FINE/1000.0;
519  }
520 
521  if( event.GetWheelRotation() >= 0 )
522  step = -step;
523 
524  incrementTextCtrl( textCtrl, step, -MAX_OFFSET, MAX_OFFSET );
525 }
526 
527 void PANEL_PREV_3D::getOrientationVars( SGPOINT& aScale, SGPOINT& aRotation, SGPOINT& aOffset )
528 {
529  if( NULL == xscale || NULL == yscale || NULL == zscale
530  || NULL == xrot || NULL == yrot || NULL == zrot
531  || NULL == xoff || NULL == yoff || NULL == zoff )
532  {
533  return;
534  }
535 
536  xscale->GetValue().ToDouble( &aScale.x );
537  yscale->GetValue().ToDouble( &aScale.y );
538  zscale->GetValue().ToDouble( &aScale.z );
539 
540  xrot->GetValue().ToDouble( &aRotation.x );
541  yrot->GetValue().ToDouble( &aRotation.y );
542  zrot->GetValue().ToDouble( &aRotation.z );
543 
544  checkRotation( aRotation.x );
545  checkRotation( aRotation.y );
546  checkRotation( aRotation.z );
547 
548  xoff->GetValue().ToDouble( &aOffset.x );
549  yoff->GetValue().ToDouble( &aOffset.y );
550  zoff->GetValue().ToDouble( &aOffset.z );
551 
552  switch( g_UserUnit )
553  {
554  case MILLIMETRES:
555  // Convert to Inches. Offset is stored in inches.
556  aOffset.x = aOffset.x / 25.4;
557  aOffset.y = aOffset.y / 25.4;
558  aOffset.z = aOffset.z / 25.4;
559  break;
560 
561  case INCHES:
562  // It is already in Inches
563  break;
564 
565  case DEGREES:
566  case UNSCALED_UNITS:
567  default:
568  wxASSERT(0);
569  }
570 
571  return;
572 }
573 
574 
575 bool PANEL_PREV_3D::ValidateWithMessage( wxString& aErrorMessage )
576 {
577  bool invalidScale = false;
578 
579  for( unsigned int idx = 0; idx < m_parentInfoList->size(); ++idx )
580  {
581  wxString msg;
582  bool addError = false;
583  S3D_INFO& s3dshape = (*m_parentInfoList)[idx];
584 
585  SGPOINT scale = s3dshape.m_Scale;
586 
587  if( 1/MAX_SCALE > scale.x || MAX_SCALE < scale.x )
588  {
589  invalidScale = true;
590  addError = true;
591  msg += _( "Invalid X scale" );
592  }
593 
594  if( 1/MAX_SCALE > scale.y || MAX_SCALE < scale.y )
595  {
596  invalidScale = true;
597  addError = true;
598 
599  if( !msg.IsEmpty() )
600  msg += "\n";
601 
602  msg += _( "Invalid Y scale" );
603  }
604 
605  if( 1/MAX_SCALE > scale.z || MAX_SCALE < scale.z )
606  {
607  invalidScale = true;
608  addError = true;
609 
610  if( !msg.IsEmpty() )
611  msg += "\n";
612 
613  msg += _( "Invalid Z scale" );
614  }
615 
616  if( addError )
617  {
618  msg.Prepend( s3dshape.m_Filename + "\n" );
619 
620  if( !aErrorMessage.IsEmpty() )
621  aErrorMessage += "\n\n";
622 
623  aErrorMessage += msg;
624  }
625  }
626 
627  if( !aErrorMessage.IsEmpty() )
628  {
629  aErrorMessage += "\n\n";
630  aErrorMessage += wxString::Format( "Min value = %.4f and max value = %.4f",
631  1/MAX_SCALE, MAX_SCALE );
632  }
633 
634  return invalidScale == false;
635 }
636 
638 {
639  std::list<S3D_INFO>* draw3D = &m_copyModule->Models();
640  draw3D->clear();
641  draw3D->insert( draw3D->end(), m_parentInfoList->begin(), m_parentInfoList->end() );
642 }
wxBitmapButton * m_bpvTop
wxBitmapButton * m_bpvBottom
void ResetModelData(bool aReloadPreviewModule=false)
ResetModelData - Clear the values and reload the preview board.
wxSpinButton * m_spinZoffset
Class PANEL_PREV_3D_BASE.
MODULE * m_copyModule
A pointer to a new copy of the original module.
#define OFFSET_INCREMENT_MM_FINE
CINFO3D_VISU * m_settings3Dviewer
The settings that will be used for this 3D viewer canvas.
static const int * GetAttributesList(bool aUseAntiAliasing)
Get a list of attributes to pass to wxGLCanvas.
void onDecrementRot(wxSpinEvent &event) override
double x
Definition: sg_base.h:70
wxSpinButton * m_spinYoffset
PANEL_PREV_3D(wxWindow *aParent, S3D_CACHE *aCacheManager, MODULE *aModuleCopy, std::vector< S3D_INFO > *aParentInfoList=NULL)
void onMouseWheelScale(wxMouseEvent &event) override
wxBitmapButton * m_bpvBack
#define OFFSET_INCREMENT_MM
void onIncrementOffset(wxSpinEvent &event) override
#define SCALE_INCREMENT_FINE
wxBitmapButton * m_bpvLeft
Class BOARD to handle a board.
void getOrientationVars(SGPOINT &aScale, SGPOINT &aRotation, SGPOINT &aOffset)
getOrientationVars - gets the transformation from entries and validate it
void onMouseWheelOffset(wxMouseEvent &event) override
wxBitmapButton * m_bpUpdate
bool ValidateWithMessage(wxString &aErrorMessage)
verify X,Y and Z scale factors are acceptable (> 0.001 and < 1000.0)
static void incrementTextCtrl(wxTextCtrl *aTextCtrl, double aInc, double aMinval, double aMaxval)
Class EDA_3D_CANVAS Implement a canvas based on a wxGLCanvas.
Definition: eda_3d_canvas.h:53
void onDecrementScale(wxSpinEvent &event) override
wxBoxSizer * m_SizerPanelView
double y
Definition: sg_base.h:71
SGPOINT m_Offset
an offset (unit = inch) for the 3D shape
Definition: 3d_info.h:44
std::list< S3D_INFO > & Models()
Definition: class_module.h:139
void Request_refresh(bool aRedrawImmediately=true)
Request_refresh - Schedule a refresh update of the canvas.
void ReloadRequest(BOARD *aBoard=NULL, S3D_CACHE *aCachePointer=NULL)
#define ROTATION_INCREMENT
int m_currentSelectedIdx
The current selected index of the S3D_INFO list.
wxBitmapButton * m_bpvRight
static bool validateFloatTextCtrl(wxTextCtrl *aTextCtrl)
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Function KiBitmap constructs a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:36
void updateListOnModelCopy()
updateListOnModelCopy - copy the current shape list to the copy of module that is on the preview dumm...
wxSpinButton * m_spinZrot
void SetModelDataIdx(int idx, bool aReloadPreviewModule=false)
SetModelDataIdx - This will set the index of the INFO list that was set on the parent.
Defines a panel which is to be added to a wxFileDialog via SetExtraControl(); The panel shows a previ...
#define SCALE_INCREMENT
S3D_FILENAME_RESOLVER * m_resolver
Used to get the full path name.
wxSpinButton * m_spinXoffset
Definition: common.h:145
void onEnterPreviewCanvas(wxMouseEvent &event)
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
>
EDA_3D_CANVAS * m_previewPane
The 3D canvas.
Class CINFO3D_VISU Helper class to handle information needed to display 3D board. ...
Definition: cinfo3d_visu.h:70
wxSpinButton * m_spinYrot
void onIncrementRot(wxSpinEvent &event) override
Declaration of the cogl_att_list class.
wxSpinButton * m_spinXrot
wxBitmapButton * m_bpvFront
wxSpinButton * m_spinZscale
wxSpinButton * m_spinXscale
S3D_FILENAME_RESOLVER * GetResolver(void)
Definition: 3d_cache.cpp:739
void onDecrementOffset(wxSpinEvent &event) override
void onMouseWheelRot(wxMouseEvent &event) override
EDA_UNITS_T g_UserUnit
Global variables definitions.
Definition: common.cpp:56
const int scale
#define OFFSET_INCREMENT_MIL_FINE
#define OFFSET_INCREMENT_MIL
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
void updateOrientation(wxCommandEvent &event) override
updateOrientation - it will receive the events from editing the fields
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:166
wxString ResolvePath(const wxString &aFileName)
Function ResolvePath determines the full path of the given file name.
void onIncrementScale(wxSpinEvent &event) override
SGPOINT m_Rotation
an X,Y,Z rotation (unit = degrees) for the 3D shape
Definition: 3d_info.h:43
wxBitmapButton * m_bpvISO
double z
Definition: sg_base.h:72
#define ROTATION_INCREMENT_WHEEL_FINE
#define ROTATION_INCREMENT_WHEEL
#define MAX_OFFSET
#define MAX_ROTATION
SGPOINT m_Scale
scaling factors for the 3D footprint shape
Definition: 3d_info.h:42
S3D_INFO m_modelInfo
Current S3D_INFO that is being edited.
BOARD * m_dummyBoard
A dummy board used to store the copy moduled.
wxString currentModelFile
Used to check if the model file was changed.
static void checkRotation(double &aRotation)
checkRotation Ensure -MAX_ROTATION <= rotation <= MAX_ROTATION aRotation will be normalized between -...
std::vector< S3D_INFO > * m_parentInfoList
A pointer to the parent S3D_INFO list that we will use to copy to the preview module.
void UpdateModelName(wxString const &aModel)
wxSpinButton * m_spinYscale
wxString m_Filename
The 3D shape filename in 3D library.
Definition: 3d_info.h:45