2
2
3
3
4
4
from PyQt5 .QtWidgets import QWidget , QApplication
5
- from PyQt5 .QtCore import pyqtSlot , pyqtSignal , Qt , QEvent
5
+ from PyQt5 .QtCore import pyqtSlot , pyqtSignal , Qt , QPoint
6
6
7
7
import OCP
8
8
9
9
from OCP .Aspect import Aspect_DisplayConnection , Aspect_TypeOfTriedronPosition
10
10
from OCP .OpenGl import OpenGl_GraphicDriver
11
11
from OCP .V3d import V3d_Viewer
12
+ from OCP .gp import gp_Trsf , gp_Ax1 , gp_Dir
12
13
from OCP .AIS import AIS_InteractiveContext , AIS_DisplayMode
13
14
from OCP .Quantity import Quantity_Color
14
15
@@ -30,6 +31,15 @@ def __init__(self, parent=None):
30
31
31
32
self ._initialized = False
32
33
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"
33
43
34
44
# OCCT secific things
35
45
self .display_connection = Aspect_DisplayConnection ()
@@ -64,6 +74,20 @@ def prepare_display(self):
64
74
ctx .SetDisplayMode (AIS_DisplayMode .AIS_Shaded , True )
65
75
ctx .DefaultDrawer ().SetFaceBoundaryDraw (True )
66
76
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
+
67
91
def wheelEvent (self , event ):
68
92
69
93
delta = event .angleDelta ().y ()
@@ -80,31 +104,51 @@ def mousePressEvent(self, event):
80
104
self .pending_select = True
81
105
self .left_press = pos
82
106
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 ())
84
110
elif event .button () == Qt .RightButton :
85
111
self .view .StartZoomAtPoint (pos .x (), pos .y ())
86
112
87
- self .old_pos = pos
113
+ self ._previous_pos = pos
88
114
89
115
def mouseMoveEvent (self , event ):
90
116
91
117
pos = event .pos ()
92
118
x , y = pos .x (), pos .y ()
93
119
120
+ # Check for mouse drag rotation
94
121
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 )
96
138
97
139
# If the user moves the mouse at all, the selection will not happen
98
140
if abs (x - self .left_press .x ()) > 2 or abs (y - self .left_press .y ()) > 2 :
99
141
self .pending_select = False
100
142
101
143
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
+ )
103
147
104
148
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 ())
106
150
107
- self .old_pos = pos
151
+ self ._previous_pos = pos
108
152
109
153
def mouseReleaseEvent (self , event ):
110
154
0 commit comments