isl-org / Open3D

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

how to move an object in the gui #6267

Open 0i0i0i opened 1 year ago

0i0i0i commented 1 year ago

Checklist

My Question

I want to create a program, with a gui and twe scenes each showing an object in it. I want to move the objects follow some coordinate sequence like playing an animation. But I tried eveything by using the translate function, and it doesn't work. For now, I just want to move the object to another place when i click the button. I guess I need to update the renderer, but I don't know where should I put the update. Can some show me?

`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)

    global w
    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)
    # w.refresh()

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()

`

0i0i0i commented 1 year ago

What does the ui label mean, instead of the question? Does it mean any question belongs to the ui has extremely low priority so it is not been treated as a question?