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,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: q3dviewer
3
- Version: 1.0.1
3
+ Version: 1.0.3
4
4
  Requires-Dist: numpy
5
5
  Requires-Dist: pyqtgraph
6
6
  Requires-Dist: pyqt5
@@ -0,0 +1,5 @@
1
+ q3dviewer-1.0.3.dist-info/METADATA,sha256=F17ziZy4LHhLDapWbZc1n0B04eSkdsAurZVmvZEXNKY,189
2
+ q3dviewer-1.0.3.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92
3
+ q3dviewer-1.0.3.dist-info/entry_points.txt,sha256=6zSxtJ5cjcpc32sR_wkRqOaeiJFpEuLnJQckZE3niU0,316
4
+ q3dviewer-1.0.3.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
5
+ q3dviewer-1.0.3.dist-info/RECORD,,
@@ -0,0 +1 @@
1
+
q3dviewer/__init__.py DELETED
@@ -1,4 +0,0 @@
1
- from q3dviewer.utils import *
2
- from q3dviewer.custom_items import *
3
- from q3dviewer.viewer_widget import *
4
- from q3dviewer.basic_viewer import *
q3dviewer/basic_viewer.py DELETED
@@ -1,56 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
- from q3dviewer.viewer_widget import *
4
- import signal
5
- import sys
6
-
7
-
8
- def handler(signal, frame):
9
- QApplication.quit()
10
- print("Force close by Ctrl+C")
11
-
12
-
13
- class Viewer(QMainWindow):
14
- def __init__(self, name='Viewer', win_size=[1920, 1080], vw=ViewWidget):
15
- signal.signal(signal.SIGINT, handler)
16
- super(Viewer, self).__init__()
17
- self.vw = vw
18
- self.setGeometry(0, 0, win_size[0], win_size[1])
19
- self.initUI()
20
- self.setWindowTitle(name)
21
-
22
- def initUI(self):
23
- centerWidget = QWidget()
24
- self.setCentralWidget(centerWidget)
25
- layout = QVBoxLayout()
26
- centerWidget.setLayout(layout)
27
- self.viewerWidget = self.vw()
28
- layout.addWidget(self.viewerWidget, 1)
29
- timer = QtCore.QTimer(self)
30
- timer.setInterval(20) # period, in milliseconds
31
- timer.timeout.connect(self.update)
32
- self.viewerWidget.setCameraPosition(distance=40)
33
- timer.start()
34
-
35
- def addItems(self, named_items: dict):
36
- for name, item in named_items.items():
37
- self.viewerWidget.addItem(name, item)
38
-
39
- def __getitem__(self, name: str):
40
- if name in self.viewerWidget.named_items:
41
- return self.viewerWidget.named_items[name]
42
- else:
43
- return None
44
-
45
- def update(self):
46
- # force update by timer
47
- self.viewerWidget.update()
48
-
49
- def closeEvent(self, event):
50
- event.accept()
51
- QApplication.quit()
52
-
53
- def show(self):
54
- self.viewerWidget.setting_window.addSetting(
55
- "main win", self.viewerWidget)
56
- super().show()
@@ -1,9 +0,0 @@
1
- from q3dviewer.custom_items.axis_item import *
2
- from q3dviewer.custom_items.cloud_item import *
3
- from q3dviewer.custom_items.cloud_io_item import *
4
- from q3dviewer.custom_items.gaussian_item import *
5
- from q3dviewer.custom_items.camera_frame_item import *
6
- from q3dviewer.custom_items.grid_item import *
7
- from q3dviewer.custom_items.text_item import *
8
- from q3dviewer.custom_items.image_item import *
9
- from q3dviewer.custom_items.trajectory_item import *
@@ -1,73 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
- import numpy as np
4
- import pyqtgraph.opengl as gl
5
- from OpenGL.GL import *
6
- from OpenGL.GLU import *
7
- from OpenGL.GLUT import *
8
- import numpy as np
9
- from PyQt5.QtWidgets import QLabel, QDoubleSpinBox
10
-
11
-
12
- class GLAxisItem(gl.GLGraphicsItem.GLGraphicsItem):
13
- def __init__(self, size=1., width=5, glOptions='translucent'):
14
- gl.GLGraphicsItem.GLGraphicsItem.__init__(self)
15
- self.size = size
16
- self.width = width
17
- self.org = np.array([0, 0, 0, 1])
18
- self.axis_x = np.array([self.size, 0, 0, 1])
19
- self.axis_y = np.array([0, self.size, 0, 1])
20
- self.axis_z = np.array([0, 0, self.size, 1])
21
- self.setGLOptions(glOptions)
22
- self.T = np.eye(4)
23
- self.settings = []
24
-
25
- def addSetting(self, layout):
26
- label1 = QLabel("Set size:")
27
- layout.addWidget(label1)
28
- box1 = QDoubleSpinBox()
29
- box1.setSingleStep(0.1)
30
- layout.addWidget(box1)
31
- box1.setValue(self.size)
32
- box1.valueChanged.connect(self.setSize)
33
- box1.setRange(0.0, 100)
34
-
35
- label2 = QLabel("Set Width:")
36
- layout.addWidget(label2)
37
- box2 = QDoubleSpinBox()
38
- layout.addWidget(box2)
39
- box2.setSingleStep(0.1)
40
- box2.setValue(self.width)
41
- box2.valueChanged.connect(self.setWidth)
42
- box2.setRange(0, 1000)
43
-
44
- def setSize(self, size):
45
- self.size = size
46
- self.axis_x = np.array([self.size, 0, 0, 1])
47
- self.axis_y = np.array([0, self.size, 0, 1])
48
- self.axis_z = np.array([0, 0, self.size, 1])
49
-
50
- def setWidth(self, width):
51
- self.width = width
52
-
53
- def setTransform(self, T):
54
- self.T = T
55
-
56
- def paint(self):
57
- org = self.T.dot(self.org)
58
- axis_x = self.T.dot(self.axis_x)
59
- axis_y = self.T.dot(self.axis_y)
60
- axis_z = self.T.dot(self.axis_z)
61
- self.setupGLState()
62
- glLineWidth(self.width)
63
- glBegin(GL_LINES)
64
- glColor4f(0, 0, 1, 1) # z is blue
65
- glVertex3f(org[0], org[1], org[2])
66
- glVertex3f(axis_z[0], axis_z[1], axis_z[2])
67
- glColor4f(0, 1, 0, 1) # y is green
68
- glVertex3f(org[0], org[1], org[2])
69
- glVertex3f(axis_y[0], axis_y[1], axis_y[2])
70
- glColor4f(1, 0, 0, 1) # x is red
71
- glVertex3f(org[0], org[1], org[2])
72
- glVertex3f(axis_x[0], axis_x[1], axis_x[2])
73
- glEnd()
@@ -1,173 +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
-
7
-
8
- # Vertex and Fragment shader source code
9
- vertex_shader_source = """
10
- #version 330 core
11
- layout(location = 0) in vec3 position;
12
- layout(location = 1) in vec2 texCoord;
13
-
14
- out vec2 TexCoord;
15
-
16
- uniform mat4 view_matrix;
17
- uniform mat4 project_matrix;
18
-
19
- void main()
20
- {
21
- gl_Position = project_matrix * view_matrix * vec4(position, 1.0);
22
- TexCoord = texCoord;
23
- }
24
- """
25
-
26
- fragment_shader_source = """
27
- #version 330 core
28
- in vec2 TexCoord;
29
- out vec4 color;
30
- uniform sampler2D ourTexture;
31
- void main()
32
- {
33
- color = texture(ourTexture, TexCoord);
34
- }
35
- """
36
-
37
-
38
- def set_uniform_mat4(shader, content, name):
39
- content = content.T
40
- glUniformMatrix4fv(
41
- glGetUniformLocation(shader, name),
42
- 1,
43
- GL_FALSE,
44
- content.astype(np.float32)
45
- )
46
-
47
-
48
- class GLCameraFrameItem(gl.GLGraphicsItem.GLGraphicsItem):
49
- def __init__(self, T=np.eye(4), size=1, width=3, path=None):
50
- gl.GLGraphicsItem.GLGraphicsItem.__init__(self)
51
- self.size = size
52
- self.width = width
53
- self.T = T
54
- self.path = path
55
-
56
- def initializeGL(self):
57
- # Rectangle vertices and texture coordinates
58
- hsize = self.size / 2
59
- self.vertices = np.array([
60
- # positions # texture coords
61
- [-hsize, -hsize, 0.0, 0.0, 0.0], # bottom-left
62
- [hsize, -hsize, 0.0, 1.0, 0.0], # bottom-right
63
- [hsize, hsize, 0.0, 1.0, 1.0], # top-right
64
- [-hsize, hsize, 0.0, 0.0, 1.0], # top-left
65
- [0, 0, -hsize * 0.66, 0.0, 0.0], # top-left
66
- ], dtype=np.float32)
67
-
68
- R = self.T[:3, :3]
69
- t = self.T[:3, 3]
70
- self.vertices[:, :3] = (
71
- R @ self.vertices[:, :3].T + t[:, np.newaxis]).T
72
-
73
- self.focal_p = np.array([0, 0, hsize * 0.66])
74
-
75
- indices = np.array([
76
- 0, 1, 2, # first triangle
77
- 2, 3, 0 # second triangle
78
- ], dtype=np.uint32)
79
-
80
- self.vao = glGenVertexArrays(1)
81
- vbo = glGenBuffers(1)
82
- ebo = glGenBuffers(1)
83
-
84
- glBindVertexArray(self.vao)
85
-
86
- glBindBuffer(GL_ARRAY_BUFFER, vbo)
87
- glBufferData(GL_ARRAY_BUFFER, self.vertices.itemsize *
88
- 5 * 4, self.vertices, GL_STATIC_DRAW)
89
-
90
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo)
91
- glBufferData(GL_ELEMENT_ARRAY_BUFFER,
92
- indices.nbytes, indices, GL_STATIC_DRAW)
93
-
94
- # Vertex positions
95
-
96
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
97
- 20, ctypes.c_void_p(0))
98
- glEnableVertexAttribArray(0)
99
- # Texture coordinates
100
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
101
- 20, ctypes.c_void_p(12))
102
- glEnableVertexAttribArray(1)
103
-
104
- project_matrix = np.array(self._GLGraphicsItem__view.projectionMatrix().data(),
105
- np.float32).reshape([4, 4]).T
106
- # Compile shaders and create shader program
107
- self.program = shaders.compileProgram(
108
- shaders.compileShader(vertex_shader_source, GL_VERTEX_SHADER),
109
- shaders.compileShader(fragment_shader_source, GL_FRAGMENT_SHADER),
110
- )
111
- glUseProgram(self.program)
112
- set_uniform_mat4(self.program, project_matrix, 'project_matrix')
113
- glUseProgram(0)
114
-
115
- self.texture = glGenTextures(1)
116
- glBindTexture(GL_TEXTURE_2D, self.texture)
117
-
118
- # Load image
119
- image = PIL_Image.open(self.path)
120
- # image = image.transpose(Image.FLIP_TOP_BOTTOM)
121
- img_data = image.convert("RGBA").tobytes()
122
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width,
123
- image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data)
124
- glGenerateMipmap(GL_TEXTURE_2D)
125
- glBindTexture(GL_TEXTURE_2D, 0)
126
- glBindVertexArray(0)
127
-
128
- def setTransform(self, T):
129
- self.T = T
130
-
131
- def paint(self):
132
- self.view_matrix = np.array(
133
- self._GLGraphicsItem__view.viewMatrix().data(), np.float32).reshape([4, 4]).T
134
- project_matrix = np.array(self._GLGraphicsItem__view.projectionMatrix(
135
- ).data(), np.float32).reshape([4, 4]).T
136
-
137
- glEnable(GL_DEPTH_TEST)
138
- glEnable(GL_BLEND)
139
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
140
-
141
- glUseProgram(self.program)
142
- set_uniform_mat4(self.program, self.view_matrix, 'view_matrix')
143
- set_uniform_mat4(self.program, project_matrix, 'project_matrix')
144
- glBindVertexArray(self.vao)
145
- glBindTexture(GL_TEXTURE_2D, self.texture)
146
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
147
- glBindTexture(GL_TEXTURE_2D, 0)
148
- glBindVertexArray(0)
149
- glUseProgram(0)
150
-
151
- glLineWidth(self.width)
152
- glBegin(GL_LINES)
153
- glColor4f(1, 1, 1, 1) # z is blue
154
- glVertex3f(*self.vertices[0, :3])
155
- glVertex3f(*self.vertices[1, :3])
156
- glVertex3f(*self.vertices[1, :3])
157
- glVertex3f(*self.vertices[2, :3])
158
- glVertex3f(*self.vertices[2, :3])
159
- glVertex3f(*self.vertices[3, :3])
160
- glVertex3f(*self.vertices[3, :3])
161
- glVertex3f(*self.vertices[0, :3])
162
- glVertex3f(*self.vertices[4, :3])
163
- glVertex3f(*self.vertices[0, :3])
164
- glVertex3f(*self.vertices[4, :3])
165
- glVertex3f(*self.vertices[1, :3])
166
- glVertex3f(*self.vertices[4, :3])
167
- glVertex3f(*self.vertices[2, :3])
168
- glVertex3f(*self.vertices[4, :3])
169
- glVertex3f(*self.vertices[3, :3])
170
- glEnd()
171
-
172
- glDisable(GL_DEPTH_TEST)
173
- glDisable(GL_BLEND)
@@ -1,83 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
- from q3dviewer.custom_items.cloud_item import CloudItem
4
- from pypcd4 import PointCloud, MetaData
5
- from pathlib import Path
6
- import os
7
- from PyQt5.QtWidgets import QPushButton, QLabel, QLineEdit, QMessageBox
8
- import numpy as np
9
-
10
-
11
- class CloudIOItem(CloudItem):
12
- """
13
- add save/load function to CloudItem
14
- """
15
- def __init__(self, **kwargs):
16
- super().__init__(**kwargs)
17
- self.save_path = str(Path(os.getcwd(), "data.pcd"))
18
-
19
- def addSetting(self, layout):
20
- super().addSetting(layout)
21
-
22
- label4 = QLabel("Save Path:")
23
- layout.addWidget(label4)
24
- box4 = QLineEdit()
25
- box4.setText(self.save_path)
26
- box4.textChanged.connect(self.setPath)
27
- layout.addWidget(box4)
28
- save_button = QPushButton("Save Cloud")
29
- save_button.clicked.connect(self.save)
30
- layout.addWidget(save_button)
31
-
32
- def save(self):
33
- cloud = self.buff[:self.valid_buff_top]
34
- if self.save_path.endswith(".pcd"):
35
- fields = ("x", "y", "z", "rgb")
36
- metadata = MetaData.model_validate(
37
- {
38
- "fields": fields,
39
- "size": [4, 4, 4, 4],
40
- "type": ['F', 'F', 'F', 'U'],
41
- "count": [1, 1, 1, 1],
42
- "width": cloud.shape[0],
43
- "points": cloud.shape[0],
44
- })
45
- pc = PointCloud(metadata, cloud)
46
- try:
47
- pc.save(self.save_path)
48
- save_msg = QMessageBox()
49
- save_msg.setIcon(QMessageBox.Information)
50
- save_msg.setWindowTitle("save")
51
- save_msg.setStandardButtons(QMessageBox.Ok)
52
- save_msg.setText("save cloud to %s" % self.save_path)
53
- except:
54
- save_msg.setText("Cannot save to %s" % self.save_path)
55
- save_msg.exec()
56
-
57
- elif self.save_path.endswith(".ply"):
58
- print("Not implment yet!")
59
- else:
60
- print("Not supported cloud file type!")
61
-
62
- def load(self, file):
63
- print("Try to load %s ..." % file)
64
- pc = PointCloud.from_path(file).pc_data
65
-
66
- try:
67
- color = pc["rgb"].astype(np.uint32)
68
- self.setColorMode('RGB')
69
- except ValueError:
70
- try:
71
- color = pc["intensity"].astype(np.uint32)
72
- self.setColorMode('I')
73
- except ValueError:
74
- color = pc['z'].astype(np.uint32)
75
- self.setColorMode('#FFFFFF')
76
-
77
- cloud = np.rec.fromarrays(
78
- [np.stack([pc["x"], pc["y"], pc["z"]], axis=1), color],
79
- dtype=self.data_type)
80
- self.setData(data=cloud)
81
-
82
- def setPath(self, path):
83
- self.save_path = path