You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

292 lines
9.6 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
  5. * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #ifndef EDA_3D_CANVAS_H
  25. #define EDA_3D_CANVAS_H
  26. #include <atomic>
  27. #include "board_adapter.h"
  28. #include "3d_rendering/raytracing/accelerators/accelerator_3d.h"
  29. #include "3d_rendering/render_3d_base.h"
  30. #include "3d_cache/3d_cache.h"
  31. #include <gal/hidpi_gl_canvas.h>
  32. #include <wx/image.h>
  33. #include <wx/timer.h>
  34. class WX_INFOBAR;
  35. class wxStatusBar;
  36. class BOARD;
  37. class RENDER_3D_RAYTRACE;
  38. class RENDER_3D_OPENGL;
  39. /**
  40. * Implement a canvas based on a wxGLCanvas
  41. */
  42. class EDA_3D_CANVAS : public HIDPI_GL_CANVAS
  43. {
  44. public:
  45. /**
  46. * Create a new 3D Canvas with an attribute list.
  47. *
  48. * @param aParent the parent creator of this canvas.
  49. * @param aAttribList a list of openGL options created by GetOpenGL_AttributesList.
  50. * @param aBoard The board.
  51. * @param aSettings the settings options to be used by this canvas.
  52. */
  53. EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList,
  54. BOARD_ADAPTER& aSettings, CAMERA& aCamera, S3D_CACHE* a3DCachePointer );
  55. ~EDA_3D_CANVAS();
  56. /**
  57. * Set a dispatcher that processes events and forwards them to tools.
  58. *
  59. * #DRAW_PANEL_GAL does not take over the ownership. Passing NULL disconnects all event
  60. * handlers from the DRAW_PANEL_GAL and parent frame.
  61. *
  62. * @param aEventDispatcher is the object that will be used for dispatching events.
  63. */
  64. void SetEventDispatcher( TOOL_DISPATCHER* aEventDispatcher );
  65. void SetStatusBar( wxStatusBar* aStatusBar )
  66. {
  67. m_parentStatusBar = aStatusBar;
  68. }
  69. void SetInfoBar( WX_INFOBAR* aInfoBar )
  70. {
  71. m_parentInfoBar = aInfoBar;
  72. }
  73. void ReloadRequest( BOARD* aBoard = nullptr, S3D_CACHE* aCachePointer = nullptr );
  74. /**
  75. * Query if there is a pending reload request.
  76. *
  77. * @return true if it wants to reload, false if there is no reload pending.
  78. */
  79. bool IsReloadRequestPending() const
  80. {
  81. if( m_3d_render )
  82. return m_3d_render->IsReloadRequestPending();
  83. else
  84. return false;
  85. }
  86. /**
  87. * @return the current render ( a RENDER_3D_RAYTRACE* or a RENDER_3D_OPENGL* render )
  88. */
  89. RENDER_3D_BASE* GetCurrentRender() const { return m_3d_render; }
  90. /**
  91. * Request to render the current view in Raytracing mode.
  92. */
  93. void RenderRaytracingRequest();
  94. /**
  95. * Request a screenshot and output it to the \a aDstImage
  96. *
  97. * @param aDstImage - Screenshot destination image
  98. */
  99. void GetScreenshot( wxImage& aDstImage );
  100. /**
  101. * Helper function to call view commands.
  102. *
  103. * @param aKeycode ascii key commands.
  104. * @return true if the key code was handled, false if no command found for this code.
  105. */
  106. bool SetView3D( int aKeycode );
  107. /**
  108. * Enable or disable camera animation when switching to a pre-defined view.
  109. */
  110. void SetAnimationEnabled( bool aEnable ) { m_animation_enabled = aEnable; }
  111. bool GetAnimationEnabled() const { return m_animation_enabled; }
  112. /**
  113. * Set the camera animation moving speed multiplier option.
  114. *
  115. * @param aMultiplier one of the possible integer options: [1,2,3,4,5].
  116. */
  117. void SetMovingSpeedMultiplier( int aMultiplier ) { m_moving_speed_multiplier = aMultiplier; }
  118. int GetMovingSpeedMultiplier() const { return m_moving_speed_multiplier; }
  119. int GetProjectionMode() const { return (int) m_camera.GetProjection(); };
  120. void SetProjectionMode( int aMode ) { m_camera.SetProjection( (PROJECTION_TYPE) aMode ); }
  121. /**
  122. * Notify that the render engine was changed.
  123. */
  124. void RenderEngineChanged();
  125. /**
  126. * Update the status bar with the position information.
  127. */
  128. void DisplayStatus();
  129. /**
  130. * Schedule a refresh update of the canvas.
  131. *
  132. * @param aRedrawImmediately true will request a redraw, false will schedule a redraw
  133. * after a short timeout.
  134. */
  135. void Request_refresh( bool aRedrawImmediately = true );
  136. /**
  137. * Used to forward events to the canvas from popups, etc.
  138. */
  139. void OnEvent( wxEvent& aEvent );
  140. private:
  141. /**
  142. * Called by a wxPaintEvent event
  143. */
  144. void OnPaint( wxPaintEvent& aEvent );
  145. /**
  146. * The actual function to repaint the canvas.
  147. *
  148. * It is usually called by OnPaint() but because it does not use a wxPaintDC it can be
  149. * called outside a wxPaintEvent
  150. */
  151. void DoRePaint();
  152. void OnEraseBackground( wxEraseEvent& event );
  153. void OnRefreshRequest( wxEvent& aEvent );
  154. void OnMouseWheel( wxMouseEvent& event );
  155. #if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
  156. void OnMagnify( wxMouseEvent& event );
  157. #endif
  158. void OnMouseMove( wxMouseEvent& event );
  159. void OnLeftDown( wxMouseEvent& event );
  160. void OnLeftUp( wxMouseEvent& event );
  161. void OnMiddleUp( wxMouseEvent& event );
  162. void OnMiddleDown( wxMouseEvent& event );
  163. void OnTimerTimeout_Editing( wxTimerEvent& event );
  164. void OnCloseWindow( wxCloseEvent& event );
  165. void OnResize( wxSizeEvent& event );
  166. void OnTimerTimeout_Redraw( wxTimerEvent& event );
  167. DECLARE_EVENT_TABLE()
  168. /**
  169. *Stop the editing time so it will not timeout.
  170. */
  171. void stop_editingTimeOut_Timer();
  172. /**
  173. * Reset the editing timer.
  174. */
  175. void restart_editingTimeOut_Timer();
  176. /**
  177. * Start a camera movement.
  178. *
  179. * @param aMovingSpeed the time speed.
  180. * @param aRenderPivot if it should display pivot cursor while move.
  181. */
  182. void request_start_moving_camera( float aMovingSpeed = 2.0f, bool aRenderPivot = true );
  183. /**
  184. * This function hits a ray to the board and start a movement.
  185. */
  186. void move_pivot_based_on_cur_mouse_position();
  187. /**
  188. * Render the pivot cursor.
  189. *
  190. * @param t time between 0.0 and 1.0.
  191. * @param aScale scale to apply on the cursor.
  192. */
  193. void render_pivot( float t, float aScale );
  194. /**
  195. * @return true if OpenGL initialization succeeded.
  196. */
  197. bool initializeOpenGL();
  198. /**
  199. * Free created targets and openGL context.
  200. */
  201. void releaseOpenGL();
  202. RAY getRayAtCurrrentMousePosition();
  203. private:
  204. TOOL_DISPATCHER* m_eventDispatcher;
  205. wxStatusBar* m_parentStatusBar; // Parent statusbar to report progress
  206. WX_INFOBAR* m_parentInfoBar;
  207. wxGLContext* m_glRC; // Current OpenGL context
  208. bool m_is_opengl_initialized;
  209. bool m_is_opengl_version_supported;
  210. wxTimer m_editing_timeout_timer; // Expires after some time signaling that
  211. // the mouse / keyboard movements are over
  212. wxTimer m_redraw_trigger_timer; // Used to schedule a redraw event
  213. std::atomic_flag m_is_currently_painting; // Avoid drawing twice at the same time
  214. bool m_mouse_is_moving; // Mouse activity is in progress
  215. bool m_mouse_was_moved;
  216. bool m_camera_is_moving; // Camera animation is ongoing
  217. bool m_render_pivot; // Render the pivot while camera moving
  218. float m_camera_moving_speed; // 1.0f will be 1:1
  219. unsigned m_strtime_camera_movement; // Ticktime of camera movement start
  220. bool m_animation_enabled; // Camera animation enabled
  221. int m_moving_speed_multiplier; // Camera animation speed multiplier option
  222. BOARD_ADAPTER& m_boardAdapter; // Pre-computed 3D info and settings
  223. CAMERA& m_camera;
  224. RENDER_3D_BASE* m_3d_render;
  225. RENDER_3D_RAYTRACE* m_3d_render_raytracing;
  226. RENDER_3D_OPENGL* m_3d_render_opengl;
  227. static const float m_delta_move_step_factor; // Step factor to used with cursor on
  228. // relation to the current zoom
  229. bool m_opengl_supports_raytracing;
  230. bool m_render_raytracing_was_requested;
  231. ACCELERATOR_3D* m_accelerator3DShapes; // used for mouse over searching
  232. BOARD_ITEM* m_currentRollOverItem;
  233. /**
  234. * Trace mask used to enable or disable the trace output of this class.
  235. * The debug output can be turned on by setting the WXTRACE environment variable to
  236. * "KI_TRACE_EDA_3D_CANVAS". See the wxWidgets documentation on wxLogTrace for
  237. * more information.
  238. */
  239. static const wxChar* m_logTrace;
  240. };
  241. #endif // EDA_3D_CANVAS_H