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-2018 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 <bitmaps.h>
34 #include <base_units.h>
35 
36 #include "project.h"
37 #include "panel_prev_model.h"
38 #include <class_board.h>
39 #include <class_drawpanel.h>
40 #include <pgm_base.h>
41 
42 PANEL_PREV_3D::PANEL_PREV_3D( wxWindow* aParent, PCB_BASE_FRAME* aFrame, MODULE* aModule,
43  std::vector<MODULE_3D_SETTINGS> *aParentModelList ) :
44  PANEL_PREV_3D_BASE( aParent, wxID_ANY )
45 {
46  m_userUnits = aFrame->GetUserUnits();
47 
48  initPanel();
49 
50  // Initialize the color settings to draw the board and the footprint
52 
53  m_parentModelList = aParentModelList;
54 
55  m_dummyModule = new MODULE( *aModule );
57 
58  // Set 3d viewer configuration for preview
60 
61  bool option;
62  Pgm().CommonSettings()->Read( ENBL_MOUSEWHEEL_PAN_KEY, &option, false );
64 
65  // Create the 3D canvas
68  aFrame->Prj().Get3DCacheManager() );
69 
70  m_SizerPanelView->Add( m_previewPane, 1, wxEXPAND, 5 );
71 }
72 
73 
75 {
76  delete m_settings3Dviewer;
77  delete m_dummyBoard;
78  delete m_previewPane;
79 }
80 
81 
83 {
84  m_dummyBoard = new BOARD();
85  m_selected = -1;
86 
87  // Set the bitmap of 3D view buttons:
88  m_bpvTop->SetBitmap( KiBitmap( axis3d_top_xpm ) );
89  m_bpvFront->SetBitmap( KiBitmap( axis3d_front_xpm ) );
90  m_bpvBack->SetBitmap( KiBitmap( axis3d_back_xpm ) );
91  m_bpvLeft->SetBitmap( KiBitmap( axis3d_left_xpm ) );
92  m_bpvRight->SetBitmap( KiBitmap( axis3d_right_xpm ) );
93  m_bpvBottom->SetBitmap( KiBitmap( axis3d_bottom_xpm ) );
94  m_bpvISO->SetBitmap( KiBitmap( ortho_xpm ) );
95  m_bpUpdate->SetBitmap( KiBitmap( reload_xpm ) );
96 
97  // Set the min and max values of spin buttons (mandatory on Linux)
98  // They are not used, so they are set to min and max 32 bits int values
99  // (the min and max values supported by a wxSpinButton)
100  // It avoids blocking the up or down arrows when reaching this limit after
101  // a few clicks.
102  wxSpinButton* spinButtonList[] =
103  {
107  };
108 
109  for( int ii = 0; ii < 9; ii++ )
110  spinButtonList[ii]->SetRange( INT_MIN, INT_MAX );
111 }
112 
113 
119 static double rotationFromString( const wxString& aValue )
120 {
121  double rotation = DoubleValueFromString( DEGREES, aValue ) / 10.0;
122 
123  if( rotation > MAX_ROTATION )
124  {
125  int n = rotation / MAX_ROTATION;
126  rotation -= MAX_ROTATION * n;
127  }
128  else if( rotation < -MAX_ROTATION )
129  {
130  int n = -rotation / MAX_ROTATION;
131  rotation += MAX_ROTATION * n;
132  }
133 
134  return rotation;
135 }
136 
137 
138 wxString PANEL_PREV_3D::formatScaleValue( double aValue )
139 {
140  return wxString::Format( "%.4f", aValue );
141 }
142 
143 
144 wxString PANEL_PREV_3D::formatRotationValue( double aValue )
145 {
146  return wxString::Format( "%.2f %s", aValue, GetAbbreviatedUnitsLabel( DEGREES ) );
147 }
148 
149 
150 wxString PANEL_PREV_3D::formatOffsetValue( double aValue )
151 {
152  // Convert from internal units (mm) to user units
153  if( m_userUnits == INCHES )
154  aValue /= 25.4f;
155 
156  return wxString::Format( "%.4f %s", aValue, GetAbbreviatedUnitsLabel( m_userUnits ) );
157 }
158 
159 
161 {
162  if( m_parentModelList && idx >= 0 && idx < (int) m_parentModelList->size() )
163  {
164  m_selected = idx;
165  const MODULE_3D_SETTINGS& modelInfo = m_parentModelList->at( (unsigned) m_selected );
166 
167  // Use ChangeValue() instead of SetValue(). It's not the user making the change, so we
168  // don't want to generate wxEVT_GRID_CELL_CHANGED events.
169 
170  xscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.x ) );
171  yscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.y ) );
172  zscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.z ) );
173 
174  xrot->ChangeValue( formatRotationValue( modelInfo.m_Rotation.x ) );
175  yrot->ChangeValue( formatRotationValue( modelInfo.m_Rotation.y ) );
176  zrot->ChangeValue( formatRotationValue( modelInfo.m_Rotation.z ) );
177 
178  xoff->ChangeValue( formatOffsetValue( modelInfo.m_Offset.x ) );
179  yoff->ChangeValue( formatOffsetValue( modelInfo.m_Offset.y ) );
180  zoff->ChangeValue( formatOffsetValue( modelInfo.m_Offset.z ) );
181  }
182  else
183  {
184  m_selected = -1;
185 
186  xscale->ChangeValue( wxEmptyString );
187  yscale->ChangeValue( wxEmptyString );
188  zscale->ChangeValue( wxEmptyString );
189 
190  xrot->ChangeValue( wxEmptyString );
191  yrot->ChangeValue( wxEmptyString );
192  zrot->ChangeValue( wxEmptyString );
193 
194  xoff->ChangeValue( wxEmptyString );
195  yoff->ChangeValue( wxEmptyString );
196  zoff->ChangeValue( wxEmptyString );
197  }
198 }
199 
200 
201 void PANEL_PREV_3D::updateOrientation( wxCommandEvent &event )
202 {
203  if( m_parentModelList && m_selected >= 0 && m_selected < (int) m_parentModelList->size() )
204  {
205  // Write settings back to the parent
206  MODULE_3D_SETTINGS* modelInfo = &m_parentModelList->at( (unsigned) m_selected );
207 
208  modelInfo->m_Scale.x = DoubleValueFromString( UNSCALED_UNITS, xscale->GetValue() );
209  modelInfo->m_Scale.y = DoubleValueFromString( UNSCALED_UNITS, yscale->GetValue() );
210  modelInfo->m_Scale.z = DoubleValueFromString( UNSCALED_UNITS, zscale->GetValue() );
211 
212  modelInfo->m_Rotation.x = rotationFromString( xrot->GetValue() );
213  modelInfo->m_Rotation.y = rotationFromString( yrot->GetValue() );
214  modelInfo->m_Rotation.z = rotationFromString( zrot->GetValue() );
215 
216  modelInfo->m_Offset.x = DoubleValueFromString( m_userUnits, xoff->GetValue() ) / IU_PER_MM;
217  modelInfo->m_Offset.y = DoubleValueFromString( m_userUnits, yoff->GetValue() ) / IU_PER_MM;
218  modelInfo->m_Offset.z = DoubleValueFromString( m_userUnits, zoff->GetValue() ) / IU_PER_MM;
219 
220  // Update the dummy module for the preview
221  UpdateDummyModule( false );
222  }
223 }
224 
225 
226 void PANEL_PREV_3D::doIncrementScale( wxSpinEvent& event, double aSign )
227 {
228  wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
229 
230  wxTextCtrl * textCtrl = xscale;
231 
232  if( spinCtrl == m_spinYscale )
233  textCtrl = yscale;
234  else if( spinCtrl == m_spinZscale )
235  textCtrl = zscale;
236 
237  double curr_value = DoubleValueFromString( UNSCALED_UNITS, textCtrl->GetValue() );
238 
239  curr_value += ( SCALE_INCREMENT * aSign );
240  curr_value = std::max( 1/MAX_SCALE, curr_value );
241  curr_value = std::min( curr_value, MAX_SCALE );
242 
243  textCtrl->SetValue( formatScaleValue( curr_value ) );
244 }
245 
246 
247 void PANEL_PREV_3D::doIncrementRotation( wxSpinEvent& aEvent, double aSign )
248 {
249  wxSpinButton* spinCtrl = (wxSpinButton*) aEvent.GetEventObject();
250  wxTextCtrl* textCtrl = xrot;
251 
252  if( spinCtrl == m_spinYrot )
253  textCtrl = yrot;
254  else if( spinCtrl == m_spinZrot )
255  textCtrl = zrot;
256 
257  double curr_value = DoubleValueFromString( DEGREES, textCtrl->GetValue() ) / 10.0;
258 
259  curr_value += ( ROTATION_INCREMENT * aSign );
260  curr_value = std::max( -MAX_ROTATION, curr_value );
261  curr_value = std::min( curr_value, MAX_ROTATION );
262 
263  textCtrl->SetValue( formatRotationValue( curr_value ) );
264 }
265 
266 
267 void PANEL_PREV_3D::doIncrementOffset( wxSpinEvent& event, double aSign )
268 {
269  wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
270 
271  wxTextCtrl * textCtrl = xoff;
272 
273  if( spinCtrl == m_spinYoffset )
274  textCtrl = yoff;
275  else if( spinCtrl == m_spinZoffset )
276  textCtrl = zoff;
277 
278  double step = OFFSET_INCREMENT_MM;
279 
280  if( m_userUnits == INCHES )
281  step = OFFSET_INCREMENT_MIL/1000.0;
282 
283  double curr_value = DoubleValueFromString( m_userUnits, textCtrl->GetValue() ) / IU_PER_MM;
284 
285  curr_value += ( step * aSign );
286  curr_value = std::max( -MAX_OFFSET, curr_value );
287  curr_value = std::min( curr_value, MAX_OFFSET );
288 
289  textCtrl->SetValue( formatOffsetValue( curr_value ) );
290 }
291 
292 
293 void PANEL_PREV_3D::onMouseWheelScale( wxMouseEvent& event )
294 {
295  wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
296 
297  double step = SCALE_INCREMENT;
298 
299  if( event.ShiftDown( ) )
300  step = SCALE_INCREMENT_FINE;
301 
302  if( event.GetWheelRotation() >= 0 )
303  step = -step;
304 
305  double curr_value = DoubleValueFromString( UNSCALED_UNITS, textCtrl->GetValue() );
306 
307  curr_value += step;
308  curr_value = std::max( 1/MAX_SCALE, curr_value );
309  curr_value = std::min( curr_value, MAX_SCALE );
310 
311  textCtrl->SetValue( formatScaleValue( curr_value ) );
312 }
313 
314 
315 void PANEL_PREV_3D::onMouseWheelRot( wxMouseEvent& event )
316 {
317  wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
318 
319  double step = ROTATION_INCREMENT_WHEEL;
320 
321  if( event.ShiftDown( ) )
323 
324  if( event.GetWheelRotation() >= 0 )
325  step = -step;
326 
327  double curr_value = DoubleValueFromString( DEGREES, textCtrl->GetValue() ) / 10.0;
328 
329  curr_value += step;
330  curr_value = std::max( -MAX_ROTATION, curr_value );
331  curr_value = std::min( curr_value, MAX_ROTATION );
332 
333  textCtrl->SetValue( formatRotationValue( curr_value ) );
334 }
335 
336 
337 void PANEL_PREV_3D::onMouseWheelOffset( wxMouseEvent& event )
338 {
339  wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
340 
341  double step = OFFSET_INCREMENT_MM;
342 
343  if( event.ShiftDown( ) )
345 
346  if( m_userUnits == INCHES )
347  {
348  step = OFFSET_INCREMENT_MIL/1000.0;
349  if( event.ShiftDown( ) )
350  step = OFFSET_INCREMENT_MIL_FINE/1000.0;
351  }
352 
353  if( event.GetWheelRotation() >= 0 )
354  step = -step;
355 
356  double curr_value = DoubleValueFromString( m_userUnits, textCtrl->GetValue() ) / IU_PER_MM;
357 
358  curr_value += step;
359  curr_value = std::max( -MAX_OFFSET, curr_value );
360  curr_value = std::min( curr_value, MAX_OFFSET );
361 
362  textCtrl->SetValue( formatOffsetValue( curr_value ) );
363 }
364 
365 
366 void PANEL_PREV_3D::UpdateDummyModule( bool aReloadRequired )
367 {
368  m_dummyModule->Models().clear();
369 
370  for( size_t i = 0; i < m_parentModelList->size(); ++i )
371  {
372  if( m_parentModelList->at( i ).m_Preview )
373  {
374  m_dummyModule->Models().insert( m_dummyModule->Models().end(),
375  m_parentModelList->at( i ) );
376  }
377  }
378 
379  if( aReloadRequired )
381 
383 }
wxBitmapButton * m_bpvTop
void SetColorsSettings(COLORS_DESIGN_SETTINGS *aColorsSettings)
Function SetColorsSettings.
Definition: class_board.h:575
wxBitmapButton * m_bpvBottom
wxSpinButton * m_spinZoffset
Class PANEL_PREV_3D_BASE.
#define OFFSET_INCREMENT_MM_FINE
CINFO3D_VISU * m_settings3Dviewer
static const int * GetAttributesList(bool aUseAntiAliasing)
Get a list of attributes to pass to wxGLCanvas.
wxSpinButton * m_spinYoffset
void onMouseWheelScale(wxMouseEvent &event) override
wxBitmapButton * m_bpvBack
#define OFFSET_INCREMENT_MM
Implementation of conversion functions that require both schematic and board internal units...
#define SCALE_INCREMENT_FINE
wxBitmapButton * m_bpvLeft
Class BOARD to handle a board.
void onMouseWheelOffset(wxMouseEvent &event) override
wxBitmapButton * m_bpUpdate
Class EDA_3D_CANVAS Implement a canvas based on a wxGLCanvas.
Definition: eda_3d_canvas.h:53
wxString formatRotationValue(double aValue)
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: kicad.cpp:66
wxBoxSizer * m_SizerPanelView
void UpdateDummyModule(bool aRelaodRequired=true)
UpdateModelInfoList - copy shapes from the current shape list which are flagged for preview to the co...
void doIncrementScale(wxSpinEvent &aEvent, double aSign)
std::vector< MODULE_3D_SETTINGS > * m_parentModelList
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
void doIncrementRotation(wxSpinEvent &aEvent, double aSign)
wxString formatScaleValue(double aValue)
VECTOR3D m_Offset
3D model offset (mm)
Definition: class_module.h:102
wxBitmapButton * m_bpvRight
wxString formatOffsetValue(double aValue)
void doIncrementOffset(wxSpinEvent &aEvent, double aSign)
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:79
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
wxSpinButton * m_spinZrot
Defines a panel which is to be added to a wxFileDialog via SetExtraControl(); The panel shows a previ...
#define SCALE_INCREMENT
PCB_GENERAL_SETTINGS & Settings()
EDA_UNITS_T GetUserUnits() const override
Return the user units currently in use.
Definition: draw_frame.h:284
wxSpinButton * m_spinXoffset
Definition: common.h:160
double DoubleValueFromString(EDA_UNITS_T aUnits, const wxString &aTextValue, bool aUseMils)
Function DoubleValueFromString converts aTextValue to a double.
Definition: base_units.cpp:302
MODULE * m_dummyModule
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_INSERT) override
Adds an item to the container.
EDA_3D_CANVAS * m_previewPane
Class CINFO3D_VISU Helper class to handle information needed to display 3D board. ...
Definition: cinfo3d_visu.h:70
#define ENBL_MOUSEWHEEL_PAN_KEY
Definition: pgm_base.h:48
wxSpinButton * m_spinYrot
#define MAX_SCALE
Declaration of the cogl_att_list class.
EDA_UNITS_T m_userUnits
Index into m_parentInfoList.
void SetSelectedModel(int idx)
SetModelDataIdx - Sets the currently selected index in the model list so that the scale/rotation/offs...
wxSpinButton * m_spinXrot
wxBitmapButton * m_bpvFront
wxSpinButton * m_spinZscale
wxSpinButton * m_spinXscale
COLORS_DESIGN_SETTINGS & Colors()
void onMouseWheelRot(wxMouseEvent &event) override
std::list< MODULE_3D_SETTINGS > & Models()
Definition: class_module.h:179
#define OFFSET_INCREMENT_MIL_FINE
see class PGM_BASE
#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
VECTOR3D m_Rotation
3D model rotation (degrees)
Definition: class_module.h:101
void updateOrientation(wxCommandEvent &event) override
updateOrientation - it will receive the events from editing the fields
#define max(a, b)
Definition: auxiliary.h:86
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:170
wxBitmapButton * m_bpvISO
VTBL_ENTRY wxConfigBase * CommonSettings() const
Definition: pgm_base.h:187
size_t i
Definition: json11.cpp:597
VECTOR3D m_Scale
3D model scaling factor (dimensionless)
Definition: class_module.h:100
#define ROTATION_INCREMENT_WHEEL_FINE
#define ROTATION_INCREMENT_WHEEL
PANEL_PREV_3D(wxWindow *aParent, PCB_BASE_FRAME *aFrame, MODULE *aModule, std::vector< MODULE_3D_SETTINGS > *aParentModelList)
#define MAX_OFFSET
#define MAX_ROTATION
static double rotationFromString(const wxString &aValue)
rotationFromString Ensure -MAX_ROTATION <= rotation <= MAX_ROTATION aRotation will be normalized betw...
BOARD * m_dummyBoard
void SetFlag(DISPLAY3D_FLG aFlag, bool aState)
SetFlag - set the status of a flag.
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...
wxString GetAbbreviatedUnitsLabel(EDA_UNITS_T aUnit, bool aUseMils)
Get the units string for a given units type.
Definition: base_units.cpp:432
#define min(a, b)
Definition: auxiliary.h:85
wxSpinButton * m_spinYscale