-
-
Save notaTeapot/5feea53dccc921ea6af88a4d222e1e2b to your computer and use it in GitHub Desktop.
# Partially Working Error on Exit | |
from PySide2 import QtWidgets, QtGui,QtCore | |
import open3d as o3d | |
import win32gui | |
import sys | |
import threading | |
import time | |
class Worker(QtCore.QObject): | |
def run(self,vis): | |
vis.run() | |
class MainWindow(QtWidgets.QMainWindow): | |
def __init__(self): | |
super(MainWindow, self).__init__() | |
widget = QtWidgets.QWidget() | |
layout = QtWidgets.QGridLayout(widget) | |
self.setCentralWidget(widget) | |
file_path = "C:\\test\test.pcd" | |
self.pcd = o3d.io.read_point_cloud(file_path) | |
self.vis = o3d.visualization.VisualizerWithEditing() | |
self.vis.create_window() | |
self.vis.add_geometry(self.pcd) | |
hwnd = win32gui.FindWindowEx(0, 0, None, "Open3D - free view") | |
self.window = QtGui.QWindow.fromWinId(hwnd) | |
self.windowcontainer = self.createWindowContainer(self.window, widget) | |
layout.addWidget(self.windowcontainer, 0, 0) | |
self.thread = QtCore.QThread() | |
self.worker = Worker() | |
self.thread.started.connect(lambda: self.worker.run(self.vis)) | |
self.thread.start() | |
timer = QtCore.QTimer(self) | |
timer.timeout.connect(self.blub) | |
timer.start(100) | |
#print("starting vis") | |
btn = QtWidgets.QPushButton(text="test") | |
btn.clicked.connect(lambda: print("Button pressed!")) | |
layout.addWidget(btn) | |
def blub(self): | |
#Function to keep PySide eventloop running | |
pass | |
def start_vis(self): | |
print("thread start") | |
self.vis.run() | |
print("thread end") | |
def update_vis(self): | |
#self.vis.update_geometry() | |
self.vis.poll_events() | |
self.vis.update_renderer() | |
if __name__ == '__main__': | |
app = QtWidgets.QApplication(sys.argv) | |
form = MainWindow() | |
form.setWindowTitle('o3d Embed') | |
form.setGeometry(100, 100, 600, 500) | |
form.show() | |
sys.exit(app.exec_()) |
I want to press btn to add another geometry, but run() will block the current thread. So I didn't succeed, Do you know how to solve it, thank you very much!
Overriding the closeEvent
of your MainWindow
could fix your Error on Exit
def closeEvent(self, event):
self.vis.destroy_window()
self.thread.quit()
event.accept()
Overriding the
closeEvent
of yourMainWindow
could fix your Error on Exitdef closeEvent(self, event): self.vis.destroy_window() self.thread.quit() event.accept()
yes, this works 👍
And you can add visible=False
as parameter to self.vis.create_window(visible=False)
to get rid of the open3D window flash on startup.
I want to press btn to add another geometry, but run() will block the current thread. So I didn't succeed, Do you know how to solve it, thank you very much!
I have the same problem, did you find the solution yet?
Thanks for your help.
Could anyone hint me on how this code could be changed to visualize a .OBJ or .PLY file with texture? (still using VisualizerWithEditing() within a Qt widget)
Here is what I have been able to achieve (and not):
-
using o3d.io.read_triangle_mesh() on a .PLY file instead of o3d.io.read_point_cloud() for a .PCD brings the object with texture in the visualizer, but then clicking does not do anything.
-
using o3d.io.read_triangle_mesh() on a .OBJ brings the object but does not load the texture, and again clicking does not do anything.
-
using o3d.io.read_triangle_model() yields an error as self.vis.add_geometry() does not support "triangle_model" object type. self.vis Class only has add_geometry(), and does not support add_model() as some other open3d classes have.
I am thinking about finding a way to convert the OBJ or PLY object to a point-cloud (with texture) in open3d and then loading it into the visualizer as a workaround if no other way exists (and need to figure out how to perform that conversion).
[Edit] I converted a textured mesh (.PLY) to point-count simply with the following:
filepath1 = 'my_filepath_to_my_ply_file'
obj1 = o3d.io.read_triangle_mesh(filepath1)
pcd = o3d.geometry.PointCloud()
pcd.points = obj1.vertices
pcd.colors = obj1.vertex_colors
pcd.normals = obj1.vertex_normals
It is not ideal as clicking between points results in "no click", or may hit a point located on a face behind the intended face.
It also seems that VisualizerWithEditing() ignores further add_geometry() calls, so it is not possible to have more than one object in the visualizer.
I am thinking it may then be best to use the standard open3d visualizer and use ray_casting to identify the location where the user clicked.
https://www.open3d.org/docs/release/tutorial/geometry/ray_casting.html#Creating-a-virtual-point-cloud
Anyone tried doing that?
I want to press btn to add another geometry, but run() will block the current thread. So I didn't succeed, Do you know how to solve it, thank you very much!
I solved it by using open3d.visualization.Visualizer() instead of self.vis = o3d.visualization.VisualizerWithEditing()
VisualizerWithEditing() can only render one geometry at a time even though you succeeded in adding it whereas Visualizer can only render more than one geometry.
not working on mac or linux, if use hwnd = widget.winId() working partially