trimesh.scene.scene module

class trimesh.scene.scene.Scene(geometry: Geometry | Iterable[Geometry] | dict[str, Geometry] | None = None, base_frame: str = 'world', metadata: dict | None = None, graph: SceneGraph | None = None, camera: Camera | None = None, lights: Sequence[Light] | None = None, camera_transform: ndarray[tuple[int, ...], dtype[_ScalarType_co]] | None = None)

Bases: Geometry3D

A simple scene graph which can be rendered directly via pyglet/openGL or through other endpoints such as a raytracer. Meshes are added by name, which can then be moved by updating transform in the transform tree.

__init__(geometry: Geometry | Iterable[Geometry] | dict[str, Geometry] | None = None, base_frame: str = 'world', metadata: dict | None = None, graph: SceneGraph | None = None, camera: Camera | None = None, lights: Sequence[Light] | None = None, camera_transform: ndarray[tuple[int, ...], dtype[_ScalarType_co]] | None = None)

Create a new Scene object.

Parameters:
  • geometry (Trimesh, Path2D, Path3D PointCloud or list) – Geometry to initially add to the scene

  • base_frame – Name of base frame

  • metadata – Any metadata about the scene

  • graph – A passed transform graph to use

  • camera (Camera or None) – A passed camera to use

  • lights ([trimesh.scene.lighting.Light] or None) – A passed lights to use

  • camera_transform – Homogeneous (4, 4) camera transform in the base frame

add_geometry(geometry: Geometry | Iterable[Geometry] | dict[str, Geometry], node_name: str | None = None, geom_name: str | None = None, parent_node_name: str | None = None, transform: ndarray[tuple[int, ...], dtype[_ScalarType_co]] | None = None, metadata: dict | None = None)

Add a geometry to the scene.

If the mesh has multiple transforms defined in its metadata, they will all be copied into the TransformForest of the current scene automatically.

Parameters:
  • geometry (Trimesh, Path2D, Path3D PointCloud or list) – Geometry to initially add to the scene

  • node_name (None or str) – Name of the added node.

  • geom_name (None or str) – Name of the added geometry.

  • parent_node_name (None or str) – Name of the parent node in the graph.

  • transform (None or (4, 4) float) – Transform that applies to the added node.

  • metadata (None or dict) – Optional metadata for the node.

Returns:

node_name – Name of single node in self.graph (passed in) or None if node was not added (eg. geometry was null or a Scene).

Return type:

str

apply_transform(transform)

Apply a transform to all children of the base frame without modifying any geometry.

Parameters:

transform ((4, 4)) – Homogeneous transformation matrix.

property area: float

What is the summed area of every geometry which has area.

Returns:

area – Summed area of every instanced geometry

Return type:

float

property bounds: ndarray[tuple[int, ...], dtype[float64]] | None

Return the overall bounding box of the scene.

Returns:

bounds – Position of [min, max] bounding box Returns None if no valid bounds exist

Return type:

(2, 3) float or None

property bounds_corners: dict[str, ndarray[tuple[int, ...], dtype[float64]]]

Get the post-transform AABB for each node which has geometry defined.

Returns:

Bounds for each node with vertices:

{node_name : (2, 3) float}

Return type:

corners

property camera: Camera

Get the single camera for the scene. If not manually set one will abe automatically generated.

Returns:

camera – Camera object defined for the scene

Return type:

trimesh.scene.Camera

camera_rays() tuple[ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[float64]], ndarray[tuple[int, ...], dtype[int64]]]

Calculate the trimesh.scene.Camera origin and ray direction vectors. Returns one ray per pixel as set in camera.resolution

Returns:

  • origin ((n, 3) float) – Ray origins in space

  • vectors ((n, 3) float) – Ray direction unit vectors in world coordinates

  • pixels ((n, 2) int) – Which pixel does each ray correspond to in an image

property camera_transform

Get camera transform in the base frame.

Returns:

camera_transform – Camera transform in the base frame

Return type:

(4, 4) float

property center_mass: ndarray[tuple[int, ...], dtype[_ScalarType_co]]

Find the center of mass for every instance in the scene.

Returns:

center_mass – The center of mass of the scene

Return type:

(3,) float

property centroid: ndarray[tuple[int, ...], dtype[float64]] | None

Return the center of the bounding box for the scene.

Returns:

centroid – Point for center of bounding box

Return type:

  1. float

convert_units(desired: str, guess: bool = False) Scene

If geometry has units defined convert them to new units.

Returns a new scene with geometries and transforms scaled.

Parameters:
  • desired (str) – Desired final unit system: ‘inches’, ‘mm’, etc.

  • guess (bool) – Is the converter allowed to guess scale when models don’t have it specified in their metadata.

Returns:

scaled – Copy of scene with scaling applied and units set for every model

Return type:

trimesh.Scene

property convex_hull

The convex hull of the whole scene.

Returns:

hull – Trimesh object which is a convex hull of all meshes in scene

Return type:

trimesh.Trimesh

copy() Scene

Return a deep copy of the current scene

Returns:

copied – Copy of the current scene

Return type:

trimesh.Scene

deduplicated() Scene

DEPRECATED: REMOVAL JANUARY 2025, this is one line and not that useful.

Return a new scene where each unique geometry is only included once and transforms are discarded.

Returns:

dedupe – One copy of each unique geometry from scene

Return type:

Scene

delete_geometry(names: set | str | Sequence) None

Delete one more multiple geometries from the scene and also remove any node in the transform graph which references it.

Parameters:

name (hashable) – Name that references self.geometry

dump(concatenate: bool = False) list[Geometry]

Get a list of every geometry moved to its instance position, i.e. freezing or “baking” transforms.

Parameters:

concatenate

KWARG IS DEPRECATED FOR REMOVAL APRIL 2025 Concatenate results into single geometry. This keyword argument will make the type hint incorrect and you should replace Scene.dump(concatenate=True) with:

  • Scene.to_geometry() for a Trimesh, Path2D or Path3D

  • Scene.to_mesh() for only Trimesh components.

Returns:

Copies of Scene.geometry transformed to their instance position.

Return type:

dumped

property duplicate_nodes: list[list[str]]

Return a sequence of node keys of identical meshes.

Will include meshes with different geometry but identical spatial hashes as well as meshes repeated by self.nodes.

Returns:

Keys of self.graph that represent identical geometry

Return type:

duplicates

explode(vector=None, origin=None) None

Explode the current scene in-place around a point and vector.

Parameters:
  • vector ((3,) float or float) – Explode radially around a direction vector or spherically

  • origin ((3,) float) – Point to explode around

export(file_obj=None, file_type=None, **kwargs)

Export a snapshot of the current scene.

Parameters:
  • file_obj (str, file-like, or None) – File object to export to

  • file_type (str or None) – What encoding to use for meshes IE: dict, dict64, stl

Returns:

export – Only returned if file_obj is None

Return type:

bytes

property extents: ndarray[tuple[int, ...], dtype[float64]] | None

Return the axis aligned box size of the current scene or None if the scene is empty.

Returns:

Bounding box sides length or None for empty scene.

Return type:

extents

property geometry_identifiers: dict[str, str]

Look up geometries by identifier hash.

Returns:

{Identifier hash: key in self.geometry}

Return type:

identifiers

property has_camera: bool
property is_empty: bool

Does the scene have anything in it.

Returns:

True if nothing is in the scene

Return type:

is_empty

property is_valid: bool

Is every geometry connected to the root node.

Returns:

is_valid – Does every geometry have a transform

Return type:

bool

property lights: list[Light]

Get a list of the lights in the scene. If nothing is set it will generate some automatically.

Returns:

lights – Lights in the scene.

Return type:

[trimesh.scene.lighting.Light]

property moment_inertia

Return the moment of inertia of the current scene with respect to the center of mass of the current scene.

Returns:

inertia – Inertia with respect to cartesian axis at scene.center_mass

Return type:

(3, 3) float

moment_inertia_frame(transform)

Return the moment of inertia of the current scene relative to a transform from the base frame.

Parameters transform : (4, 4) float

Homogeneous transformation matrix.

Returns:

inertia – Inertia tensor at requested frame.

Return type:

(3, 3) float

reconstruct_instances(cost_threshold: float | floating = 1e-05) Scene

If a scene has been “baked” with meshes it means that the duplicate nodes have corresponding vertices but are rigidly transformed to different places.

This means the problem of finding ab instance transform can use the procrustes analysis which is very fast relative to more complicated registration problems that require ICP and nearest-point-on-surface calculations.

TODO : construct a parent non-geometry node for containing every group.

Parameters:
  • scene

  • handle. (The scene to)

  • cost_threshold

  • mean (The maximum value for procrustes cost which is "squared)

  • value (vertex distance between pair". If the fit is above this)

  • duplicate. (the instance will be left even if it is a)

Returns:

  • dedupe

  • A copy of the scene de-duplicated as much as possible.

rezero() None

Move the current scene so that the AABB of the whole scene is centered at the origin.

Does this by changing the base frame to a new, offset base frame.

save_image(resolution=None, **kwargs) bytes

Get a PNG image of a scene.

Parameters:
  • resolution ((2,) int) – Resolution to render image

  • **kwargs – Passed to SceneViewer constructor

Returns:

png – Render of scene as a PNG

Return type:

bytes

property scale: float

The approximate scale of the mesh

Returns:

scale – The mean of the bounding box edge lengths

Return type:

float

scaled(scale: float | floating | Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]) Scene

Return a copy of the current scene, with meshes and scene transforms scaled to the requested factor.

Parameters:

scale (float or (3,) float) – Factor to scale meshes and transforms

Returns:

scaled – A copy of the current scene but scaled

Return type:

trimesh.Scene

set_camera(angles=None, distance=None, center=None, resolution=None, fov=None) Camera

Create a camera object for self.camera, and add a transform to self.graph for it.

If arguments are not passed sane defaults will be figured out which show the mesh roughly centered.

Parameters:
  • angles ((3,) float) – Initial euler angles in radians

  • distance (float) – Distance from centroid

  • center ((3,) float) – Point camera should be center on

  • camera (Camera object) – Object that stores camera parameters

show(viewer=None, **kwargs)

Display the current scene.

Parameters:
  • viewer (Union[str, callable, None]) – What kind of viewer to use, such as ‘gl’ to open a pyglet window, ‘notebook’ for a jupyter notebook or None

  • kwargs (dict) – Includes smooth, which will turn on or off automatic smooth shading

simplify_quadric_decimation(percent: float | floating | None = None, face_count: int | integer | unsignedinteger | None = None, aggression: int | integer | unsignedinteger | None = None) None

Apply in-place mesh.simplify_quadric_decimation to any meshes in the scene.

Parameters:
  • percent – A number between 0.0 and 1.0 for how much

  • face_count – Target number of faces desired in the resulting mesh.

  • agression – An integer between 0 and 10, the scale being roughly 0 is “slow and good” and 10 being “fast and bad.”

strip_visuals() None

Strip visuals from every Trimesh geometry and set them to an empty ColorVisuals.

subscene(node: str) Scene

Get part of a scene that succeeds a specified node.

Parameters:

node – Hashable key in scene.graph

Returns:

Partial scene generated from current.

Return type:

subscene

to_geometry() Geometry

Concatenate geometry in the scene into a single like-typed geometry, applying the transforms and “baking” the result. May drop geometry if the scene has mixed geometry.

Returns:

Either a Trimesh, Path2D, or Path3D depending on what is in the scene.

Return type:

concat

to_mesh() trimesh.Trimesh

Concatenate every mesh instances in the scene into a single mesh, applying transforms and “baking” the result. Will drop any geometry in the scene that is not a Trimesh object.

Returns:

All meshes in the scene concatenated into one.

Return type:

mesh

property triangles: ndarray[tuple[int, ...], dtype[float64]]

Return a correctly transformed polygon soup of the current scene.

Returns:

triangles – Triangles in space

Return type:

(n, 3, 3) float

property triangles_node

Which node of self.graph does each triangle come from.

Returns:

triangles_index – Node name for each triangle

Return type:

(len(self.triangles),)

property units: str | None

Get the units for every model in the scene. If the scene has mixed units or no units this will return None.

Returns:

Units for every model in the scene or None if there are no units or mixed units

Return type:

units

property volume: float64

What is the summed volume of every geometry which has volume

Returns:

volume – Summed area of every instanced geometry

Return type:

float

trimesh.scene.scene.append_scenes(iterable, common=None, base_frame='world')

Concatenate multiple scene objects into one scene.

Parameters:
  • iterable ((n,) Trimesh or Scene) – Geometries that should be appended

  • common ((n,) str) – Nodes that shouldn’t be remapped

  • base_frame (str) – Base frame of the resulting scene

Returns:

result – Scene containing all geometry

Return type:

trimesh.Scene

trimesh.scene.scene.reconstruct_instances(scene: Scene, cost_threshold: float | floating = 1e-06) Scene

If a scene has been “baked” with meshes it means that the duplicate nodes have corresponding vertices but are rigidly transformed to different places.

This means the problem of finding ab instance transform can use the procrustes analysis which is very fast relative to more complicated registration problems that require ICP and nearest-point-on-surface calculations.

TODO : construct a parent non-geometry node for containing every group.

Parameters:
  • scene – The scene to handle.

  • cost_threshold – The maximum value for procrustes cost which is “squared mean vertex distance between pair”. If the fit is above this value the instance will be left even if it is a duplicate.

Returns:

A copy of the scene de-duplicated as much as possible.

Return type:

dedupe

trimesh.scene.scene.split_scene(geometry, **kwargs)

Given a geometry, list of geometries, or a Scene return them as a single Scene object.

Parameters:

geometry (splittable)

Returns:

scene

Return type:

trimesh.Scene