27#include <wx/tokenzr.h>
29#include "../common_ogl/ogl_utils.h"
94 wxID_ANY, wxDefaultPosition,
95 wxDefaultSize, wxFULL_REPAINT_ON_RESIZE ),
96 m_eventDispatcher(
nullptr ),
97 m_parentStatusBar(
nullptr ),
98 m_parentInfoBar(
nullptr ),
100 m_is_opengl_initialized( false ),
101 m_is_opengl_version_supported( true ),
102 m_editing_timeout_timer( this, wxID_HIGHEST + 1 ),
103 m_redraw_trigger_timer( this, wxID_HIGHEST + 2 ),
104 m_render_pivot( false ),
105 m_camera_moving_speed( 1.0f ),
106 m_strtime_camera_movement( 0 ),
107 m_animation_enabled( true ),
108 m_moving_speed_multiplier( 3 ),
109 m_boardAdapter( aBoardAdapter ),
110 m_3d_render(
nullptr ),
111 m_opengl_supports_raytracing( true ),
112 m_render_raytracing_was_requested( false ),
113 m_accelerator3DShapes(
nullptr ),
114 m_currentRollOverItem(
nullptr )
116 wxLogTrace( m_logTrace, wxT(
"EDA_3D_CANVAS::EDA_3D_CANVAS" ) );
118 m_editing_timeout_timer.SetOwner(
this );
119 Connect( m_editing_timeout_timer.GetId(), wxEVT_TIMER,
122 m_redraw_trigger_timer.SetOwner(
this );
123 Connect( m_redraw_trigger_timer.GetId(), wxEVT_TIMER,
126 m_is_currently_painting.clear();
129 m_3d_render_opengl =
new RENDER_3D_OPENGL(
this, m_boardAdapter, m_camera );
131 wxASSERT( m_3d_render_raytracing !=
nullptr );
132 wxASSERT( m_3d_render_opengl !=
nullptr );
134 auto busy_indicator_factory =
137 return std::make_unique<WX_BUSY_INDICATOR>();
140 m_3d_render_raytracing->SetBusyIndicatorFactory( busy_indicator_factory );
141 m_3d_render_opengl->SetBusyIndicatorFactory( busy_indicator_factory );
145 m_3d_render = m_3d_render_opengl;
147 m_boardAdapter.ReloadColorSettings();
149 wxASSERT( a3DCachePointer !=
nullptr );
150 m_boardAdapter.Set3dCacheManager( a3DCachePointer );
153 EnableTouchEvents( wxTOUCH_ZOOM_GESTURE | wxTOUCH_PAN_GESTURES | wxTOUCH_ROTATE_GESTURE );
156 const wxEventType events[] =
162 wxEVT_LEFT_UP, wxEVT_LEFT_DOWN, wxEVT_LEFT_DCLICK,
163 wxEVT_RIGHT_UP, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_DCLICK,
164 wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_DCLICK,
165 wxEVT_MOTION, wxEVT_MOUSEWHEEL, wxEVT_CHAR, wxEVT_CHAR_HOOK,
167 wxEVT_MENU_OPEN, wxEVT_MENU_CLOSE, wxEVT_MENU_HIGHLIGHT
170 for( wxEventType eventType : events )
177 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_CANVAS::~EDA_3D_CANVAS" ) );
224 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_CANVAS::initializeOpenGL" ) );
226 const GLenum err = glewInit();
230 const wxString msgError = (
const char*) glewGetErrorString( err );
232 wxLogMessage( msgError );
238 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_CANVAS::initializeOpenGL Using GLEW version %s" ),
239 From_UTF8( (
char*) glewGetString( GLEW_VERSION ) ) );
242 SetOpenGLInfo( (
const char*) glGetString( GL_VENDOR ), (
const char*) glGetString( GL_RENDERER ),
243 (
const char*) glGetString( GL_VERSION ) );
245 wxString version =
From_UTF8( (
char *) glGetString( GL_VERSION ) );
247 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_CANVAS::%s OpenGL version string %s." ),
248 __WXFUNCTION__, version );
254 wxStringTokenizer tokenizer( version );
256 if( tokenizer.HasMoreTokens() )
261 tmp = tokenizer.GetNextToken();
263 tokenizer.SetString( tmp, wxString( wxT(
"." ) ) );
265 if( tokenizer.HasMoreTokens() )
266 tokenizer.GetNextToken().ToLong( &major );
268 if( tokenizer.HasMoreTokens() )
269 tokenizer.GetNextToken().ToLong( &minor );
271 if( major < 2 || ( ( major == 2 ) && ( minor < 1 ) ) )
273 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_CANVAS::%s OpenGL ray tracing not supported." ),
279 GetParent()->ProcessWindowEvent( evt );
285 if( ( major == 1 ) && ( minor < 5 ) )
287 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_CANVAS::%s OpenGL not supported." ),
309 if( aCachePointer !=
nullptr )
312 if( aBoard !=
nullptr )
342 m_parentStatusBar->SetStatusText( msg,
static_cast<int>( EDA_3D_VIEWER_STATUSBAR::X_POS ) );
345 m_parentStatusBar->SetStatusText( msg,
static_cast<int>( EDA_3D_VIEWER_STATUSBAR::Y_POS ) );
348 m_parentStatusBar->SetStatusText( msg,
static_cast<int>( EDA_3D_VIEWER_STATUSBAR::ZOOM_LEVEL ) );
366 if( !IsShownOnScreen() )
368 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_CANVAS::DoRePaint !IsShown" ) );
379 if( !GetParent()->GetParent()->IsShownOnScreen() )
382 wxString err_messages;
429 warningReporter.
Report(
_(
"Your OpenGL version is not supported. Minimum required "
438 glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
439 glClear( GL_COLOR_BUFFER_BIT );
465 || windows_size_changed )
473 float curtime_delta_s = 0.0f;
481 if( curtime_delta_s > 1.0f )
497 bool requested_redraw =
false;
505 bool reloadRaytracingForCalculations =
false;
510 reloadRaytracingForCalculations =
true;
514 &activityReporter, &warningReporter );
523 if( reloadRaytracingForCalculations )
526 catch( std::runtime_error& )
563 activityReporter.
Report( wxString::Format(
_(
"Last render time %.0f ms" ),
564 calculation_time ) );
572 if( !err_messages.IsEmpty() )
573 wxLogMessage( err_messages );
604 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_CANVAS::OnEraseBackground" ) );
611 wxLogTrace(
m_logTrace, wxT(
"EDA_3D_CANVAS::OnMouseWheel" ) );
634 float magnification = (
event.GetMagnification() + 1.0f );
647 if( aEvent.IsGestureStart() )
674 if( aEvent.IsGestureStart() )
692 if( aEvent.IsGestureStart() )
739 return wxString::Format(
_(
"Net %s\tNet class %s" ),
740 aItem->GetNet()->GetNetname(),
741 aItem->GetNet()->GetNetClass()->GetName() );
756 switch( rollOverItem->
Type() )
760 PAD*
pad =
static_cast<PAD*
>( rollOverItem );
762 if( !
pad->GetNumber().IsEmpty() )
763 msg += wxString::Format(
_(
"Pad %s\t" ),
pad->GetNumber() );
765 if(
pad->IsOnCopperLayer() )
766 msg += printNetInfo(
pad );
783 msg += printNetInfo( track );
789 ZONE* zone =
static_cast<ZONE*
>( rollOverItem );
794 msg += wxString::Format(
_(
"Rule area %s\t" ), zone->
GetZoneName() );
796 msg += wxString::Format(
_(
"Zone %s\t" ), zone->
GetZoneName() );
800 msg += printNetInfo( zone );
819 reporter.
Report( wxEmptyString );
934 if( aRedrawImmediately )
941 wxPostEvent(
this, redrawEvent );
953 wxASSERT( aMovingSpeed > FLT_EPSILON );
1007 const float arrow_moving_time_speed = 8.0f;
1009 switch( aRequestedView )
1011 case VIEW3D_TYPE::VIEW3D_PIVOT_CENTER:
1015 case VIEW3D_TYPE::VIEW3D_PAN_LEFT:
1022 case VIEW3D_TYPE::VIEW3D_PAN_RIGHT:
1029 case VIEW3D_TYPE::VIEW3D_PAN_UP:
1036 case VIEW3D_TYPE::VIEW3D_PAN_DOWN:
1043 case VIEW3D_TYPE::VIEW3D_FIT_SCREEN:
1050 case VIEW3D_TYPE::VIEW3D_ZOOM_IN:
1059 case VIEW3D_TYPE::VIEW3D_ZOOM_OUT:
1068 case VIEW3D_TYPE::VIEW3D_RIGHT:
1069 case VIEW3D_TYPE::VIEW3D_LEFT:
1070 case VIEW3D_TYPE::VIEW3D_FRONT:
1071 case VIEW3D_TYPE::VIEW3D_BACK:
1072 case VIEW3D_TYPE::VIEW3D_FLIP:
1079 case VIEW3D_TYPE::VIEW3D_TOP:
1080 case VIEW3D_TYPE::VIEW3D_BOTTOM:
1123 mouseRay.
Init( rayOrigin, rayDir );
void SetOpenGLInfo(const char *aVendor, const char *aRenderer, const char *aVersion)
A setter for OpenGL info when it's initialized.
Helper class to handle information needed to display 3D board.
const BBOX_3D & GetBBox() const noexcept
Get the board outling bounding box.
void ReloadColorSettings() noexcept
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.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Information pertinent to a Pcbnew printed circuit board.
A class used to derive camera objects from.
virtual void Pan(const wxPoint &aNewMousePosition)=0
void RotateScreen(float aAngleInRadians)
Rotates the camera in screen plane.
bool Zoom_T1(float aFactor)
virtual void Pan_T1(const SFVEC3F &aDeltaOffsetInc)=0
virtual void Interpolate(float t)
It will update the matrix to interpolate between T0 and T1 values.
bool SetCurWindowSize(const wxSize &aSize)
Update the windows size of the camera.
void SetInterpolateMode(CAMERA_INTERPOLATION aInterpolateMode)
bool ViewCommand_T1(VIEW3D_TYPE aRequestedView)
virtual void SetT0_and_T1_current_T()
This will set T0 and T1 with the current values.
void MakeRayAtCurrentMousePosition(SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection) const
Make a ray based on the latest mouse position.
void SetLookAtPos_T1(const SFVEC3F &aLookAtPos)
const SFVEC3F & GetCameraPos() const
void SetCurMousePosition(const wxPoint &aPosition)
Update the current mouse position without make any new calculations on camera.
Implement a canvas based on a wxGLCanvas.
RENDER_3D_OPENGL * m_3d_render_opengl
TOOL_DISPATCHER * m_eventDispatcher
void OnEvent(wxEvent &aEvent)
Used to forward events to the canvas from popups, etc.
void OnMagnify(wxMouseEvent &event)
void restart_editingTimeOut_Timer()
Reset the editing timer.
BOARD_ITEM * m_currentRollOverItem
RENDER_3D_BASE * m_3d_render
bool m_is_opengl_initialized
void OnResize(wxSizeEvent &event)
bool m_render3dmousePivot
void OnMouseWheel(wxMouseEvent &event)
WX_INFOBAR * m_parentInfoBar
wxTimer m_editing_timeout_timer
int64_t m_strtime_camera_movement
void OnLeftDown(wxMouseEvent &event)
void OnPanGesture(wxPanGestureEvent &event)
ACCELERATOR_3D * m_accelerator3DShapes
void OnTimerTimeout_Redraw(wxTimerEvent &event)
wxStatusBar * m_parentStatusBar
void DoRePaint()
The actual function to repaint the canvas.
int m_moving_speed_multiplier
bool m_is_opengl_version_supported
wxTimer m_redraw_trigger_timer
BOARD_ADAPTER & m_boardAdapter
void DisplayStatus()
Update the status bar with the position information.
void render3dmousePivot(float aScale)
Render the 3dmouse pivot cursor.
void OnPaint(wxPaintEvent &aEvent)
void RenderRaytracingRequest()
Request to render the current view in Raytracing mode.
void SetEventDispatcher(TOOL_DISPATCHER *aEventDispatcher)
Set a dispatcher that processes events and forwards them to tools.
bool m_render_raytracing_was_requested
float m_camera_moving_speed
void OnLeftUp(wxMouseEvent &event)
void ReloadRequest(BOARD *aBoard=nullptr, S3D_CACHE *aCachePointer=nullptr)
RAY getRayAtCurrentMousePosition()
double m_gestureLastZoomFactor
< Used to track gesture events.
void OnCloseWindow(wxCloseEvent &event)
bool SetView3D(VIEW3D_TYPE aRequestedView)
Select a specific 3D view or operation.
void OnMiddleDown(wxMouseEvent &event)
void GetScreenshot(wxImage &aDstImage)
Request a screenshot and output it to the aDstImage.
RENDER_3D_RAYTRACE_GL * m_3d_render_raytracing
void OnZoomGesture(wxZoomGestureEvent &event)
void OnMiddleUp(wxMouseEvent &event)
void render_pivot(float t, float aScale)
Render the pivot cursor.
void request_start_moving_camera(float aMovingSpeed=2.0f, bool aRenderPivot=true)
Start a camera movement.
void RenderEngineChanged()
Notify that the render engine was changed.
std::atomic_flag m_is_currently_painting
void OnRefreshRequest(wxEvent &aEvent)
void OnEraseBackground(wxEraseEvent &event)
void releaseOpenGL()
Free created targets and openGL context.
void Request_refresh(bool aRedrawImmediately=true)
Schedule a refresh update of the canvas.
bool m_opengl_supports_raytracing
void OnMouseMove(wxMouseEvent &event)
void OnRotateGesture(wxRotateGestureEvent &event)
void move_pivot_based_on_cur_mouse_position()
This function hits a ray to the board and start a movement.
double m_gestureLastAngle
void OnTimerTimeout_Editing(wxTimerEvent &event)
void stop_editingTimeOut_Timer()
Stop the editing time so it will not timeout.
KICAD_T Type() const
Returns the type of object.
void UnlockCtx(wxGLContext *aContext)
Allow other canvases to bind an OpenGL context.
void DestroyCtx(wxGLContext *aContext)
Destroy a managed OpenGL context.
void LockCtx(wxGLContext *aContext, wxGLCanvas *aCanvas)
Set a context as current and prevents other canvases from switching it.
static GL_CONTEXT_MANAGER & Get()
Return the GL_CONTEXT_MANAGER instance (singleton).
wxGLContext * CreateCtx(wxGLCanvas *aCanvas, const wxGLContext *aOther=nullptr)
Create a managed OpenGL context.
static int SetSwapInterval(int aVal)
Attempts to set the OpenGL swap interval.
Provides basic 3D controls ( zoom, rotate, translate, ... )
static const float m_delta_move_step_factor
void OnMouseWheelCamera(wxMouseEvent &event, bool aPan)
void OnMouseMoveCamera(wxMouseEvent &event)
virtual wxSize GetNativePixelSize() const
A wrapper for reporting to a WX_INFOBAR UI element.
void Finalize()
Update the infobar with the reported text.
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
virtual SETTINGS_MANAGER & GetSettingsManager() const
virtual bool Redraw(bool aIsMoving, REPORTER *aStatusReporter=nullptr, REPORTER *aWarningReporter=nullptr)=0
Redraw the view.
virtual int GetWaitForEditingTimeOut()=0
Give the interface the time (in ms) that it should wait for editing or movements before (this works f...
virtual void SetCurWindowSize(const wxSize &aSize)=0
Before each render, the canvas will tell the render what is the size of its windows,...
bool IsReloadRequestPending() const
Query if there is a pending reload request.
Object to render the board using openGL.
void SetCurrentRollOverItem(BOARD_ITEM *aRollOverItem)
void Reload(REPORTER *aStatusReporter, REPORTER *aWarningReporter, bool aOnlyLoadCopperAndShapes)
BOARD_ITEM * IntersectBoardItem(const RAY &aRay)
Cache for storing the 3D shapes.
T * GetAppSettings()
Returns a handle to the a given settings by type If the settings have already been loaded,...
A wrapper for reporting to a specific text location in a statusbar.
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Handle a list of polygons defining a copper zone.
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
const wxString & GetZoneName() const
bool IsOnCopperLayer() const override
wxDEFINE_EVENT(wxEVT_REFRESH_CUSTOM_COMMAND, wxEvent)
Declaration of the eda_3d_viewer class.
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.
This file contains miscellaneous commonly used macros and functions.
void OglGetScreenshot(wxImage &aDstImage)
Get the pixel data of current OpenGL image.
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
PGM_BASE & Pgm()
The global Program "get" accessor.
int64_t GetRunningMicroSecs()
An alternate way to calculate an elapsed time (in microsecondes) to class PROF_COUNTER.
wxString From_UTF8(const char *cstring)
bool Intersect(const RAY &aRay, float *t) const
void Init(const SFVEC3F &o, const SFVEC3F &d)
SFVEC3F at(float t) const
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)