27 #include <wx/tokenzr.h> 29 #include "../common_ogl/ogl_utils.h" 75 #if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT ) 76 EVT_MAGNIFY( EDA_3D_CANVAS::OnMagnify )
92 :
HIDPI_GL_CANVAS( aParent, wxID_ANY, aAttribList, wxDefaultPosition, wxDefaultSize,
93 wxFULL_REPAINT_ON_RESIZE ),
94 m_eventDispatcher(
nullptr ),
95 m_parentStatusBar(
nullptr ),
96 m_parentInfoBar(
nullptr ),
98 m_is_opengl_initialized( false ),
99 m_is_opengl_version_supported( true ),
100 m_mouse_is_moving( false ),
101 m_mouse_was_moved( false ),
102 m_camera_is_moving( false ),
103 m_render_pivot( false ),
104 m_camera_moving_speed( 1.0f ),
105 m_strtime_camera_movement( 0 ),
106 m_animation_enabled( true ),
107 m_moving_speed_multiplier( 3 ),
108 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_currentIntersectedBoardItem(
nullptr )
116 wxLogTrace( m_logTrace,
"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();
131 wxASSERT( m_3d_render_raytracing !=
nullptr );
132 wxASSERT( m_3d_render_ogl_legacy !=
nullptr );
134 auto busy_indicator_factory = []() {
return std::make_unique<WX_BUSY_INDICATOR>(); };
136 m_3d_render_raytracing->SetBusyIndicatorFactory( busy_indicator_factory );
137 m_3d_render_ogl_legacy->SetBusyIndicatorFactory( busy_indicator_factory );
139 RenderEngineChanged();
141 wxASSERT( aBoard !=
nullptr );
142 m_boardAdapter.SetBoard( aBoard );
146 wxASSERT( a3DCachePointer !=
nullptr );
147 m_boardAdapter.Set3dCacheManager( a3DCachePointer );
149 const wxEventType events[] =
155 wxEVT_LEFT_UP, wxEVT_LEFT_DOWN, wxEVT_LEFT_DCLICK,
156 wxEVT_RIGHT_UP, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_DCLICK,
157 wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_DCLICK,
158 wxEVT_MOTION, wxEVT_MOUSEWHEEL, wxEVT_CHAR, wxEVT_CHAR_HOOK,
159 #if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT ) 162 wxEVT_MENU_OPEN, wxEVT_MENU_CLOSE, wxEVT_MENU_HIGHLIGHT
165 for( wxEventType eventType : events )
172 wxLogTrace(
m_logTrace,
"EDA_3D_CANVAS::~EDA_3D_CANVAS" );
219 wxLogTrace(
m_logTrace,
"EDA_3D_CANVAS::initializeOpenGL" );
221 const GLenum err = glewInit();
225 const wxString msgError = (
const char*) glewGetErrorString( err );
227 wxLogMessage( msgError );
233 wxLogTrace(
m_logTrace,
"EDA_3D_CANVAS::initializeOpenGL Using GLEW version %s",
234 FROM_UTF8( (
char*) glewGetString( GLEW_VERSION ) ) );
237 wxString version =
FROM_UTF8( (
char *) glGetString( GL_VERSION ) );
239 wxLogTrace(
m_logTrace,
"EDA_3D_CANVAS::%s OpenGL version string %s.",
240 __WXFUNCTION__, version );
246 wxStringTokenizer tokenizer( version );
248 if( tokenizer.HasMoreTokens() )
253 tmp = tokenizer.GetNextToken();
255 tokenizer.SetString( tmp, wxString(
"." ) );
257 if( tokenizer.HasMoreTokens() )
258 tokenizer.GetNextToken().ToLong( &major );
260 if( tokenizer.HasMoreTokens() )
261 tokenizer.GetNextToken().ToLong( &minor );
263 if( major < 2 || ( ( major == 2 ) && ( minor < 1 ) ) )
265 wxLogTrace(
m_logTrace,
"EDA_3D_CANVAS::%s OpenGL ray tracing not supported.",
271 GetParent()->ProcessWindowEvent( evt );
277 if( ( major == 1 ) && ( minor < 5 ) )
279 wxLogTrace(
m_logTrace,
"EDA_3D_CANVAS::%s OpenGL not supported.", __WXFUNCTION__ );
300 if( aCachePointer !=
nullptr )
303 if( aBoard !=
nullptr )
354 if( !IsShownOnScreen() )
356 wxLogTrace(
m_logTrace,
"EDA_3D_CANVAS::DoRePaint !IsShown" );
367 if( !GetParent()->GetParent()->IsShown() )
370 wxString err_messages;
412 warningReporter.
Report(
_(
"Your OpenGL version is not supported. Minimum required " 421 glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
422 glClear( GL_COLOR_BUFFER_BIT );
448 || windows_size_changed )
456 float curtime_delta_s = 0.0f;
464 if( curtime_delta_s > 1.0f )
480 bool requested_redraw =
false;
488 bool reloadRaytracingForIntersectionCalculations =
false;
493 reloadRaytracingForIntersectionCalculations =
true;
497 &activityReporter, &warningReporter );
499 if( reloadRaytracingForIntersectionCalculations )
502 catch( std::runtime_error& )
534 calculation_time ) );
543 if( !err_messages.IsEmpty() )
544 wxLogMessage( err_messages );
562 m_parent->Connect( wxEVT_TOOL,
569 while( m_parent->Disconnect( wxEVT_TOOL,
589 wxLogTrace(
m_logTrace,
"EDA_3D_CANVAS::OnEraseBackground" );
596 bool mouseActivity =
false;
598 wxLogTrace(
m_logTrace,
"EDA_3D_CANVAS::OnMouseWheel" );
606 delta_move *= 0.01f * event.GetWheelRotation();
608 if( event.GetWheelRotation() < 0 )
609 delta_move = -delta_move;
622 if( event.GetWheelAxis() == wxMOUSE_WHEEL_HORIZONTAL ||
event.ShiftDown() )
627 mouseActivity =
true;
632 mouseActivity =
true;
637 mouseActivity =
true;
641 mouseActivity =
m_camera.
Zoom( event.GetWheelRotation() > 0 ? 1.1f : 1/1.1f );
661 #if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT ) 662 void EDA_3D_CANVAS::OnMagnify( wxMouseEvent& event )
672 float magnification = (
event.GetMagnification() + 1.0f );
691 if( event.Dragging() )
693 if( event.LeftIsDown() )
695 else if( event.MiddleIsDown() )
706 const wxPoint eventPosition =
event.GetPosition();
709 if( !event.Dragging() &&
719 if( intersectedBoardItem )
729 switch( intersectedBoardItem->
Type() )
733 PAD* pad = dynamic_cast<PAD*>( intersectedBoardItem );
747 FOOTPRINT* footprint = dynamic_cast<FOOTPRINT *>( intersectedBoardItem );
758 TRACK* track = dynamic_cast<TRACK *>( intersectedBoardItem );
771 ZONE* zone = dynamic_cast<ZONE*>( intersectedBoardItem );
894 if( aRedrawImmediately )
901 wxPostEvent(
this, redrawEvent );
913 wxASSERT( aMovingSpeed > FLT_EPSILON );
967 const float arrow_moving_time_speed = 8.0f;
968 bool handled =
false;
1150 mouseRay.
Init( rayOrigin, rayDir );
A wrapper for reporting to a specific text location in a statusbar.
virtual wxSize GetNativePixelSize() const
void SetLookAtPos_T1(const SFVEC3F &aLookAtPos)
virtual void Pan(const wxPoint &aNewMousePosition)=0
bool GetFlag(DISPLAY3D_FLG aFlag) const
Get a configuration status of a flag.
void RotateZ_T1(float aAngleInRadians)
bool IsReloadRequestPending() const
Query if there is a pending reload request.
void OnMouseMove(wxMouseEvent &event)
bool Zoom_T1(float aFactor)
void OnResize(wxSizeEvent &event)
void request_start_moving_camera(float aMovingSpeed=2.0f, bool aRenderPivot=true)
Start a camera movement.
void releaseOpenGL()
Free created targets and openGL context.
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
virtual void Pan_T1(const SFVEC3F &aDeltaOffsetInc)=0
void OnRefreshRequest(wxEvent &aEvent)
unsigned m_strtime_camera_movement
wxDEFINE_EVENT(wxEVT_REFRESH_CUSTOM_COMMAND, wxEvent)
WX_INFOBAR * m_parentInfoBar
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
RAY getRayAtCurrrentMousePosition()
wxString GetNetClassName() const
void stop_editingTimeOut_Timer()
Stop the editing time so it will not timeout.
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
void Init(const SFVEC3F &o, const SFVEC3F &d)
bool Intersect(const RAY &aRay, float *t) const
wxStatusBar * m_parentStatusBar
virtual void SetCurWindowSize(const wxSize &aSize)=0
Before each render, the canvas will tell the render what is the size of its windows,...
void RotateY_T1(float aAngleInRadians)
void OnCloseWindow(wxCloseEvent &event)
wxGLCanvas wrapper for HiDPI/Retina support.
class ARC, an arc track segment on a copper layer
Implement a canvas based on a wxGLCanvas.
wxTimer m_editing_timeout_timer
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.
BOARD_ITEM * m_currentIntersectedBoardItem
class PAD, a pad in a footprint
void DisplayStatus()
Update the status bar with the position information.
Cache for storing the 3D shapes.
void Request_refresh(bool aRedrawImmediately=true)
Schedule a refresh update of the canvas.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
void UnlockCtx(wxGLContext *aContext)
Allow other canvases to bind an OpenGL context.
virtual void Drag(const wxPoint &aNewMousePosition)=0
Calculate a new mouse drag position.
SFVEC3F at(float t) const
void DoRePaint()
The actual function to repaint the canvas.
class TRACK, a track segment (segment on a copper layer)
void SetBoard(BOARD *aBoard) noexcept
Set current board to be rendered.
BOARD_ADAPTER & m_boardAdapter
void OnLeftDown(wxMouseEvent &event)
float m_camera_moving_speed
RENDER_ENGINE GetRenderEngine() const noexcept
bool m_is_opengl_version_supported
A class used to derive camera objects from.
static GL_CONTEXT_MANAGER & Get()
Return the GL_CONTEXT_MANAGER instance (singleton).
void OnLeftUp(wxMouseEvent &event)
virtual int GetWaitForEditingTimeOut()=0
Give the interface the time (in ms) that it should wait for editing or movements before (this works f...
void restart_editingTimeOut_Timer()
Reset the editing timer.
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.
RENDER_3D_LEGACY * m_3d_render_ogl_legacy
void Set3dCacheManager(S3D_CACHE *aCachePointer) noexcept
Update the cache manager pointer.
void OnMiddleDown(wxMouseEvent &event)
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
void OnPaint(wxPaintEvent &aEvent)
Called by a wxPaintEvent event.
void OnEraseBackground(wxEraseEvent &event)
void OnMouseWheel(wxMouseEvent &event)
void RenderEngineChanged()
Notify that the render engine was changed.
RENDER_3D_RAYTRACE * m_3d_render_raytracing
Object to render the board using openGL legacy mode.
void SetCurrentIntersectedBoardItem(BOARD_ITEM *aCurrentIntersectedBoardItem)
const wxString & GetName() const
void SetCurMousePosition(const wxPoint &aPosition)
Update the current mouse position without make any new calculations on camera.
RENDER_3D_BASE * m_3d_render
EVT_MIDDLE_DOWN(mpWindow::OnMouseMiddleDown) EVT_MOUSEWHEEL(mpWindow
const wxString & GetNetname() const
virtual bool Redraw(bool aIsMoving, REPORTER *aStatusReporter=nullptr, REPORTER *aWarningReporter=nullptr)=0
Redraw the view.
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
void Reload(REPORTER *aStatusReporter, REPORTER *aWarningReporter, bool aOnlyLoadCopperAndShapes)
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
ZONE handles a list of polygons defining a copper zone.
class ZONE, a copper pour area
void Finalize()
Update the infobar with the reported text.
wxGLContext * CreateCtx(wxGLCanvas *aCanvas, const wxGLContext *aOther=nullptr)
Create a managed OpenGL context.
void MakeRayAtCurrrentMousePosition(SFVEC3F &aOutOrigin, SFVEC3F &aOutDirection) const
Make a ray based on the latest mouse position.
bool IsOnCopperLayer() const override
void OnTimerTimeout_Redraw(wxTimerEvent &event)
SETTINGS_MANAGER * GetSettingsManager()
void SetRenderEngine(RENDER_ENGINE aRenderEngine) noexcept
void LockCtx(wxGLContext *aContext, wxGLCanvas *aCanvas)
Set a context as current and prevents other canvases from switching it.
class FOOTPRINT, a footprint
BOARD_ITEM * IntersectBoardItem(const RAY &aRay)
bool m_is_opengl_initialized
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
void SetInterpolateMode(CAMERA_INTERPOLATION aInterpolateMode)
void OnMiddleUp(wxMouseEvent &event)
bool SetCurWindowSize(const wxSize &aSize)
Update the windows size of the camera.
const BBOX_3D & GetBBox() const noexcept
Get the board outling bounding box.
TOOL_DISPATCHER * m_eventDispatcher
void GetScreenshot(wxImage &aDstImage)
Request a screenshot and output it to the aDstImage.
int m_moving_speed_multiplier
virtual void SetT0_and_T1_current_T()
This will set T0 and T1 with the current values.
void OnEvent(wxEvent &aEvent)
Used to forward events to the canvas from popups, etc.
bool m_opengl_supports_raytracing
Declaration of the eda_3d_viewer class.
ACCELERATOR_3D * m_accelerator3DShapes
void move_pivot_based_on_cur_mouse_position()
This function hits a ray to the board and start a movement.
std::atomic_flag m_is_currently_painting
virtual void Interpolate(float t)
It will update the matrix to interpolate between T0 and T1 values.
Information pertinent to a Pcbnew printed circuit board.
unsigned GetRunningMicroSecs()
An alternate way to calculate an elapset time (in microsecondes) to class PROF_COUNTER.
bool SetView3D(int aKeycode)
Helper function to call view commands.
bool IsOnCopperLayer() const override
Function IsOnCopperLayer.
const SFVEC3F & GetCameraPos() const
void OnTimerTimeout_Editing(wxTimerEvent &event)
void ReloadRequest(BOARD *aBoard=nullptr, S3D_CACHE *aCachePointer=nullptr)
class VIA, a via (like a track segment on a copper layer)
void DestroyCtx(wxGLContext *aContext)
Destroy a managed OpenGL context.
void SetColorSettings(COLOR_SETTINGS *aSettings) noexcept
static int SetSwapInterval(int aVal)
Attempts to set the OpenGL swap interval.
void OglGetScreenshot(wxImage &aDstImage)
Get the pixel data of current OpenGL image.
wxTimer m_redraw_trigger_timer
Helper class to handle information needed to display 3D board.
static const float m_delta_move_step_factor
void render_pivot(float t, float aScale)
Render the pivot cursor.
A wrapper for reporting to a WX_INFOBAR UI element.
KICAD_T Type() const
Returns the type of object.
void RotateX_T1(float aAngleInRadians)
bool HasMessage() const override
Returns true if the reporter client is non-empty.
bool m_render_raytracing_was_requested