Skip to content

[MRG] Viser visualization backend - #362

Open
AlexanderFabisch wants to merge 12 commits into
developfrom
feature/viser_backend
Open

[MRG] Viser visualization backend#362
AlexanderFabisch wants to merge 12 commits into
developfrom
feature/viser_backend

Conversation

@AlexanderFabisch

@AlexanderFabisch AlexanderFabisch commented May 7, 2026

Copy link
Copy Markdown
Member

pytransform3d.viser — web-based visualization backend

A new pytransform3d.viser module backed by viser that is a drop-in replacement for pytransform3d.visualizer. It renders in a browser via WebSocket, so it works in headless environments (remote servers, containers, notebooks) where an OpenGL window is unavailable. Switching backends is a one-line import change; both modules share the same public API.

Differences from the Open3D backend: show() is non-blocking and prints a URL instead of opening a window; save_image() raises NotImplementedError; set_line_width() is a no-op. view_init() gains center and distance parameters for controlling the orbit target.

Install with pip install 'pytransform3d[all]' or pip install viser. trimesh is required for shapes without a native viser primitive (cylinders, cones, capsules, ellipsoids, vector arrows) and is included in the all extras group.

New examples

Six new examples in examples/viser/:

  • vis_viser_shapes — all geometric primitives in one static scene
  • vis_viser_robot_arm — animated 6-DOF robot arm with growing TCP trajectory
  • vis_viser_wrench_dynamics — rigid-body simulation driven by a body-fixed wrench with rolling position trail
  • vis_viser_camera_orbit — pinhole camera orbiting a static scene, frustum updated every frame
  • vis_viser_uncertain_transforms — banana distribution from SE(3) uncertainty propagation: MC paths, mean trajectory, projected hyperellipsoid, and Cartesian position ellipsoid
  • vis_viser_probabilistic_robot_kinematics — PPOE probabilistic forward kinematics with animated end-effector pose-uncertainty ellipsoid

A new user-guide page covers installation, the API, differences from the Open3D backend, and the animation workflow.

@AlexanderFabisch AlexanderFabisch changed the title Viser visualization backend [MRG] Viser visualization backend May 7, 2026
return tuple(int(np.clip(v * 255.0, 0, 255)) for v in arr[:3])


def _wxyz_from_matrix(A2B):

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be inlined

return pr.quaternion_from_matrix(A2B[:3, :3], strict_check=False)


def _make_arrow_mesh(length):

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not tested yet

B1: Remove redundant set_data(H) call at end of Trajectory.__init__.
    Child artists are already created with the correct data; calling
    set_data again reprocessed the trajectory twice including an
    expensive np.linspace recomputation.

B2: Plane._resolve_point now normalises the normal vector before
    multiplying by d.  The Hesse normal form requires a unit normal;
    unnormalised inputs placed the plane centre at the wrong position
    and caused plane_basis_from_normal to produce an incorrect basis.

B4: Graph.set_data now guards the visuals and collision_objects loops
    with try/except KeyError, matching the existing guard on the frames
    and connections loops.  A disconnected URDF link after a joint
    update previously raised an uncaught KeyError.

B5: Trajectory.set_data recomputes key_frames_indices when the new H
    array has a different length.  Using stale indices from the original
    length caused an IndexError when set_data was called with a shorter
    or longer trajectory.

B8: Plane._make_mesh now uses two faces instead of four.  The last two
    faces were reversed-winding duplicates of the first two; add_mesh_simple
    with side="double" already renders both sides, so the duplicates only
    doubled the triangle count without any visual benefit.

B9: Frame.set_data now updates _label_handle.text in addition to
    _label_handle.position so that label text changes after construction
    are reflected in the scene.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant