open3d-gui 通过菜单栏添加几何体

application, window, menu操作. 线程异步, 菜单栏关联回调函数.

application操作

gui.Application.instance.initialize()  # 初始化application
gui.Application.instance.run()  # 运行
gui.Application.instance.quit()  # 停止整个application

window操作

self.window = gui.Application.instance.create_window("Add Spheres Example", 1024, 768)  # 创建window
self.scene = gui.SceneWidget()  # 创建scene
self.window.add_child(self.scene)  # win里面添加scene

menu操作

debug_menu = gui.Menu()  # 增加一个菜单
debug_menu.add_item("Add Sphere", SpheresApp.MENU_SPHERE)  # 绑定数字1
gui.Application.instance.menubar = menu  # 再将次菜单放到菜单栏上
# 不同的按钮,关联不同的回调函数,和qt是一样的
self.window.set_on_menu_item_activated(SpheresApp.MENU_SPHERE,
                                               self._on_menu_sphere)  

 add_geometry.py 

import open3d as o3d
import open3d.visualization.gui as gui
import open3d.visualization.rendering as rendering
import platform
import random
import threading
import time

isMacOS = (platform.system() == "Darwin")  # 是否为苹果开源系统 returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.


# This example shows two methods of adding geometry to an existing scene.
# 1) add via a UI callback (in this case a menu, but a button would be similar,
#    you would call `button.set_on_clicked(self.on_menu_sphere_)` when
#    configuring the button. See `on_menu_sphere()`.
# 2) add asynchronously by polling from another thread. GUI functions must be
#    called from the UI thread, so use Application.post_to_main_thread().
#    See `on_menu_random()`.
# Running the example will show a simple window with a Debug menu item with the
# two different options. The second method will add random spheres for
# 20 seconds, during which time you can be interacting with the scene, rotating,
# etc.
class SpheresApp:
    MENU_SPHERE = 1
    MENU_RANDOM = 2
    MENU_QUIT = 3

    def __init__(self):
        """
        添加菜单操作
        """
        self._id = 0  # 记录球id
        self.window = gui.Application.instance.create_window("Add Spheres Example", 1024, 768)

        self.scene = gui.SceneWidget()
        self.scene.scene = rendering.Open3DScene(self.window.renderer)
        self.scene.scene.set_background([1, 1, 1, 1])
        self.scene.scene.scene.set_sun_light(  # 设置太阳光方向,颜色,亮度
            [-1, -1, -1],  # direction
            [1, 1, 1],  # color
            100000)  # intensity
        self.scene.scene.scene.enable_sun_light(True)
        bbox = o3d.geometry.AxisAlignedBoundingBox([-10, -10, -10],  # 定一个bbox
                                                   [10, 10, 10])
        self.scene.setup_camera(60, bbox, [0, 0, 0])  # (field_of_view, model_bounds, center_of_rotation)

        self.window.add_child(self.scene)  # win里面添加场景

        # The menu is global (because the macOS menu is global), so only create
        # it once, no matter how many windows are created
        if gui.Application.instance.menubar is None:
            if isMacOS: 
                app_menu = gui.Menu()
                app_menu.add_item("Quit", SpheresApp.MENU_QUIT)
            debug_menu = gui.Menu()  # 增加一个菜单
            debug_menu.add_item("Add Sphere", SpheresApp.MENU_SPHERE)  # 绑定数字1
            debug_menu.add_item("Add Random Spheres", SpheresApp.MENU_RANDOM)  # 
            if not isMacOS:
                debug_menu.add_separator()  # 添加分割线,与前面的item隔开
                debug_menu.add_item("Quit", SpheresApp.MENU_QUIT)

            menu = gui.Menu()  # 再新增一个菜单, 此菜单把前面的debug菜单包含进去.
            if isMacOS:
                # macOS will name the first menu item for the running application
                # (in our case, probably "Python"), regardless of what we call
                # it. This is the application menu, and it is where the
                # About..., Preferences..., and Quit menu items typically go.
                menu.add_menu("Example", app_menu)
                menu.add_menu("Debug", debug_menu)
            else:
                menu.add_menu("Debug", debug_menu)  # 此菜单把前面的debug菜单包含进去.
            gui.Application.instance.menubar = menu  # 再将次菜单放到菜单栏上

        # The menubar is global, but we need to connect the menu items to the
        # window, so that the window can call the appropriate function when the
        # menu item is activated.
        self.window.set_on_menu_item_activated(SpheresApp.MENU_SPHERE,
                                               self._on_menu_sphere)  # 不同的按钮,关联不同的回调函数,和qt是一样的
        self.window.set_on_menu_item_activated(SpheresApp.MENU_RANDOM,
                                               self._on_menu_random)
        self.window.set_on_menu_item_activated(SpheresApp.MENU_QUIT,
                                               self._on_menu_quit)

    def add_sphere(self):
        self._id += 1  # 球id+1
        mat = rendering.MaterialRecord()  # Describes the real-world
        mat.base_color = [  # 随机颜色
            random.random(),
            random.random(),
            random.random(), 1.0  # color为啥有4个值
        ]
        mat.shader = "defaultLit"  # ?
        sphere = o3d.geometry.TriangleMesh.create_sphere(0.5)  # 半径0.5
        sphere.compute_vertex_normals()
        sphere.translate([
            10.0 * random.uniform(-1.0, 1.0), 10.0 * random.uniform(-1.0, 1.0),
            10.0 * random.uniform(-1.0, 1.0)
        ])  # 沿着x,y,z轴随机平移
        self.scene.scene.add_geometry("sphere" + str(self._id), sphere, mat)

    def _on_menu_sphere(self):
        # GUI callbacks happen on the main thread, so we can do everything
        # normally here.
        self.add_sphere()

    def _on_menu_random(self):
        # This adds spheres asynchronously. This pattern is useful if you have
        # data coming in from another source than user interaction.
        def thread_main():
            for _ in range(0, 20):
                # We can only modify GUI objects on the main thread, so we
                # need to post the function to call to the main thread.
                gui.Application.instance.post_to_main_thread(
                    self.window, self.add_sphere)
                time.sleep(1)  # 每1s运行一次add_sphere函数.

        threading.Thread(target=thread_main).start()  # 线程异步添加

    def _on_menu_quit(self):
        gui.Application.instance.quit()  # 停止整个application


def main():
    gui.Application.instance.initialize()  # 初始化application
    SpheresApp()  # 赋值application
    gui.Application.instance.run()  # 运行 


if __name__ == "__main__":
    main()

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值