1+ import math
12from sys import platform
23
3-
4- from PyQt5 .QtWidgets import QWidget , QApplication
5- from PyQt5 .QtCore import pyqtSlot , pyqtSignal , Qt , QEvent
6-
7- import OCP
8-
4+ from OCP .AIS import AIS_InteractiveContext , AIS_DisplayMode
95from OCP .Aspect import Aspect_DisplayConnection , Aspect_TypeOfTriedronPosition
106from OCP .OpenGl import OpenGl_GraphicDriver
11- from OCP .V3d import V3d_Viewer
12- from OCP .AIS import AIS_InteractiveContext , AIS_DisplayMode
137from OCP .Quantity import Quantity_Color
8+ from OCP .V3d import V3d_Viewer
9+ from OCP .gp import gp_Trsf , gp_Ax1 , gp_Dir
10+ from PyQt5 .QtCore import pyqtSignal , Qt , QPoint
11+ from PyQt5 .QtWidgets import QWidget
1412
1513
16- ZOOM_STEP = 0.9
17-
18-
1914class OCCTWidget (QWidget ):
2015
2116 sigObjectSelected = pyqtSignal (list )
2217
23- def __init__ (self ,parent = None ):
18+ def __init__ (self , parent = None , * ,
19+ orbital_rotation : bool = True ,
20+ rotate_step : float = 0.008 ,
21+ zoom_step : float = 0.1 ):
2422
25- super (OCCTWidget ,self ).__init__ (parent )
23+ super (OCCTWidget , self ).__init__ (parent )
2624
2725 self .setAttribute (Qt .WA_NativeWindow )
2826 self .setAttribute (Qt .WA_PaintOnScreen )
2927 self .setAttribute (Qt .WA_NoSystemBackground )
3028
3129 self ._initialized = False
3230 self ._needs_update = False
31+ self ._old_pos = QPoint (0 , 0 )
32+ self ._rotate_step = rotate_step
33+ self ._zoom_step = zoom_step
34+ self ._orbital_rotation = orbital_rotation
3335
34- #OCCT secific things
36+ # OCCT secific things
3537 self .display_connection = Aspect_DisplayConnection ()
3638 self .graphics_driver = OpenGl_GraphicDriver (self .display_connection )
3739
3840 self .viewer = V3d_Viewer (self .graphics_driver )
3941 self .view = self .viewer .CreateView ()
4042 self .context = AIS_InteractiveContext (self .viewer )
4143
42- #Trihedorn, lights, etc
44+ # Trihedorn, lights, etc
4345 self .prepare_display ()
44-
46+
47+ def set_orbital_rotation (self , new_value : bool ):
48+ if self ._orbital_rotation != new_value :
49+ self ._orbital_rotation = new_value
50+ if self ._orbital_rotation :
51+ self .view .SetUp (0 , 0 , 1 )
52+
4553 def prepare_display (self ):
4654
4755 view = self .view
@@ -65,49 +73,58 @@ def prepare_display(self):
6573 ctx .DefaultDrawer ().SetFaceBoundaryDraw (True )
6674
6775 def wheelEvent (self , event ):
68-
69- delta = event .angleDelta ().y ()
70- factor = ZOOM_STEP if delta < 0 else 1 / ZOOM_STEP
71-
76+
77+ # dividing by 120 gets number of notches on a typical scroll wheel.
78+ # See QWheelEvent documentation
79+ delta_notches = event .angleDelta ().y () / 120
80+ direction = math .copysign (1 , delta_notches )
81+ factor = (1 + self ._zoom_step * direction ) ** abs (delta_notches )
82+
7283 self .view .SetZoom (factor )
7384
74- def mousePressEvent (self ,event ):
85+ def mousePressEvent (self , event ):
7586
7687 pos = event .pos ()
77-
88+
7889 if event .button () == Qt .LeftButton :
79- self .view .StartRotation (pos .x (), pos .y ())
90+ if not self ._orbital_rotation :
91+ self .view .StartRotation (pos .x (), pos .y ())
8092 elif event .button () == Qt .RightButton :
8193 self .view .StartZoomAtPoint (pos .x (), pos .y ())
8294
83- self .old_pos = pos
84-
85- def mouseMoveEvent (self ,event ):
95+ self ._old_pos = pos
96+
97+ def mouseMoveEvent (self , event ):
8698
8799 pos = event .pos ()
88- x ,y = pos .x (),pos .y ()
89-
100+ x , y = pos .x (), pos .y ()
101+
90102 if event .buttons () == Qt .LeftButton :
91- self .view .Rotation (x ,y )
92-
103+ if self ._orbital_rotation :
104+ delta_x , delta_y = x - self ._old_pos .x (), y - self ._old_pos .y ()
105+ cam = self .view .Camera ()
106+ z_rotation = gp_Trsf ()
107+ z_rotation .SetRotation (gp_Ax1 (cam .Center (), gp_Dir (0 , 0 , 1 )), - delta_x * self ._rotate_step )
108+ cam .Transform (z_rotation )
109+ self .view .Rotate (0 , - delta_y * self ._rotate_step , 0 )
110+ else :
111+ self .view .Rotation (x , y )
112+
93113 elif event .buttons () == Qt .MiddleButton :
94- self .view . Pan ( x - self .old_pos . x (),
95- self .old_pos . y () - y , theToStart = True )
114+ delta_x , delta_y = x - self ._old_pos . x (), y - self ._old_pos . y ()
115+ self .view . Pan ( delta_x , - delta_y , theToStart = True )
96116
97117 elif event .buttons () == Qt .RightButton :
98- self .view .ZoomAtPoint (self .old_pos .x (), y ,
99- x , self .old_pos .y ())
118+ self .view .ZoomAtPoint (self ._old_pos .x (), y ,
119+ x , self ._old_pos .y ())
100120
101- self .old_pos = pos
121+ self ._old_pos = pos
102122
103- def mouseReleaseEvent (self ,event ):
123+ def mouseReleaseEvent (self , event ):
104124
105125 if event .button () == Qt .LeftButton :
106126 pos = event .pos ()
107- x ,y = pos .x (),pos .y ()
108-
109- self .context .MoveTo (x ,y ,self .view ,True )
110-
127+ self .context .MoveTo (pos .x (), pos .y (), self .view , True )
111128 self ._handle_selection ()
112129
113130 def _handle_selection (self ):
0 commit comments