Skip to content

Commit

Permalink
Update docs, improve type checking, hotfix recursion edge case
Browse files Browse the repository at this point in the history
  • Loading branch information
brentyi committed Sep 10, 2024
1 parent 54a94d9 commit ccd821a
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 37 deletions.
3 changes: 2 additions & 1 deletion docs/source/examples/09_urdf_visualizer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ and viser. It can also take a path to a local URDF file as input.
import numpy as onp
import tyro
import viser
from robot_descriptions.loaders.yourdfpy import load_robot_description
import viser
from viser.extras import ViserUrdf
Expand Down
52 changes: 28 additions & 24 deletions docs/source/examples/11_colmap_visualizer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Visualize COLMAP sparse reconstruction outputs. To get demo data, see ``./assets
import random
import time
from pathlib import Path
from typing import List
import imageio.v3 as iio
import numpy as onp
Expand Down Expand Up @@ -77,26 +78,30 @@ Visualize COLMAP sparse reconstruction outputs. To get demo data, see ``./assets
step=1,
initial_value=min(len(images), 100),
)
gui_point_size = server.gui.add_number("Point size", initial_value=0.05)
gui_point_size = server.gui.add_slider(
"Point size", min=0.01, max=0.1, step=0.001, initial_value=0.05
)
points = onp.array([points3d[p_id].xyz for p_id in points3d])
colors = onp.array([points3d[p_id].rgb for p_id in points3d])
point_mask = onp.random.choice(points.shape[0], gui_points.value, replace=False)
point_cloud = server.scene.add_point_cloud(
name="/colmap/pcd",
points=points[point_mask],
colors=colors[point_mask],
point_size=gui_point_size.value,
)
frames: List[viser.FrameHandle] = []
def visualize_colmap() -> None:
def visualize_frames() -> None:
"""Send all COLMAP elements to viser for visualization. This could be optimized
a ton!"""
# Set the point cloud.
points = onp.array([points3d[p_id].xyz for p_id in points3d])
colors = onp.array([points3d[p_id].rgb for p_id in points3d])
points_selection = onp.random.choice(
points.shape[0], gui_points.value, replace=False
)
points = points[points_selection]
colors = colors[points_selection]
server.scene.add_point_cloud(
name="/colmap/pcd",
points=points,
colors=colors,
point_size=gui_point_size.value,
)
# Remove existing image frames.
for frame in frames:
frame.remove()
frames.clear()
# Interpret the images and cameras.
img_ids = [im.id for im in images.values()]
Expand Down Expand Up @@ -131,6 +136,7 @@ Visualize COLMAP sparse reconstruction outputs. To get demo data, see ``./assets
axes_length=0.1,
axes_radius=0.005,
)
frames.append(frame)
# For pinhole cameras, cam.params will be (fx, fy, cx, cy).
if cam.model != "PINHOLE":
Expand All @@ -153,8 +159,9 @@ Visualize COLMAP sparse reconstruction outputs. To get demo data, see ``./assets
@gui_points.on_update
def _(_) -> None:
nonlocal need_update
need_update = True
point_mask = onp.random.choice(points.shape[0], gui_points.value, replace=False)
point_cloud.points = points[point_mask]
point_cloud.colors = colors[point_mask]
@gui_frames.on_update
def _(_) -> None:
Expand All @@ -163,15 +170,12 @@ Visualize COLMAP sparse reconstruction outputs. To get demo data, see ``./assets
@gui_point_size.on_update
def _(_) -> None:
nonlocal need_update
need_update = True
point_cloud.point_size = gui_point_size.value
while True:
if need_update:
need_update = False
server.scene.reset()
visualize_colmap()
visualize_frames()
time.sleep(1e-3)
Expand Down
13 changes: 13 additions & 0 deletions docs/source/examples/25_smpl_visualizer_skinned.rst
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ See here for download instructions:
gui_rgb = server.gui.add_rgb("Color", initial_value=(90, 200, 255))
gui_wireframe = server.gui.add_checkbox("Wireframe", initial_value=False)
gui_show_controls = server.gui.add_checkbox("Handles", initial_value=True)
gui_control_size = server.gui.add_slider(
"Handle size", min=0.0, max=10.0, step=0.01, initial_value=1.0
)
gui_rgb.on_update(set_changed)
gui_wireframe.on_update(set_changed)
Expand All @@ -189,6 +192,16 @@ See here for download instructions:
for control in transform_controls:
control.visible = gui_show_controls.value
@gui_control_size.on_update
def _(_):
for control in transform_controls:
prefixed_joint_name = control.name
control.scale = (
0.2
* (0.75 ** prefixed_joint_name.count("/"))
* gui_control_size.value
)
# GUI elements: shape parameters.
with tab_group.add_tab("Shape", viser.Icon.BOX):
gui_reset_shape = server.gui.add_button("Reset Shape")
Expand Down
28 changes: 16 additions & 12 deletions src/viser/_scene_handles.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,7 @@ def colors_to_uint8(colors: onp.ndarray) -> onpt.NDArray[onp.uint8]:
return colors


class _OverridablePropApi:
"""Mixin that allows reading/assigning properties defined in each scene node message."""

_PropHints: ClassVar[Dict[str, type]]

def __init__(self) -> None:
assert False

def __init_subclass__(cls, PropClass: type):
cls._PropHints = get_type_hints(PropClass)

class _OverridablePropSettersAndGetters:
def __setattr__(self, name: str, value: Any) -> None:
handle = cast(SceneNodeHandle, self)
# Get the value of the T TypeVar.
Expand All @@ -70,14 +60,28 @@ def __setattr__(self, name: str, value: Any) -> None:
return object.__setattr__(self, name, value)

def __getattr__(self, name: str) -> Any:
if name in self._PropClass:
if name in self._PropHints:
return getattr(self._impl.props, name)
else:
raise AttributeError(
f"'{self.__class__.__name__}' object has no attribute '{name}'"
)


class _OverridablePropApi(
_OverridablePropSettersAndGetters if not TYPE_CHECKING else object
):
"""Mixin that allows reading/assigning properties defined in each scene node message."""

_PropHints: ClassVar[Dict[str, type]]

def __init__(self) -> None:
assert False

def __init_subclass__(cls, PropClass: type):
cls._PropHints = get_type_hints(PropClass)


@dataclasses.dataclass(frozen=True)
class ScenePointerEvent:
"""Event passed to pointer callbacks for the scene (currently only clicks)."""
Expand Down

0 comments on commit ccd821a

Please sign in to comment.