Open3D
Open3D copied to clipboard
Scene disapears when clicked on
trafficstars
Checklist
- [X] I have searched for similar issues.
- [X] For Python issues, I have tested with the latest development wheel.
- [X] I have checked the release documentation and the latest documentation (for
masterbranch).
Describe the issue
In the below code, when I click on the SceneWidget, it disapears.
To reproduce:
python3 main.py- Click on
Start mapping - Left-click on the scene (the control panel also disapear somewhere)
- Scene is gone ...
Steps to reproduce the bug
import open3d.visualization.gui as gui
import open3d.visualization.rendering as rendering
######################################
## Object to handle a single camera ##
######################################
class Zed:
zed = None
label = ''
class MultiCameraWindow:
MENU_SHOW_SETTINGS = 1
MENU_QUIT = 3
def __init__(self):
self.window = gui.Application.instance.create_window("Zed Multi-cameras")
w = self.window
em = w.theme.font_size
# Create the menu. The menu is global (because the macOS menu is global),
# so only create it once.
if gui.Application.instance.menubar is None:
menubar = gui.Menu()
menu_settings = gui.Menu()
menu_settings.add_item("Toggle settings panel", MultiCameraWindow.MENU_SHOW_SETTINGS)
menu_settings.set_checked(MultiCameraWindow.MENU_SHOW_SETTINGS, True)
menu_settings.add_separator()
menu_settings.add_item("Quit", MultiCameraWindow.MENU_QUIT)
menubar.add_menu("File", menu_settings)
gui.Application.instance.menubar = menubar
# Each window needs to know what to do with the menu items, so we need
# to tell the window how to handle menu items.
w.set_on_menu_item_activated(MultiCameraWindow.MENU_SHOW_SETTINGS, self._on_menu_toggle)
w.set_on_menu_item_activated(MultiCameraWindow.MENU_QUIT, self._on_menu_quit)
#######################
## Display ##
#######################
self._mainlayout = gui.Vert()
# 3D scene
self._scene = gui.SceneWidget()
self._scene.scene = rendering.Open3DScene(w.renderer)
self._scene.scene.set_background([255, 255, 0, 255])
self._scene.scene.show_skybox(True)
self._scene.scene.show_axes(True)
self._scene.visible = False
self._scene.set_view_controls(gui.SceneWidget.Controls.ROTATE_CAMERA)
self._mainlayout.add_child(self._scene)
# Camera preview (during calibration)
self._camerasgrid = gui.VGrid(2, 0.25 * em)
self._camerasgrid.enabled = False
self._camera_previews = []
for i in range(4):
self._camera_previews.append(gui.WidgetProxy())
self._camera_previews[i].set_widget(gui.ImageWidget("./sample.jpg"))
self._camerasgrid.add_child(self._camera_previews[i])
self._mainlayout.add_child(self._camerasgrid)
#######################
## Control panel ##
#######################
self._controlpanel = gui.Vert(0, gui.Margins(0.5 * em, 0.5 * em, 0.5 * em, 0.5 * em))
#######################
## Cameras ##
#######################
cameras_collapse = gui.CollapsableVert("Cameras", 0.33 * em, gui.Margins(em, 0, 0, 0))
cameras_collapse.set_is_open(True)
# Add a list of cameras
self._cameras_list = gui.ListView()
self._cameras_list.set_items([])
self._cameras_list.set_max_visible_items(4)
cameras_collapse.add_child(self._cameras_list)
# Add button
cameras_refresh = gui.Button('Refresh')
cameras_refresh.set_on_clicked(self._on_cameras_reset)
cameras_collapse.add_child(cameras_refresh)
# Attach to control panel
self._controlpanel.add_child(cameras_collapse)
#######################
## View control ##
#######################
view_collapse = gui.CollapsableVert("Scene", 0.33 * em, gui.Margins(em, 0, 0, 0))
view_collapse.set_is_open(False)
# View controls
view_controls = gui.Horiz(spacing=5)
view_controls.add_child(gui.Label('View controls '))
view_controls_list = gui.Combobox()
view_controls_list.add_item("Fly")
view_controls_list.add_item("Follow camera")
view_controls_list.selected_index = view_controls_list.selected_index + 2
view_controls_list.set_on_selection_changed(self._on_viewcontrol_change)
view_controls.add_child(view_controls_list)
view_collapse.add_child(view_controls)
# Attach to control panel
self._controlpanel.add_child(view_collapse)
#######################
## Calibration ##
#######################
calibration_collapse = gui.CollapsableVert("Calibration", 0.33 * em, gui.Margins(em, 0, 0, 0))
calibration_collapse.set_is_open(False)
# Add toggle
calibration_toggle = gui.Checkbox("Enable calibration")
calibration_toggle.set_on_checked(self._on_toggle_calibration)
calibration_collapse.add_child(calibration_toggle)
# Add button
calibration_reset = gui.Button('Calibrate with ArUco')
calibration_reset.set_on_clicked(self._on_reset_calibration)
calibration_collapse.add_child(calibration_reset)
# Attach to control panel
self._controlpanel.add_child(calibration_collapse)
#######################
## Zed settings ##
#######################
settings_collapse = gui.CollapsableVert("Settings", 0.33 * em, gui.Margins(em, 0, 0, 0))
settings_collapse.set_is_open(False)
# Add resolution and FPS
settings_resolution = gui.Horiz(spacing=5)
settings_resolution.add_child(gui.Label('Resolution '))
settings_resolution_list = gui.Combobox()
settings_resolution_list.add_item("VGA")
settings_resolution_list.add_item("HD720")
settings_resolution_list.add_item("HD1080")
settings_resolution_list.add_item("HD2K")
settings_resolution_list.selected_index = settings_resolution_list.selected_index + 3
settings_resolution_list.set_on_selection_changed(self._on_resolution_change)
settings_resolution.add_child(settings_resolution_list)
settings_resolution.add_child(gui.Label('FPS '))
settings_fps = gui.NumberEdit(gui.NumberEdit.INT)
settings_fps.int_value = 30
settings_fps.set_limits(1, 60)
settings_resolution.add_child(settings_fps)
settings_collapse.add_child(settings_resolution)
# Add Depth mode
settings_depthmode = gui.Horiz(spacing=5)
settings_depthmode.add_child(gui.Label('Depth mode '))
settings_depthmode_list = gui.Combobox()
settings_depthmode_list.add_item("NEURAL")
settings_depthmode_list.add_item("ULTRA")
settings_depthmode_list.add_item("QUALITY")
settings_depthmode_list.add_item("PERFORMANCE")
settings_depthmode_list.add_item("NONE")
settings_depthmode_list.selected_index = settings_depthmode_list.selected_index + 2
settings_depthmode_list.set_on_selection_changed(self._on_depthmode_change)
settings_depthmode.add_child(settings_depthmode_list)
settings_collapse.add_child(settings_depthmode)
# Add depth minimum distance
settings_depthdistance = gui.Horiz(spacing=5)
settings_depthdistance.add_child(gui.Label('Depth min. distance (mm) '))
settings_depthdistance_mm = gui.NumberEdit(gui.NumberEdit.INT)
settings_depthdistance_mm.int_value = 200
settings_depthdistance_mm.set_limits(200, 700)
settings_depthdistance.add_child(settings_depthdistance_mm)
settings_collapse.add_child(settings_depthdistance)
# Attach to control panel
self._controlpanel.add_child(settings_collapse)
#######################
## Mapping ##
#######################
mapping_collapse = gui.CollapsableVert("Mapping", 0.33 * em, gui.Margins(em, 0, 0, 0))
mapping_collapse.set_is_open(False)
# Point cloud or Mesh
mapping_type = gui.Horiz(spacing=5)
mapping_type.add_child(gui.Label('Type '))
mapping_type_list = gui.Combobox()
mapping_type_list.add_item("Point cloud (PLY)")
mapping_type_list.add_item("Mesh (OBJ)")
mapping_type_list.selected_index = mapping_type_list.selected_index + 2
mapping_type_list.set_on_selection_changed(self._on_mappingrange_change)
mapping_type.add_child(mapping_type_list)
mapping_collapse.add_child(mapping_type)
# Range
mapping_range = gui.Horiz(spacing=5)
mapping_range.add_child(gui.Label('Range '))
mapping_range_list = gui.Combobox()
mapping_range_list.add_item("AUTO")
mapping_range_list.add_item("LONG")
mapping_range_list.add_item("MEDIUM")
mapping_range_list.add_item("SHORT")
mapping_range_list.selected_index = mapping_range_list.selected_index + 2
mapping_range_list.set_on_selection_changed(self._on_mappingrange_change)
mapping_range.add_child(mapping_range_list)
mapping_collapse.add_child(mapping_range)
# Resolution
mapping_resolution = gui.Horiz(spacing=5)
mapping_resolution.add_child(gui.Label('Resolution '))
mapping_resolution_list = gui.Combobox()
mapping_resolution_list.add_item("HIGH")
mapping_resolution_list.add_item("MEDIUM")
mapping_resolution_list.add_item("LOW")
mapping_resolution_list.selected_index = mapping_resolution_list.selected_index + 2
mapping_resolution_list.set_on_selection_changed(self._on_mappingresolution_change)
mapping_resolution.add_child(mapping_resolution_list)
mapping_collapse.add_child(mapping_resolution)
# Attach to control panel
self._controlpanel.add_child(mapping_collapse)
#######################
## Save ##
#######################
save_collapse = gui.CollapsableVert("Save", 0.33 * em, gui.Margins(em, 0, 0, 0.25 * em))
save_collapse.set_is_open(False)
# SVO
self._save_toggle_svo = gui.ToggleSwitch("Save SVO")
save_collapse.add_child(self._save_toggle_svo)
# Area
self._save_toggle_area = gui.ToggleSwitch("Save Area")
save_collapse.add_child(self._save_toggle_area)
# PLY or OBJ
self._save_toggle_map = gui.ToggleSwitch("Save PLY or OBJ")
save_collapse.add_child(self._save_toggle_map)
# Attach to control panel
self._controlpanel.add_child(save_collapse)
#######################
## Controls ##
#######################
self._controls = gui.Horiz(0, gui.Margins(0.25 * em, 0.25 * em, 0.25 * em, 0.25 * em))
self._controls.background_color = gui.Color(0.9, 0.9, 0.9)
# Start / Stop
self._controls_start = gui.Button("Start mapping")
self._controls_start.set_on_clicked(self._on_start)
self._controls.add_child(self._controls_start)
self._controls.add_stretch()
# Save
self._controls_save = gui.Button("Save")
self._controls_save.enabled = False
self._controls_save.set_on_clicked(self._on_save)
self._controls.add_child(self._controls_save)
#######################
## Global ##
#######################
w.set_on_layout(self._on_layout)
w.add_child(self._mainlayout)
w.add_child(self._controls)
w.add_child(self._controlpanel)
#######################
## Initialization ##
#######################
self._cameras_list.set_items(list(map(lambda x:x.label, self._zed_load_cameras())))
# TODO : Load configuration from file
def _on_layout(self, layout_context):
r = self.window.content_rect
controlpanel_width = 21 * layout_context.theme.font_size
controlpanel_height = min(r.height, self._controlpanel.calc_preferred_size(layout_context, gui.Widget.Constraints()).height)
self._controlpanel.frame = gui.Rect(r.get_right() - controlpanel_width, r.y, controlpanel_width, controlpanel_height)
controls_height = 2.8 * layout_context.theme.font_size
self._controls.frame = gui.Rect(r.x, r.get_bottom() - controls_height, r.width, controls_height)
self._mainlayout.frame = self._camerasgrid.frame = self._scene.frame = gui.Rect(r.x, r.y, r.width, r.height - controls_height)
def _on_menu_toggle(self, force=None):
self._controlpanel.visible = force if force is not None else not self._controlpanel.visible
gui.Application.instance.menubar.set_checked(MultiCameraWindow.MENU_SHOW_SETTINGS, self._controlpanel.visible)
def _on_menu_quit(self):
gui.Application.instance.quit()
def _on_viewcontrol_change(self, new_val, is_dbl_click):
print(new_val)
def _on_cameras_reset(self):
self._cameras_list.set_items(list(map(lambda x:x.label, self._zed_load_cameras())))
def _on_reset_calibration(self):
self.show_message_dialog("There might be a problem...", "Reset")
def _on_toggle_calibration(self, is_checked):
if is_checked:
text = "Sorry, effects are unimplemented"
else:
text = "Good choice"
self.show_message_dialog("There might be a problem...", text)
def _on_resolution_change(self, new_val, is_dbl_click):
print(new_val)
def _on_depthmode_change(self, new_val, is_dbl_click):
print(new_val)
def _on_mappingrange_change(self, new_val, is_dbl_click):
print(new_val)
def _on_mappingresolution_change(self, new_val, is_dbl_click):
print(new_val)
def _on_start(self):
if self._scene.visible == False:
self._camerasgrid.visible = False
self._scene.visible = True
self._on_menu_toggle(False)
self._controls_start.text = "Pause mapping"
self._zed_start_mapping()
else:
self._camerasgrid.visible = True
self._scene.visible = False
self._controls_start.text = "Start mapping"
self._controls_save.enabled = True
self._zed_stop_mapping()
def _on_save(self):
self._zed_save()
def _on_exit(self):
gui.Application.instance.quit()
# This function is essentially the same as window.show_message_box(),
# so for something this simple just use that, but it illustrates making a
# dialog.
def show_message_dialog(self, title, message):
# A Dialog is just a widget, so you make its child a layout just like
# a Window.
dlg = gui.Dialog(title)
# Add the message text
em = self.window.theme.font_size
dlg_layout = gui.Vert(em, gui.Margins(em, em, em, em))
dlg_layout.add_child(gui.Label(message))
# Add the Ok button. We need to define a callback function to handle
# the click.
ok_button = gui.Button("Ok")
ok_button.set_on_clicked(self._on_dialog_ok)
# We want the Ok button to be an the right side, so we need to add
# a stretch item to the layout, otherwise the button will be the size
# of the entire row. A stretch item takes up as much space as it can,
# which forces the button to be its minimum size.
button_layout = gui.Horiz()
button_layout.add_stretch()
button_layout.add_child(ok_button)
# Add the button layout,
dlg_layout.add_child(button_layout)
# ... then add the layout as the child of the Dialog
dlg.add_child(dlg_layout)
# ... and now we can show the dialog
self.window.show_dialog(dlg)
def _on_dialog_ok(self):
self.window.close_dialog()
def _zed_load_cameras(self):
z1 = Zed()
z1.label = "ZED2i_0000000"
z2 = Zed()
z2.label = "ZED2i_0000001"
z3 = Zed()
z3.label = "ZED2i_0000002"
z4 = Zed()
z4.label = "ZED2i_0000003"
self._zeds = [z1, z2, z3, z4]
return self._zeds
def _zed_start_mapping(self):
print('Start mapping')
def _zed_stop_mapping(self):
print('Stop mapping')
def _zed_save(self):
print('Save')
if self._save_toggle_svo.is_on:
print('Save SVO')
if self._save_toggle_area.is_on:
print('Save Area')
if self._save_toggle_map.is_on:
print('Save Map')
def main():
gui.Application.instance.initialize()
w = MultiCameraWindow()
gui.Application.instance.run()
if __name__ == "__main__":
main()
Error message
No message
Expected behavior
The scene should be displayed.
Open3D, Python and System information
- Operating system: Jetson Xavier NX JP 4.6.1
- Python version: Python 3.7
- Open3D version: output from python: 0.15.2
- System architecture: Jetson
- Is this a remote workstation?: yes or no
- How did you install Open3D?: build from source
- Compiler version (if built from source): gcc 7.5.0
Additional information
No response
I had this issue and it got solved when I assigned the SceneWidget as a direct child of the window and not as a child of a layout.
Seems weird but it solved my issue.
For maintainers, the above issue can be easily reproduced using code from PR itself - https://github.com/isl-org/Open3D/pull/3212