isl-org / Open3D

Open3D: A Modern Library for 3D Data Processing
http://www.open3d.org
Other
11.44k stars 2.31k forks source link

window quits when I click the button #6266

Closed 0i0i0i closed 1 year ago

0i0i0i commented 1 year ago

Checklist

Describe the issue

I have a window and two scenes in it to display objects, and with one button. When I resized the window, it shows strange residue of the previous frame. So I tried to refresh the window at some point. One way is to refresh it when I click the button (the following code), but when I click the button, I tried to refresh the window, but the window just quits and the program quits. Any idea?

Steps to reproduce the bug

import open3d as o3d
import open3d.visualization.gui as gui
import open3d.visualization.rendering as rendering
import numpy as np

class App:

    MENU_OPEN = 1   #

    MENU_SHOW = 5   # 

    MENU_QUIT = 20
    MENU_ABOUT = 21

    show = True

    def __init__(self): #
        gui.Application.instance.initialize()

        self.window = gui.Application.instance.create_window("X System",1920,1080)
        w = self.window
        em = w.theme.font_size

        # render window
        self._scene = gui.SceneWidget()
        self._scene.scene = rendering.Open3DScene(w.renderer)

        self._scene2 = gui.SceneWidget()
        self._scene2.scene = rendering.Open3DScene(w.renderer)

        # panel
        self._pannel = gui.CollapsableVert('panel',0, gui.Margins(0.25*em,0.25*em,0.25*em,0.25*em))     
        for i in range(15):
            self._pannel.add_child(gui.Label(f"{i}-th label"))

        self._button = gui.Button("button")
        self._button.set_on_clicked(self._on_button_clicked)

        # layout callback

        w.add_child(self._scene)
        w.add_child(self._scene2)
        w.add_child(self._pannel)
        w.add_child(self._button)
        w.set_on_layout(self._on_layout)

        # --------  for windows menu  ------------
        if gui.Application.instance.menubar is None:
            # file  menu
            file_menu = gui.Menu()
            file_menu.add_item("open",App.MENU_OPEN)
            file_menu.add_separator()
            file_menu.add_item("Quit",App.MENU_QUIT)

            #   show menu
            show_menu = gui.Menu()
            show_menu.add_item("Show Geometry",App.MENU_SHOW)
            show_menu.set_checked(App.MENU_SHOW,True)

            # help  menu
            help_menu = gui.Menu()
            help_menu.add_item("About",App.MENU_ABOUT)
            help_menu.set_enabled(App.MENU_ABOUT,False)

            # menu
            menu = gui.Menu()
            menu.add_menu("File",file_menu)
            menu.add_menu("Show",show_menu)
            menu.add_menu("Help",help_menu)

            gui.Application.instance.menubar = menu

            #-register menu callback
            w.set_on_menu_item_activated(App.MENU_OPEN,self._menu_open)
            w.set_on_menu_item_activated(App.MENU_QUIT,self._menu_quit)
            w.set_on_menu_item_activated(App.MENU_SHOW,self._menu_show)

    # open3d 
    def _menu_open(self):
        # file picker
        file_picker = gui.FileDialog(gui.FileDialog.OPEN,"Select file...",self.window.theme)

        # file  filter
        file_picker.add_filter('.ply', 'ply model files')
        file_picker.add_filter('', 'All files')

        # set path
        file_picker.set_path('./')

        # set callback
        file_picker.set_on_cancel(self._on_cancel)
        file_picker.set_on_done(self._on_done)

        # show file picker dialog
        self.window.show_dialog(file_picker)

    def _on_cancel(self):
        # close file picker dialog
        self.window.close_dialog()

    def _on_done(self, filename): 
        self.window.close_dialog()
        self.load(filename)

    def load(self, file):
        # load  
        global mesh
        mesh = o3d.io.read_triangle_mesh(file)
        mesh.compute_vertex_normals()
        # define material
        material = rendering.MaterialRecord()
        material.shader = 'defaultLit'

        # add model to scene
        self._scene.scene.add_geometry('bunny', mesh, material)
        # self._scene.scene.add_geometry('bunny',mesh,material)
        bounds = mesh.get_axis_aligned_bounding_box()
        self._scene.setup_camera(60,bounds,bounds.get_center())

        # add  model to scene2
        self._scene2.scene.add_geometry('bunny',mesh,material)
        bounds = mesh.get_axis_aligned_bounding_box()
        self._scene2.setup_camera(60,bounds,bounds.get_center())
        # mesh.translate([100,200,500])

        # refresh the window
        self._scene.force_redraw()

        self._scene2.force_redraw()

    # quit
    def _menu_quit(self):
        self.window.close()

    # show and hide the model
    def _menu_show(self):
        self.show = not self.show
        gui.Application.instance.menubar.set_checked(App.MENU_SHOW,self.show)

        self._scene.scene.show_geometry('bunny',self.show)

    def _on_button_clicked(self):
        #if 'bunny' in self._scene.scene.geometry:
        # global mesh
        # mesh.translate([100, 200, 300])
        # self._scene.scene.update_geometry(mesh)  # Update the geometry in the scene
        # self._scene.force_redraw()  # Force a redraw of the scene
        print('aaa')
        #refresh the window
        self.window.refresh()

    def _on_layout(self, layout_context):
        #   in on_layout callback, one should set the position of all the children (position + size),
        #   after finish, one should call the base class's on_layout to layout the children's children

        r = self.window.content_rect    # get the content rect
        self._scene.frame = r
        self._scene2.frame = r

        #scene1:
        scene_pref = self._scene.calc_preferred_size(   # calculate the height
        layout_context, gui.Widget.Constraints())    # calculate the width
        print(r.get_bottom())
        print(scene_pref.width)
        # self._scene.frame = gui.Rect(r.x,r.get_bottom()-scene_pref.height, scene_pref.width,scene_pref.height)  # 设置框架
        self._scene.frame =gui.Rect(r.x, r.y, r.width / 2-200, r.height)

        #scene2:
        scene_pref2 = self._scene2.calc_preferred_size(   # calculate the height
        layout_context, gui.Widget.Constraints())   # calculate the width
        print(r.get_bottom())
        print(scene_pref2.width)
        # self._scene.frame = gui.Rect(r.x,r.get_bottom()-scene_pref.height, scene_pref.width,scene_pref.height)  # 设置框架
        self._scene2.frame =gui.Rect(r.x + r.width / 2 -200+ 3, r.y, r.width / 2-200, r.height)

        #pannel:
        pannel_width = 17*layout_context.theme.font_size #  size 17 
        pannel_height = min(    # limit the hei ght
            r.height, self._pannel.calc_preferred_size(      
                layout_context, gui.Widget.Constraints()).height    
        )   
        self._pannel.frame = gui.Rect(r.get_right()-pannel_width,r.y,pannel_width,pannel_height)   

        #button:
        button_pref = self._button.calc_preferred_size(       
            layout_context, gui.Widget.Constraints())    
        self._button.frame = gui.Rect(r.x,r.get_bottom()-button_pref.height, button_pref.width,button_pref.height)  # 设置框架

    def run(self):        
        gui.Application.instance.run()

if __name__ == "__main__":
    app = App()
    app.run()

Error message

No error message shown

Expected behavior

the window just refresh

Open3D, Python and System information

Windows 10 64-bit
Python 3.8 
- Open3D version: 0.17.0
- System architecture: x86 
- Is this a remote workstation?: no
- How did you install Open3D?: pip 
- Compiler version (if built from source): gcc 7.5

Additional information

No response

theNded commented 1 year ago

Closed as a duplicate of #6267

0i0i0i commented 1 year ago

The code might be same as the #6267. But the issue described there is different and was not mentioned in the #6267 thread.