22
33
44from PyQt5 .QtWidgets import QWidget , QApplication
5- from PyQt5 .QtCore import pyqtSlot , pyqtSignal , Qt , QEvent
5+ from PyQt5 .QtCore import pyqtSlot , pyqtSignal , Qt , QPoint
66
77import OCP
88
99from OCP .Aspect import Aspect_DisplayConnection , Aspect_TypeOfTriedronPosition
1010from OCP .OpenGl import OpenGl_GraphicDriver
1111from OCP .V3d import V3d_Viewer
12+ from OCP .gp import gp_Trsf , gp_Ax1 , gp_Dir
1213from OCP .AIS import AIS_InteractiveContext , AIS_DisplayMode
1314from OCP .Quantity import Quantity_Color
1415
@@ -30,6 +31,15 @@ def __init__(self, parent=None):
3031
3132 self ._initialized = False
3233 self ._needs_update = False
34+ self ._previous_pos = QPoint (
35+ 0 , 0 # Keeps track of where the previous mouse position
36+ )
37+ self ._rotate_step = (
38+ 0.008 # Controls the speed of rotation with the turntable orbit method
39+ )
40+
41+ # Orbit method settings
42+ self ._orbit_method = "Turntable"
3343
3444 # OCCT secific things
3545 self .display_connection = Aspect_DisplayConnection ()
@@ -64,6 +74,20 @@ def prepare_display(self):
6474 ctx .SetDisplayMode (AIS_DisplayMode .AIS_Shaded , True )
6575 ctx .DefaultDrawer ().SetFaceBoundaryDraw (True )
6676
77+ def set_orbit_method (self , method ):
78+ """
79+ Set the orbit method for the OCCT view.
80+ """
81+
82+ # Keep track of which orbit method is used
83+ if method == "Turntable" :
84+ self ._orbit_method = "Turntable"
85+ self .view .SetUp (0 , 0 , 1 )
86+ elif method == "Trackball" :
87+ self ._orbit_method = "Trackball"
88+ else :
89+ raise ValueError (f"Unknown orbit method: { method } " )
90+
6791 def wheelEvent (self , event ):
6892
6993 delta = event .angleDelta ().y ()
@@ -80,31 +104,51 @@ def mousePressEvent(self, event):
80104 self .pending_select = True
81105 self .left_press = pos
82106
83- self .view .StartRotation (pos .x (), pos .y ())
107+ # We only start the rotation if the orbit method is set to Trackball
108+ if self ._orbit_method == "Trackball" :
109+ self .view .StartRotation (pos .x (), pos .y ())
84110 elif event .button () == Qt .RightButton :
85111 self .view .StartZoomAtPoint (pos .x (), pos .y ())
86112
87- self .old_pos = pos
113+ self ._previous_pos = pos
88114
89115 def mouseMoveEvent (self , event ):
90116
91117 pos = event .pos ()
92118 x , y = pos .x (), pos .y ()
93119
120+ # Check for mouse drag rotation
94121 if event .buttons () == Qt .LeftButton :
95- self .view .Rotation (x , y )
122+ # Set the rotation differently based on the orbit method
123+ if self ._orbit_method == "Trackball" :
124+ self .view .Rotation (x , y )
125+ elif self ._orbit_method == "Turntable" :
126+ # Control the turntable rotation manually
127+ delta_x , delta_y = (
128+ x - self ._previous_pos .x (),
129+ y - self ._previous_pos .y (),
130+ )
131+ cam = self .view .Camera ()
132+ z_rotation = gp_Trsf ()
133+ z_rotation .SetRotation (
134+ gp_Ax1 (cam .Center (), gp_Dir (0 , 0 , 1 )), - delta_x * self ._rotate_step
135+ )
136+ cam .Transform (z_rotation )
137+ self .view .Rotate (0 , - delta_y * self ._rotate_step , 0 )
96138
97139 # If the user moves the mouse at all, the selection will not happen
98140 if abs (x - self .left_press .x ()) > 2 or abs (y - self .left_press .y ()) > 2 :
99141 self .pending_select = False
100142
101143 elif event .buttons () == Qt .MiddleButton :
102- self .view .Pan (x - self .old_pos .x (), self .old_pos .y () - y , theToStart = True )
144+ self .view .Pan (
145+ x - self ._previous_pos .x (), self ._previous_pos .y () - y , theToStart = True
146+ )
103147
104148 elif event .buttons () == Qt .RightButton :
105- self .view .ZoomAtPoint (self .old_pos .x (), y , x , self .old_pos .y ())
149+ self .view .ZoomAtPoint (self ._previous_pos .x (), y , x , self ._previous_pos .y ())
106150
107- self .old_pos = pos
151+ self ._previous_pos = pos
108152
109153 def mouseReleaseEvent (self , event ):
110154
0 commit comments