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 
27 #include "panel_prev_model.h"
30 #include <class_board.h>
31 #include <base_units.h>
32 #include <bitmaps.h>
33 #include <dpi_scaling.h>
34 #include <pgm_base.h>
35 #include <project.h>
36 
37 
38 PANEL_PREV_3D::PANEL_PREV_3D( wxWindow* aParent, PCB_BASE_FRAME* aFrame, MODULE* aModule,
39  std::vector<MODULE_3D_SETTINGS> *aParentModelList ) :
40  PANEL_PREV_3D_BASE( aParent, wxID_ANY )
41 {
42  m_userUnits = aFrame->GetUserUnits();
43 
44  initPanel();
45 
46  // Initialize the color settings to draw the board and the footprint
48 
49  m_parentModelList = aParentModelList;
50 
51  m_dummyModule = new MODULE( *aModule );
53 
54  // Set 3d viewer configuration for preview
56 
57  // Create the 3D canvas
60  aFrame->Prj().Get3DCacheManager() );
61 
63 
64  m_SizerPanelView->Add( m_previewPane, 1, wxEXPAND, 5 );
65 }
66 
67 
69 {
70  delete m_settings3Dviewer;
71  delete m_dummyBoard;
72  delete m_previewPane;
73 }
74 
75 
77 {
78  m_dummyBoard = new BOARD();
79  m_selected = -1;
80 
81  // Set the bitmap of 3D view buttons:
82  m_bpvTop->SetBitmap( KiBitmap( axis3d_top_xpm ) );
83  m_bpvFront->SetBitmap( KiBitmap( axis3d_front_xpm ) );
84  m_bpvBack->SetBitmap( KiBitmap( axis3d_back_xpm ) );
85  m_bpvLeft->SetBitmap( KiBitmap( axis3d_left_xpm ) );
86  m_bpvRight->SetBitmap( KiBitmap( axis3d_right_xpm ) );
87  m_bpvBottom->SetBitmap( KiBitmap( axis3d_bottom_xpm ) );
88  m_bpvISO->SetBitmap( KiBitmap( ortho_xpm ) );
89  m_bpUpdate->SetBitmap( KiBitmap( reload_xpm ) );
90 
91  // Set the min and max values of spin buttons (mandatory on Linux)
92  // They are not used, so they are set to min and max 32 bits int values
93  // (the min and max values supported by a wxSpinButton)
94  // It avoids blocking the up or down arrows when reaching this limit after
95  // a few clicks.
96  wxSpinButton* spinButtonList[] =
97  {
101  };
102 
103  for( int ii = 0; ii < 9; ii++ )
104  spinButtonList[ii]->SetRange( INT_MIN, INT_MAX );
105 }
106 
107 
109 {
110  wxCHECK_RET( m_previewPane, "Cannot load settings to null canvas" );
111 
112  wxConfigBase& cmnCfg = *Pgm().CommonSettings();
113 
114  {
115  const DPI_SCALING dpi{ &cmnCfg, this };
116  m_previewPane->SetScaleFactor( dpi.GetScaleFactor() );
117  }
118 
119  {
120  bool option;
121  cmnCfg.Read( ENBL_MOUSEWHEEL_PAN_KEY, &option, false );
123  }
124 }
125 
126 
132 static double rotationFromString( const wxString& aValue )
133 {
134  double rotation = DoubleValueFromString( DEGREES, aValue ) / 10.0;
135 
136  if( rotation > MAX_ROTATION )
137  {
138  int n = rotation / MAX_ROTATION;
139  rotation -= MAX_ROTATION * n;
140  }
141  else if( rotation < -MAX_ROTATION )
142  {
143  int n = -rotation / MAX_ROTATION;
144  rotation += MAX_ROTATION * n;
145  }
146 
147  return rotation;
148 }
149 
150 
151 wxString PANEL_PREV_3D::formatScaleValue( double aValue )
152 {
153  return wxString::Format( "%.4f", aValue );
154 }
155 
156 
157 wxString PANEL_PREV_3D::formatRotationValue( double aValue )
158 {
159  return wxString::Format( "%.2f %s", aValue, GetAbbreviatedUnitsLabel( DEGREES ) );
160 }
161 
162 
163 wxString PANEL_PREV_3D::formatOffsetValue( double aValue )
164 {
165  // Convert from internal units (mm) to user units
166  if( m_userUnits == INCHES )
167  aValue /= 25.4f;
168 
169  return wxString::Format( "%.4f %s", aValue, GetAbbreviatedUnitsLabel( m_userUnits ) );
170 }
171 
172 
174 {
175  if( m_parentModelList && idx >= 0 && idx < (int) m_parentModelList->size() )
176  {
177  m_selected = idx;
178  const MODULE_3D_SETTINGS& modelInfo = m_parentModelList->at( (unsigned) m_selected );
179 
180  // Use ChangeValue() instead of SetValue(). It's not the user making the change, so we
181  // don't want to generate wxEVT_GRID_CELL_CHANGED events.
182 
183  xscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.x ) );
184  yscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.y ) );
185  zscale->ChangeValue( formatScaleValue( modelInfo.m_Scale.z ) );
186 
187  xrot->ChangeValue( formatRotationValue( modelInfo.m_Rotation.x ) );
188  yrot->ChangeValue( formatRotationValue( modelInfo.m_Rotation.y ) );
189  zrot->ChangeValue( formatRotationValue( modelInfo.m_Rotation.z ) );
190 
191  xoff->ChangeValue( formatOffsetValue( modelInfo.m_Offset.x ) );
192  yoff->ChangeValue( formatOffsetValue( modelInfo.m_Offset.y ) );
193  zoff->ChangeValue( formatOffsetValue( modelInfo.m_Offset.z ) );
194  }
195  else
196  {
197  m_selected = -1;
198 
199  xscale->ChangeValue( wxEmptyString );
200  yscale->ChangeValue( wxEmptyString );
201  zscale->ChangeValue( wxEmptyString );
202 
203  xrot->ChangeValue( wxEmptyString );
204  yrot->ChangeValue( wxEmptyString );
205  zrot->ChangeValue( wxEmptyString );
206 
207  xoff->ChangeValue( wxEmptyString );
208  yoff->ChangeValue( wxEmptyString );
209  zoff->ChangeValue( wxEmptyString );
210  }
211 }
212 
213 
214 void PANEL_PREV_3D::updateOrientation( wxCommandEvent &event )
215 {
216  if( m_parentModelList && m_selected >= 0 && m_selected < (int) m_parentModelList->size() )
217  {
218  // Write settings back to the parent
219  MODULE_3D_SETTINGS* modelInfo = &m_parentModelList->at( (unsigned) m_selected );
220 
221  modelInfo->m_Scale.x = DoubleValueFromString( UNSCALED_UNITS, xscale->GetValue() );
222  modelInfo->m_Scale.y = DoubleValueFromString( UNSCALED_UNITS, yscale->GetValue() );
223  modelInfo->m_Scale.z = DoubleValueFromString( UNSCALED_UNITS, zscale->GetValue() );
224 
225  modelInfo->m_Rotation.x = rotationFromString( xrot->GetValue() );
226  modelInfo->m_Rotation.y = rotationFromString( yrot->GetValue() );
227  modelInfo->m_Rotation.z = rotationFromString( zrot->GetValue() );
228 
229  modelInfo->m_Offset.x = DoubleValueFromString( m_userUnits, xoff->GetValue() ) / IU_PER_MM;
230  modelInfo->m_Offset.y = DoubleValueFromString( m_userUnits, yoff->GetValue() ) / IU_PER_MM;
231  modelInfo->m_Offset.z = DoubleValueFromString( m_userUnits, zoff->GetValue() ) / IU_PER_MM;
232 
233  // Update the dummy module for the preview
234  UpdateDummyModule( false );
235  }
236 }
237 
238 
239 void PANEL_PREV_3D::doIncrementScale( wxSpinEvent& event, double aSign )
240 {
241  wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
242 
243  wxTextCtrl * textCtrl = xscale;
244 
245  if( spinCtrl == m_spinYscale )
246  textCtrl = yscale;
247  else if( spinCtrl == m_spinZscale )
248  textCtrl = zscale;
249 
250  double curr_value = DoubleValueFromString( UNSCALED_UNITS, textCtrl->GetValue() );
251 
252  curr_value += ( SCALE_INCREMENT * aSign );
253  curr_value = std::max( 1/MAX_SCALE, curr_value );
254  curr_value = std::min( curr_value, MAX_SCALE );
255 
256  textCtrl->SetValue( formatScaleValue( curr_value ) );
257 }
258 
259 
260 void PANEL_PREV_3D::doIncrementRotation( wxSpinEvent& aEvent, double aSign )
261 {
262  wxSpinButton* spinCtrl = (wxSpinButton*) aEvent.GetEventObject();
263  wxTextCtrl* textCtrl = xrot;
264 
265  if( spinCtrl == m_spinYrot )
266  textCtrl = yrot;
267  else if( spinCtrl == m_spinZrot )
268  textCtrl = zrot;
269 
270  double curr_value = DoubleValueFromString( DEGREES, textCtrl->GetValue() ) / 10.0;
271 
272  curr_value += ( ROTATION_INCREMENT * aSign );
273  curr_value = std::max( -MAX_ROTATION, curr_value );
274  curr_value = std::min( curr_value, MAX_ROTATION );
275 
276  textCtrl->SetValue( formatRotationValue( curr_value ) );
277 }
278 
279 
280 void PANEL_PREV_3D::doIncrementOffset( wxSpinEvent& event, double aSign )
281 {
282  wxSpinButton* spinCtrl = (wxSpinButton*) event.GetEventObject();
283 
284  wxTextCtrl * textCtrl = xoff;
285 
286  if( spinCtrl == m_spinYoffset )
287  textCtrl = yoff;
288  else if( spinCtrl == m_spinZoffset )
289  textCtrl = zoff;
290 
291  double step = OFFSET_INCREMENT_MM;
292 
293  if( m_userUnits == INCHES )
294  step = OFFSET_INCREMENT_MIL/1000.0;
295 
296  double curr_value = DoubleValueFromString( m_userUnits, textCtrl->GetValue() ) / IU_PER_MM;
297 
298  curr_value += ( step * aSign );
299  curr_value = std::max( -MAX_OFFSET, curr_value );
300  curr_value = std::min( curr_value, MAX_OFFSET );
301 
302  textCtrl->SetValue( formatOffsetValue( curr_value ) );
303 }
304 
305 
306 void PANEL_PREV_3D::onMouseWheelScale( wxMouseEvent& event )
307 {
308  wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
309 
310  double step = SCALE_INCREMENT;
311 
312  if( event.ShiftDown( ) )
313  step = SCALE_INCREMENT_FINE;
314 
315  if( event.GetWheelRotation() >= 0 )
316  step = -step;
317 
318  double curr_value = DoubleValueFromString( UNSCALED_UNITS, textCtrl->GetValue() );
319 
320  curr_value += step;
321  curr_value = std::max( 1/MAX_SCALE, curr_value );
322  curr_value = std::min( curr_value, MAX_SCALE );
323 
324  textCtrl->SetValue( formatScaleValue( curr_value ) );
325 }
326 
327 
328 void PANEL_PREV_3D::onMouseWheelRot( wxMouseEvent& event )
329 {
330  wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
331 
332  double step = ROTATION_INCREMENT_WHEEL;
333 
334  if( event.ShiftDown( ) )
336 
337  if( event.GetWheelRotation() >= 0 )
338  step = -step;
339 
340  double curr_value = DoubleValueFromString( DEGREES, textCtrl->GetValue() ) / 10.0;
341 
342  curr_value += step;
343  curr_value = std::max( -MAX_ROTATION, curr_value );
344  curr_value = std::min( curr_value, MAX_ROTATION );
345 
346  textCtrl->SetValue( formatRotationValue( curr_value ) );
347 }
348 
349 
350 void PANEL_PREV_3D::onMouseWheelOffset( wxMouseEvent& event )
351 {
352  wxTextCtrl* textCtrl = (wxTextCtrl*) event.GetEventObject();
353 
354  double step = OFFSET_INCREMENT_MM;
355 
356  if( event.ShiftDown( ) )
358 
359  if( m_userUnits == INCHES )
360  {
361  step = OFFSET_INCREMENT_MIL/1000.0;
362  if( event.ShiftDown( ) )
363  step = OFFSET_INCREMENT_MIL_FINE/1000.0;
364  }
365 
366  if( event.GetWheelRotation() >= 0 )
367  step = -step;
368 
369  double curr_value = DoubleValueFromString( m_userUnits, textCtrl->GetValue() ) / IU_PER_MM;
370 
371  curr_value += step;
372  curr_value = std::max( -MAX_OFFSET, curr_value );
373  curr_value = std::min( curr_value, MAX_OFFSET );
374 
375  textCtrl->SetValue( formatOffsetValue( curr_value ) );
376 }
377 
378 
379 void PANEL_PREV_3D::UpdateDummyModule( bool aReloadRequired )
380 {
381  m_dummyModule->Models().clear();
382 
383  for( size_t i = 0; i < m_parentModelList->size(); ++i )
384  {
385  if( m_parentModelList->at( i ).m_Preview )
386  {
387  m_dummyModule->Models().insert( m_dummyModule->Models().end(),
388  m_parentModelList->at( i ) );
389  }
390  }
391 
392  if( aReloadRequired )
394 
396 }
wxBitmapButton * m_bpvTop
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
void onMouseWheelOffset(wxMouseEvent &event) override
wxBitmapButton * m_bpUpdate
Implement a canvas based on a wxGLCanvas.
Definition: eda_3d_canvas.h:52
wxString formatRotationValue(double aValue)
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: kicad.cpp:65
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:101
Class to handle configuration and automatic determination of the DPI scale to use for canvases.
Definition: dpi_scaling.h:35
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
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()
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
wxSpinButton * m_spinXoffset
Definition: common.h:158
double DoubleValueFromString(EDA_UNITS_T aUnits, const wxString &aTextValue, bool aUseMils)
Function DoubleValueFromString converts aTextValue to a double.
Definition: base_units.cpp:307
MODULE * m_dummyModule
void loadCommonSettings()
Load 3D relevant settings from the user configuration.
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:51
wxSpinButton * m_spinYrot
void SetGeneralSettings(PCB_GENERAL_SETTINGS *aGeneralSettings)
Definition: class_board.h:577
#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
VTBL_ENTRY wxConfigBase * CommonSettings() const
Definition: pgm_base.h:201
void onMouseWheelRot(wxMouseEvent &event) override
std::list< MODULE_3D_SETTINGS > & Models()
Definition: class_module.h:183
#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:100
EDA_UNITS_T GetUserUnits() const
Return the user units currently in use.
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:161
wxBitmapButton * m_bpvISO
size_t i
Definition: json11.cpp:597
VECTOR3D m_Scale
3D model scaling factor (dimensionless)
Definition: class_module.h:99
void SetScaleFactor(double aFactor)
Set the canvas scale factor, probably for a hi-DPI display.
#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:437
#define min(a, b)
Definition: auxiliary.h:85
wxSpinButton * m_spinYscale