q3dviewer 1.0.1__py3-none-any.whl → 1.0.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.
@@ -1,169 +0,0 @@
1
- import pyqtgraph.opengl as gl
2
- from OpenGL.GL import *
3
- import numpy as np
4
- from OpenGL.GL import shaders
5
- from PIL import Image as PIL_Image
6
- from PyQt5.QtWidgets import QLabel, QSpinBox
7
-
8
-
9
- # Vertex and Fragment shader source code
10
- vertex_shader_source = """
11
- #version 330 core
12
- layout(location = 0) in vec3 position;
13
- layout(location = 1) in vec2 texCoord;
14
-
15
- out vec2 TexCoord;
16
-
17
- uniform mat4 view_matrix;
18
- uniform mat4 project_matrix;
19
-
20
- void main()
21
- {
22
- gl_Position = vec4(position, 1.0);
23
- TexCoord = texCoord;
24
- }
25
- """
26
-
27
- fragment_shader_source = """
28
- #version 330 core
29
- in vec2 TexCoord;
30
- out vec4 color;
31
- uniform sampler2D ourTexture;
32
- void main()
33
- {
34
- color = texture(ourTexture, TexCoord);
35
- }
36
- """
37
-
38
-
39
- def set_uniform_mat4(shader, content, name):
40
- content = content.T
41
- glUniformMatrix4fv(
42
- glGetUniformLocation(shader, name),
43
- 1,
44
- GL_FALSE,
45
- content.astype(np.float32)
46
- )
47
-
48
-
49
- class ImageItem(gl.GLGraphicsItem.GLGraphicsItem):
50
- def __init__(self, pos=np.array([0, 0]), size=np.array([1280/2, 720/2])):
51
- gl.GLGraphicsItem.GLGraphicsItem.__init__(self)
52
- self.pos = pos # bottom-left
53
- self.size = size
54
- self.image = np.zeros((self.size[0], self.size[1], 4), dtype=np.uint8)
55
- self.alpha = 255
56
-
57
- def initializeGL(self):
58
- # Rectangle vertices and texture coordinates
59
- width = self._GLGraphicsItem__view.deviceWidth()
60
- height = self._GLGraphicsItem__view.deviceHeight()
61
- x0, y0 = self.pos
62
- x1, y1 = self.pos + self.size
63
- x0 = x0 / width * 2 - 1
64
- y0 = y0 / height * 2 - 1
65
- x1 = x1 / width * 2 - 1
66
- y1 = y1 / height * 2 - 1
67
-
68
- self.vertices = np.array([
69
- # positions # texture coords
70
- [x0, y0, 0.0, 0.0, 0.0], # bottom-left
71
- [x1, y0, 0.0, 1.0, 0.0], # bottom-right
72
- [x1, y1, 0.0, 1.0, 1.0], # top-right
73
- [x0, y1, 0.0, 0.0, 1.0], # top-left
74
- ], dtype=np.float32)
75
-
76
- indices = np.array([
77
- 0, 1, 2, # first triangle
78
- 2, 3, 0 # second triangle
79
- ], dtype=np.uint32)
80
-
81
- self.vao = glGenVertexArrays(1)
82
- vbo = glGenBuffers(1)
83
- ebo = glGenBuffers(1)
84
-
85
- glBindVertexArray(self.vao)
86
-
87
- glBindBuffer(GL_ARRAY_BUFFER, vbo)
88
- glBufferData(GL_ARRAY_BUFFER, self.vertices.itemsize *
89
- 5 * 4, self.vertices, GL_STATIC_DRAW)
90
-
91
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo)
92
- glBufferData(GL_ELEMENT_ARRAY_BUFFER,
93
- indices.nbytes, indices, GL_STATIC_DRAW)
94
-
95
- # Vertex positions
96
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
97
- 20, ctypes.c_void_p(0))
98
- glEnableVertexAttribArray(0)
99
-
100
- # Texture coordinates
101
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
102
- 20, ctypes.c_void_p(12))
103
- glEnableVertexAttribArray(1)
104
-
105
- # Compile shaders and create shader program
106
- self.program = shaders.compileProgram(
107
- shaders.compileShader(vertex_shader_source, GL_VERTEX_SHADER),
108
- shaders.compileShader(fragment_shader_source, GL_FRAGMENT_SHADER),
109
- )
110
-
111
- self.texture = glGenTextures(1)
112
- glBindTexture(GL_TEXTURE_2D, self.texture)
113
- glBindVertexArray(0)
114
-
115
- def setData(self, data):
116
- if isinstance(data, np.ndarray):
117
- pass
118
- elif isinstance(data, PIL_Image.Image):
119
- data = np.array(data)
120
- else:
121
- print("not support image type")
122
- raise NotImplementedError
123
-
124
- if data.ndim == 2: # Grayscale image
125
- data = np.stack((data,) * 3 + (np.ones_like(data) * 255,), axis=-1)
126
- elif data.shape[-1] == 3: # RGB image
127
- alpha_channel = np.ones((data.shape[0], data.shape[1], 1), dtype=data.dtype) * self.alpha
128
- data = np.concatenate((data, alpha_channel), axis=-1)
129
- self.image = data
130
-
131
- def paint(self):
132
- if self.image is not None:
133
- img_data = self.image
134
- img_data = np.flipud(img_data) # Flip the image vertically
135
- img_data = img_data.tobytes()
136
- glBindTexture(GL_TEXTURE_2D, self.texture)
137
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self.image.shape[1],
138
- self.image.shape[0], 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data)
139
- glGenerateMipmap(GL_TEXTURE_2D)
140
- glBindTexture(GL_TEXTURE_2D, 0)
141
- self.image = None
142
-
143
- glEnable(GL_DEPTH_TEST)
144
- glEnable(GL_BLEND)
145
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
146
-
147
- glUseProgram(self.program)
148
- glBindVertexArray(self.vao)
149
- glBindTexture(GL_TEXTURE_2D, self.texture)
150
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
151
- glBindTexture(GL_TEXTURE_2D, 0)
152
- glBindVertexArray(0)
153
- glUseProgram(0)
154
-
155
- glDisable(GL_DEPTH_TEST)
156
- glDisable(GL_BLEND)
157
-
158
- def addSetting(self, layout):
159
- label1 = QLabel("Set Alpha:")
160
- layout.addWidget(label1)
161
- box1 = QSpinBox()
162
- box1.setSingleStep(1)
163
- box1.setRange(0, 255)
164
- box1.setValue(self.alpha)
165
- box1.valueChanged.connect(self.setAlpha)
166
- layout.addWidget(box1)
167
-
168
- def setAlpha(self, alpha):
169
- self.alpha = alpha
@@ -1,53 +0,0 @@
1
- from pyqtgraph.Qt import QtCore
2
- import pyqtgraph.opengl as gl
3
- from OpenGL.GL import *
4
- from PyQt5 import QtGui, QtCore
5
-
6
-
7
- class GL2DTextItem(gl.GLGraphicsItem.GLGraphicsItem):
8
- """Draws text over opengl 3D."""
9
-
10
- def __init__(self, **kwds):
11
- """All keyword arguments are passed to setData()"""
12
- gl.GLGraphicsItem.GLGraphicsItem.__init__(self)
13
- glopts = kwds.pop('glOptions', 'additive')
14
- self.setGLOptions(glopts)
15
- self.pos = (100, 100)
16
- self.color = QtCore.Qt.GlobalColor.white
17
- self.text = ''
18
- self.font = QtGui.QFont('Helvetica', 16)
19
- self.setData(**kwds)
20
-
21
- def setData(self, **kwds):
22
- args = ['pos', 'color', 'text', 'size', 'font']
23
- for k in kwds.keys():
24
- if k not in args:
25
- raise ValueError('Invalid keyword argument: %s (allowed arguments are %s)' % (k, str(args)))
26
- for arg in args:
27
- if arg in kwds:
28
- value = kwds[arg]
29
- if arg == 'pos':
30
- self.pos = value
31
- elif arg == 'color':
32
- value = value
33
- elif arg == 'font':
34
- if isinstance(value, QtGui.QFont) is False:
35
- raise TypeError('"font" must be QFont.')
36
- elif arg == 'size':
37
- self.font.setPointSize(value)
38
- setattr(self, arg, value)
39
- self.update()
40
-
41
- def paint(self):
42
- if len(self.text) < 1:
43
- return
44
- self.setupGLState()
45
-
46
- text_pos = QtCore.QPointF(*self.pos)
47
- painter = QtGui.QPainter(self.view())
48
- painter.setPen(self.color)
49
- painter.setFont(self.font)
50
- painter.setRenderHints(QtGui.QPainter.RenderHint.Antialiasing | QtGui.QPainter.RenderHint.TextAntialiasing)
51
- painter.drawText(text_pos, self.text)
52
- painter.end()
53
-
@@ -1,78 +0,0 @@
1
- import pyqtgraph.opengl as gl
2
- from OpenGL.GL import *
3
- import numpy as np
4
- import threading
5
-
6
-
7
- class TrajectoryItem(gl.GLGridItem):
8
- def __init__(self, width=1, color=(0, 1, 0, 1)):
9
- super(TrajectoryItem, self).__init__()
10
- self.width = width
11
- self.buff = np.empty((0, 3), np.float32)
12
- self.wait_add_data = None
13
- self.mutex = threading.Lock()
14
- self.CAPACITY = 100000
15
- self.valid_buff_top = 0
16
- self.color = color
17
-
18
- def addSetting(self, layout):
19
- pass
20
-
21
- def setData(self, data, append=True):
22
- self.mutex.acquire()
23
- data = data.astype(np.float32).reshape(-1, 3)
24
- if (append is False):
25
- self.wait_add_data = data
26
- self.add_buff_loc = 0
27
- else:
28
- if (self.wait_add_data is None):
29
- self.wait_add_data = data
30
- else:
31
- self.wait_add_data = np.concatenate([self.wait_add_data, data])
32
- self.add_buff_loc = self.valid_buff_top
33
- self.mutex.release()
34
-
35
- def updateRenderBuffer(self):
36
- if (self.wait_add_data is None):
37
- return
38
- self.mutex.acquire()
39
-
40
- new_buff_top = self.add_buff_loc + self.wait_add_data.shape[0]
41
- if new_buff_top > self.buff.shape[0]:
42
- buff_capacity = self.buff.shape[0]
43
- while (new_buff_top > buff_capacity):
44
- buff_capacity += self.CAPACITY
45
- self.buff = np.empty((buff_capacity, 3), np.float32)
46
- self.buff[self.add_buff_loc:new_buff_top] = self.wait_add_data
47
- glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
48
- glBufferData(GL_ARRAY_BUFFER, self.buff.nbytes,
49
- self.buff, GL_DYNAMIC_DRAW)
50
- glBindBuffer(GL_ARRAY_BUFFER, 0)
51
- else:
52
- self.buff[self.add_buff_loc:new_buff_top] = self.wait_add_data
53
- glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
54
- glBufferSubData(GL_ARRAY_BUFFER, self.add_buff_loc * 12,
55
- self.wait_add_data.shape[0] * 12, self.wait_add_data)
56
- self.valid_buff_top = new_buff_top
57
- self.wait_add_data = None
58
- self.mutex.release()
59
-
60
- def initializeGL(self):
61
- self.vbo = glGenBuffers(1)
62
-
63
- def paint(self):
64
- self.setupGLState()
65
- self.updateRenderBuffer()
66
- glEnable(GL_BLEND)
67
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
68
- glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
69
- glEnableClientState(GL_VERTEX_ARRAY)
70
- glVertexPointer(3, GL_FLOAT, 0, None)
71
- glLineWidth(self.width)
72
- glColor4f(*self.color) # z is blue
73
-
74
- glDrawArrays(GL_LINE_STRIP, 0, self.valid_buff_top)
75
- glDisableClientState(GL_VERTEX_ARRAY)
76
-
77
- glBindBuffer(GL_ARRAY_BUFFER, 0)
78
- glUseProgram(0)
q3dviewer/gau_io.py DELETED
@@ -1,168 +0,0 @@
1
- import numpy as np
2
- from plyfile import PlyData
3
-
4
-
5
- def gsdata_type(sh_dim):
6
- return [('pw', '<f4', (3,)),
7
- ('rot', '<f4', (4,)),
8
- ('scale', '<f4', (3,)),
9
- ('alpha', '<f4'),
10
- ('sh', '<f4', (sh_dim))]
11
-
12
-
13
- def matrix_to_quaternion_wxyz(matrices):
14
- m00, m01, m02 = matrices[:, 0, 0], matrices[:, 0, 1], matrices[:, 0, 2]
15
- m10, m11, m12 = matrices[:, 1, 0], matrices[:, 1, 1], matrices[:, 1, 2]
16
- m20, m21, m22 = matrices[:, 2, 0], matrices[:, 2, 1], matrices[:, 2, 2]
17
- t = 1 + m00 + m11 + m22
18
- s = np.ones_like(m00)
19
- w = np.ones_like(m00)
20
- x = np.ones_like(m00)
21
- y = np.ones_like(m00)
22
- z = np.ones_like(m00)
23
-
24
- t_positive = t > 0.0000001
25
- s[t_positive] = 0.5 / np.sqrt(t[t_positive])
26
- w[t_positive] = 0.25 / s[t_positive]
27
- x[t_positive] = (m21[t_positive] - m12[t_positive]) * s[t_positive]
28
- y[t_positive] = (m02[t_positive] - m20[t_positive]) * s[t_positive]
29
- z[t_positive] = (m10[t_positive] - m01[t_positive]) * s[t_positive]
30
-
31
- c1 = np.logical_and(m00 > m11, m00 > m22)
32
- cond1 = np.logical_and(np.logical_not(t_positive), np.logical_and(m00 > m11, m00 > m22))
33
-
34
- s[cond1] = 2.0 * np.sqrt(1.0 + m00[cond1] - m11[cond1] - m22[cond1])
35
- w[cond1] = (m21[cond1] - m12[cond1]) / s[cond1]
36
- x[cond1] = 0.25 * s[cond1]
37
- y[cond1] = (m01[cond1] + m10[cond1]) / s[cond1]
38
- z[cond1] = (m02[cond1] + m20[cond1]) / s[cond1]
39
-
40
- c2 = np.logical_and(np.logical_not(c1), m11 > m22)
41
- cond2 = np.logical_and(np.logical_not(t_positive), c2)
42
- s[cond2] = 2.0 * np.sqrt(1.0 + m11[cond2] - m00[cond2] - m22[cond2])
43
- w[cond2] = (m02[cond2] - m20[cond2]) / s[cond2]
44
- x[cond2] = (m01[cond2] + m10[cond2]) / s[cond2]
45
- y[cond2] = 0.25 * s[cond2]
46
- z[cond2] = (m12[cond2] + m21[cond2]) / s[cond2]
47
-
48
- c3 = np.logical_and(np.logical_not(c1), np.logical_not(c2))
49
- cond3 = np.logical_and(np.logical_not(t_positive), c3)
50
- s[cond3] = 2.0 * np.sqrt(1.0 + m22[cond3] - m00[cond3] - m11[cond3])
51
- w[cond3] = (m10[cond3] - m01[cond3]) / s[cond3]
52
- x[cond3] = (m02[cond3] + m20[cond3]) / s[cond3]
53
- y[cond3] = (m12[cond3] + m21[cond3]) / s[cond3]
54
- z[cond3] = 0.25 * s[cond3]
55
- return np.array([w, x, y, z]).T
56
-
57
-
58
- def load_ply(path, T=None):
59
- plydata = PlyData.read(path)
60
- pws = np.stack((np.asarray(plydata.elements[0]["x"]),
61
- np.asarray(plydata.elements[0]["y"]),
62
- np.asarray(plydata.elements[0]["z"])), axis=1)
63
-
64
- alphas = np.asarray(plydata.elements[0]["opacity"])
65
- alphas = 1/(1 + np.exp(-alphas))
66
-
67
- scales = np.stack((np.asarray(plydata.elements[0]["scale_0"]),
68
- np.asarray(plydata.elements[0]["scale_1"]),
69
- np.asarray(plydata.elements[0]["scale_2"])), axis=1)
70
-
71
- rots = np.stack((np.asarray(plydata.elements[0]["rot_0"]),
72
- np.asarray(plydata.elements[0]["rot_1"]),
73
- np.asarray(plydata.elements[0]["rot_2"]),
74
- np.asarray(plydata.elements[0]["rot_3"])), axis=1)
75
-
76
- rots /= np.linalg.norm(rots, axis=1)[:, np.newaxis]
77
-
78
- sh_dim = len(plydata.elements[0][0])-14
79
- shs = np.zeros([pws.shape[0], sh_dim])
80
- shs[:, 0] = np.asarray(plydata.elements[0]["f_dc_0"])
81
- shs[:, 1] = np.asarray(plydata.elements[0]["f_dc_1"])
82
- shs[:, 2] = np.asarray(plydata.elements[0]["f_dc_2"])
83
-
84
- sh_rest_dim = sh_dim - 3
85
- for i in range(sh_rest_dim):
86
- name = "f_rest_%d" % i
87
- shs[:, 3 + i] = np.asarray(plydata.elements[0][name])
88
-
89
- shs[:, 3:] = shs[:, 3:].reshape(-1, 3, sh_rest_dim//3).transpose([0, 2, 1]).reshape(-1, sh_rest_dim)
90
-
91
- pws = pws.astype(np.float32)
92
- rots = rots.astype(np.float32)
93
- scales = np.exp(scales)
94
- scales = scales.astype(np.float32)
95
- alphas = alphas.astype(np.float32)
96
- shs = shs.astype(np.float32)
97
-
98
- dtypes = gsdata_type(sh_dim)
99
-
100
- gs = np.rec.fromarrays(
101
- [pws, rots, scales, alphas, shs], dtype=dtypes)
102
-
103
- return gs
104
-
105
-
106
- def rotate_gaussian(T, gs):
107
- # Transform to world
108
- pws = (T @ gs['pw'].T).T
109
- w = gs['rot'][:, 0]
110
- x = gs['rot'][:, 1]
111
- y = gs['rot'][:, 2]
112
- z = gs['rot'][:, 3]
113
- R = np.array([
114
- [1.0 - 2*(y**2 + z**2), 2*(x*y - z*w), 2*(x * z + y * w)],
115
- [2*(x*y + z*w), 1.0 - 2*(x**2 + z**2), 2*(y*z - x*w)],
116
- [2*(x*z - y*w), 2*(y*z + x*w), 1.0 - 2*(x**2 + y**2)]
117
- ]).transpose(2, 0, 1)
118
- R_new = T @ R
119
- rots = matrix_to_quaternion_wxyz(R_new)
120
- gs['pw'] = pws
121
- gs['rot'] = rots
122
- return gs
123
-
124
-
125
- def load_gs(fn):
126
- if fn.endswith('.ply'):
127
- return load_ply(fn)
128
- elif fn.endswith('.npy'):
129
- return np.load(fn)
130
- else:
131
- print("%s is not a supported file." % fn)
132
- exit(0)
133
-
134
-
135
- def save_gs(fn, gs):
136
- np.save(fn, gs)
137
-
138
-
139
- def get_example_gs():
140
- gs_data = np.array([[0., 0., 0., # xyz
141
- 1., 0., 0., 0., # rot
142
- 0.05, 0.05, 0.05, # size
143
- 1.,
144
- 1.772484, -1.772484, 1.772484],
145
- [1., 0., 0.,
146
- 1., 0., 0., 0.,
147
- 0.2, 0.05, 0.05,
148
- 1.,
149
- 1.772484, -1.772484, -1.772484],
150
- [0., 1., 0.,
151
- 1., 0., 0., 0.,
152
- 0.05, 0.2, 0.05,
153
- 1.,
154
- -1.772484, 1.772484, -1.772484],
155
- [0., 0., 1.,
156
- 1., 0., 0., 0.,
157
- 0.05, 0.05, 0.2,
158
- 1.,
159
- -1.772484, -1.772484, 1.772484]
160
- ], dtype=np.float32)
161
- dtypes = gsdata_type(3)
162
- gs = np.frombuffer(gs_data.tobytes(), dtype=dtypes)
163
- return gs
164
-
165
-
166
- if __name__ == "__main__":
167
- gs = load_gs("/home/liu/workspace/EasyGaussianSplatting/data/final.npy")
168
- print(gs.shape)
@@ -1,6 +0,0 @@
1
- from q3dviewer.tools.cloud_viewer import main as cloud_viewer
2
- from q3dviewer.tools.ros_viewer import main as ros_viewer
3
- from q3dviewer.tools.mesh_viewer import main as mesh_viewer
4
- from q3dviewer.tools.gaussian_viewer import main as gaussian_viewer
5
- from q3dviewer.tools.lidar_cam_calib import main as lidar_cam_calib
6
- from q3dviewer.tools.lidar_calib import main as lidar_calib
@@ -1,75 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
- import numpy as np
4
- from pypcd4 import PointCloud
5
- import q3dviewer as q3d
6
-
7
-
8
- class CloudViewer(q3d.Viewer):
9
- def __init__(self, **kwargs):
10
- super(CloudViewer, self).__init__(**kwargs)
11
- self.setAcceptDrops(True)
12
-
13
- def dragEnterEvent(self, event):
14
- if event.mimeData().hasUrls():
15
- event.accept()
16
- else:
17
- event.ignore()
18
-
19
- def dropEvent(self, event):
20
- for url in event.mimeData().urls():
21
- file_path = url.toLocalFile()
22
- self.openCloudFile(file_path)
23
-
24
- def openCloudFile(self, file):
25
- cloud_item = self['cloud']
26
- if cloud_item is None:
27
- print("Can't find clouditem.")
28
- return
29
- if file.endswith('.pcd'):
30
- pc = PointCloud.from_path(file).pc_data
31
- if 'rgb' in pc.dtype.names:
32
- color = pc["rgb"].astype(np.uint32)
33
- cloud_item.setColorMode('RGB')
34
- elif 'intensity' in pc.dtype.names:
35
- color = pc["intensity"].astype(np.uint32)
36
- cloud_item.setColorMode('I')
37
- else:
38
- color = pc['z'].astype(np.uint32)
39
- cloud_item.setColorMode('#FFFFFF')
40
- cloud = np.rec.fromarrays(
41
- [np.stack([pc["x"], pc["y"], pc["z"]], axis=1), color],
42
- dtype=cloud_item.data_type)
43
- elif file.endswith('.npy'):
44
- pc = np.load(file)
45
- cloud = np.rec.fromarrays(
46
- [np.stack([pc[:, 0], pc[:, 1], pc[:, 2]], axis=1),
47
- pc[:, 3].astype(np.uint32)],
48
- dtype=cloud_item.data_type)
49
- cloud_item.setData(data=cloud)
50
-
51
-
52
- def main():
53
- import argparse
54
- parser = argparse.ArgumentParser()
55
- parser.add_argument("--pcd", help="the pcd path")
56
- args = parser.parse_args()
57
- app = q3d.QApplication(['Cloud Viewer'])
58
- viewer = CloudViewer(name='Cloud Viewer')
59
- cloud_item = q3d.CloudIOItem(size=1, alpha=0.1)
60
- axis_item = q3d.GLAxisItem(size=0.5, width=5)
61
- grid_item = q3d.GridItem(size=1000, spacing=20)
62
-
63
- viewer.addItems(
64
- {'cloud': cloud_item, 'grid': grid_item, 'axis': axis_item})
65
-
66
- if args.pcd:
67
- pcd_fn = args.pcd
68
- viewer.openCloudFile(pcd_fn)
69
-
70
- viewer.show()
71
- app.exec_()
72
-
73
-
74
- if __name__ == '__main__':
75
- main()
@@ -1,38 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
- import numpy as np
4
- import threading
5
- import time
6
- import q3dviewer as q3d
7
-
8
-
9
- def update(viewer):
10
- i = 0.0
11
- while True:
12
- i += 0.05
13
- time.sleep(0.1)
14
- viewer['traj'].setData(np.array([np.sin(i) * i, np.cos(i) * i, i]))
15
-
16
-
17
- def main():
18
- app = q3d.QApplication([])
19
-
20
- axis_item = q3d.GLAxisItem(size=0.5, width=5)
21
- grid_item = q3d.GridItem(size=10, spacing=1)
22
- traj_item = q3d.TrajectoryItem(width=2)
23
-
24
- viewer = q3d.Viewer(name='example')
25
- th = threading.Thread(target=update, args=(viewer, ))
26
- th.start()
27
-
28
- viewer.addItems({
29
- 'grid': grid_item,
30
- 'axis': axis_item,
31
- 'traj': traj_item})
32
-
33
- viewer.show()
34
- app.exec_()
35
-
36
-
37
- if __name__ == '__main__':
38
- main()
@@ -1,55 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
- import numpy as np
4
- import q3dviewer as q3d
5
- from q3dviewer.gau_io import load_gs, rotate_gaussian
6
-
7
-
8
- class GuassianViewer(q3d.Viewer):
9
- def __init__(self):
10
- super(GuassianViewer, self).__init__(name="Guassian Viewer")
11
- self.setAcceptDrops(True)
12
-
13
- def dragEnterEvent(self, event):
14
- if event.mimeData().hasUrls():
15
- event.accept()
16
- else:
17
- event.ignore()
18
-
19
- def dropEvent(self, event):
20
- for url in event.mimeData().urls():
21
- file_path = url.toLocalFile()
22
- self.openGuassianFile(file_path)
23
-
24
- def openGuassianFile(self, file):
25
- gau_item = self['gaussian']
26
- if gau_item is None:
27
- print("Can't find gaussianitem")
28
- return
29
-
30
- print("Try to load %s ..." % file)
31
- gs = load_gs(file)
32
- # convert camera optical frame (b) to camera frame (c).
33
- Rcb = np.array([[0, -1, 0],
34
- [0, 0, -1],
35
- [1, 0, 0]]).T
36
- gs = rotate_gaussian(Rcb, gs)
37
- gs_data = gs.view(np.float32).reshape(gs.shape[0], -1)
38
- gau_item.setData(gs_data=gs_data)
39
-
40
-
41
- def main():
42
- app = q3d.QApplication(['Guassian Viewer'])
43
- viewer = GuassianViewer(name='Guassian Viewer')
44
-
45
- grid_item = q3d.GridItem(size=1000, spacing=20)
46
- gau_item = q3d.GaussianItem()
47
-
48
- viewer.addItems({'grid': grid_item, 'gaussian': gau_item})
49
-
50
- viewer.show()
51
- app.exec_()
52
-
53
-
54
- if __name__ == '__main__':
55
- main()