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