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 <mrluzeiro@ua.pt>
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( RANGE_SCALE_3D, 0.66f )
94 {
95  wxLogTrace( m_logTrace, "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, "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, "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, "EDA_3D_VIEWER_FRAME::Process_Special_Functions id %d isChecked %d",
312  id,
313  isChecked );
314 
315  if( m_canvas == nullptr )
316  return;
317 
318  switch( id )
319  {
320  case ID_RELOAD3D_BOARD:
321  NewDisplay( true );
322  break;
323 
327  takeScreenshot( event );
328  return;
329 
331  {
332  auto cfg = Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>();
333  cfg->ResetToDefaults();
334  LoadSettings( cfg );
335 
336  // Tell canvas that we (may have) changed the render engine
338 
339  NewDisplay( true );
340  }
341  return;
342 
343  default:
344  wxFAIL_MSG( "Invalid event in EDA_3D_VIEWER_FRAME::Process_Special_Functions()" );
345  return;
346  }
347 }
348 
349 
350 void EDA_3D_VIEWER_FRAME::OnRenderEngineSelection( wxCommandEvent &event )
351 {
352  const RENDER_ENGINE old_engine = m_boardAdapter.GetRenderEngine();
353 
354  if( old_engine == RENDER_ENGINE::OPENGL )
356  else
358 
359  wxLogTrace( m_logTrace, "EDA_3D_VIEWER_FRAME::OnRenderEngineSelection type %s ",
361  "realtime" );
362 
363  if( old_engine != m_boardAdapter.GetRenderEngine() )
365 }
366 
367 
368 void EDA_3D_VIEWER_FRAME::OnDisableRayTracing( wxCommandEvent& aEvent )
369 {
370  wxLogTrace( m_logTrace, "EDA_3D_VIEWER_FRAME::%s disabling ray tracing.", __WXFUNCTION__ );
371 
372  m_disable_ray_tracing = true;
374 }
375 
376 
377 void EDA_3D_VIEWER_FRAME::OnActivate( wxActivateEvent &aEvent )
378 {
379  wxLogTrace( m_logTrace, "EDA_3D_VIEWER_FRAME::OnActivate" );
380 
381  if( aEvent.GetActive() && m_canvas )
382  {
383  // Reload data if 3D frame shows a board,
384  // because it can be changed since last frame activation
387 
388  // Activates again the focus of the canvas so it will catch mouse and key events
389  m_canvas->SetFocus();
390  }
391 
392  aEvent.Skip(); // required under wxMAC
393 }
394 
395 
396 void EDA_3D_VIEWER_FRAME::OnSetFocus( wxFocusEvent& aEvent )
397 {
398  // Activates again the focus of the canvas so it will catch mouse and key events
399  if( m_canvas )
400  m_canvas->SetFocus();
401 
402  aEvent.Skip();
403 }
404 
405 
407 {
409 
410  EDA_3D_VIEWER_SETTINGS* cfg = dynamic_cast<EDA_3D_VIEWER_SETTINGS*>( aCfg );
411  wxASSERT( cfg );
412 
413  wxLogTrace( m_logTrace, "EDA_3D_VIEWER_FRAME::LoadSettings" );
414 
415  if( cfg )
416  {
423 
426 
427  for( size_t i = 0; i < cfg->m_Render.raytrace_lightColor.size(); ++i )
428  {
431 
432  SFVEC2F sphericalCoord =
433  SFVEC2F( ( cfg->m_Render.raytrace_lightElevation[i] + 90.0f ) / 180.0f,
434  cfg->m_Render.raytrace_lightAzimuth[i] / 180.0f );
435 
436  sphericalCoord.x = glm::clamp( sphericalCoord.x, 0.0f, 1.0f );
437  sphericalCoord.y = glm::clamp( sphericalCoord.y, 0.0f, 2.0f );
438 
439  m_boardAdapter.m_RtLightSphericalCoords[i] = sphericalCoord;
440  }
441 
442 #define TRANSFER_SETTING( flag, field ) m_boardAdapter.SetFlag( flag, cfg->m_Render.field )
443 
445  TRANSFER_SETTING( FL_SUBTRACT_MASK_FROM_SILK, subtract_mask_from_silk );
446 
447  // OpenGL options
448  TRANSFER_SETTING( FL_RENDER_OPENGL_COPPER_THICKNESS, opengl_copper_thickness );
449  TRANSFER_SETTING( FL_RENDER_OPENGL_SHOW_MODEL_BBOX, opengl_show_model_bbox );
450  TRANSFER_SETTING( FL_HIGHLIGHT_ROLLOVER_ITEM, opengl_highlight_on_rollover );
451  TRANSFER_SETTING( FL_RENDER_OPENGL_AA_DISABLE_ON_MOVE, opengl_AA_disableOnMove );
452  TRANSFER_SETTING( FL_RENDER_OPENGL_THICKNESS_DISABLE_ON_MOVE, opengl_thickness_disableOnMove );
453  TRANSFER_SETTING( FL_RENDER_OPENGL_VIAS_DISABLE_ON_MOVE, opengl_vias_disableOnMove );
454  TRANSFER_SETTING( FL_RENDER_OPENGL_HOLES_DISABLE_ON_MOVE, opengl_holes_disableOnMove );
455 
456  // Raytracing options
457  TRANSFER_SETTING( FL_RENDER_RAYTRACING_SHADOWS, raytrace_shadows );
458  TRANSFER_SETTING( FL_RENDER_RAYTRACING_BACKFLOOR, raytrace_backfloor );
459  TRANSFER_SETTING( FL_RENDER_RAYTRACING_REFRACTIONS, raytrace_refractions );
460  TRANSFER_SETTING( FL_RENDER_RAYTRACING_REFLECTIONS, raytrace_reflections );
461  TRANSFER_SETTING( FL_RENDER_RAYTRACING_POST_PROCESSING, raytrace_post_processing );
462  TRANSFER_SETTING( FL_RENDER_RAYTRACING_ANTI_ALIASING, raytrace_anti_aliasing );
463  TRANSFER_SETTING( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES, raytrace_procedural_textures );
464 
465  TRANSFER_SETTING( FL_AXIS, show_axis );
466  TRANSFER_SETTING( FL_FP_ATTRIBUTES_NORMAL, show_footprints_normal );
467  TRANSFER_SETTING( FL_FP_ATTRIBUTES_NORMAL_INSERT, show_footprints_insert );
468  TRANSFER_SETTING( FL_FP_ATTRIBUTES_VIRTUAL, show_footprints_virtual );
469  TRANSFER_SETTING( FL_ZONE, show_zones );
470  TRANSFER_SETTING( FL_ADHESIVE, show_adhesive );
471  TRANSFER_SETTING( FL_SILKSCREEN, show_silkscreen );
472  TRANSFER_SETTING( FL_SOLDERMASK, show_soldermask );
473  TRANSFER_SETTING( FL_SOLDERPASTE, show_solderpaste );
474  TRANSFER_SETTING( FL_COMMENTS, show_comments );
475  TRANSFER_SETTING( FL_ECO, show_eco );
476  TRANSFER_SETTING( FL_SHOW_BOARD_BODY, show_board_body );
477  TRANSFER_SETTING( FL_CLIP_SILK_ON_VIA_ANNULUS, clip_silk_on_via_annulus );
478  TRANSFER_SETTING( FL_RENDER_PLATED_PADS_AS_PLATED, renderPlatedPadsAsPlated );
479 
480  m_boardAdapter.SetGridType( static_cast<GRID3D_TYPE>( cfg->m_Render.grid_type ) );
482  static_cast<ANTIALIASING_MODE>( cfg->m_Render.opengl_AA_mode ) );
483 
486 
490 
494 
499 
500  // When opening the 3D viewer, we use the opengl mode, not the ray tracing engine
501  // because the ray tracing is very time consumming, and can be seen as not working
502  // (freeze window) with large boards.
503 #if 0
504  RENDER_ENGINE engine = static_cast<RENDER_ENGINE>( cfg->m_Render.engine );
505  wxLogTrace( m_logTrace, engine == RENDER_ENGINE::RAYTRACING ?
506  "EDA_3D_VIEWER_FRAME::LoadSettings render setting Ray Trace" :
507  "EDA_3D_VIEWER_FRAME::LoadSettings render setting OpenGL" );
508 #else
510 #endif
511 
512  m_boardAdapter.SetMaterialMode( static_cast<MATERIAL_MODE>( cfg->m_Render.material_mode ) );
513 
517 
518 #undef TRANSFER_SETTING
519  }
520 }
521 
522 
524 {
525  auto cfg = Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>();
526 
528 
529  wxLogTrace( m_logTrace, "EDA_3D_VIEWER_FRAME::SaveSettings" );
530 
532  "EDA_3D_VIEWER_FRAME::SaveSettings render setting Ray Trace" :
533  "EDA_3D_VIEWER_FRAME::SaveSettings render setting OpenGL" );
534 
535  if( cfg )
536  {
537  auto save_color =
538  [] ( const SFVEC3F& aSource, COLOR4D& aTarget )
539  {
540  aTarget = COLOR4D( aSource.r, aSource.g, aSource.b, 1.0 );
541  };
542 
543  save_color( m_boardAdapter.m_RtCameraLightColor, cfg->m_Render.raytrace_lightColorCamera );
544  save_color( m_boardAdapter.m_RtLightColorTop, cfg->m_Render.raytrace_lightColorTop );
545  save_color( m_boardAdapter.m_RtLightColorBottom, cfg->m_Render.raytrace_lightColorBottom );
546 
547  for( size_t i = 0; i < cfg->m_Render.raytrace_lightColor.size(); ++i )
548  {
549  save_color( m_boardAdapter.m_RtLightColor[i], cfg->m_Render.raytrace_lightColor[i] );
550 
551  cfg->m_Render.raytrace_lightElevation[i] =
552  (int)( m_boardAdapter.m_RtLightSphericalCoords[i].x * 180.0f - 90.0f );
553  cfg->m_Render.raytrace_lightAzimuth[i] =
554  (int)( m_boardAdapter.m_RtLightSphericalCoords[i].y * 180.0f );
555  }
556 
557  cfg->m_Render.raytrace_nrsamples_shadows = m_boardAdapter.m_RtShadowSampleCount;
558  cfg->m_Render.raytrace_nrsamples_reflections = m_boardAdapter.m_RtReflectionSampleCount;
559  cfg->m_Render.raytrace_nrsamples_refractions = m_boardAdapter.m_RtRefractionSampleCount;
560 
561  cfg->m_Render.raytrace_spread_shadows = m_boardAdapter.m_RtSpreadShadows;
562  cfg->m_Render.raytrace_spread_reflections = m_boardAdapter.m_RtSpreadReflections;
563  cfg->m_Render.raytrace_spread_refractions = m_boardAdapter.m_RtSpreadRefractions;
564 
565  cfg->m_Render.raytrace_recursivelevel_refractions =
567  cfg->m_Render.raytrace_recursivelevel_reflections =
569 
570 #define TRANSFER_SETTING( field, flag ) cfg->m_Render.field = m_boardAdapter.GetFlag( flag )
571 
572  cfg->m_Render.engine = static_cast<int>( m_boardAdapter.GetRenderEngine() );
573  cfg->m_Render.grid_type = static_cast<int>( m_boardAdapter.GetGridType() );
574  cfg->m_Render.material_mode = static_cast<int>( m_boardAdapter.GetMaterialMode() );
575  cfg->m_Render.opengl_AA_mode = static_cast<int>( m_boardAdapter.GetAntiAliasingMode() );
576 
577  save_color( m_boardAdapter.m_OpenGlSelectionColor, cfg->m_Render.opengl_selection_color );
578 
579  cfg->m_Camera.animation_enabled = m_canvas->GetAnimationEnabled();
580  cfg->m_Camera.moving_speed_multiplier = m_canvas->GetMovingSpeedMultiplier();
581  cfg->m_Camera.projection_mode = m_canvas->GetProjectionMode();
582 
583  if( EDA_3D_CONTROLLER* ctrlTool = GetToolManager()->GetTool<EDA_3D_CONTROLLER>() )
584  cfg->m_Camera.rotation_increment = ctrlTool->GetRotationIncrement();
585 
586  TRANSFER_SETTING( opengl_AA_disableOnMove, FL_RENDER_OPENGL_AA_DISABLE_ON_MOVE );
587  TRANSFER_SETTING( opengl_copper_thickness, FL_RENDER_OPENGL_COPPER_THICKNESS );
588  TRANSFER_SETTING( opengl_show_model_bbox, FL_RENDER_OPENGL_SHOW_MODEL_BBOX );
589  TRANSFER_SETTING( opengl_highlight_on_rollover, FL_HIGHLIGHT_ROLLOVER_ITEM );
590  TRANSFER_SETTING( opengl_thickness_disableOnMove, FL_RENDER_OPENGL_THICKNESS_DISABLE_ON_MOVE );
591  TRANSFER_SETTING( opengl_vias_disableOnMove, FL_RENDER_OPENGL_VIAS_DISABLE_ON_MOVE );
592  TRANSFER_SETTING( opengl_holes_disableOnMove, FL_RENDER_OPENGL_HOLES_DISABLE_ON_MOVE );
593 
594  TRANSFER_SETTING( raytrace_anti_aliasing, FL_RENDER_RAYTRACING_ANTI_ALIASING );
595  TRANSFER_SETTING( raytrace_backfloor, FL_RENDER_RAYTRACING_BACKFLOOR );
596  TRANSFER_SETTING( raytrace_post_processing, FL_RENDER_RAYTRACING_POST_PROCESSING );
597  TRANSFER_SETTING( raytrace_procedural_textures, FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES );
598  TRANSFER_SETTING( raytrace_reflections, FL_RENDER_RAYTRACING_REFLECTIONS );
599  TRANSFER_SETTING( raytrace_refractions, FL_RENDER_RAYTRACING_REFRACTIONS );
600  TRANSFER_SETTING( raytrace_shadows, FL_RENDER_RAYTRACING_SHADOWS );
601 
603  TRANSFER_SETTING( show_adhesive, FL_ADHESIVE );
604  TRANSFER_SETTING( show_axis, FL_AXIS );
605  TRANSFER_SETTING( show_board_body, FL_SHOW_BOARD_BODY );
606  TRANSFER_SETTING( clip_silk_on_via_annulus, FL_CLIP_SILK_ON_VIA_ANNULUS );
607  TRANSFER_SETTING( renderPlatedPadsAsPlated, FL_RENDER_PLATED_PADS_AS_PLATED );
608  TRANSFER_SETTING( show_comments, FL_COMMENTS );
609  TRANSFER_SETTING( show_eco, FL_ECO );
610  TRANSFER_SETTING( show_footprints_insert, FL_FP_ATTRIBUTES_NORMAL_INSERT );
611  TRANSFER_SETTING( show_footprints_normal, FL_FP_ATTRIBUTES_NORMAL );
612  TRANSFER_SETTING( show_footprints_virtual, FL_FP_ATTRIBUTES_VIRTUAL );
613  TRANSFER_SETTING( show_silkscreen, FL_SILKSCREEN );
614  TRANSFER_SETTING( show_soldermask, FL_SOLDERMASK );
615  TRANSFER_SETTING( show_solderpaste, FL_SOLDERPASTE );
616  TRANSFER_SETTING( show_zones, FL_ZONE );
617  TRANSFER_SETTING( subtract_mask_from_silk, FL_SUBTRACT_MASK_FROM_SILK );
618 
619 #undef TRANSFER_SETTING
620  }
621 }
622 
623 
624 void EDA_3D_VIEWER_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
625 {
626  wxLogTrace( m_logTrace, "EDA_3D_VIEWER_FRAME::CommonSettingsChanged" );
627 
628  // Regen menu bars, etc
629  EDA_BASE_FRAME::CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
630 
631  // There is no base class that handles toolbars for this frame
633 
635 
636  NewDisplay( true );
637 }
638 
639 
640 void EDA_3D_VIEWER_FRAME::takeScreenshot( wxCommandEvent& event )
641 {
642  wxString fullFileName;
643  bool fmt_is_jpeg = false;
644 
645  if( event.GetId() == ID_MENU_SCREENCOPY_JPEG )
646  fmt_is_jpeg = true;
647 
648  if( event.GetId() != ID_TOOL_SCREENCOPY_TOCLIBBOARD )
649  {
650  // Remember path between saves during this session only.
651  const wxString wildcard = fmt_is_jpeg ? JpegFileWildcard() : PngFileWildcard();
652  const wxString ext = fmt_is_jpeg ? JpegFileExtension : PngFileExtension;
653 
654  // First time path is set to the project path.
655  if( !m_defaultSaveScreenshotFileName.IsOk() )
657 
658  m_defaultSaveScreenshotFileName.SetExt( ext );
659 
660  wxFileDialog dlg( this, _( "3D Image File Name" ),
662  m_defaultSaveScreenshotFileName.GetFullName(), wildcard,
663  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
664 
665  if( dlg.ShowModal() == wxID_CANCEL )
666  return;
667 
668  m_defaultSaveScreenshotFileName = dlg.GetPath();
669 
670  if( m_defaultSaveScreenshotFileName.GetExt().IsEmpty() )
671  m_defaultSaveScreenshotFileName.SetExt( ext );
672 
673  fullFileName = m_defaultSaveScreenshotFileName.GetFullPath();
674 
675  wxFileName fn = fullFileName;
676 
677  if( !fn.IsDirWritable() )
678  {
679  wxString msg;
680 
681  msg.Printf( _( "Insufficient permissions to save file '%s'." ), fullFileName );
682  wxMessageBox( msg, _( "Error" ), wxOK | wxICON_ERROR, this );
683  return;
684  }
685 
686  // Be sure the screen area destroyed by the file dialog is redrawn
687  // before making a screen copy.
688  // Without this call, under Linux the screen refresh is made to late.
689  wxYield();
690  }
691 
692  // Be sure we have the latest 3D view (remember 3D view is buffered)
693  m_canvas->Request_refresh( true );
694  wxYield();
695 
696  // Build image from the 3D buffer
697  wxWindowUpdateLocker noUpdates( this );
698 
699  wxImage screenshotImage;
700 
701  if( m_canvas )
702  m_canvas->GetScreenshot( screenshotImage );
703 
704  if( event.GetId() == ID_TOOL_SCREENCOPY_TOCLIBBOARD )
705  {
706  wxBitmap bitmap( screenshotImage );
707 
708  wxLogNull doNotLog; // disable logging of failed clipboard actions
709 
710  if( wxTheClipboard->Open() )
711  {
712  wxBitmapDataObject* dobjBmp = new wxBitmapDataObject( bitmap );
713 
714  if( !wxTheClipboard->SetData( dobjBmp ) )
715  wxMessageBox( _( "Failed to copy image to clipboard" ) );
716 
717  wxTheClipboard->Flush(); /* the data in clipboard will stay
718  * available after the application exits */
719  wxTheClipboard->Close();
720  }
721  }
722  else
723  {
724  if( !screenshotImage.SaveFile( fullFileName,
725  fmt_is_jpeg ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG ) )
726  wxMessageBox( _( "Can't save file" ) );
727 
728  screenshotImage.Destroy();
729  }
730 }
731 
732 
734 {
735  wxLogTrace( m_logTrace, "EDA_3D_VIEWER_FRAME::RenderEngineChanged()" );
736 
737  if( m_canvas )
739 }
740 
741 
743 {
744  wxCHECK_RET( m_canvas, "Cannot load settings to null canvas" );
745 
746  COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
747 
748  const DPI_SCALING dpi{ settings, this };
749  m_canvas->SetScaleFactor( dpi.GetScaleFactor() );
750  // TODO(JE) use all control options
752 }
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:160
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