Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
brentyi committed Aug 6, 2023
1 parent 67eb074 commit b93d25c
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 66 deletions.
21 changes: 15 additions & 6 deletions examples/15_gui_in_scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
# Asymmetric properties are supported in Pyright, but not yet in mypy.
# - https://github.com/python/mypy/issues/3004
# - https://github.com/python/mypy/pull/11643
"""Camera commands
"""3D GUI Elements
In addition to reads, camera parameters also support writes. These are synced to the
corresponding client automatically.
"""

import time
Expand All @@ -31,6 +29,7 @@ def _(client: viser.ClientHandle) -> None:
rng = onp.random.default_rng(0)

displayed_3d_container: Optional[viser.Gui3dContainerHandle] = None
displayed_index: Optional[int] = None

def make_frame(i: int) -> None:
# Sample a random orientation + position.
Expand All @@ -40,20 +39,28 @@ def make_frame(i: int) -> None:

# Create a coordinate frame and label.
frame = client.add_frame(f"/frame_{i}", wxyz=wxyz, position=position)
client.add_label(f"/frame_{i}/label", text=f"Frame {i}")

# Move the camera when we click a frame.
@frame.on_click
def _(_):
nonlocal displayed_3d_container
nonlocal displayed_index

# Close previously opened GUI.
if displayed_3d_container is not None:
displayed_3d_container.remove()

displayed_3d_container = client.add_gui_3d_container(f"/frame_{i}/gui")
# Don't re-show the same GUI element.
if displayed_index == i:
return

displayed_index = i

displayed_3d_container = client.add_3d_gui_container(f"/frame_{i}/gui")
with displayed_3d_container:
go_to = client.add_gui_button("Go to")
randomize_orientation = client.add_gui_button("Randomize orientation")
close = client.add_gui_button("[Close]")
close = client.add_gui_button("Close GUI")

@go_to.on_click
def _(_) -> None:
Expand Down Expand Up @@ -90,10 +97,12 @@ def _(_) -> None:
@close.on_click
def _(_) -> None:
nonlocal displayed_3d_container
nonlocal displayed_index
if displayed_3d_container is None:
return
displayed_3d_container.remove()
displayed_3d_container = None
displayed_index = None

for i in range(num_frames):
make_frame(i)
Expand Down
2 changes: 1 addition & 1 deletion viser/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from ._gui_api import Gui3dContainerHandle as Gui3dContainerHandle
from ._gui_api import GuiFolderHandle as GuiFolderHandle
from ._gui_api import GuiTabGroupHandle as GuiTabGroupHandle
from ._gui_api import GuiTabHandle as GuiTabHandle
Expand All @@ -9,6 +8,7 @@
from ._icons_enum import Icon as Icon
from ._scene_handles import CameraFrustumHandle as CameraFrustumHandle
from ._scene_handles import FrameHandle as FrameHandle
from ._scene_handles import Gui3dContainerHandle as Gui3dContainerHandle
from ._scene_handles import ImageHandle as ImageHandle
from ._scene_handles import LabelHandle as LabelHandle
from ._scene_handles import MeshHandle as MeshHandle
Expand Down
51 changes: 0 additions & 51 deletions viser/_gui_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,26 +111,6 @@ def gui_folder(self, label: str) -> GuiFolderHandle:
)
return self.add_gui_folder(label)

def add_gui_3d_container(
self,
name: str,
wxyz: Tuple[float, float, float, float] | onp.ndarray = (1.0, 0.0, 0.0, 0.0),
position: Tuple[float, float, float] | onp.ndarray = (0.0, 0.0, 0.0),
) -> Gui3dContainerHandle:
"""Add a 3D gui to the scene."""
print("here")
container_id = _make_unique_id()
self._get_api()._queue(
_messages.Gui3DMessage(
order=time.time(),
name=name,
container_id=container_id,
)
)
assert isinstance(self, MessageApi)
node_handle = SceneNodeHandle._make(self, name, wxyz, position)
return Gui3dContainerHandle(node_handle._impl, self, container_id)

def add_gui_folder(self, label: str) -> GuiFolderHandle:
"""Add a folder, and return a handle that can be used to populate it."""
folder_container_id = _make_unique_id()
Expand Down Expand Up @@ -690,37 +670,6 @@ def _sync_with_client(self) -> None:
)


@dataclasses.dataclass
class Gui3dContainerHandle(SceneNodeHandle):
"""Use as a context to place GUI elements into a folder."""

_gui_api: GuiApi
_container_id: str
_container_id_restore: Optional[str] = None

def __enter__(self) -> None:
self._container_id_restore = self._gui_api._get_container_id()
self._gui_api._set_container_id(self._container_id)

def __exit__(self, *args) -> None:
del args
assert self._container_id_restore is not None
self._gui_api._set_container_id(self._container_id_restore)
self._container_id_restore = None

def remove(self) -> None:
"""Permanently remove this GUI container
visualizer."""

# Call scene node remove.
super().remove()

# Clean up contained GUI elements.
self._gui_api._get_api()._queue(
_messages.GuiRemoveContainerChildrenMessage(self._container_id)
)


@dataclasses.dataclass
class GuiFolderHandle:
"""Use as a context to place GUI elements into a folder."""
Expand Down
26 changes: 26 additions & 0 deletions viser/_message_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from ._scene_handles import (
CameraFrustumHandle,
FrameHandle,
Gui3dContainerHandle,
ImageHandle,
LabelHandle,
MeshHandle,
Expand Down Expand Up @@ -521,3 +522,28 @@ def _handle_click_updates(
return
for cb in handle._impl.click_cb:
cb(handle)

def add_3d_gui_container(
self,
name: str,
wxyz: Tuple[float, float, float, float] | onp.ndarray = (1.0, 0.0, 0.0, 0.0),
position: Tuple[float, float, float] | onp.ndarray = (0.0, 0.0, 0.0),
) -> Gui3dContainerHandle:
"""Add a 3D gui container to the scene. The returned container handle can be
used as a context to place GUI elements into the 3D scene."""

# Avoids circular import.
from ._gui_api import GuiApi, _make_unique_id

container_id = _make_unique_id()
self._queue(
_messages.Gui3DMessage(
order=time.time(),
name=name,
container_id=container_id,
)
)
assert isinstance(self, MessageApi)
node_handle = SceneNodeHandle._make(self, name, wxyz, position)
assert isinstance(self, GuiApi)
return Gui3dContainerHandle(node_handle._impl, self, container_id)
31 changes: 31 additions & 0 deletions viser/_scene_handles.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from . import _messages

if TYPE_CHECKING:
from ._gui_api import GuiApi
from ._message_api import ClientId, MessageApi


Expand Down Expand Up @@ -201,3 +202,33 @@ def on_update(
"""Attach a callback for when the gizmo is moved."""
self._impl_aux.update_cb.append(func)
return func


@dataclasses.dataclass
class Gui3dContainerHandle(SceneNodeHandle):
"""Use as a context to place GUI elements into a 3D GUI container."""

_gui_api: GuiApi
_container_id: str
_container_id_restore: Optional[str] = None

def __enter__(self) -> None:
self._container_id_restore = self._gui_api._get_container_id()
self._gui_api._set_container_id(self._container_id)

def __exit__(self, *args) -> None:
del args
assert self._container_id_restore is not None
self._gui_api._set_container_id(self._container_id_restore)
self._container_id_restore = None

def remove(self) -> None:
"""Permanently remove this GUI container from the visualizer."""

# Call scene node remove.
super().remove()

# Clean up contained GUI elements.
self._gui_api._get_api()._queue(
_messages.GuiRemoveContainerChildrenMessage(self._container_id)
)
12 changes: 4 additions & 8 deletions viser/client/src/ControlPanel/Generated.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,10 @@ export default function GeneratedGuiContainer({
containerId: string;
viewer?: ViewerContextContents;
}) {
if (viewer === undefined) {
viewer = React.useContext(ViewerContext)!;
}
if (viewer === null) {
return null;
}
if (viewer === undefined) viewer = React.useContext(ViewerContext)!;

const guiIdSet = viewer.useGui(
(state) => state.guiIdSetFromContainerId[containerId],
(state) => state.guiIdSetFromContainerId[containerId]
);
const guiConfigFromId = viewer.useGui((state) => state.guiConfigFromId);

Expand Down Expand Up @@ -427,7 +423,7 @@ function VectorInput(
precision: number;
onChange: (value: number[]) => void;
disabled: boolean;
},
}
) {
return (
<Flex justify="space-between" style={{ columnGap: "0.3rem" }}>
Expand Down

0 comments on commit b93d25c

Please sign in to comment.