KiCad PCB EDA Suite
eda_3d_viewer_frame.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) 2015-2016 Mario Luzeiro <[email protected]>
5  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
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 #include <wx/filename.h>
26 #include <wx/msgdlg.h>
27 #include <wx/string.h>
28 #include <wx/wupdlock.h>
29 #include <wx/clipbrd.h>
30 #include <wx/filedlg.h>
31 #include <wx/treebook.h>
32 #include "eda_3d_viewer_frame.h"
33 #include <eda_3d_viewer_settings.h>
34 #include <3d_viewer_id.h>
38 #include <bitmaps.h>
39 #include <board_design_settings.h>
40 #include <core/arraydim.h>
41 #include <gal/dpi_scaling.h>
42 #include <pgm_base.h>
43 #include <project.h>
46 #include <tool/action_manager.h>
47 #include <tool/common_control.h>
48 #include <tool/tool_manager.h>
49 #include <tool/tool_dispatcher.h>
50 #include <tool/action_toolbar.h>
51 #include <widgets/infobar.h>
52 #include <widgets/paged_dialog.h>
57 #include <panel_hotkeys_editor.h>
59 
67 const wxChar* EDA_3D_VIEWER_FRAME::m_logTrace = wxT( "KI_TRACE_EDA_3D_VIEWER" );
68 
69 
70 BEGIN_EVENT_TABLE( EDA_3D_VIEWER_FRAME, EDA_BASE_FRAME )
71 
72  EVT_ACTIVATE( EDA_3D_VIEWER_FRAME::OnActivate )
73  EVT_SET_FOCUS( EDA_3D_VIEWER_FRAME::OnSetFocus )
74 
76  EDA_3D_VIEWER_FRAME::Process_Special_Functions )
77 
78  EVT_MENU( wxID_CLOSE, EDA_3D_VIEWER_FRAME::Exit3DFrame )
79  EVT_MENU( ID_RENDER_CURRENT_VIEW, EDA_3D_VIEWER_FRAME::OnRenderEngineSelection )
80  EVT_MENU( ID_DISABLE_RAY_TRACING, EDA_3D_VIEWER_FRAME::OnDisableRayTracing )
81 
82  EVT_CLOSE( EDA_3D_VIEWER_FRAME::OnCloseWindow )
83 END_EVENT_TABLE()
84 
85 
87  const wxString &aTitle, long style ) :
88  KIWAY_PLAYER( aKiway, aParent, FRAME_PCB_DISPLAY3D, aTitle, wxDefaultPosition,
89  wxDefaultSize, style, QUALIFIED_VIEWER3D_FRAMENAME( aParent ) ),
90  m_mainToolBar( nullptr ),
91  m_canvas( nullptr ),
92  m_currentCamera( m_trackBallCamera ),
93  m_trackBallCamera( 2 * RANGE_SCALE_3D )
94 {
95  wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME %s" ), aTitle );
96 
97  m_disable_ray_tracing = false;
98  m_aboutTitle = _( "KiCad 3D Viewer" );
99 
100  // Give it an icon
101  wxIcon icon;
102  icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_3d ) );
103  SetIcon( icon );
104 
105  // Create the status line
106  static const int status_dims[4] = { -1, 170, 130, 130 };
107 
108  wxStatusBar *status_bar = CreateStatusBar( arrayDim( status_dims ) );
109  SetStatusWidths( arrayDim( status_dims ), status_dims );
110 
111  m_canvas = new EDA_3D_CANVAS( this,
112  OGL_ATT_LIST::GetAttributesList( m_boardAdapter.GetAntiAliasingMode() ),
113  m_boardAdapter, m_currentCamera,
114  Prj().Get3DCacheManager() );
115 
116  auto config = Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>();
117  LoadSettings( config );
118 
119  // Some settings need the canvas
120  loadCommonSettings();
121 
122  // Create the manager
123  m_toolManager = new TOOL_MANAGER;
124  m_toolManager->SetEnvironment( GetBoard(), nullptr, nullptr, config, this );
125 
126  m_actions = new EDA_3D_ACTIONS();
127  m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager );
128  m_canvas->SetEventDispatcher( m_toolDispatcher );
129 
130  // Register tools
131  m_toolManager->RegisterTool( new COMMON_CONTROL );
132  m_toolManager->RegisterTool( new EDA_3D_CONTROLLER );
133  m_toolManager->InitTools();
134 
135  setupUIConditions();
136 
137  if( EDA_3D_CONTROLLER* ctrlTool = GetToolManager()->GetTool<EDA_3D_CONTROLLER>() )
138  ctrlTool->SetRotationIncrement( config->m_Camera.rotation_increment );
139 
140  // Run the viewer control tool, it is supposed to be always active
141  m_toolManager->InvokeTool( "3DViewer.Control" );
142 
143  CreateMenuBar();
144  ReCreateMainToolbar();
145 
146  m_infoBar = new WX_INFOBAR( this, &m_auimgr );
147 
148  m_auimgr.SetManagedWindow( this );
149 
150  m_auimgr.AddPane( m_mainToolBar, EDA_PANE().HToolbar().Name( "MainToolbar" ).Top().Layer( 6 ) );
151  m_auimgr.AddPane( m_infoBar, EDA_PANE().InfoBar().Name( "InfoBar" ).Top().Layer(1) );
152  m_auimgr.AddPane( m_canvas, EDA_PANE().Canvas().Name( "DrawFrame" ).Center() );
153 
154  // Call Update() to fix all pane default sizes, especially the "InfoBar" pane before
155  // hiding it.
156  m_auimgr.Update();
157 
158  // We don't want the infobar displayed right away
159  m_auimgr.GetPane( "InfoBar" ).Hide();
160  m_auimgr.Update();
161 
162  m_canvas->SetInfoBar( m_infoBar );
163  m_canvas->SetStatusBar( status_bar );
164 
165  // Fixes bug in Windows (XP and possibly others) where the canvas requires the focus
166  // in order to receive mouse events. Otherwise, the user has to click somewhere on
167  // the canvas before it will respond to mouse wheel events.
168  m_canvas->SetFocus();
169 }
170 
171 
173 {
174  m_canvas->SetEventDispatcher( nullptr );
175 
176  m_auimgr.UnInit();
177 
178  // m_canvas delete will be called by wxWidget manager
179  //delete m_canvas;
180  //m_canvas = nullptr;
181 }
182 
183 
185 {
187 
190 
191 // Helper to define check conditions
192 #define FlagCheck( x ) ACTION_CONDITIONS().Check( cond.Flag( x ) )
193 #define GridSizeCheck( x ) ACTION_CONDITIONS().Check( cond.GridSize( x ) )
194 
195  auto raytracingCondition =
196  [this]( const SELECTION& aSel )
197  {
199  };
200 
202  ACTION_CONDITIONS().Check( raytracingCondition ) );
203 
207 
210 
216 
217 
218  auto orthoCondition =
219  [this]( const SELECTION& )
220  {
222  };
223 
224  mgr->SetConditions( EDA_3D_ACTIONS::toggleOrtho, ACTION_CONDITIONS().Check( orthoCondition ) );
225 
226 #undef FlagCheck
227 #undef GridSizeCheck
228 }
229 
230 
232  PANEL_HOTKEYS_EDITOR* aHotkeysPanel )
233 {
234  wxTreebook* book = aParent->GetTreebook();
235 
236  book->AddPage( new wxPanel( book ), _( "3D Viewer" ) );
237  book->AddSubPage( new PANEL_3D_DISPLAY_OPTIONS( this, book ), _( "General" ) );
238  book->AddSubPage( new PANEL_3D_OPENGL_OPTIONS( this, book ), _( "Realtime Renderer" ) );
239  book->AddSubPage( new PANEL_3D_RAYTRACING_OPTIONS( this, book ), _( "Raytracing Renderer" ) );
240  book->AddSubPage( new PANEL_3D_COLORS( this, book ), _( "Colors" ) );
241 
242  aHotkeysPanel->AddHotKeys( GetToolManager() );
243 }
244 
245 
247 {
248  // This will schedule a request to load later
249  if( m_canvas )
250  m_canvas->ReloadRequest( GetBoard(), Prj().Get3DCacheManager() );
251 }
252 
253 
254 void EDA_3D_VIEWER_FRAME::NewDisplay( bool aForceImmediateRedraw )
255 {
256  ReloadRequest();
257 
258  // After the ReloadRequest call, the refresh often takes a bit of time,
259  // and it is made here only on request.
260  if( aForceImmediateRedraw )
261  m_canvas->Refresh();
262 }
263 
264 
266 {
267  // Only update in OpenGL for an interactive interaction
269  m_canvas->Request_refresh( true );
270 }
271 
272 
274 {
277  else
278  NewDisplay( true );
279 }
280 
281 
282 void EDA_3D_VIEWER_FRAME::Exit3DFrame( wxCommandEvent &event )
283 {
284  wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::Exit3DFrame" ) );
285 
286  Close( true );
287 }
288 
289 
290 void EDA_3D_VIEWER_FRAME::OnCloseWindow( wxCloseEvent &event )
291 {
292  wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::OnCloseWindow" ) );
293 
294  if( m_canvas )
295  m_canvas->Close();
296 
297  // m_canvas delete will be called by wxWidget manager
298  //delete m_canvas;
299  //m_canvas = nullptr;
300 
301  Destroy();
302  event.Skip( true );
303 }
304 
305 
307 {
308  int id = event.GetId();
309  bool isChecked = event.IsChecked();
310 
311  wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::Process_Special_Functions id %d "
312  "isChecked %d" ),
313  id,
314  isChecked );
315 
316  if( m_canvas == nullptr )
317  return;
318 
319  switch( id )
320  {
321  case ID_RELOAD3D_BOARD:
322  NewDisplay( true );
323  break;
324 
328  takeScreenshot( event );
329  return;
330 
332  {
333  auto cfg = Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>();
334  cfg->ResetToDefaults();
335  LoadSettings( cfg );
336 
337  // Tell canvas that we (may have) changed the render engine
339 
340  NewDisplay( true );
341  }
342  return;
343 
344  default:
345  wxFAIL_MSG( wxT( "Invalid event in EDA_3D_VIEWER_FRAME::Process_Special_Functions()" ) );
346  return;
347  }
348 }
349 
350 
351 void EDA_3D_VIEWER_FRAME::OnRenderEngineSelection( wxCommandEvent &event )
352 {
353  const RENDER_ENGINE old_engine = m_boardAdapter.GetRenderEngine();
354 
355  if( old_engine == RENDER_ENGINE::OPENGL )
357  else
359 
360  wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::OnRenderEngineSelection type %s " ),
361  m_boardAdapter.GetRenderEngine() == RENDER_ENGINE::RAYTRACING ? wxT( "raytracing" )
362  : wxT( "realtime" ) );
363 
364  if( old_engine != m_boardAdapter.GetRenderEngine() )
366 }
367 
368 
369 void EDA_3D_VIEWER_FRAME::OnDisableRayTracing( wxCommandEvent& aEvent )
370 {
371  wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::%s disabling ray tracing." ),
372  __WXFUNCTION__ );
373 
374  m_disable_ray_tracing = true;
376 }
377 
378 
379 void EDA_3D_VIEWER_FRAME::OnActivate( wxActivateEvent &aEvent )
380 {
381  wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::OnActivate" ) );
382 
383  if( aEvent.GetActive() && m_canvas )
384  {
385  // Reload data if 3D frame shows a board,
386  // because it can be changed since last frame activation
389 
390  // Activates again the focus of the canvas so it will catch mouse and key events
391  m_canvas->SetFocus();
392  }
393 
394  aEvent.Skip(); // required under wxMAC
395 }
396 
397 
398 void EDA_3D_VIEWER_FRAME::OnSetFocus( wxFocusEvent& aEvent )
399 {
400  // Activates again the focus of the canvas so it will catch mouse and key events
401  if( m_canvas )
402  m_canvas->SetFocus();
403 
404  aEvent.Skip();
405 }
406 
407 
409 {
411 
412  EDA_3D_VIEWER_SETTINGS* cfg = dynamic_cast<EDA_3D_VIEWER_SETTINGS*>( aCfg );
413  wxASSERT( cfg );
414 
415  wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::LoadSettings" ) );
416 
417  if( cfg )
418  {
425 
428 
429  for( size_t i = 0; i < cfg->m_Render.raytrace_lightColor.size(); ++i )
430  {
433 
434  SFVEC2F sphericalCoord =
435  SFVEC2F( ( cfg->m_Render.raytrace_lightElevation[i] + 90.0f ) / 180.0f,
436  cfg->m_Render.raytrace_lightAzimuth[i] / 180.0f );
437 
438  sphericalCoord.x = glm::clamp( sphericalCoord.x, 0.0f, 1.0f );
439  sphericalCoord.y = glm::clamp( sphericalCoord.y, 0.0f, 2.0f );
440 
441  m_boardAdapter.m_RtLightSphericalCoords[i] = sphericalCoord;
442  }
443 
444 #define TRANSFER_SETTING( flag, field ) m_boardAdapter.SetFlag( flag, cfg->m_Render.field )
445 
447  TRANSFER_SETTING( FL_SUBTRACT_MASK_FROM_SILK, subtract_mask_from_silk );
448 
449  // OpenGL options
450  TRANSFER_SETTING( FL_RENDER_OPENGL_COPPER_THICKNESS, opengl_copper_thickness );
451  TRANSFER_SETTING( FL_RENDER_OPENGL_SHOW_MODEL_BBOX, opengl_show_model_bbox );
452  TRANSFER_SETTING( FL_HIGHLIGHT_ROLLOVER_ITEM, opengl_highlight_on_rollover );
453  TRANSFER_SETTING( FL_RENDER_OPENGL_AA_DISABLE_ON_MOVE, opengl_AA_disableOnMove );
454  TRANSFER_SETTING( FL_RENDER_OPENGL_THICKNESS_DISABLE_ON_MOVE, opengl_thickness_disableOnMove );
455  TRANSFER_SETTING( FL_RENDER_OPENGL_VIAS_DISABLE_ON_MOVE, opengl_vias_disableOnMove );
456  TRANSFER_SETTING( FL_RENDER_OPENGL_HOLES_DISABLE_ON_MOVE, opengl_holes_disableOnMove );
457 
458  // Raytracing options
459  TRANSFER_SETTING( FL_RENDER_RAYTRACING_SHADOWS, raytrace_shadows );
460  TRANSFER_SETTING( FL_RENDER_RAYTRACING_BACKFLOOR, raytrace_backfloor );
461  TRANSFER_SETTING( FL_RENDER_RAYTRACING_REFRACTIONS, raytrace_refractions );
462  TRANSFER_SETTING( FL_RENDER_RAYTRACING_REFLECTIONS, raytrace_reflections );
463  TRANSFER_SETTING( FL_RENDER_RAYTRACING_POST_PROCESSING, raytrace_post_processing );
464  TRANSFER_SETTING( FL_RENDER_RAYTRACING_ANTI_ALIASING, raytrace_anti_aliasing );
465  TRANSFER_SETTING( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES, raytrace_procedural_textures );
466 
467  TRANSFER_SETTING( FL_AXIS, show_axis );
468  TRANSFER_SETTING( FL_FP_ATTRIBUTES_NORMAL, show_footprints_normal );
469  TRANSFER_SETTING( FL_FP_ATTRIBUTES_NORMAL_INSERT, show_footprints_insert );
470  TRANSFER_SETTING( FL_FP_ATTRIBUTES_VIRTUAL, show_footprints_virtual );
471  TRANSFER_SETTING( FL_ZONE, show_zones );
472  TRANSFER_SETTING( FL_ADHESIVE, show_adhesive );
473  TRANSFER_SETTING( FL_SILKSCREEN, show_silkscreen );
474  TRANSFER_SETTING( FL_SOLDERMASK, show_soldermask );
475  TRANSFER_SETTING( FL_SOLDERPASTE, show_solderpaste );
476  TRANSFER_SETTING( FL_COMMENTS, show_comments );
477  TRANSFER_SETTING( FL_ECO, show_eco );
478  TRANSFER_SETTING( FL_SHOW_BOARD_BODY, show_board_body );
479  TRANSFER_SETTING( FL_CLIP_SILK_ON_VIA_ANNULUS, clip_silk_on_via_annulus );
480  TRANSFER_SETTING( FL_RENDER_PLATED_PADS_AS_PLATED, renderPlatedPadsAsPlated );
481 
482  m_boardAdapter.SetGridType( static_cast<GRID3D_TYPE>( cfg->m_Render.grid_type ) );
484  static_cast<ANTIALIASING_MODE>( cfg->m_Render.opengl_AA_mode ) );
485 
488 
492 
496 
501 
502  // When opening the 3D viewer, we use the opengl mode, not the ray tracing engine
503  // because the ray tracing is very time consumming, and can be seen as not working
504  // (freeze window) with large boards.
505 #if 0
506  RENDER_ENGINE engine = static_cast<RENDER_ENGINE>( cfg->m_Render.engine );
507  wxLogTrace( m_logTrace, engine == RENDER_ENGINE::RAYTRACING ?
508  wxT( "EDA_3D_VIEWER_FRAME::LoadSettings render setting Ray Trace" )
509  :
510  wxT( "EDA_3D_VIEWER_FRAME::LoadSettings render setting OpenGL" ) );
511 #else
513 #endif
514 
515  m_boardAdapter.SetMaterialMode( static_cast<MATERIAL_MODE>( cfg->m_Render.material_mode ) );
516 
520 
521 #undef TRANSFER_SETTING
522  }
523 }
524 
525 
527 {
528  auto cfg = Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>();
529 
531 
532  wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::SaveSettings" ) );
533 
535  wxT( "EDA_3D_VIEWER_FRAME::SaveSettings render setting Ray Trace" ) :
536  wxT( "EDA_3D_VIEWER_FRAME::SaveSettings render setting OpenGL" ) );
537 
538  if( cfg )
539  {
540  auto save_color =
541  [] ( const SFVEC3F& aSource, COLOR4D& aTarget )
542  {
543  aTarget = COLOR4D( aSource.r, aSource.g, aSource.b, 1.0 );
544  };
545 
546  save_color( m_boardAdapter.m_RtCameraLightColor, cfg->m_Render.raytrace_lightColorCamera );
547  save_color( m_boardAdapter.m_RtLightColorTop, cfg->m_Render.raytrace_lightColorTop );
548  save_color( m_boardAdapter.m_RtLightColorBottom, cfg->m_Render.raytrace_lightColorBottom );
549 
550  for( size_t i = 0; i < cfg->m_Render.raytrace_lightColor.size(); ++i )
551  {
552  save_color( m_boardAdapter.m_RtLightColor[i], cfg->m_Render.raytrace_lightColor[i] );
553 
554  cfg->m_Render.raytrace_lightElevation[i] =
555  (int)( m_boardAdapter.m_RtLightSphericalCoords[i].x * 180.0f - 90.0f );
556  cfg->m_Render.raytrace_lightAzimuth[i] =
557  (int)( m_boardAdapter.m_RtLightSphericalCoords[i].y * 180.0f );
558  }
559 
560  cfg->m_Render.raytrace_nrsamples_shadows = m_boardAdapter.m_RtShadowSampleCount;
561  cfg->m_Render.raytrace_nrsamples_reflections = m_boardAdapter.m_RtReflectionSampleCount;
562  cfg->m_Render.raytrace_nrsamples_refractions = m_boardAdapter.m_RtRefractionSampleCount;
563 
564  cfg->m_Render.raytrace_spread_shadows = m_boardAdapter.m_RtSpreadShadows;
565  cfg->m_Render.raytrace_spread_reflections = m_boardAdapter.m_RtSpreadReflections;
566  cfg->m_Render.raytrace_spread_refractions = m_boardAdapter.m_RtSpreadRefractions;
567 
568  cfg->m_Render.raytrace_recursivelevel_refractions =
570  cfg->m_Render.raytrace_recursivelevel_reflections =
572 
573 #define TRANSFER_SETTING( field, flag ) cfg->m_Render.field = m_boardAdapter.GetFlag( flag )
574 
575  cfg->m_Render.engine = static_cast<int>( m_boardAdapter.GetRenderEngine() );
576  cfg->m_Render.grid_type = static_cast<int>( m_boardAdapter.GetGridType() );
577  cfg->m_Render.material_mode = static_cast<int>( m_boardAdapter.GetMaterialMode() );
578  cfg->m_Render.opengl_AA_mode = static_cast<int>( m_boardAdapter.GetAntiAliasingMode() );
579 
580  save_color( m_boardAdapter.m_OpenGlSelectionColor, cfg->m_Render.opengl_selection_color );
581 
582  cfg->m_Camera.animation_enabled = m_canvas->GetAnimationEnabled();
583  cfg->m_Camera.moving_speed_multiplier = m_canvas->GetMovingSpeedMultiplier();
584  cfg->m_Camera.projection_mode = m_canvas->GetProjectionMode();
585 
586  if( EDA_3D_CONTROLLER* ctrlTool = GetToolManager()->GetTool<EDA_3D_CONTROLLER>() )
587  cfg->m_Camera.rotation_increment = ctrlTool->GetRotationIncrement();
588 
589  TRANSFER_SETTING( opengl_AA_disableOnMove, FL_RENDER_OPENGL_AA_DISABLE_ON_MOVE );
590  TRANSFER_SETTING( opengl_copper_thickness, FL_RENDER_OPENGL_COPPER_THICKNESS );
591  TRANSFER_SETTING( opengl_show_model_bbox, FL_RENDER_OPENGL_SHOW_MODEL_BBOX );
592  TRANSFER_SETTING( opengl_highlight_on_rollover, FL_HIGHLIGHT_ROLLOVER_ITEM );
593  TRANSFER_SETTING( opengl_thickness_disableOnMove, FL_RENDER_OPENGL_THICKNESS_DISABLE_ON_MOVE );
594  TRANSFER_SETTING( opengl_vias_disableOnMove, FL_RENDER_OPENGL_VIAS_DISABLE_ON_MOVE );
595  TRANSFER_SETTING( opengl_holes_disableOnMove, FL_RENDER_OPENGL_HOLES_DISABLE_ON_MOVE );
596 
597  TRANSFER_SETTING( raytrace_anti_aliasing, FL_RENDER_RAYTRACING_ANTI_ALIASING );
598  TRANSFER_SETTING( raytrace_backfloor, FL_RENDER_RAYTRACING_BACKFLOOR );
599  TRANSFER_SETTING( raytrace_post_processing, FL_RENDER_RAYTRACING_POST_PROCESSING );
600  TRANSFER_SETTING( raytrace_procedural_textures, FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES );
601  TRANSFER_SETTING( raytrace_reflections, FL_RENDER_RAYTRACING_REFLECTIONS );
602  TRANSFER_SETTING( raytrace_refractions, FL_RENDER_RAYTRACING_REFRACTIONS );
603  TRANSFER_SETTING( raytrace_shadows, FL_RENDER_RAYTRACING_SHADOWS );
604 
606  TRANSFER_SETTING( show_adhesive, FL_ADHESIVE );
607  TRANSFER_SETTING( show_axis, FL_AXIS );
608  TRANSFER_SETTING( show_board_body, FL_SHOW_BOARD_BODY );
609  TRANSFER_SETTING( clip_silk_on_via_annulus, FL_CLIP_SILK_ON_VIA_ANNULUS );
610  TRANSFER_SETTING( renderPlatedPadsAsPlated, FL_RENDER_PLATED_PADS_AS_PLATED );
611  TRANSFER_SETTING( show_comments, FL_COMMENTS );
612  TRANSFER_SETTING( show_eco, FL_ECO );
613  TRANSFER_SETTING( show_footprints_insert, FL_FP_ATTRIBUTES_NORMAL_INSERT );
614  TRANSFER_SETTING( show_footprints_normal, FL_FP_ATTRIBUTES_NORMAL );
615  TRANSFER_SETTING( show_footprints_virtual, FL_FP_ATTRIBUTES_VIRTUAL );
616  TRANSFER_SETTING( show_silkscreen, FL_SILKSCREEN );
617  TRANSFER_SETTING( show_soldermask, FL_SOLDERMASK );
618  TRANSFER_SETTING( show_solderpaste, FL_SOLDERPASTE );
619  TRANSFER_SETTING( show_zones, FL_ZONE );
620  TRANSFER_SETTING( subtract_mask_from_silk, FL_SUBTRACT_MASK_FROM_SILK );
621 
622 #undef TRANSFER_SETTING
623  }
624 }
625 
626 
627 void EDA_3D_VIEWER_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
628 {
629  wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::CommonSettingsChanged" ) );
630 
631  // Regen menu bars, etc
632  EDA_BASE_FRAME::CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
633 
634  // There is no base class that handles toolbars for this frame
636 
638 
639  NewDisplay( true );
640 }
641 
642 
643 void EDA_3D_VIEWER_FRAME::takeScreenshot( wxCommandEvent& event )
644 {
645  wxString fullFileName;
646  bool fmt_is_jpeg = false;
647 
648  if( event.GetId() == ID_MENU_SCREENCOPY_JPEG )
649  fmt_is_jpeg = true;
650 
651  if( event.GetId() != ID_TOOL_SCREENCOPY_TOCLIBBOARD )
652  {
653  // Remember path between saves during this session only.
654  const wxString wildcard = fmt_is_jpeg ? JpegFileWildcard() : PngFileWildcard();
655  const wxString ext = fmt_is_jpeg ? JpegFileExtension : PngFileExtension;
656 
657  // First time path is set to the project path.
658  if( !m_defaultSaveScreenshotFileName.IsOk() )
660 
661  m_defaultSaveScreenshotFileName.SetExt( ext );
662 
663  wxFileDialog dlg( this, _( "3D Image File Name" ),
665  m_defaultSaveScreenshotFileName.GetFullName(), wildcard,
666  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
667 
668  if( dlg.ShowModal() == wxID_CANCEL )
669  return;
670 
671  m_defaultSaveScreenshotFileName = dlg.GetPath();
672 
673  if( m_defaultSaveScreenshotFileName.GetExt().IsEmpty() )
674  m_defaultSaveScreenshotFileName.SetExt( ext );
675 
676  fullFileName = m_defaultSaveScreenshotFileName.GetFullPath();
677 
678  wxFileName fn = fullFileName;
679 
680  if( !fn.IsDirWritable() )
681  {
682  wxString msg;
683 
684  msg.Printf( _( "Insufficient permissions to save file '%s'." ), fullFileName );
685  wxMessageBox( msg, _( "Error" ), wxOK | wxICON_ERROR, this );
686  return;
687  }
688 
689  // Be sure the screen area destroyed by the file dialog is redrawn
690  // before making a screen copy.
691  // Without this call, under Linux the screen refresh is made to late.
692  wxYield();
693  }
694 
695  // Be sure we have the latest 3D view (remember 3D view is buffered)
696  m_canvas->Request_refresh( true );
697  wxYield();
698 
699  // Build image from the 3D buffer
700  wxWindowUpdateLocker noUpdates( this );
701 
702  wxImage screenshotImage;
703 
704  if( m_canvas )
705  m_canvas->GetScreenshot( screenshotImage );
706 
707  if( event.GetId() == ID_TOOL_SCREENCOPY_TOCLIBBOARD )
708  {
709  wxBitmap bitmap( screenshotImage );
710 
711  wxLogNull doNotLog; // disable logging of failed clipboard actions
712 
713  if( wxTheClipboard->Open() )
714  {
715  wxBitmapDataObject* dobjBmp = new wxBitmapDataObject( bitmap );
716 
717  if( !wxTheClipboard->SetData( dobjBmp ) )
718  wxMessageBox( _( "Failed to copy image to clipboard" ) );
719 
720  wxTheClipboard->Flush(); /* the data in clipboard will stay
721  * available after the application exits */
722  wxTheClipboard->Close();
723  }
724  }
725  else
726  {
727  if( !screenshotImage.SaveFile( fullFileName,
728  fmt_is_jpeg ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG ) )
729  wxMessageBox( _( "Can't save file" ) );
730 
731  screenshotImage.Destroy();
732  }
733 }
734 
735 
737 {
738  wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::RenderEngineChanged()" ) );
739 
740  if( m_canvas )
742 }
743 
744 
746 {
747  wxCHECK_RET( m_canvas, wxT( "Cannot load settings to null canvas" ) );
748 
749  COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
750 
751  const DPI_SCALING dpi{ settings, this };
752  m_canvas->SetScaleFactor( dpi.GetScaleFactor() );
753  // TODO(JE) use all control options
755 }
void ResetToDefaults()
Resets all parameters to default values.
GRID3D_TYPE GetGridType() const noexcept
Get the current grid.
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
void setupUIConditions() override
Setup the UI conditions for the various actions and their controls in this frame.
int GetMovingSpeedMultiplier() const
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:64
int m_RtShadowSampleCount
#define FlagCheck(x)
PROJECTION_TYPE GetProjection()
Definition: camera.h:161
const std::string JpegFileExtension
static TOOL_ACTION show10mmGrid
#define TRANSFER_SETTING(flag, field)
virtual void SaveSettings(APP_SETTINGS_BASE *aCfg)
Save common frame parameters to a configuration data file.
BOARD_ADAPTER m_boardAdapter
void SetAntiAliasingMode(ANTIALIASING_MODE aAAmode)
Set the current antialiasing mode value.
SFVEC4F GetColor(const COLOR4D &aColor) const
PCB_BASE_FRAME * Parent() const
void OnSetFocus(wxFocusEvent &event)
PROJECT & Prj()
Definition: kicad.cpp:403
void ReCreateMainToolbar()
Definition: 3d_toolbar.cpp:36
void SetFlag(DISPLAY3D_FLG aFlag, bool aState)
Set the status of a flag.
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.
EDA_3D_ACTIONS.
void SetProjectionMode(int aMode)
void Process_Special_Functions(wxCommandEvent &event)
virtual void setupUIConditions()
Setup the UI conditions for the various actions and their controls in this frame.
EDA_3D_CANVAS * m_canvas
void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged) override
Notification that common settings are updated.
void OnDisableRayTracing(wxCommandEvent &aEvent)
virtual void RegisterUIUpdateHandler(int aID, const ACTION_CONDITIONS &aConditions) override
Register a UI update handler for the control with ID aID.
std::vector< SFVEC2F > m_RtLightSphericalCoords
Implement a canvas based on a wxGLCanvas.
Definition: eda_3d_canvas.h:48
bool IsReloadRequestPending() const
Query if there is a pending reload request.
Definition: eda_3d_canvas.h:91
#define GridSizeCheck(x)
void AddHotKeys(TOOL_MANAGER *aToolMgr)
wxString JpegFileWildcard()
void SetGridType(GRID3D_TYPE aGridType) noexcept
Set the current grid.
wxAuiManager m_auimgr
Manage TOOL_ACTION objects.
wxFileName m_defaultSaveScreenshotFileName
void loadCommonSettings()
Load configuration from common settings.
void Request_refresh(bool aRedrawImmediately=true)
Schedule a refresh update of the canvas.
void SetAnimationEnabled(bool aEnable)
Enable or disable camera animation when switching to a pre-defined view.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
static const int * GetAttributesList(ANTIALIASING_MODE aAntiAliasingMode)
Get a list of attributes to pass to wxGLCanvas.
float m_RtSpreadRefractions
SFVEC3F m_RtCameraLightColor
static TOOL_ACTION showBBoxes
Class to handle configuration and automatic determination of the DPI scale to use for canvases.
Definition: dpi_scaling.h:36
void InstallPreferences(PAGED_DIALOG *aParent, PANEL_HOTKEYS_EDITOR *aHotkeysPanel) override
Allow a frame to load its preference panels (if any) into the preferences dialog.
RENDER_ENGINE GetRenderEngine() const noexcept
wxTreebook * GetTreebook()
Definition: paged_dialog.h:37
void OnCloseWindow(wxCloseEvent &event)
Master controller class:
Definition: tool_manager.h:54
static TOOL_ACTION showSMD
static TOOL_ACTION showVirtual
int m_RtRecursiveReflectionCount
float m_RtSpreadReflections
void SetEventDispatcher(TOOL_DISPATCHER *aEventDispatcher)
Set a dispatcher that processes events and forwards them to tools.
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Definition: app_settings.h:99
static TOOL_ACTION show5mmGrid
glm::vec2 SFVEC2F
Definition: xv3d_types.h:42
static TOOL_ACTION showTHT
void NewDisplay(bool aForceImmediateRedraw=false)
Reload and refresh (rebuild) the 3D scene.
Create and handle a window for the 3d viewer connected to a Kiway and a pcbboard.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
void RenderEngineChanged()
Notify that the render engine was changed.
EDA_3D_CONTROLLER.
MATERIAL_MODE GetMaterialMode() const noexcept
SFVEC3F m_RtLightColorTop
void SetMaterialMode(MATERIAL_MODE aMaterialMode) noexcept
Definition of file extensions used in Kicad.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:260
#define _(s)
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition: project.cpp:116
int m_RtRecursiveRefractionCount
std::vector< SFVEC3F > m_RtLightColor
static TOOL_ACTION showAxis
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:105
Handle actions that are shared between different applications.
int m_RtRefractionSampleCount
Specialization of the wxAuiPaneInfo class for KiCad panels.
void SetConditions(const TOOL_ACTION &aAction, const ACTION_CONDITIONS &aConditions)
Set the conditions the UI elements for activating a specific tool action should use for determining t...
void SetMovingSpeedMultiplier(int aMultiplier)
Set the camera animation moving speed multiplier option.
void SetRenderEngine(RENDER_ENGINE aRenderEngine) noexcept
void SaveSettings(APP_SETTINGS_BASE *aCfg) override
Save common frame parameters to a configuration data file.
wxString PngFileWildcard()
BOARD * GetBoard()
void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged) override
Notification event that some of the common (suite-wide) settings have changed.
A modified version of the wxInfoBar class that allows us to:
Definition: infobar.h:73
void GetScreenshot(wxImage &aDstImage)
Request a screenshot and output it to the aDstImage.
void takeScreenshot(wxCommandEvent &event)
Create a Screenshot of the current 3D view.
void ReloadRequest()
Request reloading the 3D view.
static TOOL_ACTION show2_5mmGrid
static TOOL_ACTION show1mmGrid
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:158
see class PGM_BASE
int GetProjectionMode() const
ANTIALIASING_MODE GetAntiAliasingMode() const
Get the current antialiasing mode value.
void SetEnvironment(EDA_ITEM *aModel, KIGFX::VIEW *aView, KIGFX::VIEW_CONTROLS *aViewControls, APP_SETTINGS_BASE *aSettings, TOOLS_HOLDER *aFrame)
Set the work environment (model, view, view controls and the parent window).
glm::vec3 SFVEC3F
Definition: xv3d_types.h:44
Functors that can be used to figure out how the action controls should be displayed in the UI and if ...
The base frame for deriving all KiCad main window classes.
bool GetAnimationEnabled() const
const std::string PngFileExtension
void SetScaleFactor(double aFactor)
Set the canvas scale factor, probably for a hi-DPI display.
std::vector< KIGFX::COLOR4D > raytrace_lightColor
RENDER_ENGINE
Render engine mode.
Definition: 3d_enums.h:110
ACTION_MANAGER * GetActionManager() const
Definition: tool_manager.h:199
static TOOL_ACTION noGrid
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
SFVEC3F m_OpenGlSelectionColor
void ReloadRequest(BOARD *aBoard=nullptr, S3D_CACHE *aCachePointer=nullptr)
#define QUALIFIED_VIEWER3D_FRAMENAME(parent)
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:54
EVT_TOOL_RANGE(ID_START_COMMAND_3D, ID_MENU_COMMAND_END, EDA_3D_VIEWER_FRAME::Process_Special_Functions) EDA_3D_VIEWER_FRAME
static TOOL_ACTION toggleOrtho
SFVEC3F m_RtLightColorBottom
float m_RtSpreadShadows
#define RANGE_SCALE_3D
This defines the range that all coord will have to be rendered.
Definition: board_adapter.h:62
int m_RtReflectionSampleCount
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
void OnRenderEngineSelection(wxCommandEvent &event)
void RenderEngineChanged()
RenderEngineChanged - Update toolbar icon and call canvas RenderEngineChanged.
void OnActivate(wxActivateEvent &event)
virtual void LoadSettings(APP_SETTINGS_BASE *aCfg)
Load common frame parameters from a configuration file.
void Exit3DFrame(wxCommandEvent &event)
Called when user press the File->Exit.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103