q3dviewer 1.1.2__py3-none-any.whl → 1.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- q3dviewer/base_glwidget.py +59 -31
- q3dviewer/custom_items/image_item.py +2 -7
- {q3dviewer-1.1.2.dist-info → q3dviewer-1.1.3.dist-info}/METADATA +1 -2
- {q3dviewer-1.1.2.dist-info → q3dviewer-1.1.3.dist-info}/RECORD +8 -8
- {q3dviewer-1.1.2.dist-info → q3dviewer-1.1.3.dist-info}/LICENSE +0 -0
- {q3dviewer-1.1.2.dist-info → q3dviewer-1.1.3.dist-info}/WHEEL +0 -0
- {q3dviewer-1.1.2.dist-info → q3dviewer-1.1.3.dist-info}/entry_points.txt +0 -0
- {q3dviewer-1.1.2.dist-info → q3dviewer-1.1.3.dist-info}/top_level.txt +0 -0
q3dviewer/base_glwidget.py
CHANGED
|
@@ -25,7 +25,7 @@ class BaseGLWidget(QtOpenGLWidgets.QOpenGLWidget):
|
|
|
25
25
|
self.active_keys = set()
|
|
26
26
|
self.show_center = False
|
|
27
27
|
self.enable_show_center = True
|
|
28
|
-
self.
|
|
28
|
+
self.need_recalc_view = True
|
|
29
29
|
self.view_matrix = self.get_view_matrix()
|
|
30
30
|
self.projection_matrix = self.get_projection_matrix()
|
|
31
31
|
|
|
@@ -98,7 +98,7 @@ class BaseGLWidget(QtOpenGLWidgets.QOpenGLWidget):
|
|
|
98
98
|
|
|
99
99
|
def set_view_matrix(self, view_matrix):
|
|
100
100
|
self.view_matrix = view_matrix
|
|
101
|
-
self.
|
|
101
|
+
self.need_recalc_view = False
|
|
102
102
|
|
|
103
103
|
def mouseReleaseEvent(self, ev):
|
|
104
104
|
if hasattr(self, 'mousePos'):
|
|
@@ -106,13 +106,13 @@ class BaseGLWidget(QtOpenGLWidgets.QOpenGLWidget):
|
|
|
106
106
|
|
|
107
107
|
def set_dist(self, dist):
|
|
108
108
|
self.dist = dist
|
|
109
|
-
self.
|
|
109
|
+
self.need_recalc_view = True
|
|
110
110
|
|
|
111
111
|
def update_dist(self, delta):
|
|
112
112
|
self.dist += delta
|
|
113
113
|
if self.dist < 0.1:
|
|
114
114
|
self.dist = 0.1
|
|
115
|
-
self.
|
|
115
|
+
self.need_recalc_view = True
|
|
116
116
|
|
|
117
117
|
def wheelEvent(self, ev):
|
|
118
118
|
delta = ev.angleDelta().x()
|
|
@@ -121,6 +121,24 @@ class BaseGLWidget(QtOpenGLWidgets.QOpenGLWidget):
|
|
|
121
121
|
self.update_dist(-delta * self.dist * 0.001)
|
|
122
122
|
self.show_center = True
|
|
123
123
|
|
|
124
|
+
|
|
125
|
+
def rotate_keep_cam_pos(self, rx=0, ry=0, rz=0):
|
|
126
|
+
"""
|
|
127
|
+
Rotate the camera while keeping the current camera position.
|
|
128
|
+
This updates both the Euler angles and the center point.
|
|
129
|
+
"""
|
|
130
|
+
new_euler = self.euler + np.array([rx, ry, rz])
|
|
131
|
+
new_euler = (new_euler + np.pi) % (2 * np.pi) - np.pi
|
|
132
|
+
|
|
133
|
+
Rwc_old = euler_to_matrix(self.euler)
|
|
134
|
+
tco = np.array([0, 0, self.dist])
|
|
135
|
+
twc = self.center + Rwc_old @ tco
|
|
136
|
+
|
|
137
|
+
Rwc_new = euler_to_matrix(new_euler)
|
|
138
|
+
self.center = twc - Rwc_new @ tco
|
|
139
|
+
self.euler = new_euler
|
|
140
|
+
self.need_recalc_view = True
|
|
141
|
+
|
|
124
142
|
def mouseMoveEvent(self, ev):
|
|
125
143
|
lpos = ev.localPos()
|
|
126
144
|
if not hasattr(self, 'mousePos'):
|
|
@@ -131,24 +149,26 @@ class BaseGLWidget(QtOpenGLWidgets.QOpenGLWidget):
|
|
|
131
149
|
rot_speed = 0.2
|
|
132
150
|
dyaw = radians(-diff.x() * rot_speed)
|
|
133
151
|
droll = radians(-diff.y() * rot_speed)
|
|
134
|
-
|
|
152
|
+
if ev.modifiers() & QtCore.Qt.ShiftModifier:
|
|
153
|
+
self.rotate_keep_cam_pos(droll, 0, dyaw)
|
|
154
|
+
else:
|
|
155
|
+
self.rotate(droll, 0, dyaw)
|
|
135
156
|
elif ev.buttons() == QtCore.Qt.MouseButton.LeftButton:
|
|
136
157
|
Rwc = euler_to_matrix(self.euler)
|
|
137
158
|
Kinv = np.linalg.inv(self.get_K())
|
|
138
159
|
dist = max(self.dist, 0.5)
|
|
139
|
-
self.
|
|
160
|
+
self.translate(Rwc @ Kinv @ np.array([-diff.x(), diff.y(), 0]) * dist)
|
|
140
161
|
self.show_center = True
|
|
141
|
-
self.view_need_update = True
|
|
142
162
|
|
|
143
163
|
def set_center(self, center):
|
|
144
164
|
self.center = center
|
|
145
|
-
self.
|
|
165
|
+
self.need_recalc_view = True
|
|
146
166
|
|
|
147
167
|
def paintGL(self):
|
|
148
168
|
# if the camera is moved, update the model view matrix.
|
|
149
|
-
if self.
|
|
169
|
+
if self.need_recalc_view:
|
|
150
170
|
self.view_matrix = self.get_view_matrix()
|
|
151
|
-
self.
|
|
171
|
+
self.need_recalc_view = False
|
|
152
172
|
self.update_model_view()
|
|
153
173
|
|
|
154
174
|
# set the background color
|
|
@@ -192,45 +212,48 @@ class BaseGLWidget(QtOpenGLWidgets.QOpenGLWidget):
|
|
|
192
212
|
return
|
|
193
213
|
rot_speed = 0.5
|
|
194
214
|
trans_speed = max(self.dist * 0.005, 0.1)
|
|
215
|
+
shift_pressed = QtCore.Qt.Key_Shift in self.active_keys
|
|
195
216
|
# Handle rotation keys
|
|
196
217
|
if QtCore.Qt.Key_Up in self.active_keys:
|
|
197
|
-
|
|
198
|
-
|
|
218
|
+
if shift_pressed:
|
|
219
|
+
self.rotate_keep_cam_pos(radians(rot_speed), 0, 0)
|
|
220
|
+
else:
|
|
221
|
+
self.rotate(radians(rot_speed), 0, 0)
|
|
199
222
|
if QtCore.Qt.Key_Down in self.active_keys:
|
|
200
|
-
|
|
201
|
-
|
|
223
|
+
if shift_pressed:
|
|
224
|
+
self.rotate_keep_cam_pos(radians(-rot_speed), 0, 0)
|
|
225
|
+
else:
|
|
226
|
+
self.rotate(radians(-rot_speed), 0, 0)
|
|
202
227
|
if QtCore.Qt.Key_Left in self.active_keys:
|
|
203
|
-
|
|
204
|
-
|
|
228
|
+
if shift_pressed:
|
|
229
|
+
self.rotate_keep_cam_pos(0, 0, radians(rot_speed))
|
|
230
|
+
else:
|
|
231
|
+
self.rotate(0, 0, radians(rot_speed))
|
|
205
232
|
if QtCore.Qt.Key_Right in self.active_keys:
|
|
206
|
-
|
|
207
|
-
|
|
233
|
+
if shift_pressed:
|
|
234
|
+
self.rotate_keep_cam_pos(0, 0, radians(-rot_speed))
|
|
235
|
+
else:
|
|
236
|
+
self.rotate(0, 0, radians(-rot_speed))
|
|
208
237
|
# Handle zoom keys
|
|
209
238
|
xz_keys = {QtCore.Qt.Key_Z, QtCore.Qt.Key_X}
|
|
210
239
|
if self.active_keys & xz_keys:
|
|
211
240
|
Rwc = euler_to_matrix(self.euler)
|
|
212
241
|
if QtCore.Qt.Key_Z in self.active_keys:
|
|
213
|
-
self.
|
|
214
|
-
self.view_need_update = True
|
|
242
|
+
self.translate(Rwc @ np.array([0, 0, -trans_speed]))
|
|
215
243
|
if QtCore.Qt.Key_X in self.active_keys:
|
|
216
|
-
self.
|
|
217
|
-
self.view_need_update = True
|
|
244
|
+
self.translate(Rwc @ np.array([0, 0, trans_speed]))
|
|
218
245
|
# Handle translation keys on the z plane
|
|
219
246
|
dir_keys = {QtCore.Qt.Key_W, QtCore.Qt.Key_S, QtCore.Qt.Key_A, QtCore.Qt.Key_D}
|
|
220
247
|
if self.active_keys & dir_keys:
|
|
221
248
|
Rz = euler_to_matrix([0, 0, self.euler[2]])
|
|
222
249
|
if QtCore.Qt.Key_W in self.active_keys:
|
|
223
|
-
self.
|
|
224
|
-
self.view_need_update = True
|
|
250
|
+
self.translate(Rz @ np.array([0, trans_speed, 0]))
|
|
225
251
|
if QtCore.Qt.Key_S in self.active_keys:
|
|
226
|
-
self.
|
|
227
|
-
self.view_need_update = True
|
|
252
|
+
self.translate(Rz @ np.array([0, -trans_speed, 0]))
|
|
228
253
|
if QtCore.Qt.Key_A in self.active_keys:
|
|
229
|
-
self.
|
|
230
|
-
self.view_need_update = True
|
|
254
|
+
self.translate(Rz @ np.array([-trans_speed, 0, 0]))
|
|
231
255
|
if QtCore.Qt.Key_D in self.active_keys:
|
|
232
|
-
self.
|
|
233
|
-
self.view_need_update = True
|
|
256
|
+
self.translate(Rz @ np.array([trans_speed, 0, 0]))
|
|
234
257
|
|
|
235
258
|
def update_model_view(self):
|
|
236
259
|
glMatrixMode(GL_MODELVIEW)
|
|
@@ -259,7 +282,7 @@ class BaseGLWidget(QtOpenGLWidgets.QOpenGLWidget):
|
|
|
259
282
|
|
|
260
283
|
def set_euler(self, euler):
|
|
261
284
|
self.euler = euler
|
|
262
|
-
self.
|
|
285
|
+
self.need_recalc_view = True
|
|
263
286
|
|
|
264
287
|
def set_color(self, color):
|
|
265
288
|
self.color = color
|
|
@@ -303,6 +326,11 @@ class BaseGLWidget(QtOpenGLWidgets.QOpenGLWidget):
|
|
|
303
326
|
self.euler[2] = (self.euler[2] + np.pi) % (2 * np.pi) - np.pi
|
|
304
327
|
self.euler[1] = (self.euler[1] + np.pi) % (2 * np.pi) - np.pi
|
|
305
328
|
self.euler[0] = np.clip(self.euler[0], 0, np.pi)
|
|
329
|
+
self.need_recalc_view = True
|
|
330
|
+
|
|
331
|
+
def translate(self, trans):
|
|
332
|
+
self.center += trans
|
|
333
|
+
self.need_recalc_view = True
|
|
306
334
|
|
|
307
335
|
def change_show_center(self, state):
|
|
308
336
|
self.enable_show_center = state
|
|
@@ -7,7 +7,6 @@ from q3dviewer.base_item import BaseItem
|
|
|
7
7
|
from OpenGL.GL import *
|
|
8
8
|
import numpy as np
|
|
9
9
|
from OpenGL.GL import shaders
|
|
10
|
-
from PIL import Image as PIL_Image
|
|
11
10
|
from PySide6.QtWidgets import QLabel, QSpinBox, QCheckBox
|
|
12
11
|
|
|
13
12
|
|
|
@@ -108,12 +107,8 @@ class ImageItem(BaseItem):
|
|
|
108
107
|
glBindVertexArray(0)
|
|
109
108
|
|
|
110
109
|
def set_data(self, data):
|
|
111
|
-
if isinstance(data, np.ndarray):
|
|
112
|
-
|
|
113
|
-
elif isinstance(data, PIL_Image.Image):
|
|
114
|
-
data = np.array(data)
|
|
115
|
-
else:
|
|
116
|
-
print("not support image type")
|
|
110
|
+
if not isinstance(data, np.ndarray):
|
|
111
|
+
print("The image type is not supported.")
|
|
117
112
|
raise NotImplementedError
|
|
118
113
|
|
|
119
114
|
if data.ndim == 2: # Grayscale image
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: q3dviewer
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.3
|
|
4
4
|
Summary: A library designed for quickly deploying a 3D viewer.
|
|
5
5
|
Home-page: https://github.com/scomup/q3dviewer
|
|
6
6
|
Author: Liu Yang
|
|
@@ -16,7 +16,6 @@ Requires-Dist: imageio[ffmpeg]
|
|
|
16
16
|
Requires-Dist: laspy
|
|
17
17
|
Requires-Dist: meshio
|
|
18
18
|
Requires-Dist: numpy
|
|
19
|
-
Requires-Dist: pillow
|
|
20
19
|
Requires-Dist: pye57
|
|
21
20
|
Requires-Dist: pypcd4
|
|
22
21
|
Requires-Dist: pyside6
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
q3dviewer/__init__.py,sha256=rP5XX_x8g7hxIMqNHlU89BN4dt5MSvoYYwip68fCmhc,173
|
|
2
|
-
q3dviewer/base_glwidget.py,sha256=
|
|
2
|
+
q3dviewer/base_glwidget.py,sha256=yQb4ckj4ldmiFoKL_TdZAqZNeBnMeSRDhLbMaruM3nk,12298
|
|
3
3
|
q3dviewer/base_item.py,sha256=lzb04oRaS4rRJrAP6C1Bu4ugK237FgupMTB97zjNVFw,1768
|
|
4
4
|
q3dviewer/basic_window.py,sha256=CFErOPRMysFcCqq3vhDsQ-xZzLArO3m1yABCTIhq5do,7946
|
|
5
5
|
q3dviewer/cloud_viewer.py,sha256=IxxrB6Sl6aPCr9P9QzKHGkMcDP_DjsBWbkmIbsAoIM4,2358
|
|
@@ -15,7 +15,7 @@ q3dviewer/custom_items/cloud_item.py,sha256=s46TxNDw7E6DW3V-ek_PF7egB3kRbnqpOBNU
|
|
|
15
15
|
q3dviewer/custom_items/frame_item.py,sha256=6BOM3MXi-Akv6KUXDC3QYEAXKxwk0Eo1KQn-F7jkqrQ,7559
|
|
16
16
|
q3dviewer/custom_items/gaussian_item.py,sha256=CZoXMmj2JPFfMqu7v4q4dLUI2cg_WfE1DHWGXjEYn6M,9869
|
|
17
17
|
q3dviewer/custom_items/grid_item.py,sha256=20n4TGm5YEaudhnEOCOk-HtsKwxVxaPr8YV36kO04yU,4802
|
|
18
|
-
q3dviewer/custom_items/image_item.py,sha256=
|
|
18
|
+
q3dviewer/custom_items/image_item.py,sha256=3FYAVlNLEILKZplkt2wbL8y16ke124GmwxcSmWmJY8Q,5357
|
|
19
19
|
q3dviewer/custom_items/line_item.py,sha256=u0oFN2iHzsRHtnbvyvC_iglEkCwEU2NnTuE536sKUAE,4348
|
|
20
20
|
q3dviewer/custom_items/text_item.py,sha256=nuHMVMQrwy50lNk9hxB94criFxbJJK-SYiK2fSXWUMQ,2158
|
|
21
21
|
q3dviewer/custom_items/trajectory_item.py,sha256=uoKQSrTs_m_m1M8iNAm3peiXnZ9uVPsYQLYas3Gksjg,2754
|
|
@@ -39,9 +39,9 @@ q3dviewer/utils/convert_ros_msg.py,sha256=sAoQfy3qLQKsIArBAVm8H--wlQXOcmkKK3-Ox9
|
|
|
39
39
|
q3dviewer/utils/gl_helper.py,sha256=dRY_kUqyPMr7NTcupUr6_VTvgnj53iE2C0Lk0-oFYsI,1435
|
|
40
40
|
q3dviewer/utils/maths.py,sha256=5TmjWUX1K3UjygXxrUsydjbo7tPzu0gD-yy7qtQUGBU,10588
|
|
41
41
|
q3dviewer/utils/range_slider.py,sha256=jZJQL-uQgnpgLvtYSWpKTrJlLkt3aqNpaRQAePEpNd0,3174
|
|
42
|
-
q3dviewer-1.1.
|
|
43
|
-
q3dviewer-1.1.
|
|
44
|
-
q3dviewer-1.1.
|
|
45
|
-
q3dviewer-1.1.
|
|
46
|
-
q3dviewer-1.1.
|
|
47
|
-
q3dviewer-1.1.
|
|
42
|
+
q3dviewer-1.1.3.dist-info/LICENSE,sha256=81cMOyNfw8KLb1JnPYngGHJ5W83gSbZEBU9MEP3tl-E,1124
|
|
43
|
+
q3dviewer-1.1.3.dist-info/METADATA,sha256=AXXroAQRcP2jMPxZCzpiR0tu-Ykj2lHUg28rQQZvM6I,7010
|
|
44
|
+
q3dviewer-1.1.3.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92
|
|
45
|
+
q3dviewer-1.1.3.dist-info/entry_points.txt,sha256=EOjker7XYaBk70ffvNB_knPcfA33Bnlg21ZjEeM1EyI,362
|
|
46
|
+
q3dviewer-1.1.3.dist-info/top_level.txt,sha256=HFFDCbGu28txcGe2HPc46A7EPaguBa_b5oH7bufmxHM,10
|
|
47
|
+
q3dviewer-1.1.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|