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