22#include <wx/filename.h>
25#include <wx/wupdlock.h>
26#include <wx/clipbrd.h>
27#include <wx/filedlg.h>
61#if defined(__linux__) || defined(__FreeBSD__)
94 const wxString& aTitle,
long style ) :
97 m_canvasHolder(
nullptr ),
99 m_currentCamera( m_trackBallCamera ),
102 wxLogTrace( m_logTrace, wxT(
"EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME %s" ), aTitle );
104 m_disable_ray_tracing =
false;
105 m_aboutTitle =
_HKI(
"KiCad 3D Viewer" );
113 std::vector<int> status_dims{ -1,
116 GetTextExtent( wxS(
"dx -88.88" ) ).x + 10,
117 GetTextExtent( wxS(
"dy -88.88" ) ).x + 10,
118 GetTextExtent( wxS(
"zoom -88.88" ) ).x + 10 };
120 wxStatusBar* status_bar = CreateStatusBar( status_dims.size() );
121 SetStatusWidths( status_dims.size(), status_dims.data() );
129 m_canvasHolder =
new wxPanel(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER );
132 m_boardAdapter, m_currentCamera,
135 wxBoxSizer* canvasSizer =
new wxBoxSizer( wxVERTICAL );
136 canvasSizer->Add( m_canvas, 1, wxEXPAND, 0 );
137 m_canvasHolder->SetSizer( canvasSizer );
142 loadCommonSettings();
144 m_appearancePanel->SetUserViewports(
Prj().GetProjectFile().m_Viewports3D );
153 m_canvas->SetEventDispatcher( m_toolDispatcher );
158 m_toolManager->InitTools();
162 if(
EDA_3D_CONTROLLER* ctrlTool = GetToolManager()->GetTool<EDA_3D_CONTROLLER>() )
166 m_toolManager->InvokeTool(
"3DViewer.Control" );
174 m_infoBar =
new WX_INFOBAR( m_canvasHolder, wxID_ANY,
true );
176 m_auimgr.SetManagedWindow(
this );
178 m_auimgr.AddPane( m_tbTopMain,
EDA_PANE().HToolbar().Name( wxS(
"TopMainToolbar" ) )
180 m_auimgr.AddPane( m_appearancePanel,
EDA_PANE().Name(
"LayersManager" )
182 .Caption(
_(
"Appearance" ) ).PaneBorder(
false )
183 .MinSize( FromDIP( 180 ), -1 ).BestSize( FromDIP( 190 ), -1 ) );
184 m_auimgr.AddPane( m_canvasHolder,
EDA_PANE().Canvas().Name( wxS(
"DrawFrame" ) )
187 wxAuiPaneInfo& layersManager = m_auimgr.GetPane(
"LayersManager" );
197 m_canvas->SetInfoBar( m_infoBar );
198 m_canvas->SetStatusBar( status_bar );
202#if defined(__linux__) || defined(__FreeBSD__)
203 m_spaceMouse = std::make_unique<SPNAV_VIEWER_PLUGIN>( m_canvas );
205 m_spaceMouse = std::make_unique<NL_3D_VIEWER_PLUGIN>( m_canvas );
208 catch(
const std::exception& e )
210 wxLogTrace( wxT(
"KI_TRACE_NAVLIB" ), wxS(
"%s" ), e.what() );
214 wxLogTrace( wxT(
"KI_TRACE_NAVLIB" ),
215 wxT(
"Unknown exception during SpaceMouse initialization" ) );
221 m_canvas->SetFocus();
233 m_canvas->SetEventDispatcher(
nullptr );
256#define GridSizeCheck( x ) ACTION_CONDITIONS().Check( cond.GridSize( x ) )
263 auto showMissingModels =
283 auto show_NotInPosfile =
286 return m_boardAdapter.m_Cfg->m_Render.show_footprints_not_in_posfile;
344 static bool s_presetSwitcherShown =
false;
345 static bool s_viewportSwitcherShown =
false;
352 if( wxGetKeyState( WXK_TAB ) )
354 if( ( aEvent.GetEventType() == wxEVT_CHAR || aEvent.GetEventType() == wxEVT_CHAR_HOOK )
355 &&
static_cast<wxKeyEvent&
>( aEvent ).GetKeyCode() == WXK_TAB )
366 for( wxString& str : mru )
369 str =
_(
"Follow PCB Editor" );
371 str =
_(
"Follow PCB Plot Settings" );
376 s_presetSwitcherShown =
true;
378 s_presetSwitcherShown =
false;
382 if( idx >= 0 && idx < (
int) mru.size() )
394 if( this->IsActive() )
398 if( viewportMRU.size() > 0 )
402 s_viewportSwitcherShown =
true;
404 s_viewportSwitcherShown =
false;
408 if( idx >= 0 && idx < (
int) viewportMRU.size() )
417 return wxFrame::TryBefore( aEvent );
449 if(
m_canvas && aForceImmediateRedraw )
473 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_VIEWER_FRAME::Exit3DFrame" ) );
481 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_VIEWER_FRAME::OnCloseWindow" ) );
485 if(
m_auimgr.GetPane( wxS(
"LayersManager" ) ).IsShown() )
486 m_auimgr.GetPane( wxS(
"LayersManager" ) ).Show(
false );
501 switch( event.GetId() )
508 cfg->ResetToDefaults();
519 wxFAIL_MSG( wxT(
"Invalid event in EDA_3D_VIEWER_FRAME::Process_Special_Functions()" ) );
527 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_VIEWER_FRAME::%s disabling ray tracing." ), __WXFUNCTION__ );
536 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_VIEWER_FRAME::OnActivate" ) );
538 if( aEvent.GetActive() &&
m_canvas )
542 if(
m_canvas->IsReloadRequestPending() )
573 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_VIEWER_FRAME::LoadSettings" ) );
588 wxString legacyColorsPresetName =
_(
"legacy colors" );
592 if( !cfg->
FindPreset( legacyColorsPresetName ) )
618 cfg->m_Camera.animation_enabled =
m_canvas->GetAnimationEnabled();
619 cfg->m_Camera.moving_speed_multiplier =
m_canvas->GetMovingSpeedMultiplier();
620 cfg->m_Camera.projection_mode =
m_canvas->GetProjectionMode();
627 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_VIEWER_FRAME::CommonSettingsChanged" ) );
652 SetTitle(
_(
"3D Viewer" ) );
658 lm_pane_info.Caption(
_(
"Appearance" ) );
661 SetStatusText( wxEmptyString,
ACTIVITY );
669 wxAuiPaneInfo& layersManager =
m_auimgr.GetPane(
"LayersManager" );
674 cfg->m_AuiPanels.show_layer_manager = !cfg->m_AuiPanels.show_layer_manager;
676 layersManager.Show( cfg->m_AuiPanels.show_layer_manager );
678 if( cfg->m_AuiPanels.show_layer_manager )
700 wxString fullFileName;
710 if( screenshotImage.IsOk() )
734 wxImage screenshotImage;
739 wxWindowUpdateLocker noUpdates(
this );
740 m_canvas->GetScreenshot( screenshotImage );
746 return screenshotImage;
752 wxString fullFileName;
762 if( screenshotImage.IsOk() )
782 wxFileDialog dlg(
this,
_(
"3D Image File Name" ),
785 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
792 if( dlg.ShowModal() == wxID_CANCEL )
800 bool formatDetected =
false;
802 if( fileExt == wxT(
"jpg") || fileExt == wxT(
"jpeg") )
805 formatDetected =
true;
807 else if( fileExt == wxT(
"png") )
810 formatDetected =
true;
814 if( !formatDetected )
816 int filterIndex = dlg.GetFilterIndex();
827 aFormat = detectedFormat;
832 if( !fn.IsDirWritable() )
835 msg.Printf(
_(
"Insufficient permissions to save file '%s'." ),
837 wxMessageBox( msg,
_(
"Error" ), wxOK | wxICON_ERROR,
this );
854 auto configRestorer = std::unique_ptr<void, std::function<void(
void*)>>(
855 reinterpret_cast<void*
>(1),
874 aAdapter.
m_Cfg = cfg;
890 while( raytrace.
Redraw(
false ) );
892 uint8_t* rgbaBuffer = raytrace.
GetBuffer();
904 const unsigned int wxh = aRealSize.x * aRealSize.y;
906 unsigned char* rgbBuffer = (
unsigned char*) malloc( wxh * 3 );
907 unsigned char* alphaBuffer = (
unsigned char*) malloc( wxh );
909 unsigned char* rgbaPtr = aRGBABuffer;
910 unsigned char* rgbPtr = rgbBuffer;
911 unsigned char* alphaPtr = alphaBuffer;
913 for(
int y = 0; y < aRealSize.y; y++ )
915 for(
int x = 0; x < aRealSize.x; x++ )
917 rgbPtr[0] = rgbaPtr[0];
918 rgbPtr[1] = rgbaPtr[1];
919 rgbPtr[2] = rgbaPtr[2];
920 alphaPtr[0] = rgbaPtr[3];
928 wxImage screenshotImage;
929 screenshotImage.Create( aRealSize );
930 screenshotImage.SetData( rgbBuffer );
931 screenshotImage.SetAlpha( alphaBuffer );
932 return screenshotImage.Mirror(
false );
942 wxFrame temp(
this, wxID_ANY, wxEmptyString, wxDefaultPosition, aSize, wxFRAME_NO_TASKBAR );
951 auto canvas = std::make_unique<EDA_3D_CANVAS>( &temp,
953 tempadapter, aCamera,
956 canvas->SetSize( aSize );
958 wxWindowUpdateLocker noUpdates(
this );
967 std::vector<unsigned char> buffer(aSize.x * aSize.y * 4);
968 canvas->RenderToFrameBuffer( buffer.data(), aSize.x, aSize.y );
1007 wxBitmap bitmap( aScreenshotImage );
1010 if( wxTheClipboard->Open() )
1012 wxBitmapDataObject* dobjBmp =
new wxBitmapDataObject( bitmap );
1014 if( !wxTheClipboard->SetData( dobjBmp ) )
1015 wxMessageBox(
_(
"Failed to copy image to clipboard" ) );
1017 wxTheClipboard->Flush();
1018 wxTheClipboard->Close();
1027 if( !aScreenshotImage.SaveFile( aFullFileName, fmt_is_jpeg ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG ) )
1029 wxMessageBox(
_(
"Can't save file" ) );
1036 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_VIEWER_FRAME::RenderEngineChanged()" ) );
1045 wxCHECK_RET(
m_canvas, wxT(
"Cannot load settings to null canvas" ) );
@ ID_MENU3D_RESET_DEFAULTS
constexpr EDA_IU_SCALE unityScale
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
#define RANGE_SCALE_3D
This defines the range that all coord will have to be rendered.
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...
APP_SETTINGS_BASE is a settings class that should be derived for each standalone KiCad application.
Helper class to handle information needed to display 3D board.
void CreateLayers(std::shared_ptr< REPORTER > aStatusReporter, std::stop_token aStop=std::stop_token())
Creates the layers for the board, should be called after InitSettings.
void InitSettings(std::shared_ptr< REPORTER > aStatusReporter, std::shared_ptr< 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
void Set3dCacheManager(S3D_CACHE *aCacheMgr) noexcept
Update the cache manager pointer.
S3D_CACHE * Get3dCacheManager() const noexcept
bool SetCurWindowSize(const wxSize &aSize)
Update the windows size of the camera.
Handle actions that are shared between different applications.
static TOOL_ACTION showNavigator
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 toggleShowMissingModels
static TOOL_ACTION show10mmGrid
static TOOL_ACTION toggleRaytacing
static TOOL_ACTION show5mmGrid
static TOOL_ACTION showSMD
static TOOL_ACTION showVirtual
static TOOL_ACTION showBBoxes
Implement a canvas based on a wxGLCanvas.
Handle view actions for various 3D canvases.
Create and handle a window for the 3d viewer connected to a Kiway and a pcbboard.
void saveOrCopyImage(const wxImage &screenshotImage, EDA_3D_VIEWER_EXPORT_FORMAT aFormat, const wxString &fullFileName)
Save image to file or copy to clipboard based on format.
void OnSetFocus(wxFocusEvent &event)
void onDisableRayTracing(wxCommandEvent &aEvent)
void CommonSettingsChanged(int aFlags) override
Notification that common settings are updated.
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 configureCanvas(std::unique_ptr< EDA_3D_CANVAS > &canvas, EDA_3D_VIEWER_SETTINGS *cfg)
Configure canvas settings for screenshot capture.
bool m_disable_ray_tracing
wxImage captureOpenGLScreenshot(BOARD_ADAPTER &adapter, TRACK_BALL &camera, const wxSize &aSize)
Capture screenshot using OpenGL renderer.
bool getExportFileName(EDA_3D_VIEWER_EXPORT_FORMAT &aFormat, wxString &fullFileName)
Get export filename through file dialog.
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
void Exit3DFrame(wxCommandEvent &event)
Called when user press the File->Exit.
BOARD_ADAPTER m_boardAdapter
void ToggleAppearanceManager()
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)
wxImage captureCurrentViewScreenshot()
Capture screenshot of the current view using the configured renderer.
void OnCloseWindow(wxCloseEvent &event)
void ShowChangedLanguage() override
wxImage captureScreenshot(const wxSize &aSize)
Capture screenshot using appropriate rendering method.
void setupRenderingConfig(BOARD_ADAPTER &adapter)
Setup rendering configuration for screenshot capture.
void ReloadRequest()
Request reloading the 3D view.
wxFileName m_defaultSaveScreenshotFileName
wxImage convertRGBAToImage(uint8_t *rgbaBuffer, const wxSize &realSize)
Convert RGBA buffer to wxImage format.
TRACK_BALL m_trackBallCamera
APP_SETTINGS_BASE * config() const override
Return the settings object used in SaveSettings(), and is overloaded in KICAD_MANAGER_FRAME.
BOARD_ADAPTER & GetAdapter()
void LoadSettings(APP_SETTINGS_BASE *aCfg) override
Load common frame parameters from a configuration file.
void saveImageToFile(const wxImage &screenshotImage, EDA_3D_VIEWER_EXPORT_FORMAT aFormat, const wxString &fullFileName)
Save image to file.
void copyImageToClipboard(const wxImage &screenshotImage)
Copy image to system clipboard.
void loadCommonSettings()
Load configuration from common settings.
void ExportImage(EDA_3D_VIEWER_EXPORT_FORMAT aFormat, const wxSize &aSize)
Export 3D viewer image to file or clipboard.
wxImage captureRaytracingScreenshot(BOARD_ADAPTER &adapter, TRACK_BALL &camera, const wxSize &aSize)
Capture screenshot using raytracing renderer.
void TakeScreenshot(EDA_3D_VIEWER_EXPORT_FORMAT aFormat)
Create a Screenshot of the current 3D view.
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 CommonSettingsChanged(int aFlags) override
Notification event that some of the common (suite-wide) settings have changed.
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.
virtual void RecreateToolbars()
virtual void LoadSettings(APP_SETTINGS_BASE *aCfg)
Load common frame parameters from a configuration file.
virtual void SaveSettings(APP_SETTINGS_BASE *aCfg)
Save common frame parameters to a configuration data file.
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.
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.
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...
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
virtual SETTINGS_MANAGER & GetSettingsManager() const
std::vector< VIEWPORT3D > m_Viewports3D
List of stored viewports (pos + zoom)
static S3D_CACHE * Get3DCacheManager(PROJECT *aProject, bool updateProjDir=false)
Return a pointer to an instance of the 3D cache manager.
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
virtual PROJECT_FILE & GetProjectFile() const
wxSize GetRealBufferSize()
bool Redraw(bool aIsMoving) override
Redraw the view.
void SetCurWindowSize(const wxSize &aSize) override
Before each render, the canvas will tell the render what is the size of its windows,...
T * GetToolbarSettings(const wxString &aFilename)
Return a handle to the given toolbar settings.
A modified version of the wxInfoBar class that allows us to:
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.
EDA_3D_VIEWER_EXPORT_FORMAT
#define FOLLOW_PLOT_SETTINGS
#define LEGACY_PRESET_FLAG
#define QUALIFIED_VIEWER3D_FRAMENAME(parent)
#define VIEWPORT_SWITCH_KEY
#define PRESET_SWITCH_KEY
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.
EVT_MENU(ID_COMPARE_PROJECT_BRANCHES, KICAD_MANAGER_FRAME::OnCompareProjectBranches) KICAD_MANAGER_FRAME
Declaration of the NL_3D_VIEWER_PLUGIN class.
ANTIALIASING_MODE
Anti-aliasing options.
PGM_BASE & Pgm()
The global program "get" accessor.
T * GetAppSettings(const char *aFilename)
Functors that can be used to figure out how the action controls should be displayed in the UI and if ...
double rotation_increment
int moving_speed_multiplier
ANTIALIASING_MODE opengl_AA_mode
bool highlight_on_rollover
wxString result
Test unit parsing edge cases and error handling.
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.