GUI basics#

Examples of basic GUI elements that we can create, read from, and write to.

  1import time
  2
  3import numpy as onp
  4import viser
  5
  6
  7def main() -> None:
  8    server = viser.ViserServer()
  9
 10    # Add some common GUI elements: number inputs, sliders, vectors, checkboxes.
 11    with server.gui.add_folder("Read-only"):
 12        gui_counter = server.gui.add_number(
 13            "Counter",
 14            initial_value=0,
 15            disabled=True,
 16        )
 17
 18        gui_slider = server.gui.add_slider(
 19            "Slider",
 20            min=0,
 21            max=100,
 22            step=1,
 23            initial_value=0,
 24            disabled=True,
 25        )
 26
 27    with server.gui.add_folder("Editable"):
 28        gui_vector2 = server.gui.add_vector2(
 29            "Position",
 30            initial_value=(0.0, 0.0),
 31            step=0.1,
 32        )
 33        gui_vector3 = server.gui.add_vector3(
 34            "Size",
 35            initial_value=(1.0, 1.0, 1.0),
 36            step=0.25,
 37        )
 38        with server.gui.add_folder("Text toggle"):
 39            gui_checkbox_hide = server.gui.add_checkbox(
 40                "Hide",
 41                initial_value=False,
 42            )
 43            gui_text = server.gui.add_text(
 44                "Text",
 45                initial_value="Hello world",
 46            )
 47            gui_button = server.gui.add_button("Button")
 48            gui_checkbox_disable = server.gui.add_checkbox(
 49                "Disable",
 50                initial_value=False,
 51            )
 52            gui_rgb = server.gui.add_rgb(
 53                "Color",
 54                initial_value=(255, 255, 0),
 55            )
 56            gui_multi_slider = server.gui.add_multi_slider(
 57                "Multi slider",
 58                min=0,
 59                max=100,
 60                step=1,
 61                initial_value=(0, 30, 100),
 62                marks=((0, "0"), (50, "5"), (70, "7"), 99),
 63            )
 64            gui_slider_positions = server.gui.add_slider(
 65                "# sliders",
 66                min=0,
 67                max=10,
 68                step=1,
 69                initial_value=3,
 70                marks=((0, "0"), (5, "5"), (7, "7"), 10),
 71            )
 72            gui_upload_button = server.gui.add_upload_button(
 73                "Upload", icon=viser.Icon.UPLOAD
 74            )
 75
 76    @gui_upload_button.on_upload
 77    def _(_) -> None:
 78        """Callback for when a file is uploaded."""
 79        file = gui_upload_button.value
 80        print(file.name, len(file.content), "bytes")
 81
 82    # Pre-generate a point cloud to send.
 83    point_positions = onp.random.uniform(low=-1.0, high=1.0, size=(5000, 3))
 84    color_coeffs = onp.random.uniform(0.4, 1.0, size=(point_positions.shape[0]))
 85
 86    counter = 0
 87    while True:
 88        # We can set the value of an input to a particular value. Changes are
 89        # automatically reflected in connected clients.
 90        gui_counter.value = counter
 91        gui_slider.value = counter % 100
 92
 93        # We can set the position of a scene node with `.position`, and read the value
 94        # of a gui element with `.value`. Changes are automatically reflected in
 95        # connected clients.
 96        server.scene.add_point_cloud(
 97            "/point_cloud",
 98            points=point_positions * onp.array(gui_vector3.value, dtype=onp.float32),
 99            colors=(
100                onp.tile(gui_rgb.value, point_positions.shape[0]).reshape((-1, 3))
101                * color_coeffs[:, None]
102            ).astype(onp.uint8),
103            position=gui_vector2.value + (0,),
104            point_shape="circle",
105        )
106
107        # We can use `.visible` and `.disabled` to toggle GUI elements.
108        gui_text.visible = not gui_checkbox_hide.value
109        gui_button.visible = not gui_checkbox_hide.value
110        gui_rgb.disabled = gui_checkbox_disable.value
111        gui_button.disabled = gui_checkbox_disable.value
112        gui_upload_button.disabled = gui_checkbox_disable.value
113
114        # Update the number of handles in the multi-slider.
115        if gui_slider_positions.value != len(gui_multi_slider.value):
116            gui_multi_slider.value = onp.linspace(
117                0, 100, gui_slider_positions.value, dtype=onp.int64
118            )
119
120        counter += 1
121        time.sleep(0.01)
122
123
124if __name__ == "__main__":
125    main()