Skip to content

Model (Bodies, Shapes, Terrain)

simview.model defines the static, once-per-scene part of the JSON format: SimViewModel, the bodies/shapes that make it up, static (non-moving) objects, and the terrain heightfield.

simview.model

BodyShapeType

Bases: StrEnum

Shape kind of a body or static object (the wire shape.type).

OptionalBodyStateAttribute

Bases: StrEnum

Optional per-body state fields beyond bodyTransform (wire keys).

SimViewBody dataclass

SimViewBody(
    name: str,
    shape: dict,
    available_attributes: list[OptionalBodyStateAttribute]
    | None = None,
    parent: str | None = None,
    local_transform: list[float] | None = None,
    color: list[float] | None = None,
    opacity: float | None = None,
    visible: bool = True,
    visible_ranges: list[list[float]] | None = None,
)

A dynamic body: its shape, look, optional parent attachment and the optional state attributes its states carry.

create staticmethod

create(
    name: str,
    body_type: BodyShapeType,
    available_attributes: list[
        OptionalBodyStateAttribute | str
    ]
    | None = None,
    parent: str | None = None,
    local_transform: Any | None = None,
    color: Any | None = None,
    opacity: float | None = None,
    visible: bool = True,
    visible_ranges: list | None = None,
    **kwargs,
) -> SimViewBody

Build a body of body_type; **kwargs are its shape parameters (e.g. hx/hy/hz for a box, radius for a sphere, radius/ height for a cylinder, vertices/faces for a mesh). The other parameters are as on SimulationScene.create_body.

create_box staticmethod

create_box(
    name: str, hx: float, hy: float, hz: float, **kwargs
) -> SimViewBody

Build a box body with half-extents hx/hy/hz.

create_mesh staticmethod

create_mesh(
    name: str, vertices: Tensor, faces: Tensor, **kwargs
) -> SimViewBody

Build a mesh body from vertices (V, 3) and faces (F, 3).

create_pointcloud staticmethod

create_pointcloud(
    name: str,
    points: Tensor,
    color: Tensor | None = None,
    embedding: Tensor | None = None,
    color_layers: dict[str, Tensor] | None = None,
    **kwargs,
) -> SimViewBody

Build a point-cloud body from (N, 3) points.

color (N, 3) in [0, 1] is an optional static per-point RGB color, used by the viewer for vertex-colored rendering. embedding (N, K) is an optional per-point K-wide feature vector (e.g. a reduced-dim PCA projection of a learned backbone's features) enabling the viewer's click-to-similarity color mode: cosine similarity to a clicked point, computed entirely in-browser from this data. color_layers maps a name to another (N, 3) RGB coloring (e.g. a class or session label); each becomes an extra choice of the viewer's "Point Color Mode", shown by every body that ships a layer of that name. All are stored as __b64__ blobs.

from_dict classmethod

from_dict(d: dict) -> SimViewBody

Reconstruct a SimViewBody from the dict produced by to_json.

set_available_attributes

set_available_attributes(
    available_attributes: list[
        str | OptionalBodyStateAttribute
    ],
) -> None

Set the optional attributes this body's states carry (once only).

SimViewEpisode dataclass

SimViewEpisode(start_index: int, label: str | None = None)

One episode boundary in an otherwise continuous timeline.

RL runs are episodic: the states array is one long recording, but it is really a sequence of resets. An episode marks the frame a run starts at, so episodes is a list of starts and each episode implicitly ends where the next one begins (the last runs to the end of the states).

Purely descriptive metadata -- the viewer uses it to draw boundaries on the playback bar, offer next/previous-episode navigation, and aggregate scalars per episode. Nothing about playback itself changes.

from_dict classmethod

from_dict(d: dict) -> SimViewEpisode

Reconstruct a SimViewEpisode from the dict produced by to_json.

SimViewModel dataclass

SimViewModel(
    batch_size: int,
    scalar_names: list[str],
    dt: float | None,
    collapse: bool,
    terrain: SimViewTerrain | None = None,
    bodies: dict[str, SimViewBody] = dict(),
    static_objects: dict[str, SimViewStaticObject] = dict(),
    polylines: dict[str, SimViewPolyline] = dict(),
    batch_names: list[str] | None = None,
    metadata: dict[str, Any] | None = None,
    episodes: list[SimViewEpisode] | None = None,
    viewer_defaults: dict[str, Any] | None = None,
)

The static part of a scene: batch layout, terrain, bodies, static objects, polylines and metadata (the wire model section).

is_complete property

is_complete: bool

True once a terrain is set (required to save or show).

add_body

add_body(body: SimViewBody) -> None

Add body; its name must be new and its parent already added.

add_polyline

add_polyline(polyline: SimViewPolyline) -> None

Add polyline; its name must be new.

add_static_object

add_static_object(
    static_object: SimViewStaticObject,
) -> None

Add static_object; its name must be new and a batched one needs one shape per batch.

from_dict classmethod

from_dict(d: dict) -> SimViewModel

Reconstruct a SimViewModel from the dict produced by to_json.

Centralizes parsing of the wire format: each part is rebuilt via its own from_dict. Bodies are checked for duplicate names and parent references inline; static objects and polylines go through add_static_object/add_polyline, so they're validated exactly as when authoring.

SimViewPolyline dataclass

SimViewPolyline(
    name: str,
    points: str | list | None = None,
    color: list[float] = (lambda: [1.0, 1.0, 1.0])(),
    width: float = 2.0,
    dashed: bool = False,
    frames: str | None = None,
    max_vertices: int | None = None,
    visible_ranges: list[list[float]] | None = None,
)

A world-space polyline: a fixed points list (a route), and/or a per-frame frames blob (a replanned local path) of shape (T, B, max_vertices, 3) float32, trailing NaN rows padding each frame up to max_vertices. Model-level by design (not a states field), so it rides the generic blob machinery; not supported in live mode.

frame_count

frame_count(batch_size: int) -> int | None

Number of frames in frames for batch_size batches (None if static).

from_dict classmethod

from_dict(d: dict) -> SimViewPolyline

Reconstruct a SimViewPolyline from the dict produced by to_json.

SimViewStaticObject dataclass

SimViewStaticObject(
    name: str,
    is_singleton: bool,
    shape: dict | None = None,
    shapes: list[dict] | None = None,
    visible_ranges: list[list[float]] | None = None,
)

A static (never-moving) object: one shape shared by every batch (singleton) or one shape per batch.

create_batched staticmethod

create_batched(
    name: str,
    shape_type: BodyShapeType,
    shapes_kwargs: list[dict[str, Any]],
    visible_ranges: list | None = None,
) -> SimViewStaticObject

Build a static object with one shape per batch, all of shape_type.

name names the group. shapes_kwargs holds one dict of shape keyword arguments per batch instance (e.g. [{"hx": 0.1, "hy": 0.1, "hz": 0.1}, {"hx": 0.2, ...}]); its length must match the model's batch size.

create_singleton staticmethod

create_singleton(
    name: str,
    shape_type: BodyShapeType,
    visible_ranges: list | None = None,
    **kwargs,
) -> SimViewStaticObject

Build a static object shared by every batch; **kwargs are the shape parameters, as on SimViewBody.create.

from_dict classmethod

from_dict(d: dict) -> SimViewStaticObject

Reconstruct a SimViewStaticObject from the dict produced by to_json.

SimViewTerrain dataclass

SimViewTerrain(
    extent_x: float,
    extent_y: float,
    shape_x: int,
    shape_y: int,
    min_x: float,
    min_y: float,
    max_x: float,
    max_y: float,
    min_z: float,
    max_z: float,
    height_data: list[list[float]] | str,
    normals: list[list[list[float]]] | str | None,
    is_singleton: bool,
    properties: dict[str, TerrainProperty] = dict(),
    embedding_data: list[list[float]] | str | None = None,
)

Terrain heightmap (plus optional normals, named properties and embeddings) over a regular x/y grid, shared or per batch.

create staticmethod

create(
    heightmap: Tensor,
    normals: Tensor | None,
    x_lim: tuple[float, float],
    y_lim: tuple[float, float],
    is_singleton: bool,
    properties: dict[str, Tensor] | None = None,
    property_bounds: dict[str, tuple[float, float]]
    | None = None,
    embedding_map: Tensor | None = None,
) -> SimViewTerrain

Build a terrain from batched tensors, encoding each field as a blob.

heightmap is (B, Dy, Dx) with torch's "xy" indexing: the column index increases with x. normals is (B, 3, Dy, Dx) or None, properties maps names to (B, Dy, Dx) maps, and embedding_map is (B, K, Dy, Dx). x_lim/y_lim are the (min, max) world extents. property_bounds optionally pins a property's color-scale range; otherwise the map's own data range is used. Every grid must match the heightmap's. Batch broadcasting is the caller's job (see SimulationScene.create_terrain).

from_dict classmethod

from_dict(d: dict) -> SimViewTerrain

Reconstruct a SimViewTerrain from the dict produced by to_json.

heightData/normals/each property's data are kept in whatever form they were serialized in (plain nested lists or a __b64__ blob string) -- decode with simview.columnar.blob_floats if you need the flat float values back out.

TerrainProperty dataclass

TerrainProperty(
    data: list[list[float]] | str,
    min: float | None = None,
    max: float | None = None,
)

One arbitrary named per-cell scalar field over the terrain grid (e.g. friction, stiffness, or any other user-defined property), stored the same way as SimViewTerrain.height_data -- a plain nested list, or an opaque __b64__-prefixed blob string for compactness.