KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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) 2023 CERN
6 * Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <wx/filename.h>
27#include <wx/msgdlg.h>
28#include <wx/string.h>
29#include <wx/wupdlock.h>
30#include <wx/clipbrd.h>
31#include <wx/filedlg.h>
32#include <wx/dialog.h>
33#include "eda_3d_viewer_frame.h"
37#include <3d_viewer_id.h>
41#include <board.h>
42#include <advanced_config.h>
43#include <bitmaps.h>
45#include <core/arraydim.h>
46#include <dpi_scaling_common.h>
47#include <pgm_base.h>
48#include <project.h>
52#include <tool/action_manager.h>
53#include <tool/common_control.h>
54#include <tool/tool_manager.h>
56#include <tool/action_toolbar.h>
57#include <widgets/wx_infobar.h>
60#include <project_pcb.h>
61
63
71const wxChar* EDA_3D_VIEWER_FRAME::m_logTrace = wxT( "KI_TRACE_EDA_3D_VIEWER" );
72
73
74BEGIN_EVENT_TABLE( EDA_3D_VIEWER_FRAME, KIWAY_PLAYER )
75
77 EVT_SET_FOCUS( EDA_3D_VIEWER_FRAME::OnSetFocus )
78
80 EDA_3D_VIEWER_FRAME::Process_Special_Functions )
81
82 EVT_MENU( wxID_CLOSE, EDA_3D_VIEWER_FRAME::Exit3DFrame )
83 EVT_MENU( ID_RENDER_CURRENT_VIEW, EDA_3D_VIEWER_FRAME::onRenderEngineSelection )
84 EVT_MENU( ID_DISABLE_RAY_TRACING, EDA_3D_VIEWER_FRAME::onDisableRayTracing )
85
86 EVT_CLOSE( EDA_3D_VIEWER_FRAME::OnCloseWindow )
87END_EVENT_TABLE()
88
89
91 const wxString& aTitle, long style ) :
92 KIWAY_PLAYER( aKiway, aParent, FRAME_PCB_DISPLAY3D, aTitle, wxDefaultPosition,
93 wxDefaultSize, style, QUALIFIED_VIEWER3D_FRAMENAME( aParent ), unityScale ),
94 m_mainToolBar( nullptr ),
95 m_canvas( nullptr ),
96 m_currentCamera( m_trackBallCamera ),
97 m_trackBallCamera( 2 * RANGE_SCALE_3D ),
98 m_spaceMouse( nullptr )
99{
100 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME %s" ), aTitle );
101
102 m_disable_ray_tracing = false;
103 m_aboutTitle = _HKI( "KiCad 3D Viewer" );
104
105 // Give it an icon
106 wxIcon icon;
107 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_3d ) );
108 SetIcon( icon );
109
110 // Create the status line
111 static const int status_dims[5] = { -1, 170, 130, 130, 130 };
112
113 wxStatusBar *status_bar = CreateStatusBar( arrayDim( status_dims ) );
114 SetStatusWidths( arrayDim( status_dims ), status_dims );
115
118 ANTIALIASING_MODE aaMode = static_cast<ANTIALIASING_MODE>( cfg->m_Render.opengl_AA_mode );
119
120 m_canvas = new EDA_3D_CANVAS( this, OGL_ATT_LIST::GetAttributesList( aaMode, true ),
121 m_boardAdapter, m_currentCamera,
123
124 m_appearancePanel = new APPEARANCE_CONTROLS_3D( this, GetCanvas() );
125
126 LoadSettings( cfg );
127 loadCommonSettings();
128
129 m_appearancePanel->SetUserViewports( Prj().GetProjectFile().m_Viewports3D );
130
131 // Create the manager
132 m_toolManager = new TOOL_MANAGER;
133 m_toolManager->SetEnvironment( GetBoard(), nullptr, nullptr, cfg, this );
134
135 m_actions = new EDA_3D_ACTIONS();
136 m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager );
137 m_canvas->SetEventDispatcher( m_toolDispatcher );
138
139 // Register tools
140 m_toolManager->RegisterTool( new COMMON_CONTROL );
141 m_toolManager->RegisterTool( new EDA_3D_CONTROLLER );
142 m_toolManager->InitTools();
143
144 setupUIConditions();
145
146 if( EDA_3D_CONTROLLER* ctrlTool = GetToolManager()->GetTool<EDA_3D_CONTROLLER>() )
147 ctrlTool->SetRotationIncrement( cfg->m_Camera.rotation_increment );
148
149 // Run the viewer control tool, it is supposed to be always active
150 m_toolManager->InvokeTool( "3DViewer.Control" );
151
152 ReCreateMenuBar();
153 ReCreateMainToolbar();
154
155 m_infoBar = new WX_INFOBAR( this, &m_auimgr );
156
157 m_auimgr.SetManagedWindow( this );
158
159 m_auimgr.AddPane( m_mainToolBar, EDA_PANE().HToolbar().Name( wxS( "MainToolbar" ) )
160 .Top().Layer( 6 ) );
161 m_auimgr.AddPane( m_infoBar, EDA_PANE().InfoBar().Name( wxS( "InfoBar" ) )
162 .Top().Layer( 1 ) );
163 m_auimgr.AddPane( m_appearancePanel, EDA_PANE().Name( "LayersManager" )
164 .Right().Layer( 3 )
165 .Caption( _( "Appearance" ) ).PaneBorder( false )
166 .MinSize( 180, -1 ).BestSize( 190, -1 ) );
167 m_auimgr.AddPane( m_canvas, EDA_PANE().Canvas().Name( wxS( "DrawFrame" ) )
168 .Center() );
169
170 wxAuiPaneInfo& layersManager = m_auimgr.GetPane( "LayersManager" );
171
172 if( cfg->m_AuiPanels.right_panel_width > 0 )
173 SetAuiPaneSize( m_auimgr, layersManager, cfg->m_AuiPanels.right_panel_width, -1 );
174
175 layersManager.Show( cfg->m_AuiPanels.show_layer_manager );
176
177 // Call Update() to fix all pane default sizes, especially the "InfoBar" pane before
178 // hiding it.
179 m_auimgr.Update();
180
181 // We don't want the infobar displayed right away
182 m_auimgr.GetPane( wxS( "InfoBar" ) ).Hide();
183 m_auimgr.Update();
184
185 m_canvas->SetInfoBar( m_infoBar );
186 m_canvas->SetStatusBar( status_bar );
187
188 try
189 {
190 m_spaceMouse = new NL_3D_VIEWER_PLUGIN( m_canvas );
191 }
192 catch( const std::system_error& e )
193 {
194 wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
195 }
196
197 // Fixes bug in Windows (XP and possibly others) where the canvas requires the focus
198 // in order to receive mouse events. Otherwise, the user has to click somewhere on
199 // the canvas before it will respond to mouse wheel events.
200 m_canvas->SetFocus();
201}
202
203
205{
206 delete m_spaceMouse;
207
209
210 m_canvas->SetEventDispatcher( nullptr );
211
212 m_auimgr.UnInit();
213}
214
215
217{
219
222
223// Helper to define check conditions
224#define GridSizeCheck( x ) ACTION_CONDITIONS().Check( cond.GridSize( x ) )
225
226 auto raytracing =
227 [this]( const SELECTION& aSel )
228 {
229 return m_boardAdapter.m_Cfg->m_Render.engine != RENDER_ENGINE::OPENGL;
230 };
231 auto showTH =
232 [this]( const SELECTION& aSel )
233 {
235 };
236 auto showSMD =
237 [this]( const SELECTION& aSel )
238 {
240 };
241 auto showVirtual =
242 [this]( const SELECTION& aSel )
243 {
245 };
246 auto show_NotInPosfile =
247 [this]( const SELECTION& aSel )
248 {
250 };
251 auto show_DNP =
252 [this]( const SELECTION& aSel )
253 {
255 };
256 auto showBBoxes =
257 [this]( const SELECTION& aSel )
258 {
260 };
261 auto showAxes =
262 [this]( const SELECTION& aSel )
263 {
265 };
266 auto ortho =
267 [this]( const SELECTION& )
268 {
269 return m_currentCamera.GetProjection() == PROJECTION_TYPE::ORTHO;
270 };
271
272 auto appearances =
273 [this]( const SELECTION& aSel )
274 {
276 };
277
279
281 mgr->SetConditions( EDA_3D_ACTIONS::showSMD, ACTION_CONDITIONS().Check( showSMD ) );
282 mgr->SetConditions( EDA_3D_ACTIONS::showVirtual, ACTION_CONDITIONS().Check( showVirtual ) );
283 mgr->SetConditions( EDA_3D_ACTIONS::showNotInPosFile, ACTION_CONDITIONS().Check( show_NotInPosfile ) );
284 mgr->SetConditions( EDA_3D_ACTIONS::showDNP, ACTION_CONDITIONS().Check( show_DNP ) );
285
286 mgr->SetConditions( EDA_3D_ACTIONS::showBBoxes, ACTION_CONDITIONS().Check( showBBoxes ) );
287 mgr->SetConditions( EDA_3D_ACTIONS::showAxis, ACTION_CONDITIONS().Check( showAxes ) );
288
289 mgr->SetConditions( EDA_3D_ACTIONS::noGrid, GridSizeCheck( GRID3D_TYPE::NONE ) );
290 mgr->SetConditions( EDA_3D_ACTIONS::show10mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_10MM ) );
291 mgr->SetConditions( EDA_3D_ACTIONS::show5mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_5MM ) );
292 mgr->SetConditions( EDA_3D_ACTIONS::show2_5mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_2P5MM ) );
293 mgr->SetConditions( EDA_3D_ACTIONS::show1mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_1MM ) );
295
297
298#undef GridSizeCheck
299}
300
301
302bool EDA_3D_VIEWER_FRAME::TryBefore( wxEvent& aEvent )
303{
304 static bool s_presetSwitcherShown = false;
305 static bool s_viewportSwitcherShown = false;
306
307 // wxWidgets generates no key events for the tab key when the ctrl key is held down. One
308 // way around this is to look at all events and inspect the keyboard state of the tab key.
309 // However, this runs into issues on some linux VMs where querying the keyboard state is
310 // very slow. Fortunately we only use ctrl-tab on Mac, so we implement this lovely hack:
311#ifdef __WXMAC__
312 if( wxGetKeyState( WXK_TAB ) )
313#else
314 if( ( aEvent.GetEventType() == wxEVT_CHAR || aEvent.GetEventType() == wxEVT_CHAR_HOOK )
315 && static_cast<wxKeyEvent&>( aEvent ).GetKeyCode() == WXK_TAB )
316#endif
317 {
318 if( !s_presetSwitcherShown && wxGetKeyState( PRESET_SWITCH_KEY ) )
319 {
320 if( m_appearancePanel && this->IsActive() )
321 {
322 wxArrayString mru = m_appearancePanel->GetLayerPresetsMRU();
323
324 if( mru.size() > 0 )
325 {
326 for( wxString& str : mru )
327 {
328 if( str == FOLLOW_PCB )
329 str = _( "Follow PCB Editor" );
330 else if( str == FOLLOW_PLOT_SETTINGS )
331 str = _( "Follow PCB Plot Settings" );
332 }
333
334 EDA_VIEW_SWITCHER switcher( this, mru, PRESET_SWITCH_KEY );
335
336 s_presetSwitcherShown = true;
337 switcher.ShowModal();
338 s_presetSwitcherShown = false;
339
340 int idx = switcher.GetSelection();
341
342 if( idx >= 0 && idx < (int) mru.size() )
343 {
344 wxString internalName = m_appearancePanel->GetLayerPresetsMRU()[idx];
345 m_appearancePanel->ApplyLayerPreset( internalName );
346 }
347
348 return true;
349 }
350 }
351 }
352 else if( !s_viewportSwitcherShown && wxGetKeyState( VIEWPORT_SWITCH_KEY ) )
353 {
354 if( this->IsActive() )
355 {
356 const wxArrayString& viewportMRU = m_appearancePanel->GetViewportsMRU();
357
358 if( viewportMRU.size() > 0 )
359 {
360 EDA_VIEW_SWITCHER switcher( this, viewportMRU, VIEWPORT_SWITCH_KEY );
361
362 s_viewportSwitcherShown = true;
363 switcher.ShowModal();
364 s_viewportSwitcherShown = false;
365
366 int idx = switcher.GetSelection();
367
368 if( idx >= 0 && idx < (int) viewportMRU.size() )
369 m_appearancePanel->ApplyViewport( viewportMRU[idx] );
370
371 return true;
372 }
373 }
374 }
375 }
376
377 return wxFrame::TryBefore( aEvent );
378}
379
380
381void EDA_3D_VIEWER_FRAME::handleIconizeEvent( wxIconizeEvent& aEvent )
382{
384
385 if( m_spaceMouse && aEvent.IsIconized() )
386 m_spaceMouse->SetFocus( false );
387}
388
389
391{
392 // This will schedule a request to load later
393 // ReloadRequest also updates the board pointer so always call it first
394 if( m_canvas )
396
399}
400
401
402void EDA_3D_VIEWER_FRAME::NewDisplay( bool aForceImmediateRedraw )
403{
404 if( m_canvas )
406
407 // After the ReloadRequest call, the refresh often takes a bit of time,
408 // and it is made here only on request.
409 if( m_canvas && aForceImmediateRedraw )
410 m_canvas->Refresh();
411}
412
413
415{
416 // Only update in OpenGL for an interactive interaction
417 if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
418 m_canvas->Request_refresh( true );
419}
420
421
423{
424 if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
426 else
427 NewDisplay( true );
428}
429
430
431void EDA_3D_VIEWER_FRAME::Exit3DFrame( wxCommandEvent &event )
432{
433 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::Exit3DFrame" ) );
434
435 Close( true );
436}
437
438
439void EDA_3D_VIEWER_FRAME::OnCloseWindow( wxCloseEvent &event )
440{
441 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::OnCloseWindow" ) );
442
443 // Do not show the layer manager during closing to avoid flicker on some platforms (Windows)
444 // that generate useless redraw of items in the Layer Manager
445 if( m_auimgr.GetPane( wxS( "LayersManager" ) ).IsShown() )
446 m_auimgr.GetPane( wxS( "LayersManager" ) ).Show( false );
447
448 if( m_canvas )
449 m_canvas->Close();
450
451 Destroy();
452 event.Skip( true );
453}
454
455
457{
458 int id = event.GetId();
459 bool isChecked = event.IsChecked();
460
461 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::Process_Special_Functions id %d "
462 "isChecked %d" ),
463 id,
464 isChecked );
465
466 if( m_canvas == nullptr )
467 return;
468
469 switch( id )
470 {
472 NewDisplay( true );
473 break;
474
478 takeScreenshot( event );
479 return;
480
482 {
485
486 cfg->ResetToDefaults();
487 LoadSettings( cfg );
488
489 // Tell canvas that we (may have) changed the render engine
491
492 NewDisplay( true );
493 }
494 return;
495
496 default:
497 wxFAIL_MSG( wxT( "Invalid event in EDA_3D_VIEWER_FRAME::Process_Special_Functions()" ) );
498 return;
499 }
500}
501
502
504{
506 RENDER_ENGINE old_engine = engine;
507
508 if( old_engine == RENDER_ENGINE::OPENGL )
509 engine = RENDER_ENGINE::RAYTRACING;
510 else
511 engine = RENDER_ENGINE::OPENGL;
512
513 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::OnRenderEngineSelection type %s " ),
514 engine == RENDER_ENGINE::RAYTRACING ? wxT( "raytracing" ) : wxT( "realtime" ) );
515
516 if( old_engine != engine )
518}
519
520
521void EDA_3D_VIEWER_FRAME::onDisableRayTracing( wxCommandEvent& aEvent )
522{
523 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::%s disabling ray tracing." ),
524 __WXFUNCTION__ );
525
527 m_boardAdapter.m_Cfg->m_Render.engine = RENDER_ENGINE::OPENGL;
528}
529
530
531void EDA_3D_VIEWER_FRAME::OnActivate( wxActivateEvent &aEvent )
532{
533 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::OnActivate" ) );
534
535 if( aEvent.GetActive() && m_canvas )
536 {
537 // Reload data if 3D frame shows a board,
538 // because it can be changed since last frame activation
541
542 // Activates again the focus of the canvas so it will catch mouse and key events
543 m_canvas->SetFocus();
544 }
545
546 if( m_spaceMouse )
547 m_spaceMouse->SetFocus( aEvent.GetActive() );
548
549 aEvent.Skip(); // required under wxMAC
550}
551
552
553void EDA_3D_VIEWER_FRAME::OnSetFocus( wxFocusEvent& aEvent )
554{
555 // Activates again the focus of the canvas so it will catch mouse and key events
556 if( m_canvas )
557 m_canvas->SetFocus();
558
559 aEvent.Skip();
560}
561
562
564{
566
567 // Dynamic_cast here will fail on Mac when called from CvPCB.
568 EDA_3D_VIEWER_SETTINGS* cfg = static_cast<EDA_3D_VIEWER_SETTINGS*>( aCfg );
569
570 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::LoadSettings" ) );
571
572 if( cfg )
573 {
574 applySettings( cfg );
575
576 if( !GetBoard()->GetProject() )
577 GetBoard()->SetProject( &Prj() );
578
580
581 // When opening the 3D viewer, we use the OpenGL mode, never the ray tracing engine
582 // because the ray tracing is very time consuming, and can be seen as not working
583 // (freeze window) with large boards.
584 m_boardAdapter.m_Cfg->m_Render.engine = RENDER_ENGINE::OPENGL;
585
587 {
588 wxString legacyColorsPresetName = _( "legacy colors" );
589
590 cfg->m_UseStackupColors = false;
591
592 if( !cfg->FindPreset( legacyColorsPresetName ) )
593 {
594 cfg->m_LayerPresets.emplace_back( legacyColorsPresetName,
595 GetAdapter().GetDefaultVisibleLayers(),
596 GetAdapter().GetDefaultColors() );
597 }
598
600 }
601
602 m_boardAdapter.InitSettings( nullptr, nullptr );
603
606 }
607}
608
609
611{
614
616
617 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::SaveSettings" ) );
618
619 wxLogTrace( m_logTrace, m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::RAYTRACING ?
620 wxT( "EDA_3D_VIEWER_FRAME::SaveSettings render setting Ray Trace" )
621 :
622 wxT( "EDA_3D_VIEWER_FRAME::SaveSettings render setting OpenGL" ) );
623
624 if( cfg )
625 {
627
631
632 if( EDA_3D_CONTROLLER* ctrlTool = GetToolManager()->GetTool<EDA_3D_CONTROLLER>() )
633 cfg->m_Camera.rotation_increment = ctrlTool->GetRotationIncrement();
634 }
635}
636
637
638void EDA_3D_VIEWER_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
639{
640 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::CommonSettingsChanged" ) );
641
642 // Regen menu bars, etc
643 EDA_BASE_FRAME::CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
644
645 // There is no base class that handles toolbars for this frame
647
649 applySettings( Pgm().GetSettingsManager().GetAppSettings<EDA_3D_VIEWER_SETTINGS>( "3d_viewer" ) );
650
652
653 NewDisplay( true );
654}
655
656
658{
660
661 SetTitle( _( "3D Viewer" ) );
663
665 {
666 wxAuiPaneInfo& lm_pane_info = m_auimgr.GetPane( m_appearancePanel );
667 lm_pane_info.Caption( _( "Appearance" ) );
668 }
669
670 SetStatusText( wxEmptyString, ACTIVITY );
671 SetStatusText( wxEmptyString, HOVERED_ITEM );
672}
673
674
676{
679 wxAuiPaneInfo& layersManager = m_auimgr.GetPane( "LayersManager" );
680
681 // show auxiliary Vertical layers and visibility manager toolbar
683
684 layersManager.Show( cfg->m_AuiPanels.show_layer_manager );
685
687 {
688 SetAuiPaneSize( m_auimgr, layersManager, cfg->m_AuiPanels.right_panel_width, -1 );
689 }
690 else
691 {
693 m_auimgr.Update();
694 }
695}
696
697
699{
702}
703
704
705void EDA_3D_VIEWER_FRAME::takeScreenshot( wxCommandEvent& event )
706{
707 wxString fullFileName;
708 bool fmt_is_jpeg = false;
709
710 if( event.GetId() == ID_MENU_SCREENCOPY_JPEG )
711 fmt_is_jpeg = true;
712
713 if( event.GetId() != ID_TOOL_SCREENCOPY_TOCLIBBOARD )
714 {
715 // Remember path between saves during this session only.
716 const wxString wildcard = fmt_is_jpeg ? FILEEXT::JpegFileWildcard() : FILEEXT::PngFileWildcard();
717 const wxString ext = fmt_is_jpeg ? FILEEXT::JpegFileExtension : FILEEXT::PngFileExtension;
718
719 // First time path is set to the project path.
722
724
725 wxFileDialog dlg( this, _( "3D Image File Name" ),
727 m_defaultSaveScreenshotFileName.GetFullName(), wildcard,
728 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
729
730 if( dlg.ShowModal() == wxID_CANCEL )
731 return;
732
733 m_defaultSaveScreenshotFileName = dlg.GetPath();
734
735 if( m_defaultSaveScreenshotFileName.GetExt().IsEmpty() )
737
738 fullFileName = m_defaultSaveScreenshotFileName.GetFullPath();
739
740 wxFileName fn = fullFileName;
741
742 if( !fn.IsDirWritable() )
743 {
744 wxString msg;
745
746 msg.Printf( _( "Insufficient permissions to save file '%s'." ), fullFileName );
747 wxMessageBox( msg, _( "Error" ), wxOK | wxICON_ERROR, this );
748 return;
749 }
750
751 // Be sure the screen area destroyed by the file dialog is redrawn
752 // before making a screen copy.
753 // Without this call, under Linux the screen refresh is made to late.
754 wxYield();
755 }
756
757 // Be sure we have the latest 3D view (remember 3D view is buffered)
758 // Also ensure any highlighted item is not highlighted when creating screen shot
760 bool allow_highlight = cfg.highlight_on_rollover;
761 cfg.highlight_on_rollover = false;
762
763 m_canvas->DoRePaint(); // init first buffer
764 m_canvas->DoRePaint(); // init second buffer
765
766 // Build image from the 3D buffer
767 wxWindowUpdateLocker noUpdates( this );
768
769 wxImage screenshotImage;
770
771 if( m_canvas )
772 m_canvas->GetScreenshot( screenshotImage );
773
774 cfg.highlight_on_rollover = allow_highlight;
775
776 if( event.GetId() == ID_TOOL_SCREENCOPY_TOCLIBBOARD )
777 {
778 wxBitmap bitmap( screenshotImage );
779
780 wxLogNull doNotLog; // disable logging of failed clipboard actions
781
782 if( wxTheClipboard->Open() )
783 {
784 wxBitmapDataObject* dobjBmp = new wxBitmapDataObject( bitmap );
785
786 if( !wxTheClipboard->SetData( dobjBmp ) )
787 wxMessageBox( _( "Failed to copy image to clipboard" ) );
788
789 wxTheClipboard->Flush(); /* the data in clipboard will stay
790 * available after the application exits */
791 wxTheClipboard->Close();
792 }
793 }
794 else
795 {
796 if( !screenshotImage.SaveFile( fullFileName,
797 fmt_is_jpeg ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG ) )
798 wxMessageBox( _( "Can't save file" ) );
799
800 screenshotImage.Destroy();
801 }
802}
803
804
806{
807 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::RenderEngineChanged()" ) );
808
809 if( m_canvas )
811}
812
813
815{
816 wxCHECK_RET( m_canvas, wxT( "Cannot load settings to null canvas" ) );
817
818 COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
819
820 // TODO(JE) use all control options
822}
823
824
826{
827 m_boardAdapter.m_Cfg = cfg;
828
832
834}
RENDER_ENGINE
Render engine mode.
Definition: 3d_enums.h:64
@ ID_MENU_SCREENCOPY_PNG
Definition: 3d_viewer_id.h:40
@ ID_DISABLE_RAY_TRACING
Definition: 3d_viewer_id.h:51
@ ID_START_COMMAND_3D
Definition: 3d_viewer_id.h:36
@ ID_MENU_COMMAND_END
Definition: 3d_viewer_id.h:47
@ ID_RELOAD3D_BOARD
Definition: 3d_viewer_id.h:37
@ ID_TOOL_SCREENCOPY_TOCLIBBOARD
Definition: 3d_viewer_id.h:38
@ ID_MENU3D_RESET_DEFAULTS
Definition: 3d_viewer_id.h:44
@ ID_RENDER_CURRENT_VIEW
Definition: 3d_viewer_id.h:49
@ ID_MENU_SCREENCOPY_JPEG
Definition: 3d_viewer_id.h:41
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
constexpr EDA_IU_SCALE unityScale
Definition: base_units.h:111
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:104
#define RANGE_SCALE_3D
This defines the range that all coord will have to be rendered.
Definition: board_adapter.h:66
Manage TOOL_ACTION objects.
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...
std::vector< VIEWPORT3D > GetUserViewports() const
Update the current viewports from those saved in the project file.
void ApplyViewport(const wxString &aPresetName)
const wxArrayString & GetViewportsMRU()
void ApplyLayerPreset(const wxString &aPresetName)
const wxArrayString & GetLayerPresetsMRU()
Return a list of viewports created by the user.
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Definition: app_settings.h:92
void InitSettings(REPORTER *aStatusReporter, REPORTER *aWarningReporter)
Function to be called by the render when it need to reload the settings for the board.
void SetBoard(BOARD *aBoard) noexcept
Set current board to be rendered.
EDA_3D_VIEWER_SETTINGS * m_Cfg
bool m_MousewheelPanning
void SetProject(PROJECT *aProject, bool aReferenceOnly=false)
Link a board to a given project.
Definition: board.cpp:197
PROJECTION_TYPE GetProjection()
Definition: camera.h:205
Handle actions that are shared between different applications.
int ShowModal() override
EDA_3D_ACTIONS.
static TOOL_ACTION showLayersManager
static TOOL_ACTION showNotInPosFile
static TOOL_ACTION showTHT
static TOOL_ACTION noGrid
static TOOL_ACTION show2_5mmGrid
static TOOL_ACTION show1mmGrid
static TOOL_ACTION showDNP
static TOOL_ACTION toggleOrtho
static TOOL_ACTION show10mmGrid
static TOOL_ACTION show5mmGrid
static TOOL_ACTION showSMD
static TOOL_ACTION showVirtual
static TOOL_ACTION showBBoxes
static TOOL_ACTION showAxis
Implement a canvas based on a wxGLCanvas.
Definition: eda_3d_canvas.h:51
int GetMovingSpeedMultiplier() const
void SetProjectionMode(int aMode)
void SetAnimationEnabled(bool aEnable)
Enable or disable camera animation when switching to a pre-defined view.
int GetProjectionMode() const
void DoRePaint()
The actual function to repaint the canvas.
void SetEventDispatcher(TOOL_DISPATCHER *aEventDispatcher)
Set a dispatcher that processes events and forwards them to tools.
bool IsReloadRequestPending() const
Query if there is a pending reload request.
Definition: eda_3d_canvas.h:93
bool GetAnimationEnabled() const
void ReloadRequest(BOARD *aBoard=nullptr, S3D_CACHE *aCachePointer=nullptr)
void GetScreenshot(wxImage &aDstImage)
Request a screenshot and output it to the aDstImage.
void SetMovingSpeedMultiplier(int aMultiplier)
Set the camera animation moving speed multiplier option.
void RenderEngineChanged()
Notify that the render engine was changed.
void Request_refresh(bool aRedrawImmediately=true)
Schedule a refresh update of the canvas.
EDA_3D_CONTROLLER.
Create and handle a window for the 3d viewer connected to a Kiway and a pcbboard.
void OnSetFocus(wxFocusEvent &event)
void onDisableRayTracing(wxCommandEvent &aEvent)
void takeScreenshot(wxCommandEvent &event)
Create a Screenshot of the current 3D view.
void applySettings(EDA_3D_VIEWER_SETTINGS *aSettings)
PCB_BASE_FRAME * Parent() const
void SaveSettings(APP_SETTINGS_BASE *aCfg) override
Save common frame parameters to a configuration data file.
void NewDisplay(bool aForceImmediateRedraw=false)
Reload and refresh (rebuild) the 3D scene.
void setupUIConditions() override
Setup the UI conditions for the various actions and their controls in this frame.
void OnActivate(wxActivateEvent &event)
bool TryBefore(wxEvent &aEvent) override
EDA_3D_CANVAS * m_canvas
void Exit3DFrame(wxCommandEvent &event)
Called when user press the File->Exit.
BOARD_ADAPTER m_boardAdapter
void RenderEngineChanged()
RenderEngineChanged - Update toolbar icon and call canvas RenderEngineChanged.
void Process_Special_Functions(wxCommandEvent &event)
void OnCloseWindow(wxCloseEvent &event)
void ReCreateMainToolbar()
Definition: 3d_toolbar.cpp:38
void ShowChangedLanguage() override
void ReloadRequest()
Request reloading the 3D view.
wxFileName m_defaultSaveScreenshotFileName
void onRenderEngineSelection(wxCommandEvent &event)
BOARD_ADAPTER & GetAdapter()
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
NL_3D_VIEWER_PLUGIN * m_spaceMouse
void loadCommonSettings()
Load configuration from common settings.
void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged) override
Notification that common settings are updated.
void handleIconizeEvent(wxIconizeEvent &aEvent) override
Handle a window iconize event.
LAYER_PRESET_3D * FindPreset(const wxString &aName)
std::vector< LAYER_PRESET_3D > m_LayerPresets
virtual void handleIconizeEvent(wxIconizeEvent &aEvent)
Handle a window iconize event.
APPEARANCE_CONTROLS_3D * m_appearancePanel
void ShowChangedLanguage() override
Redraw the menus and what not in current language.
virtual void setupUIConditions()
Setup the UI conditions for the various actions and their controls in this frame.
SETTINGS_MANAGER * GetSettingsManager() const
wxAuiManager m_auimgr
virtual void LoadSettings(APP_SETTINGS_BASE *aCfg)
Load common frame parameters from a configuration file.
void CommonSettingsChanged(bool aEnvVarsChanged, bool aTextVarsChanged) override
Notification event that some of the common (suite-wide) settings have changed.
virtual void SaveSettings(APP_SETTINGS_BASE *aCfg)
Save common frame parameters to a configuration data file.
virtual void RegisterUIUpdateHandler(int aID, const ACTION_CONDITIONS &aConditions) override
Register a UI update handler for the control with ID aID.
static KIGFX::VC_SETTINGS GetVcSettings()
Gets a populated View Controls settings object dervived from our program settings.
Specialization of the wxAuiPaneInfo class for KiCad panels.
int GetSelection() const
void SetVcSettings(const KIGFX::VC_SETTINGS &aVcSettings)
void ResetToDefaults()
Resets all parameters to default values.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
Definition: kiway_player.h:65
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition: kiway.h:284
The class that implements the public interface to the SpaceMouse plug-in.
void SetFocus(bool aFocus=true)
Set the connection to the 3Dconnexion driver to the focus state so that 3DMouse data is routed here.
static const wxGLAttributes GetAttributesList(ANTIALIASING_MODE aAntiAliasingMode, bool aAlpha=false)
Get a list of attributes to pass to wxGLCanvas.
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition: pgm_base.cpp:679
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
std::vector< VIEWPORT3D > m_Viewports3D
List of stored viewports (pos + zoom)
Definition: project_file.h:183
static S3D_CACHE * Get3DCacheManager(PROJECT *aProject, bool updateProjDir=false)
Return a pointer to an instance of the 3D cache manager.
Definition: project_pcb.cpp:77
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition: project.cpp:129
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:200
T * GetAppSettings(const wxString &aFilename)
Returns a handle to the a given settings by type If the settings have already been loaded,...
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:167
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
Master controller class:
Definition: tool_manager.h:62
ACTION_MANAGER * GetActionManager() const
Definition: tool_manager.h:302
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).
A modified version of the wxInfoBar class that allows us to:
Definition: wx_infobar.h:76
#define _HKI(x)
#define _(s)
#define GridSizeCheck(x)
EVT_TOOL_RANGE(ID_START_COMMAND_3D, ID_MENU_COMMAND_END, EDA_3D_VIEWER_FRAME::Process_Special_Functions) EDA_3D_VIEWER_FRAME
Declaration of the eda_3d_viewer class.
@ ACTIVITY
@ HOVERED_ITEM
#define FOLLOW_PLOT_SETTINGS
#define LEGACY_PRESET_FLAG
#define FOLLOW_PCB
#define QUALIFIED_VIEWER3D_FRAMENAME(parent)
#define VIEWPORT_SWITCH_KEY
#define PRESET_SWITCH_KEY
@ FRAME_PCB_DISPLAY3D
Definition: frame_type.h:47
static const std::string JpegFileExtension
static const std::string PngFileExtension
static wxString PngFileWildcard()
static wxString JpegFileWildcard()
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.
PROJECT & Prj()
Definition: kicad.cpp:597
Declaration of the NL_3D_VIEWER_PLUGIN class.
ANTIALIASING_MODE
Anti-aliasing options.
Definition: ogl_attr_list.h:37
BOARD * GetBoard()
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
see class PGM_BASE
Functors that can be used to figure out how the action controls should be displayed in the UI and if ...
Definition of file extensions used in Kicad.
void SetAuiPaneSize(wxAuiManager &aManager, wxAuiPaneInfo &aPane, int aWidth, int aHeight)
Sets the size of an AUI pane, working around http://trac.wxwidgets.org/ticket/13180.