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