为什么当我左键单击 window 时 Open3d Visualization 消失了?
Why does Open3d Visualization disappear when I left click the window?
我尝试在 python 中编写一个简单的应用程序,它在右侧查看 3d 网格,并在单个 window.
中在左侧显示一些用户输入
我使用 SceneWidget 可视化网格并将其添加到水平 gui 元素。我还向该 gui 元素添加了一个文件选择器,然后将 gui 元素添加到 window。
到目前为止一切顺利,它似乎按预期工作,但只要我在 window 内单击鼠标左键,可视化就会消失,没有任何错误消息。
有谁知道为什么并且可以帮助我吗?
代码如下:
import os.path
import sys
import open3d as o3d
import open3d.visualization.gui as gui
import open3d.visualization.rendering as rendering
print("Project")
print("python version", sys.version)
print("open3d version", o3d.__version__)
class WindowApp:
def __init__(self):
self.window = gui.Application.instance.create_window("Project", 1400, 900)
w = self.window
# member variables
self.model_dir = ""
self.model_name = ""
em = w.theme.font_size
layout = gui.Horiz(0, gui.Margins(0.5 * em, 0.5 * em, 0.5 * em, 0.5 * em))
# 3D Widget
_widget3d = gui.SceneWidget()
_widget3d.scene = rendering.Open3DScene(w.renderer)
_widget3d.set_view_controls(gui.SceneWidget.Controls.ROTATE_CAMERA)
mesh = o3d.geometry.TriangleMesh.create_sphere()
mesh.compute_vertex_normals()
material = rendering.MaterialRecord()
material.shader = "defaultLit"
_widget3d.scene.add_geometry('mesh', mesh, material)
_widget3d.scene.set_background([200, 0, 0, 200]) # not working?!
_widget3d.scene.camera.look_at([0, 0, 0], [1, 1, 1], [0, 0, 1])
_widget3d.set_on_mouse(self._on_mouse_widget3d)
# gui layout
gui_layout = gui.Vert(0, gui.Margins(0.5 * em, 0.5 * em, 0.5 * em, 0.5 * em))
# File-chooser widget
self._fileedit = gui.TextEdit()
filedlgbutton = gui.Button("...")
filedlgbutton.horizontal_padding_em = 0.5
filedlgbutton.vertical_padding_em = 0
filedlgbutton.set_on_clicked(self._on_filedlg_button)
fileedit_layout = gui.Horiz()
fileedit_layout.add_child(gui.Label("Model file"))
fileedit_layout.add_child(self._fileedit)
fileedit_layout.add_fixed(0.25 * em)
fileedit_layout.add_child(filedlgbutton)
# add to the top-level (vertical) layout
gui_layout.add_child(fileedit_layout)
layout.add_child(gui_layout)
layout.add_child(_widget3d)
w.add_child(layout)
def _on_mouse_widget3d(self, event):
print(event.type)
return gui.Widget.EventCallbackResult.IGNORED
def _on_filedlg_button(self):
filedlg = gui.FileDialog(gui.FileDialog.OPEN, "Select file",
self.window.theme)
filedlg.add_filter(".obj .ply .stl", "Triangle mesh (.obj, .ply, .stl)")
filedlg.add_filter("", "All files")
filedlg.set_on_cancel(self._on_filedlg_cancel)
filedlg.set_on_done(self._on_filedlg_done)
self.window.show_dialog(filedlg)
def _on_filedlg_cancel(self):
self.window.close_dialog()
def _on_filedlg_done(self, path):
self._fileedit.text_value = path
self.model_dir = os.path.normpath(path)
# load model
self.window.close_dialog()
def main():
gui.Application.instance.initialize()
w = WindowApp()
gui.Application.instance.run()
if __name__ == "__main__":
main()
我使用 open3d 库版本 0.15.1 和 python3.9.
注意 - 如果我将 SceneWidget 直接添加到 window 它可以工作,但是我不能在左边有 gui。
有人对此有解决方案吗?
最后我找到了解决办法:
将 Scenewidget 添加到 gui 容器似乎不起作用。但是将它封装在一个框架内并将其移动到右侧并直接将其添加到 window 工作。
_widget3d.frame = gui.Rect(500, w.content_rect.y, 900, w.content_rect.height)
也可以用类似的方式为 gui 创建框架。
这里是任何感兴趣的人的工作代码:
class WindowApp:
def __init__(self):
self.window = gui.Application.instance.create_window("Spinnables", 1400, 900)
w = self.window
# member variables
self.model_dir = ""
self.model_name = ""
em = w.theme.font_size
# 3D Widget
_widget3d = gui.SceneWidget()
_widget3d.scene = rendering.Open3DScene(w.renderer)
_widget3d.set_view_controls(gui.SceneWidget.Controls.ROTATE_CAMERA)
# create a frame that encapsulates the Scenewidget
_widget3d.frame = gui.Rect(500, w.content_rect.y,
900, w.content_rect.height)
mesh = o3d.geometry.TriangleMesh.create_sphere()
mesh.compute_vertex_normals()
material = rendering.MaterialRecord()
material.shader = "defaultLit"
_widget3d.scene.add_geometry('mesh', mesh, material)
_widget3d.scene.set_background([200, 0, 0, 200]) # not working?!
_widget3d.scene.camera.look_at([0, 0, 0], [1, 1, 1], [0, 0, 1])
_widget3d.set_on_mouse(self._on_mouse_widget3d)
# gui layout
gui_layout = gui.Vert(0, gui.Margins(0.5 * em, 0.5 * em, 0.5 * em, 0.5 * em))
# create frame that encapsulates the gui
gui_layout.frame = gui.Rect(w.content_rect.x, w.content_rect.y,
500, w.content_rect.height)
# File-chooser widget
self._fileedit = gui.TextEdit()
filedlgbutton = gui.Button("...")
filedlgbutton.horizontal_padding_em = 0.5
filedlgbutton.vertical_padding_em = 0
filedlgbutton.set_on_clicked(self._on_filedlg_button)
fileedit_layout = gui.Horiz()
fileedit_layout.add_child(gui.Label("Model file"))
fileedit_layout.add_child(self._fileedit)
fileedit_layout.add_fixed(0.25 * em)
fileedit_layout.add_child(filedlgbutton)
# add to the top-level (vertical) layout
gui_layout.add_child(fileedit_layout)
w.add_child(gui_layout)
w.add_child(_widget3d)
我尝试在 python 中编写一个简单的应用程序,它在右侧查看 3d 网格,并在单个 window.
中在左侧显示一些用户输入我使用 SceneWidget 可视化网格并将其添加到水平 gui 元素。我还向该 gui 元素添加了一个文件选择器,然后将 gui 元素添加到 window。
到目前为止一切顺利,它似乎按预期工作,但只要我在 window 内单击鼠标左键,可视化就会消失,没有任何错误消息。
有谁知道为什么并且可以帮助我吗?
代码如下:
import os.path
import sys
import open3d as o3d
import open3d.visualization.gui as gui
import open3d.visualization.rendering as rendering
print("Project")
print("python version", sys.version)
print("open3d version", o3d.__version__)
class WindowApp:
def __init__(self):
self.window = gui.Application.instance.create_window("Project", 1400, 900)
w = self.window
# member variables
self.model_dir = ""
self.model_name = ""
em = w.theme.font_size
layout = gui.Horiz(0, gui.Margins(0.5 * em, 0.5 * em, 0.5 * em, 0.5 * em))
# 3D Widget
_widget3d = gui.SceneWidget()
_widget3d.scene = rendering.Open3DScene(w.renderer)
_widget3d.set_view_controls(gui.SceneWidget.Controls.ROTATE_CAMERA)
mesh = o3d.geometry.TriangleMesh.create_sphere()
mesh.compute_vertex_normals()
material = rendering.MaterialRecord()
material.shader = "defaultLit"
_widget3d.scene.add_geometry('mesh', mesh, material)
_widget3d.scene.set_background([200, 0, 0, 200]) # not working?!
_widget3d.scene.camera.look_at([0, 0, 0], [1, 1, 1], [0, 0, 1])
_widget3d.set_on_mouse(self._on_mouse_widget3d)
# gui layout
gui_layout = gui.Vert(0, gui.Margins(0.5 * em, 0.5 * em, 0.5 * em, 0.5 * em))
# File-chooser widget
self._fileedit = gui.TextEdit()
filedlgbutton = gui.Button("...")
filedlgbutton.horizontal_padding_em = 0.5
filedlgbutton.vertical_padding_em = 0
filedlgbutton.set_on_clicked(self._on_filedlg_button)
fileedit_layout = gui.Horiz()
fileedit_layout.add_child(gui.Label("Model file"))
fileedit_layout.add_child(self._fileedit)
fileedit_layout.add_fixed(0.25 * em)
fileedit_layout.add_child(filedlgbutton)
# add to the top-level (vertical) layout
gui_layout.add_child(fileedit_layout)
layout.add_child(gui_layout)
layout.add_child(_widget3d)
w.add_child(layout)
def _on_mouse_widget3d(self, event):
print(event.type)
return gui.Widget.EventCallbackResult.IGNORED
def _on_filedlg_button(self):
filedlg = gui.FileDialog(gui.FileDialog.OPEN, "Select file",
self.window.theme)
filedlg.add_filter(".obj .ply .stl", "Triangle mesh (.obj, .ply, .stl)")
filedlg.add_filter("", "All files")
filedlg.set_on_cancel(self._on_filedlg_cancel)
filedlg.set_on_done(self._on_filedlg_done)
self.window.show_dialog(filedlg)
def _on_filedlg_cancel(self):
self.window.close_dialog()
def _on_filedlg_done(self, path):
self._fileedit.text_value = path
self.model_dir = os.path.normpath(path)
# load model
self.window.close_dialog()
def main():
gui.Application.instance.initialize()
w = WindowApp()
gui.Application.instance.run()
if __name__ == "__main__":
main()
我使用 open3d 库版本 0.15.1 和 python3.9.
注意 - 如果我将 SceneWidget 直接添加到 window 它可以工作,但是我不能在左边有 gui。
有人对此有解决方案吗?
最后我找到了解决办法:
将 Scenewidget 添加到 gui 容器似乎不起作用。但是将它封装在一个框架内并将其移动到右侧并直接将其添加到 window 工作。
_widget3d.frame = gui.Rect(500, w.content_rect.y, 900, w.content_rect.height)
也可以用类似的方式为 gui 创建框架。
这里是任何感兴趣的人的工作代码:
class WindowApp:
def __init__(self):
self.window = gui.Application.instance.create_window("Spinnables", 1400, 900)
w = self.window
# member variables
self.model_dir = ""
self.model_name = ""
em = w.theme.font_size
# 3D Widget
_widget3d = gui.SceneWidget()
_widget3d.scene = rendering.Open3DScene(w.renderer)
_widget3d.set_view_controls(gui.SceneWidget.Controls.ROTATE_CAMERA)
# create a frame that encapsulates the Scenewidget
_widget3d.frame = gui.Rect(500, w.content_rect.y,
900, w.content_rect.height)
mesh = o3d.geometry.TriangleMesh.create_sphere()
mesh.compute_vertex_normals()
material = rendering.MaterialRecord()
material.shader = "defaultLit"
_widget3d.scene.add_geometry('mesh', mesh, material)
_widget3d.scene.set_background([200, 0, 0, 200]) # not working?!
_widget3d.scene.camera.look_at([0, 0, 0], [1, 1, 1], [0, 0, 1])
_widget3d.set_on_mouse(self._on_mouse_widget3d)
# gui layout
gui_layout = gui.Vert(0, gui.Margins(0.5 * em, 0.5 * em, 0.5 * em, 0.5 * em))
# create frame that encapsulates the gui
gui_layout.frame = gui.Rect(w.content_rect.x, w.content_rect.y,
500, w.content_rect.height)
# File-chooser widget
self._fileedit = gui.TextEdit()
filedlgbutton = gui.Button("...")
filedlgbutton.horizontal_padding_em = 0.5
filedlgbutton.vertical_padding_em = 0
filedlgbutton.set_on_clicked(self._on_filedlg_button)
fileedit_layout = gui.Horiz()
fileedit_layout.add_child(gui.Label("Model file"))
fileedit_layout.add_child(self._fileedit)
fileedit_layout.add_fixed(0.25 * em)
fileedit_layout.add_child(filedlgbutton)
# add to the top-level (vertical) layout
gui_layout.add_child(fileedit_layout)
w.add_child(gui_layout)
w.add_child(_widget3d)