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 The 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{
99 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME %s" ), aTitle );
100
101 m_disable_ray_tracing = false;
102 m_aboutTitle = _HKI( "KiCad 3D Viewer" );
103
104 // Give it an icon
105 wxIcon icon;
106 icon.CopyFromBitmap( KiBitmap( BITMAPS::icon_3d ) );
107 SetIcon( icon );
108
109 // Create the status line
110 static const int status_dims[5] = { -1, 170, 130, 130, 130 };
111
112 wxStatusBar *status_bar = CreateStatusBar( arrayDim( status_dims ) );
113 SetStatusWidths( arrayDim( status_dims ), status_dims );
114
117 ANTIALIASING_MODE aaMode = static_cast<ANTIALIASING_MODE>( cfg->m_Render.opengl_AA_mode );
118
119 m_canvas = new EDA_3D_CANVAS( this, OGL_ATT_LIST::GetAttributesList( aaMode, true ),
120 m_boardAdapter, m_currentCamera,
122
123 m_appearancePanel = new APPEARANCE_CONTROLS_3D( this, GetCanvas() );
124
125 LoadSettings( cfg );
126 loadCommonSettings();
127
128 m_appearancePanel->SetUserViewports( Prj().GetProjectFile().m_Viewports3D );
129
130 // Create the manager
131 m_toolManager = new TOOL_MANAGER;
132 m_toolManager->SetEnvironment( GetBoard(), nullptr, nullptr, cfg, this );
133
134 m_actions = new EDA_3D_ACTIONS();
135 m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager );
136 m_canvas->SetEventDispatcher( m_toolDispatcher );
137
138 // Register tools
139 m_toolManager->RegisterTool( new COMMON_CONTROL );
140 m_toolManager->RegisterTool( new EDA_3D_CONTROLLER );
141 m_toolManager->InitTools();
142
143 setupUIConditions();
144
145 if( EDA_3D_CONTROLLER* ctrlTool = GetToolManager()->GetTool<EDA_3D_CONTROLLER>() )
146 ctrlTool->SetRotationIncrement( cfg->m_Camera.rotation_increment );
147
148 // Run the viewer control tool, it is supposed to be always active
149 m_toolManager->InvokeTool( "3DViewer.Control" );
150
151 ReCreateMenuBar();
152 ReCreateMainToolbar();
153
154 m_infoBar = new WX_INFOBAR( this, &m_auimgr );
155
156 m_auimgr.SetManagedWindow( this );
157
158 m_auimgr.AddPane( m_mainToolBar, EDA_PANE().HToolbar().Name( wxS( "MainToolbar" ) )
159 .Top().Layer( 6 ) );
160 m_auimgr.AddPane( m_infoBar, EDA_PANE().InfoBar().Name( wxS( "InfoBar" ) )
161 .Top().Layer( 1 ) );
162 m_auimgr.AddPane( m_appearancePanel, EDA_PANE().Name( "LayersManager" )
163 .Right().Layer( 3 )
164 .Caption( _( "Appearance" ) ).PaneBorder( false )
165 .MinSize( 180, -1 ).BestSize( 190, -1 ) );
166 m_auimgr.AddPane( m_canvas, EDA_PANE().Canvas().Name( wxS( "DrawFrame" ) )
167 .Center() );
168
169 wxAuiPaneInfo& layersManager = m_auimgr.GetPane( "LayersManager" );
170
171 if( cfg->m_AuiPanels.right_panel_width > 0 )
172 SetAuiPaneSize( m_auimgr, layersManager, cfg->m_AuiPanels.right_panel_width, -1 );
173
174 layersManager.Show( cfg->m_AuiPanels.show_layer_manager );
175
176 // Call Update() to fix all pane default sizes, especially the "InfoBar" pane before
177 // hiding it.
178 m_auimgr.Update();
179
180 // We don't want the infobar displayed right away
181 m_auimgr.GetPane( wxS( "InfoBar" ) ).Hide();
182 m_auimgr.Update();
183
184 m_canvas->SetInfoBar( m_infoBar );
185 m_canvas->SetStatusBar( status_bar );
186
187 try
188 {
189 m_spaceMouse = std::make_unique<NL_3D_VIEWER_PLUGIN>( m_canvas );
190 }
191 catch( const std::system_error& e )
192 {
193 wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
194 }
195
196 // Fixes bug in Windows (XP and possibly others) where the canvas requires the focus
197 // in order to receive mouse events. Otherwise, the user has to click somewhere on
198 // the canvas before it will respond to mouse wheel events.
199 m_canvas->SetFocus();
200}
201
202
204{
206
207 m_canvas->SetEventDispatcher( nullptr );
208
209 m_auimgr.UnInit();
210}
211
212
214{
216
219
220// Helper to define check conditions
221#define GridSizeCheck( x ) ACTION_CONDITIONS().Check( cond.GridSize( x ) )
222
223 auto raytracing =
224 [this]( const SELECTION& aSel )
225 {
226 return m_boardAdapter.m_Cfg->m_Render.engine != RENDER_ENGINE::OPENGL;
227 };
228 auto showTH =
229 [this]( const SELECTION& aSel )
230 {
232 };
233 auto showSMD =
234 [this]( const SELECTION& aSel )
235 {
237 };
238 auto showVirtual =
239 [this]( const SELECTION& aSel )
240 {
242 };
243 auto show_NotInPosfile =
244 [this]( const SELECTION& aSel )
245 {
247 };
248 auto show_DNP =
249 [this]( const SELECTION& aSel )
250 {
252 };
253 auto showBBoxes =
254 [this]( const SELECTION& aSel )
255 {
257 };
258 auto showAxes =
259 [this]( const SELECTION& aSel )
260 {
262 };
263 auto ortho =
264 [this]( const SELECTION& )
265 {
266 return m_currentCamera.GetProjection() == PROJECTION_TYPE::ORTHO;
267 };
268
269 auto appearances =
270 [this]( const SELECTION& aSel )
271 {
273 };
274
276
278 mgr->SetConditions( EDA_3D_ACTIONS::showSMD, ACTION_CONDITIONS().Check( showSMD ) );
279 mgr->SetConditions( EDA_3D_ACTIONS::showVirtual, ACTION_CONDITIONS().Check( showVirtual ) );
281 ACTION_CONDITIONS().Check( show_NotInPosfile ) );
282 mgr->SetConditions( EDA_3D_ACTIONS::showDNP, ACTION_CONDITIONS().Check( show_DNP ) );
283
284 mgr->SetConditions( EDA_3D_ACTIONS::showBBoxes, ACTION_CONDITIONS().Check( showBBoxes ) );
285 mgr->SetConditions( EDA_3D_ACTIONS::showAxis, ACTION_CONDITIONS().Check( showAxes ) );
286
287 mgr->SetConditions( EDA_3D_ACTIONS::noGrid, GridSizeCheck( GRID3D_TYPE::NONE ) );
288 mgr->SetConditions( EDA_3D_ACTIONS::show10mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_10MM ) );
289 mgr->SetConditions( EDA_3D_ACTIONS::show5mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_5MM ) );
290 mgr->SetConditions( EDA_3D_ACTIONS::show2_5mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_2P5MM ) );
291 mgr->SetConditions( EDA_3D_ACTIONS::show1mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_1MM ) );
293
295 ACTION_CONDITIONS().Check( appearances ) );
296
297#undef GridSizeCheck
298}
299
300
301bool EDA_3D_VIEWER_FRAME::TryBefore( wxEvent& aEvent )
302{
303 static bool s_presetSwitcherShown = false;
304 static bool s_viewportSwitcherShown = false;
305
306 // wxWidgets generates no key events for the tab key when the ctrl key is held down. One
307 // way around this is to look at all events and inspect the keyboard state of the tab key.
308 // However, this runs into issues on some linux VMs where querying the keyboard state is
309 // very slow. Fortunately we only use ctrl-tab on Mac, so we implement this lovely hack:
310#ifdef __WXMAC__
311 if( wxGetKeyState( WXK_TAB ) )
312#else
313 if( ( aEvent.GetEventType() == wxEVT_CHAR || aEvent.GetEventType() == wxEVT_CHAR_HOOK )
314 && static_cast<wxKeyEvent&>( aEvent ).GetKeyCode() == WXK_TAB )
315#endif
316 {
317 if( !s_presetSwitcherShown && wxGetKeyState( PRESET_SWITCH_KEY ) )
318 {
319 if( m_appearancePanel && this->IsActive() )
320 {
321 wxArrayString mru = m_appearancePanel->GetLayerPresetsMRU();
322
323 if( mru.size() > 0 )
324 {
325 for( wxString& str : mru )
326 {
327 if( str == FOLLOW_PCB )
328 str = _( "Follow PCB Editor" );
329 else if( str == FOLLOW_PLOT_SETTINGS )
330 str = _( "Follow PCB Plot Settings" );
331 }
332
333 EDA_VIEW_SWITCHER switcher( this, mru, PRESET_SWITCH_KEY );
334
335 s_presetSwitcherShown = true;
336 switcher.ShowModal();
337 s_presetSwitcherShown = false;
338
339 int idx = switcher.GetSelection();
340
341 if( idx >= 0 && idx < (int) mru.size() )
342 {
343 wxString internalName = m_appearancePanel->GetLayerPresetsMRU()[idx];
344 m_appearancePanel->ApplyLayerPreset( internalName );
345 }
346
347 return true;
348 }
349 }
350 }
351 else if( !s_viewportSwitcherShown && wxGetKeyState( VIEWPORT_SWITCH_KEY ) )
352 {
353 if( this->IsActive() )
354 {
355 const wxArrayString& viewportMRU = m_appearancePanel->GetViewportsMRU();
356
357 if( viewportMRU.size() > 0 )
358 {
359 EDA_VIEW_SWITCHER switcher( this, viewportMRU, VIEWPORT_SWITCH_KEY );
360
361 s_viewportSwitcherShown = true;
362 switcher.ShowModal();
363 s_viewportSwitcherShown = false;
364
365 int idx = switcher.GetSelection();
366
367 if( idx >= 0 && idx < (int) viewportMRU.size() )
368 m_appearancePanel->ApplyViewport( viewportMRU[idx] );
369
370 return true;
371 }
372 }
373 }
374 }
375
376 return wxFrame::TryBefore( aEvent );
377}
378
379
380void EDA_3D_VIEWER_FRAME::handleIconizeEvent( wxIconizeEvent& aEvent )
381{
383
384 if( m_spaceMouse && aEvent.IsIconized() )
385 m_spaceMouse->SetFocus( false );
386}
387
388
390{
391 // This will schedule a request to load later
392 // ReloadRequest also updates the board pointer so always call it first
393 if( m_canvas )
395
398}
399
400
401void EDA_3D_VIEWER_FRAME::NewDisplay( bool aForceImmediateRedraw )
402{
403 if( m_canvas )
405
406 // After the ReloadRequest call, the refresh often takes a bit of time,
407 // and it is made here only on request.
408 if( m_canvas && aForceImmediateRedraw )
409 m_canvas->Refresh();
410}
411
412
414{
415 // Only update in OpenGL for an interactive interaction
416 if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
417 m_canvas->Request_refresh( true );
418}
419
420
422{
423 if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
425 else
426 NewDisplay( true );
427}
428
429
430void EDA_3D_VIEWER_FRAME::Exit3DFrame( wxCommandEvent &event )
431{
432 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::Exit3DFrame" ) );
433
434 Close( true );
435}
436
437
438void EDA_3D_VIEWER_FRAME::OnCloseWindow( wxCloseEvent &event )
439{
440 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::OnCloseWindow" ) );
441
442 // Do not show the layer manager during closing to avoid flicker on some platforms (Windows)
443 // that generate useless redraw of items in the Layer Manager
444 if( m_auimgr.GetPane( wxS( "LayersManager" ) ).IsShown() )
445 m_auimgr.GetPane( wxS( "LayersManager" ) ).Show( false );
446
447 if( m_canvas )
448 m_canvas->Close();
449
450 Destroy();
451 event.Skip( true );
452}
453
454
456{
457 int id = event.GetId();
458 bool isChecked = event.IsChecked();
459
460 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::Process_Special_Functions id %d "
461 "isChecked %d" ),
462 id,
463 isChecked );
464
465 if( m_canvas == nullptr )
466 return;
467
468 switch( id )
469 {
471 NewDisplay( true );
472 break;
473
477 takeScreenshot( event );
478 return;
479
481 {
484
485 cfg->ResetToDefaults();
486 LoadSettings( cfg );
487
488 // Tell canvas that we (may have) changed the render engine
490
491 NewDisplay( true );
492 }
493 return;
494
495 default:
496 wxFAIL_MSG( wxT( "Invalid event in EDA_3D_VIEWER_FRAME::Process_Special_Functions()" ) );
497 return;
498 }
499}
500
501
503{
505 RENDER_ENGINE old_engine = engine;
506
507 if( old_engine == RENDER_ENGINE::OPENGL )
508 engine = RENDER_ENGINE::RAYTRACING;
509 else
510 engine = RENDER_ENGINE::OPENGL;
511
512 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::OnRenderEngineSelection type %s " ),
513 engine == RENDER_ENGINE::RAYTRACING ? wxT( "raytracing" ) : wxT( "realtime" ) );
514
515 if( old_engine != engine )
517}
518
519
520void EDA_3D_VIEWER_FRAME::onDisableRayTracing( wxCommandEvent& aEvent )
521{
522 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::%s disabling ray tracing." ),
523 __WXFUNCTION__ );
524
526 m_boardAdapter.m_Cfg->m_Render.engine = RENDER_ENGINE::OPENGL;
527}
528
529
530void EDA_3D_VIEWER_FRAME::OnActivate( wxActivateEvent &aEvent )
531{
532 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::OnActivate" ) );
533
534 if( aEvent.GetActive() && m_canvas )
535 {
536 // Reload data if 3D frame shows a board,
537 // because it can be changed since last frame activation
540
541 // Activates again the focus of the canvas so it will catch mouse and key events
542 m_canvas->SetFocus();
543 }
544
545 if( m_spaceMouse )
546 m_spaceMouse->SetFocus( aEvent.GetActive() );
547
548 aEvent.Skip(); // required under wxMAC
549}
550
551
552void EDA_3D_VIEWER_FRAME::OnSetFocus( wxFocusEvent& aEvent )
553{
554 // Activates again the focus of the canvas so it will catch mouse and key events
555 if( m_canvas )
556 m_canvas->SetFocus();
557
558 aEvent.Skip();
559}
560
561
563{
565
566 // Dynamic_cast here will fail on Mac when called from CvPCB.
567 EDA_3D_VIEWER_SETTINGS* cfg = static_cast<EDA_3D_VIEWER_SETTINGS*>( aCfg );
568
569 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::LoadSettings" ) );
570
571 if( cfg )
572 {
573 applySettings( cfg );
574
575 if( !GetBoard()->GetProject() )
576 GetBoard()->SetProject( &Prj() );
577
579
580 // When opening the 3D viewer, we use the OpenGL mode, never the ray tracing engine
581 // because the ray tracing is very time consuming, and can be seen as not working
582 // (freeze window) with large boards.
583 m_boardAdapter.m_Cfg->m_Render.engine = RENDER_ENGINE::OPENGL;
584
586 {
587 wxString legacyColorsPresetName = _( "legacy colors" );
588
589 cfg->m_UseStackupColors = false;
590
591 if( !cfg->FindPreset( legacyColorsPresetName ) )
592 {
593 cfg->m_LayerPresets.emplace_back( legacyColorsPresetName,
594 GetAdapter().GetDefaultVisibleLayers(),
595 GetAdapter().GetDefaultColors() );
596 }
597
599 }
600
601 m_boardAdapter.InitSettings( nullptr, nullptr );
602
605 }
606}
607
608
610{
613
615
616 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::SaveSettings" ) );
617
618 wxLogTrace( m_logTrace, m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::RAYTRACING ?
619 wxT( "EDA_3D_VIEWER_FRAME::SaveSettings render setting Ray Trace" )
620 :
621 wxT( "EDA_3D_VIEWER_FRAME::SaveSettings render setting OpenGL" ) );
622
623 if( cfg )
624 {
626
630
631 if( EDA_3D_CONTROLLER* ctrlTool = GetToolManager()->GetTool<EDA_3D_CONTROLLER>() )
632 cfg->m_Camera.rotation_increment = ctrlTool->GetRotationIncrement();
633 }
634}
635
636
637void EDA_3D_VIEWER_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
638{
639 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::CommonSettingsChanged" ) );
640
641 // Regen menu bars, etc
642 EDA_BASE_FRAME::CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
643
644 // There is no base class that handles toolbars for this frame
646
649 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 =
718 const wxString ext = fmt_is_jpeg ? FILEEXT::JpegFileExtension : FILEEXT::PngFileExtension;
719
720 // First time path is set to the project path.
723
725
726 wxFileDialog dlg( this, _( "3D Image File Name" ),
728 m_defaultSaveScreenshotFileName.GetFullName(), wildcard,
729 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
730
731 if( dlg.ShowModal() == wxID_CANCEL )
732 return;
733
734 m_defaultSaveScreenshotFileName = dlg.GetPath();
735
736 if( m_defaultSaveScreenshotFileName.GetExt().IsEmpty() )
738
739 fullFileName = m_defaultSaveScreenshotFileName.GetFullPath();
740
741 wxFileName fn = fullFileName;
742
743 if( !fn.IsDirWritable() )
744 {
745 wxString msg;
746
747 msg.Printf( _( "Insufficient permissions to save file '%s'." ), fullFileName );
748 wxMessageBox( msg, _( "Error" ), wxOK | wxICON_ERROR, this );
749 return;
750 }
751
752 // Be sure the screen area destroyed by the file dialog is redrawn
753 // before making a screen copy.
754 // Without this call, under Linux the screen refresh is made to late.
755 wxYield();
756 }
757
758 // Be sure we have the latest 3D view (remember 3D view is buffered)
759 // Also ensure any highlighted item is not highlighted when creating screen shot
761 bool allow_highlight = cfg.highlight_on_rollover;
762 cfg.highlight_on_rollover = false;
763
764 m_canvas->DoRePaint(); // init first buffer
765 m_canvas->DoRePaint(); // init second buffer
766
767 // Build image from the 3D buffer
768 wxWindowUpdateLocker noUpdates( this );
769
770 wxImage screenshotImage;
771
772 if( m_canvas )
773 m_canvas->GetScreenshot( screenshotImage );
774
775 cfg.highlight_on_rollover = allow_highlight;
776
777 if( event.GetId() == ID_TOOL_SCREENCOPY_TOCLIBBOARD )
778 {
779 wxBitmap bitmap( screenshotImage );
780
781 wxLogNull doNotLog; // disable logging of failed clipboard actions
782
783 if( wxTheClipboard->Open() )
784 {
785 wxBitmapDataObject* dobjBmp = new wxBitmapDataObject( bitmap );
786
787 if( !wxTheClipboard->SetData( dobjBmp ) )
788 wxMessageBox( _( "Failed to copy image to clipboard" ) );
789
790 wxTheClipboard->Flush(); /* the data in clipboard will stay
791 * available after the application exits */
792 wxTheClipboard->Close();
793 }
794 }
795 else
796 {
797 if( !screenshotImage.SaveFile( fullFileName,
798 fmt_is_jpeg ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG ) )
799 wxMessageBox( _( "Can't save file" ) );
800
801 screenshotImage.Destroy();
802 }
803}
804
805
807{
808 wxLogTrace( m_logTrace, wxT( "EDA_3D_VIEWER_FRAME::RenderEngineChanged()" ) );
809
810 if( m_canvas )
812}
813
814
816{
817 wxCHECK_RET( m_canvas, wxT( "Cannot load settings to null canvas" ) );
818
819 COMMON_SETTINGS* settings = Pgm().GetCommonSettings();
820
821 // TODO(JE) use all control options
823}
824
825
827{
828 m_boardAdapter.m_Cfg = cfg;
829
833
835}
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
Return a list of viewports created by the user.
void ApplyViewport(const wxString &aPresetName)
const wxArrayString & GetViewportsMRU()
void ApplyLayerPreset(const wxString &aPresetName)
const wxArrayString & GetLayerPresetsMRU()
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.
Handle view actions for various 3D canvases.
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
std::unique_ptr< NL_3D_VIEWER_PLUGIN > m_spaceMouse
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.
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:285
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:689
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:125
std::vector< VIEWPORT3D > m_Viewports3D
List of stored viewports (pos + zoom)
Definition: project_file.h:188
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:140
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:200
T * GetAppSettings(const wxString &aFilename)
Return a handle to the a given settings by type.
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:1073
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.