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.

348 lines
11 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 The 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_3D_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_GL;
  38. class RENDER_3D_OPENGL;
  39. #define EDA_3D_CANVAS_ID wxID_HIGHEST + 1321
  40. /**
  41. * Implement a canvas based on a wxGLCanvas
  42. */
  43. class EDA_3D_CANVAS : public HIDPI_GL_3D_CANVAS
  44. {
  45. public:
  46. /**
  47. * Create a new 3D Canvas with an attribute list.
  48. *
  49. * @param aParent the parent creator of this canvas.
  50. * @param aGLAttribs openGL attributes created by #OGL_ATT_LIST::GetAttributesList.
  51. * @param aBoard The board.
  52. * @param aSettings the settings options to be used by this canvas.
  53. */
  54. EDA_3D_CANVAS( wxWindow* aParent, const wxGLAttributes& aGLAttribs, BOARD_ADAPTER& aSettings,
  55. CAMERA& aCamera, S3D_CACHE* a3DCachePointer );
  56. ~EDA_3D_CANVAS();
  57. /**
  58. * Set a dispatcher that processes events and forwards them to tools.
  59. *
  60. * #DRAW_PANEL_GAL does not take over the ownership. Passing NULL disconnects all event
  61. * handlers from the DRAW_PANEL_GAL and parent frame.
  62. *
  63. * @param aEventDispatcher is the object that will be used for dispatching events.
  64. */
  65. void SetEventDispatcher( TOOL_DISPATCHER* aEventDispatcher );
  66. void SetStatusBar( wxStatusBar* aStatusBar )
  67. {
  68. m_parentStatusBar = aStatusBar;
  69. }
  70. void SetInfoBar( WX_INFOBAR* aInfoBar )
  71. {
  72. m_parentInfoBar = aInfoBar;
  73. }
  74. void ReloadRequest( BOARD* aBoard = nullptr, S3D_CACHE* aCachePointer = nullptr );
  75. /**
  76. * Query if there is a pending reload request.
  77. *
  78. * @return true if it wants to reload, false if there is no reload pending.
  79. */
  80. bool IsReloadRequestPending() const
  81. {
  82. if( m_3d_render )
  83. return m_3d_render->IsReloadRequestPending();
  84. else
  85. return false;
  86. }
  87. /**
  88. * @return the current render ( a RENDER_3D_RAYTRACE_GL* or a RENDER_3D_OPENGL* render )
  89. */
  90. RENDER_3D_BASE* GetCurrentRender() const { return m_3d_render; }
  91. /**
  92. * Request to render the current view in Raytracing mode.
  93. */
  94. void RenderRaytracingRequest();
  95. /**
  96. * Request a screenshot and output it to the \a aDstImage.
  97. *
  98. * @param aDstImage - Screenshot destination image.
  99. */
  100. void GetScreenshot( wxImage& aDstImage );
  101. /**
  102. * Select a specific 3D view or operation.
  103. *
  104. * @param aRequestedView the view to move to.
  105. * @return true if the view request was handled, false if no command found for this view.
  106. */
  107. bool SetView3D( VIEW3D_TYPE aRequestedView );
  108. /**
  109. * Enable or disable camera animation when switching to a pre-defined view.
  110. */
  111. void SetAnimationEnabled( bool aEnable ) { m_animation_enabled = aEnable; }
  112. bool GetAnimationEnabled() const { return m_animation_enabled; }
  113. /**
  114. * Set the camera animation moving speed multiplier option.
  115. *
  116. * @param aMultiplier one of the possible integer options: [1,2,3,4,5].
  117. */
  118. void SetMovingSpeedMultiplier( int aMultiplier ) { m_moving_speed_multiplier = aMultiplier; }
  119. int GetMovingSpeedMultiplier() const { return m_moving_speed_multiplier; }
  120. int GetProjectionMode() const { return (int) m_camera.GetProjection(); };
  121. void SetProjectionMode( int aMode ) { m_camera.SetProjection( (PROJECTION_TYPE) aMode ); }
  122. /**
  123. * Notify that the render engine was changed.
  124. */
  125. void RenderEngineChanged();
  126. /**
  127. * Update the status bar with the position information.
  128. */
  129. void DisplayStatus();
  130. /**
  131. * Schedule a refresh update of the canvas.
  132. *
  133. * @param aRedrawImmediately true will request a redraw, false will schedule a redraw
  134. * after a short timeout.
  135. */
  136. void Request_refresh( bool aRedrawImmediately = true );
  137. /**
  138. * Used to forward events to the canvas from popups, etc.
  139. */
  140. void OnEvent( wxEvent& aEvent );
  141. /**
  142. * Get information used to display 3D board.
  143. */
  144. const BOARD_ADAPTER& GetBoardAdapter() const { return m_boardAdapter; }
  145. /**
  146. * Get a value indicating whether to render the pivot.
  147. */
  148. bool GetRenderPivot() { return m_render_pivot; }
  149. /**
  150. * Set aValue indicating whether to render the pivot.
  151. *
  152. * @param aValue true will cause the pivot to be rendered on the next redraw.
  153. */
  154. void SetRenderPivot( bool aValue ) { m_render_pivot = aValue; }
  155. /**
  156. * Get a value indicating whether to render the 3dmouse pivot.
  157. */
  158. bool GetRender3dmousePivot()
  159. {
  160. return m_render3dmousePivot;
  161. }
  162. /**
  163. * Set aValue indicating whether to render the 3dmouse pivot.
  164. *
  165. * @param aValue true will cause the pivot to be rendered on the next redraw.
  166. */
  167. void SetRender3dmousePivot( bool aValue )
  168. {
  169. m_render3dmousePivot = aValue;
  170. }
  171. /**
  172. * Set the position of the the 3dmouse pivot.
  173. *
  174. * @param aPos is the position of the 3dmouse rotation pivot
  175. */
  176. void Set3dmousePivotPos( const SFVEC3F& aPos )
  177. {
  178. m_3dmousePivotPos = aPos;
  179. }
  180. /**
  181. * The actual function to repaint the canvas.
  182. *
  183. * It is usually called by OnPaint() but because it does not use a wxPaintDC it can be
  184. * called outside a wxPaintEvent
  185. */
  186. void DoRePaint();
  187. void OnCloseWindow( wxCloseEvent& event );
  188. private:
  189. // The wxPaintEvent event. mainly calls DoRePaint()
  190. void OnPaint( wxPaintEvent& aEvent );
  191. void OnEraseBackground( wxEraseEvent& event );
  192. void OnRefreshRequest( wxEvent& aEvent );
  193. void OnMouseWheel( wxMouseEvent& event );
  194. void OnMagnify( wxMouseEvent& event );
  195. void OnMouseMove( wxMouseEvent& event );
  196. void OnLeftDown( wxMouseEvent& event );
  197. void OnLeftUp( wxMouseEvent& event );
  198. void OnMiddleUp( wxMouseEvent& event );
  199. void OnMiddleDown( wxMouseEvent& event );
  200. void OnTimerTimeout_Editing( wxTimerEvent& event );
  201. void OnResize( wxSizeEvent& event );
  202. void OnTimerTimeout_Redraw( wxTimerEvent& event );
  203. void OnZoomGesture( wxZoomGestureEvent& event );
  204. void OnPanGesture( wxPanGestureEvent& event );
  205. void OnRotateGesture( wxRotateGestureEvent& event );
  206. DECLARE_EVENT_TABLE()
  207. /**
  208. *Stop the editing time so it will not timeout.
  209. */
  210. void stop_editingTimeOut_Timer();
  211. /**
  212. * Reset the editing timer.
  213. */
  214. void restart_editingTimeOut_Timer();
  215. /**
  216. * Start a camera movement.
  217. *
  218. * @param aMovingSpeed the time speed.
  219. * @param aRenderPivot if it should display pivot cursor while move.
  220. */
  221. void request_start_moving_camera( float aMovingSpeed = 2.0f, bool aRenderPivot = true );
  222. /**
  223. * This function hits a ray to the board and start a movement.
  224. */
  225. void move_pivot_based_on_cur_mouse_position();
  226. /**
  227. * Render the pivot cursor.
  228. *
  229. * @param t time between 0.0 and 1.0.
  230. * @param aScale scale to apply on the cursor.
  231. */
  232. void render_pivot( float t, float aScale );
  233. /**
  234. * Render the 3dmouse pivot cursor.
  235. *
  236. * @param aScale scale to apply on the cursor.
  237. */
  238. void render3dmousePivot( float aScale );
  239. /**
  240. * @return true if OpenGL initialization succeeded.
  241. */
  242. bool initializeOpenGL();
  243. /**
  244. * Free created targets and openGL context.
  245. */
  246. void releaseOpenGL();
  247. RAY getRayAtCurrentMousePosition();
  248. private:
  249. TOOL_DISPATCHER* m_eventDispatcher;
  250. wxStatusBar* m_parentStatusBar; // Parent statusbar to report progress
  251. WX_INFOBAR* m_parentInfoBar;
  252. wxGLContext* m_glRC; // Current OpenGL context
  253. bool m_is_opengl_initialized;
  254. bool m_is_opengl_version_supported;
  255. wxTimer m_editing_timeout_timer; // Expires after some time signaling that
  256. // the mouse / keyboard movements are over
  257. wxTimer m_redraw_trigger_timer; // Used to schedule a redraw event
  258. std::atomic_flag m_is_currently_painting; // Avoid drawing twice at the same time
  259. bool m_render_pivot; // Render the pivot while camera moving
  260. float m_camera_moving_speed; // 1.0f will be 1:1
  261. int64_t m_strtime_camera_movement; // Ticktime of camera movement start
  262. bool m_animation_enabled; // Camera animation enabled
  263. int m_moving_speed_multiplier; // Camera animation speed multiplier option
  264. BOARD_ADAPTER& m_boardAdapter; // Pre-computed 3D info and settings
  265. RENDER_3D_BASE* m_3d_render;
  266. RENDER_3D_RAYTRACE_GL* m_3d_render_raytracing;
  267. RENDER_3D_OPENGL* m_3d_render_opengl;
  268. bool m_opengl_supports_raytracing;
  269. bool m_render_raytracing_was_requested;
  270. ACCELERATOR_3D* m_accelerator3DShapes; // used for mouse over searching
  271. BOARD_ITEM* m_currentRollOverItem;
  272. bool m_render3dmousePivot = false; // Render the 3dmouse pivot
  273. SFVEC3F m_3dmousePivotPos; // The position of the 3dmouse pivot
  274. /// Used to track gesture events.
  275. double m_gestureLastZoomFactor = 1.0;
  276. double m_gestureLastAngle = 0.0;
  277. /**
  278. * Trace mask used to enable or disable the trace output of this class.
  279. * The debug output can be turned on by setting the WXTRACE environment variable to
  280. * "KI_TRACE_EDA_3D_CANVAS". See the wxWidgets documentation on wxLogTrace for
  281. * more information.
  282. */
  283. static const wxChar* m_logTrace;
  284. };
  285. #endif // EDA_3D_CANVAS_H