trimesh package

Subpackages

Submodules

Module contents

https://github.com/mikedh/trimesh

Trimesh is a pure Python (2.7- 3.3+) library for loading and using triangular meshes with an emphasis on watertight meshes. The goal of the library is to provide a fully featured Trimesh object which allows for easy manipulation and analysis, in the style of the Polygon object in the Shapely library.

class trimesh.Geometry

Bases: ABC

Geometry is the parent class for all geometry.

By decorating a method with abc.abstractmethod it means the objects that inherit from Geometry MUST implement those methods.

apply_scale(scaling)

Scale the mesh.

Parameters:

scaling (float or (3,) float) – Scale factor to apply to the mesh

abstract apply_transform(matrix: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]) Any
apply_translation(translation: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes])

Translate the current mesh.

Parameters:

translation ((3,) float) – Translation in XYZ

abstract property bounds: ndarray[tuple[int, ...], dtype[float64]]
abstract copy()
abstract export(file_obj, file_type=None)
abstract property extents: ndarray[tuple[int, ...], dtype[float64]]
abstract property is_empty: bool
metadata: dict
property scale: float

A loosely specified “order of magnitude scale” for the geometry which always returns a value and can be used to make code more robust to large scaling differences.

It returns the diagonal of the axis aligned bounding box or if anything is invalid or undefined, 1.0.

Returns:

scale – Approximate order of magnitude scale of the geometry.

Return type:

float

abstract show()
property units: str | None

Definition of units for the mesh.

Returns:

units – Unit system mesh is in, or None if not defined

Return type:

str

class trimesh.PointCloud(vertices, colors=None, metadata=None, **kwargs)

Bases: Geometry3D

Hold 3D points in an object which can be visualized in a scene.

__init__(vertices, colors=None, metadata=None, **kwargs)

Load an array of points into a PointCloud object.

Parameters:
  • vertices ((n, 3) float) – Points in space

  • colors ((n, 4) uint8 or None) – RGBA colors for each point

  • metadata (dict or None) – Metadata about points

apply_transform(transform)

Apply a homogeneous transformation to the PointCloud object in- place.

Parameters:

transform ((4, 4) float) – Homogeneous transformation to apply to PointCloud

property bounds

The axis aligned bounds of the PointCloud

Returns:

bounds – Minimum, Maximum verteex

Return type:

(2, 3) float

property centroid

The mean vertex position

Returns:

centroid – Mean vertex position

Return type:

(3,) float

property colors

Stored per- point color

Returns:

colors – Per- point RGBA color

Return type:

(len(self.vertices), 4) np.uint8

property convex_hull

A convex hull of every point.

Returns:

convex_hull – A watertight mesh of the hull of the points

Return type:

trimesh.Trimesh

copy()

Safely get a copy of the current point cloud.

Copied objects will have emptied caches to avoid memory issues and so may be slow on initial operations until caches are regenerated.

Current object will not have its cache cleared.

Returns:

copied – Copy of current point cloud

Return type:

trimesh.PointCloud

crc()

Get a CRC hash of the current vertices.

Returns:

crc – Hash of self.vertices

Return type:

int

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

Export the current pointcloud to a file object. If file_obj is a filename, file will be written there. Supported formats are xyz :param file_obj: str, file name where to save the pointcloud

None, if you would like this function to return the export blob

Parameters:

file_type (str) – Which file type to export as. If file name is passed this is not required

property extents

The size of the axis aligned bounds

Returns:

extents – Edge length of axis aligned bounding box

Return type:

(3,) float

hash()

Get a hash of the current vertices.

Returns:

hash – Hash of self.vertices

Return type:

str

property is_empty

Are there any vertices defined or not.

Returns:

empty – True if no vertices defined

Return type:

bool

property kdtree

Return a scipy.spatial.cKDTree of the vertices of the mesh. Not cached as this lead to observed memory issues and segfaults.

Returns:

tree – Contains mesh.vertices

Return type:

scipy.spatial.cKDTree

merge_vertices()

Merge vertices closer than tol.merge (default: 1e-8)

query(input_points, **kwargs)

Find the the closest points and associated attributes from this PointCloud. :param input_points: Input query points :type input_points: (n, 3) float :param kwargs: Arguments for proximity.query_from_points :type kwargs: dict :param result: Result of the query. :type result: proximity.NearestQueryResult

scene()

A scene containing just the PointCloud

Returns:

scene – Scene object containing this PointCloud

Return type:

trimesh.Scene

property shape

Get the shape of the pointcloud

Returns:

shape – Shape of vertex array

Return type:

(2,) int

show(**kwargs)

Open a viewer window displaying the current PointCloud

property vertices

Vertices of the PointCloud

Returns:

vertices – Points in the PointCloud

Return type:

(n, 3) float

class trimesh.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

class trimesh.Trimesh(vertices: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None, faces: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None, face_normals: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None, vertex_normals: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None, face_colors: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None, vertex_colors: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None, face_attributes: dict[str, Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]] | None = None, vertex_attributes: dict[str, Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]] | None = None, metadata: dict[str, Any] | None = None, process: bool = True, validate: bool = False, merge_tex: bool | None = None, merge_norm: bool | None = None, use_embree: bool = True, initial_cache: dict[str, ndarray] | None = None, visual: ColorVisuals | TextureVisuals | None = None, **kwargs)

Bases: Geometry3D

__init__(vertices: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None, faces: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None, face_normals: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None, vertex_normals: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None, face_colors: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None, vertex_colors: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None, face_attributes: dict[str, Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]] | None = None, vertex_attributes: dict[str, Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]] | None = None, metadata: dict[str, Any] | None = None, process: bool = True, validate: bool = False, merge_tex: bool | None = None, merge_norm: bool | None = None, use_embree: bool = True, initial_cache: dict[str, ndarray] | None = None, visual: ColorVisuals | TextureVisuals | None = None, **kwargs) None

A Trimesh object contains a triangular 3D mesh.

Parameters:
  • vertices ((n, 3) float) – Array of vertex locations

  • faces ((m, 3) or (m, 4) int) – Array of triangular or quad faces (triangulated on load)

  • face_normals ((m, 3) float) – Array of normal vectors corresponding to faces

  • vertex_normals ((n, 3) float) – Array of normal vectors for vertices

  • metadata (dict) – Any metadata about the mesh

  • process (bool) – if True, Nan and Inf values will be removed immediately and vertices will be merged

  • validate (bool) – If True, degenerate and duplicate faces will be removed immediately, and some functions will alter the mesh to ensure consistent results.

  • use_embree (bool) – If True try to use pyembree raytracer. If pyembree is not available it will automatically fall back to a much slower rtree/numpy implementation

  • initial_cache (dict) – A way to pass things to the cache in case expensive things were calculated before creating the mesh object.

  • visual (ColorVisuals or TextureVisuals) – Assigned to self.visual

apply_transform(matrix: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]) Trimesh

Transform mesh by a homogeneous transformation matrix.

Does the bookkeeping to avoid recomputing things so this function should be used rather than directly modifying self.vertices if possible.

Parameters:

matrix ((4, 4) float) – Homogeneous transformation matrix

property area: float64

Summed area of all triangles in the current mesh.

Returns:

area – Surface area of mesh

Return type:

float

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

The area of each face in the mesh.

Returns:

area_faces – Area of each face

Return type:

(n, ) float

property body_count: int

How many connected groups of vertices exist in this mesh. Note that this number may differ from result in mesh.split, which is calculated from FACE rather than vertex adjacency.

Returns:

count – Number of connected vertex groups

Return type:

int

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

The axis aligned bounds of the faces of the mesh.

Returns:

bounds – Bounding box with [min, max] coordinates If mesh is empty will return None

Return type:

(2, 3) float or None

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

The point in space which is the center of mass/volume.

Returns:

center_mass – Volumetric center of mass of the mesh.

Return type:

(3, ) float

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

The point in space which is the average of the triangle centroids weighted by the area of each triangle.

This will be valid even for non-watertight meshes, unlike self.center_mass

Returns:

centroid – The average vertex weighted by face area

Return type:

(3, ) float

compute_stable_poses(center_mass: ndarray[tuple[int, ...], dtype[float64]] | None = None, sigma: float = 0.0, n_samples: int = 1, threshold: float = 0.0)

Computes stable orientations of a mesh and their quasi-static probabilities.

This method samples the location of the center of mass from a multivariate gaussian (mean at com, cov equal to identity times sigma) over n_samples. For each sample, it computes the stable resting poses of the mesh on a a planar workspace and evaluates the probabilities of landing in each pose if the object is dropped onto the table randomly.

This method returns the 4x4 homogeneous transform matrices that place the shape against the planar surface with the z-axis pointing upwards and a list of the probabilities for each pose. The transforms and probabilities that are returned are sorted, with the most probable pose first.

Parameters:
  • center_mass ((3, ) float) – The object center of mass (if None, this method assumes uniform density and watertightness and computes a center of mass explicitly)

  • sigma (float) – The covariance for the multivariate gaussian used to sample center of mass locations

  • n_samples (int) – The number of samples of the center of mass location

  • threshold (float) – The probability value at which to threshold returned stable poses

Returns:

  • transforms ((n, 4, 4) float) – The homogeneous matrices that transform the object to rest in a stable pose, with the new z-axis pointing upwards from the table and the object just touching the table.

  • probs ((n, ) float) – A probability ranging from 0.0 to 1.0 for each pose

contains(points: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]) ndarray[tuple[int, ...], dtype[bool]]

Given an array of points determine whether or not they are inside the mesh. This raises an error if called on a non-watertight mesh.

Parameters:

points ((n, 3) float) – Points in cartesian space

Returns:

contains – Whether or not each point is inside the mesh

Return type:

(n, ) bool

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

Convert the units of the mesh into a specified unit.

Parameters:
  • desired (string) – Units to convert to (eg ‘inches’)

  • guess (boolean) – If self.units are not defined should we guess the current units of the document and then convert?

convex_decomposition(**kwargs) list[Trimesh]

Compute an approximate convex decomposition of a mesh using pip install pyVHACD.

Returns:

  • meshes – List of convex meshes that approximate the original

  • **kwargs (VHACD keyword arguments)

property convex_hull: Trimesh

Returns a Trimesh object representing the convex hull of the current mesh.

Returns:

convex – Mesh of convex hull of current mesh

Return type:

trimesh.Trimesh

copy(include_cache: bool = False, include_visual: bool = True) Trimesh

Safely return a copy of the current mesh.

By default, copied meshes will have emptied cache to avoid memory issues and so may be slow on initial operations until caches are regenerated.

Current object will never have its cache cleared.

Parameters:

include_cache (bool) – If True, will shallow copy cached data to new mesh

Returns:

copied – Copy of current mesh

Return type:

trimesh.Trimesh

property density: float

The density of the mesh used in inertia calculations.

Returns:

The density of the primitive.

Return type:

density

difference(other: Trimesh | Sequence[Trimesh], engine: str | None = None, check_volume: bool = True, **kwargs) Trimesh

Boolean difference between this mesh and other meshes.

other

One or more meshes to difference with the current mesh.

engine

Which backend to use, the default recommendation is: pip install manifold3d.

check_volume

Raise an error if not all meshes are watertight positive volumes. Advanced users may want to ignore this check as it is expensive.

kwargs

Passed through to the engine.

differencetrimesh.Trimesh

Difference between self and other Trimesh objects

property edges: ndarray[tuple[int, ...], dtype[int64]]

Edges of the mesh (derived from faces).

Returns:

edges – List of vertex indices making up edges

Return type:

(n, 2) int

property edges_face: ndarray[tuple[int, ...], dtype[int64]]

Which face does each edge belong to.

Returns:

edges_face – Index of self.faces

Return type:

(n, ) int

property edges_sorted: ndarray[tuple[int, ...], dtype[int64]]

Edges sorted along axis 1

Returns:

edges_sorted – Same as self.edges but sorted along axis 1

Return type:

(n, 2)

property edges_sorted_tree: cKDTree

A KDTree for mapping edges back to edge index.

Returns:

tree – Tree when queried with edges will return their index in mesh.edges_sorted

Return type:

scipy.spatial.cKDTree

property edges_sparse: coo_matrix

Edges in sparse bool COO graph format where connected vertices are True.

Returns:

sparse – Sparse graph in COO format

Return type:

(len(self.vertices), len(self.vertices)) bool

property edges_unique: ndarray[tuple[int, ...], dtype[int64]]

The unique edges of the mesh.

Returns:

edges_unique – Vertex indices for unique edges

Return type:

(n, 2) int

property edges_unique_inverse: ndarray[tuple[int, ...], dtype[int64]]

Return the inverse required to reproduce self.edges_sorted from self.edges_unique.

Useful for referencing edge properties: mesh.edges_unique[mesh.edges_unique_inverse] == m.edges_sorted

Returns:

inverse – Indexes of self.edges_unique

Return type:

(len(self.edges), ) int

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

How long is each unique edge.

Returns:

length – Length of each unique edge

Return type:

(len(self.edges_unique), ) float

property euler_number: int

Return the Euler characteristic (a topological invariant) for the mesh In order to guarantee correctness, this should be called after remove_unreferenced_vertices

Returns:

euler_number – Topological invariant

Return type:

int

eval_cached(statement: str, *args)

Evaluate a statement and cache the result before returning.

Statements are evaluated inside the Trimesh object, and

Parameters:
  • statement (str) – Statement of valid python code

  • *args (list) – Available inside statement as args[0], etc

Returns:

result

Return type:

result of running eval on statement with args

Examples

r = mesh.eval_cached(‘np.dot(self.vertices, args[0])’, [0, 0, 1])

export(file_obj=None, file_type: str | None = None, **kwargs)

Export the current mesh to a file object. If file_obj is a filename, file will be written there.

Supported formats are stl, off, ply, collada, json, dict, glb, dict64, msgpack.

Parameters:
  • file_obj (open writeable file object) – str, file name where to save the mesh None, return the export blob

  • file_type (str) – Which file type to export as, if file_name is passed this is not required.

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

The length, width, and height of the axis aligned bounding box of the mesh.

Returns:

extents – Array containing axis aligned [length, width, height] If mesh is empty returns None

Return type:

(3, ) float or None

property face_adjacency: ndarray[tuple[int, ...], dtype[int64]]

Find faces that share an edge i.e. ‘adjacent’ faces.

Returns:

adjacency – Pairs of faces which share an edge

Return type:

(n, 2) int

Examples

In [1]: mesh = trimesh.load(‘models/featuretype.STL’)

In [2]: mesh.face_adjacency Out[2]: array([[ 0, 1],

[ 2, 3], [ 0, 3], …, [1112, 949], [3467, 3475], [1113, 3475]])

In [3]: mesh.faces[mesh.face_adjacency[0]] Out[3]: TrackedArray([[ 1, 0, 408],

[1239, 0, 1]], dtype=int64)

In [4]: import networkx as nx

In [5]: graph = nx.from_edgelist(mesh.face_adjacency)

In [6]: groups = nx.connected_components(graph)

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

Return the angle between adjacent faces

Returns:

adjacency_angle – Angle between adjacent faces Each value corresponds with self.face_adjacency

Return type:

(n, ) float

property face_adjacency_convex: ndarray[tuple[int, ...], dtype[bool]]

Return faces which are adjacent and locally convex.

What this means is that given faces A and B, the one vertex in B that is not shared with A, projected onto the plane of A has a projection that is zero or negative.

Returns:

are_convex – Face pairs that are locally convex

Return type:

(len(self.face_adjacency), ) bool

property face_adjacency_edges: ndarray[tuple[int, ...], dtype[int64]]

Returns the edges that are shared by the adjacent faces.

Returns:

edges – Vertex indices which correspond to face_adjacency

Return type:

(n, 2) int

property face_adjacency_edges_tree: cKDTree

A KDTree for mapping edges back face adjacency index.

Returns:

tree – Tree when queried with SORTED edges will return their index in mesh.face_adjacency

Return type:

scipy.spatial.cKDTree

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

The projection of the non-shared vertex of a triangle onto its adjacent face

Returns:

projections – Dot product of vertex onto plane of adjacent triangle.

Return type:

(len(self.face_adjacency), ) float

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

The approximate radius of a cylinder that fits inside adjacent faces.

Returns:

radii – Approximate radius formed by triangle pair

Return type:

(len(self.face_adjacency), ) float

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

The approximate perpendicular projection of the non-shared vertices in a pair of adjacent faces onto the shared edge of the two faces.

Returns:

span – Approximate span between the non-shared vertices

Return type:

(len(self.face_adjacency), ) float

property face_adjacency_tree: Index

An R-tree of face adjacencies.

Returns:

Where each edge in self.face_adjacency has a rectangular cell

Return type:

tree

property face_adjacency_unshared: ndarray[tuple[int, ...], dtype[int64]]

Return the vertex index of the two vertices not in the shared edge between two adjacent faces

Returns:

vid_unshared – Indexes of mesh.vertices

Return type:

(len(mesh.face_adjacency), 2) int

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

Returns the angle at each vertex of a face.

Returns:

angles – Angle at each vertex of a face

Return type:

(len(self.faces), 3) float

property face_angles_sparse: coo_matrix

A sparse matrix representation of the face angles.

Returns:

sparse – Float sparse matrix with with shape: (len(self.vertices), len(self.faces))

Return type:

scipy.sparse.coo_matrix

property face_neighborhood: ndarray[tuple[int, ...], dtype[int64]]

Find faces that share a vertex i.e. ‘neighbors’ faces.

Returns:

neighborhood – Pairs of faces which share a vertex

Return type:

(n, 2) int

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

Return the unit normal vector for each face.

If a face is degenerate and a normal can’t be generated a zero magnitude unit vector will be returned for that face.

Returns:

normals – Normal vectors of each face

Return type:

(len(self.faces), 3) float64

property faces: TrackedArray

The faces of the mesh.

This is regarded as core information which cannot be regenerated from cache and as such is stored in self._data which tracks the array for changes and clears cached values of the mesh altered.

Returns:

faces – References for self.vertices for triangles.

Return type:

(n, 3) int64

property faces_sparse: coo_matrix

A sparse matrix representation of the faces.

Returns:

sparse – Has properties: dtype : bool shape : (len(self.vertices), len(self.faces))

Return type:

scipy.sparse.coo_matrix

property faces_unique_edges: ndarray[tuple[int, ...], dtype[int64]]

For each face return which indexes in mesh.unique_edges constructs that face.

Returns:

faces_unique_edges – Indexes of self.edges_unique that construct self.faces

Return type:

(len(self.faces), 3) int

Examples

In [0]: mesh.faces[:2] Out[0]: TrackedArray([[ 1, 6946, 24224],

[ 6946, 1727, 24225]])

In [1]: mesh.edges_unique[mesh.faces_unique_edges[:2]] Out[1]: array([[[ 1, 6946],

[ 6946, 24224], [ 1, 24224]],

[[ 1727, 6946],

[ 1727, 24225], [ 6946, 24225]]])

property facets: list[ndarray[tuple[int, ...], dtype[int64]]]

Return a list of face indices for coplanar adjacent faces.

Returns:

facets – Groups of indexes of self.faces

Return type:

(n, ) sequence of (m, ) int

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

Return an array containing the area of each facet.

Returns:

area – Total area of each facet (group of faces)

Return type:

(len(self.facets), ) float

property facets_boundary: list[ndarray[tuple[int, ...], dtype[int64]]]

Return the edges which represent the boundary of each facet

Returns:

edges_boundary – Indices of self.vertices

Return type:

sequence of (n, 2) int

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

Return the normal of each facet

Returns:

normals – A unit normal vector for each facet

Return type:

(len(self.facets), 3) float

property facets_on_hull: ndarray[tuple[int, ...], dtype[bool]]

Find which facets of the mesh are on the convex hull.

Returns:

on_hull – is A facet on the meshes convex hull or not

Return type:

(len(mesh.facets), ) bool

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

Return a point on the facet plane.

Returns:

origins – A point on each facet plane

Return type:

(len(self.facets), 3) float

fill_holes() bool

Fill single triangle and single quad holes in the current mesh.

Returns:

watertight – Is the mesh watertight after the function completes

Return type:

bool

fix_normals(multibody: bool | None = None) None

Find and fix problems with self.face_normals and self.faces winding direction.

For face normals ensure that vectors are consistently pointed outwards, and that self.faces is wound in the correct direction for all connected components.

Parameters:

multibody (None or bool) – Fix normals across multiple bodies if None automatically pick from body_count

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

Return a float vector which is unique to the mesh and is robust to rotation and translation.

Returns:

identifier – Identifying properties of the current mesh

Return type:

(7,) float

property identifier_hash: str

A hash of the rotation invariant identifier vector.

Returns:

hashed – Hex string of the SHA256 hash from the identifier vector at hand-tuned sigfigs.

Return type:

str

property integral_mean_curvature: float64

The integral mean curvature, or the surface integral of the mean curvature.

Returns:

area – Integral mean curvature of mesh

Return type:

float

intersection(other: Trimesh | Sequence[Trimesh], engine: str | None = None, check_volume: bool = True, **kwargs) Trimesh

Boolean intersection between this mesh and other meshes.

othertrimesh.Trimesh, or list of trimesh.Trimesh objects

Meshes to calculate intersections with

engine

Which backend to use, the default recommendation is: pip install manifold3d.

check_volume

Raise an error if not all meshes are watertight positive volumes. Advanced users may want to ignore this check as it is expensive.

kwargs

Passed through to the engine.

intersectiontrimesh.Trimesh

Mesh of the volume contained by all passed meshes

invert() None

Invert the mesh in-place by reversing the winding of every face and negating normals without dumping the cache.

Alters self.faces by reversing columns, and negating self.face_normals and self.vertex_normals.

property is_convex: bool

Check if a mesh is convex or not.

Returns:

is_convex – Is mesh convex or not

Return type:

bool

property is_empty: bool

Does the current mesh have data defined.

Returns:

empty – If True, no data is set on the current mesh

Return type:

bool

property is_volume: bool

Check if a mesh has all the properties required to represent a valid volume, rather than just a surface.

These properties include being watertight, having consistent winding and outward facing normals.

Returns:

valid – Does the mesh represent a volume

Return type:

bool

property is_watertight: bool

Check if a mesh is watertight by making sure every edge is included in two faces.

Returns:

is_watertight – Is mesh watertight or not

Return type:

bool

property is_winding_consistent: bool

Does the mesh have consistent winding or not. A mesh with consistent winding has each shared edge going in an opposite direction from the other in the pair.

Returns:

consistent – Is winding is consistent or not

Return type:

bool

property kdtree: cKDTree

Return a scipy.spatial.cKDTree of the vertices of the mesh. Not cached as this lead to observed memory issues and segfaults.

Returns:

tree – Contains mesh.vertices

Return type:

scipy.spatial.cKDTree

property mass: float64

Mass of the current mesh, based on specified density and volume. If the current mesh isn’t watertight this is garbage.

Returns:

mass – Mass of the current mesh

Return type:

float

property mass_properties: MassProperties

Returns the mass properties of the current mesh.

Assumes uniform density, and result is probably garbage if mesh isn’t watertight.

Returns:

properties – With keys: ‘volume’ : in global units^3 ‘mass’ : From specified density ‘density’ : Included again for convenience (same as kwarg density) ‘inertia’ : Taken at the center of mass and aligned with global

coordinate system

’center_mass’ : Center of mass location, in global coordinate system

Return type:

dict

merge_vertices(merge_tex: bool | None = None, merge_norm: bool | None = None, digits_vertex: int | integer | unsignedinteger | None = None, digits_norm: int | integer | unsignedinteger | None = None, digits_uv: int | integer | unsignedinteger | None = None) None

Removes duplicate vertices grouped by position and optionally texture coordinate and normal.

Parameters:
  • mesh (Trimesh object) – Mesh to merge vertices on

  • merge_tex (bool) – If True textured meshes with UV coordinates will have vertices merged regardless of UV coordinates

  • merge_norm (bool) – If True, meshes with vertex normals will have vertices merged ignoring different normals

  • digits_vertex (None or int) – Number of digits to consider for vertex position

  • digits_norm (int) – Number of digits to consider for unit normals

  • digits_uv (int) – Number of digits to consider for UV coordinates

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

Return the moment of inertia matrix of the current mesh. If mesh isn’t watertight this is garbage. The returned moment of inertia is axis aligned at the mesh’s center of mass mesh.center_mass. If you want the moment at any other frame including the origin call: mesh.moment_inertia_frame

Returns:

inertia – Moment of inertia of the current mesh at the center of mass and aligned with the cartesian axis.

Return type:

(3, 3) float

moment_inertia_frame(transform: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]) ndarray[tuple[int, ...], dtype[float64]]

Get the moment of inertia of this mesh with respect to an arbitrary frame, versus with respect to the center of mass as returned by mesh.moment_inertia.

For example if transform is an identity matrix np.eye(4) this will give the moment at the origin.

Uses the parallel axis theorum to move the center mass tensor to this arbitrary frame.

Parameters:

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

Returns:

inertia – Moment of inertia in the requested frame.

Return type:

(3, 3)

property mutable: bool

Is the current mesh allowed to be altered in-place?

Returns:

If data is allowed to be set for the mesh.

Return type:

mutable

nondegenerate_faces(height: float = 1e-08) ndarray[tuple[int, ...], dtype[bool]]

Identify degenerate faces (faces without 3 unique vertex indices) in the current mesh.

Usage example for removing them: mesh.update_faces(mesh.nondegenerate_faces())

If a height is specified, it will identify any face with a 2D oriented bounding box with one edge shorter than that height.

If not specified, it will identify any face with a zero normal.

Parameters:

height (float) – If specified identifies faces with an oriented bounding box shorter than this on one side.

Returns:

nondegenerate – Mask that can be used to remove faces

Return type:

(len(self.faces), ) bool

outline(face_ids: ndarray[tuple[int, ...], dtype[int64]] | None = None, **kwargs) Path3D

Given a list of face indexes find the outline of those faces and return it as a Path3D.

The outline is defined here as every edge which is only included by a single triangle.

Note that this implies a non-watertight mesh as the outline of a watertight mesh is an empty path.

Parameters:
  • face_ids ((n, ) int) – Indices to compute the outline of. If None, outline of full mesh will be computed.

  • **kwargs (passed to Path3D constructor)

Returns:

path – Curve in 3D of the outline

Return type:

Path3D

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

Return the principal components of inertia

Ordering corresponds to mesh.principal_inertia_vectors

Returns:

components – Principal components of inertia

Return type:

(3, ) float

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

A transform which moves the current mesh so the principal inertia vectors are on the X,Y, and Z axis, and the centroid is at the origin.

Returns:

transform – Homogeneous transformation matrix

Return type:

(4, 4) float

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

Return the principal axis of inertia as unit vectors. The order corresponds to mesh.principal_inertia_components.

Returns:

vectors – Three vectors pointing along the principal axis of inertia directions

Return type:

(3, 3) float

process(validate: bool = False, merge_tex: bool | None = None, merge_norm: bool | None = None) Trimesh

Do processing to make a mesh useful.

Does this by:
  1. removing NaN and Inf values

  2. merging duplicate vertices

If validate:
  1. Remove triangles which have one edge of their 2D oriented bounding box shorter than tol.merge

  2. remove duplicated triangles

  3. Attempt to ensure triangles are consistently wound and normals face outwards.

Parameters:

validate (bool) – Remove degenerate and duplicate faces.

Returns:

self – Current mesh

Return type:

trimesh.Trimesh

projected(normal, **kwargs) Path2D

Project a mesh onto a plane and then extract the polygon that outlines the mesh projection on that plane.

Parameters:
  • mesh (trimesh.Trimesh) – Source geometry

  • check (bool) – If True make sure is flat

  • normal ((3,) float) – Normal to extract flat pattern along

  • origin (None or (3,) float) – Origin of plane to project mesh onto

  • pad (float) – Proportion to pad polygons by before unioning and then de-padding result by to avoid zero-width gaps.

  • tol_dot (float) – Tolerance for discarding on-edge triangles.

  • max_regions (int) – Raise an exception if the mesh has more than this number of disconnected regions to fail quickly before unioning.

Returns:

projected – Outline of source mesh

Return type:

trimesh.path.Path2D

property referenced_vertices: ndarray[tuple[int, ...], dtype[bool]]

Which vertices in the current mesh are referenced by a face.

Returns:

referenced – Which vertices are referenced by a face

Return type:

(len(self.vertices), ) bool

register(other: Geometry3D | ndarray[tuple[int, ...], dtype[_ScalarType_co]], **kwargs)

Align a mesh with another mesh or a PointCloud using the principal axes of inertia as a starting point which is refined by iterative closest point.

Parameters:
  • other (trimesh.Trimesh or (n, 3) float) – Mesh or points in space

  • samples (int) – Number of samples from mesh surface to align

  • icp_first (int) – How many ICP iterations for the 9 possible combinations of

  • icp_final (int) – How many ICP itertations for the closest candidate from the wider search

Returns:

  • mesh_to_other ((4, 4) float) – Transform to align mesh to the other object

  • cost (float) – Average square distance per point

remove_degenerate_faces(height: float = 1e-08) None

DERECATED MARCH 2024 REPLACE WITH: self.update_faces(self.nondegenerate_faces(height=height))

remove_duplicate_faces() None

DERECATED MARCH 2024 REPLACE WITH: mesh.update_faces(mesh.unique_faces())

remove_infinite_values() None

Ensure that every vertex and face consists of finite numbers. This will remove vertices or faces containing np.nan and np.inf

Alters self.faces and self.vertices

remove_unreferenced_vertices() None

Remove all vertices in the current mesh which are not referenced by a face.

rezero() None

Translate the mesh so that all vertex vertices are positive.

Alters self.vertices.

sample(count: int, return_index: bool = False, face_weight: ndarray[tuple[int, ...], dtype[float64]] | None = None)

Return random samples distributed across the surface of the mesh

Parameters:
  • count (int) – Number of points to sample

  • return_index (bool) – If True will also return the index of which face each sample was taken from.

  • face_weight (None or len(mesh.faces) float) – Weight faces by a factor other than face area. If None will be the same as face_weight=mesh.area

Returns:

  • samples ((count, 3) float) – Points on surface of mesh

  • face_index ((count, ) int) – Index of self.faces

scene(**kwargs) Scene

Returns a Scene object containing the current mesh.

Returns:

scene – Contains just the current mesh

Return type:

trimesh.scene.scene.Scene

section(plane_normal: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes], plane_origin: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes], **kwargs) Path3D | None

Returns a 3D cross section of the current mesh and a plane defined by origin and normal.

Parameters:
  • plane_normal ((3,) float) – Normal vector of section plane.

  • plane_origin ((3, ) float) – Point on the cross section plane.

Returns:

Curve of intersection or None if it was not hit by plane.

Return type:

intersections

section_multiplane(plane_origin: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes], plane_normal: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes], heights: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]) list[Path2D | None]

Return multiple parallel cross sections of the current mesh in 2D.

Parameters:
  • plane_origin ((3, ) float) – Point on the cross section plane

  • plane_normal – Normal vector of section plane

  • heights ((n, ) float) – Each section is offset by height along the plane normal.

Returns:

paths – 2D cross sections at specified heights. path.metadata[‘to_3D’] contains transform to return 2D section back into 3D space.

Return type:

(n, ) Path2D or None

show(**kwargs)

Render the mesh in an opengl window. Requires pyglet.

Parameters:

smooth (bool) – Run smooth shading on mesh or not, large meshes will be slow

Returns:

scene – Scene with current mesh in it

Return type:

trimesh.scene.Scene

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

A thin wrapper around pip install fast-simplification.

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.”

Returns:

simple – Simplified version of mesh.

Return type:

trimesh.Trimesh

slice_plane(plane_origin, plane_normal, cap=False, face_index=None, cached_dots=None, **kwargs)

Slice the mesh with a plane, returning a new mesh that is the portion of the original mesh to the positive normal side of the plane

plane_origin(3,) float

Point on plane to intersect with mesh

plane_normal(3,) float

Normal vector of plane to intersect with mesh

capbool

If True, cap the result with a triangulated polygon

face_index((m,) int)

Indexes of mesh.faces to slice. When no mask is provided, the default is to slice all faces.

cached_dots(n, 3) float

If an external function has stored dot products pass them here to avoid recomputing

Returns:

new_mesh – Subset of current mesh that intersects the half plane to the positive normal side of the plane

Return type:

trimesh.Trimesh or None

property smooth_shaded

Smooth shading in OpenGL relies on which vertices are shared, this function will disconnect regions above an angle threshold and return a non-watertight version which will look better in an OpenGL rendering context.

If you would like to use non-default arguments see graph.smooth_shade.

Returns:

smooth_shaded – Non watertight version of current mesh.

Return type:

trimesh.Trimesh

smoothed(**kwargs)

DEPRECATED: use mesh.smooth_shaded or trimesh.graph.smooth_shade(mesh)

split(**kwargs) list[Trimesh]

Returns a list of Trimesh objects, based on face connectivity. Splits into individual components, sometimes referred to as ‘bodies’

Parameters:
  • only_watertight (bool) – Only return watertight meshes and discard remainder

  • adjacency (None or (n, 2) int) – Override face adjacency with custom values

Returns:

meshes – Separate bodies from original mesh

Return type:

(n, ) trimesh.Trimesh

subdivide(face_index: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None) Trimesh

Subdivide a mesh with each subdivided face replaced with four smaller faces. Will return a copy of current mesh with subdivided faces.

Parameters:

face_index ((m, ) int or None) – If None all faces of mesh will be subdivided If (m, ) int array of indices: only specified faces will be subdivided. Note that in this case the mesh will generally no longer be manifold, as the additional vertex on the midpoint will not be used by the adjacent faces to the faces specified, and an additional postprocessing step will be required to make resulting mesh watertight

subdivide_loop(iterations=None)

Subdivide a mesh by dividing each triangle into four triangles and approximating their smoothed surface using loop subdivision. Loop subdivision often looks better on triangular meshes than catmul-clark, which operates primarily on quads.

Parameters:
  • iterations (int) – Number of iterations to run subdivision.

  • multibody (bool) – If True will try to subdivide for each submesh

subdivide_to_size(max_edge, max_iter=10, return_index=False)

Subdivide a mesh until every edge is shorter than a specified length.

Will return a triangle soup, not a nicely structured mesh.

Parameters:
  • max_edge (float) – Maximum length of any edge in the result

  • max_iter (int) – The maximum number of times to run subdivision

  • return_index (bool) – If True, return index of original face for new faces

submesh(faces_sequence: Sequence[Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]], **kwargs) Trimesh | list[Trimesh]

Return a subset of the mesh.

Parameters:
  • faces_sequence (sequence (m, ) int) – Face indices of mesh

  • only_watertight (bool) – Only return submeshes which are watertight

  • append (bool) – Return a single mesh which has the faces appended. if this flag is set, only_watertight is ignored

Returns:

submesh – Single mesh if append or list of submeshes

Return type:

Trimesh or (n,) Trimesh

property symmetry: str | None

Check whether a mesh has rotational symmetry around an axis (radial) or point (spherical).

Returns:

symmetry – What kind of symmetry does the mesh have.

Return type:

None, ‘radial’, ‘spherical’

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

If a mesh has rotational symmetry, return the axis.

Returns:

axis – Axis around which a 2D profile was revolved to create this mesh.

Return type:

(3, ) float

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

If a mesh has rotational symmetry return the two vectors which make up a section coordinate frame.

Returns:

section – Vectors to take a section along

Return type:

(2, 3) float

to_dict() dict[str, str | list[list[float]] | list[list[int]]]

Return a dictionary representation of the current mesh with keys that can be used as the kwargs for the Trimesh constructor and matches the schema in: trimesh/resources/schema/primitive/trimesh.schema.json

Returns:

result – Matches schema and Trimesh constructor.

Return type:

dict

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

Actual triangles of the mesh (points, not indexes)

Returns:

triangles – Points of triangle vertices

Return type:

(n, 3, 3) float

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

The center of each triangle (barycentric [1/3, 1/3, 1/3])

Returns:

triangles_center – Center of each triangular face

Return type:

(len(self.faces), 3) float

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

The cross product of two edges of each triangle.

Returns:

crosses – Cross product of each triangle

Return type:

(n, 3) float

property triangles_tree: Index

An R-tree containing each face of the mesh.

Returns:

tree – Each triangle in self.faces has a rectangular cell

Return type:

rtree.index

union(other: Trimesh | Sequence[Trimesh], engine: str | None = None, check_volume: bool = True, **kwargs) Trimesh

Boolean union between this mesh and other meshes.

Parameters:
  • other (Trimesh or (n, ) Trimesh) – Other meshes to union

  • engine – Which backend to use, the default recommendation is: pip install manifold3d.

  • check_volume – Raise an error if not all meshes are watertight positive volumes. Advanced users may want to ignore this check as it is expensive.

  • kwargs – Passed through to the engine.

Returns:

union – Union of self and other Trimesh objects

Return type:

trimesh.Trimesh

unique_faces() ndarray[tuple[int, ...], dtype[bool]]

On the current mesh find which faces are unique.

Returns:

unique – A mask where the first occurrence of a unique face is true.

Return type:

(len(faces),) bool

unmerge_vertices() None

Removes all face references so that every face contains three unique vertex indices and no faces are adjacent.

unwrap(image=None)

Returns a Trimesh object equivalent to the current mesh where the vertices have been assigned uv texture coordinates. Vertices may be split into as many as necessary by the unwrapping algorithm, depending on how many uv maps they appear in.

Requires pip install xatlas

Parameters:

image (None or PIL.Image) – Image to assign to the material

Returns:

unwrapped – Mesh with unwrapped uv coordinates

Return type:

trimesh.Trimesh

update_faces(mask: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes]) None

In many cases, we will want to remove specific faces. However, there is additional bookkeeping to do this cleanly. This function updates the set of faces with a validity mask, as well as keeping track of normals and colors.

Parameters:

valid – Mask to remove faces

update_vertices(mask: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes], inverse: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes] | None = None) None

Update vertices with a mask.

Parameters:
  • vertex_mask ((len(self.vertices)) bool) – Array of which vertices to keep

  • inverse ((len(self.vertices)) int) – Array to reconstruct vertex references such as output by np.unique

property vertex_adjacency_graph: Graph

Returns a networkx graph representing the vertices and their connections in the mesh.

Returns:

graph – Graph representing vertices and edges between them where vertices are nodes and edges are edges

Return type:

networkx.Graph

Examples

This is useful for getting nearby vertices for a given vertex, potentially for some simple smoothing techniques.

mesh = trimesh.primitives.Box() graph = mesh.vertex_adjacency_graph graph.neighbors(0) > [1, 2, 3, 4]

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

Return the vertex defects, or (2*pi) minus the sum of the angles of every face that includes that vertex.

If a vertex is only included by coplanar triangles, this will be zero. For convex regions this is positive, and concave negative.

Returns:

vertex_defect – Vertex defect at the every vertex

Return type:

(len(self.vertices), ) float

property vertex_degree: ndarray[tuple[int, ...], dtype[int64]]

Return the number of faces each vertex is included in.

Returns:

degree – Number of faces each vertex is included in

Return type:

(len(self.vertices), ) int

property vertex_faces: ndarray[tuple[int, ...], dtype[int64]]

A representation of the face indices that correspond to each vertex.

Returns:

vertex_faces – Each row contains the face indices that correspond to the given vertex, padded with -1 up to the max number of faces corresponding to any one vertex Where n == len(self.vertices), m == max number of faces for a single vertex

Return type:

(n,m) int

property vertex_neighbors: list[list[int64]]

The vertex neighbors of each vertex of the mesh, determined from the cached vertex_adjacency_graph, if already existent.

Returns:

vertex_neighbors – Represents immediate neighbors of each vertex along the edge of a triangle

Return type:

(len(self.vertices), ) int

Examples

This is useful for getting nearby vertices for a given vertex, potentially for some simple smoothing techniques.

>>> mesh = trimesh.primitives.Box()
>>> mesh.vertex_neighbors[0]
[1, 2, 3, 4]
property vertex_normals: ndarray[tuple[int, ...], dtype[float64]]

The vertex normals of the mesh. If the normals were loaded we check to make sure we have the same number of vertex normals and vertices before returning them. If there are no vertex normals defined or a shape mismatch we calculate the vertex normals from the mean normals of the faces the vertex is used in.

Returns:

vertex_normals – Represents the surface normal at each vertex. Where n == len(self.vertices)

Return type:

(n, 3) float

property vertices: TrackedArray

The vertices of the mesh.

This is regarded as core information which cannot be generated from cache and as such is stored in self._data which tracks the array for changes and clears cached values of the mesh if this is altered.

Returns:

vertices – Points in cartesian space referenced by self.faces

Return type:

(n, 3) float

property visual

Get the stored visuals for the current mesh.

Returns:

visual – Contains visual information about the mesh

Return type:

ColorVisuals or TextureVisuals

property volume: float64

Volume of the current mesh calculated using a surface integral. If the current mesh isn’t watertight this is garbage.

Returns:

volume – Volume of the current mesh

Return type:

float

voxelized(pitch, method='subdivide', **kwargs)

Return a VoxelGrid object representing the current mesh discretized into voxels at the specified pitch

Parameters:
  • pitch (float) – The edge length of a single voxel

  • method (implementation key. See trimesh.voxel.creation.voxelizers)

  • **kwargs (additional kwargs passed to the specified implementation.)

Returns:

voxelized – Representing the current mesh

Return type:

VoxelGrid object

trimesh.available_formats() set

Get a list of all available loaders

Returns:

loaders – Extensions of available loaders i.e. ‘stl’, ‘ply’, ‘dxf’, etc.

Return type:

list

trimesh.load(file_obj: str | Path | IO | BytesIO | StringIO | BinaryIO | TextIO | dict | None, file_type: str | None = None, resolver: Resolver | dict | None = None, force: str | None = None, **kwargs) Geometry | list[Geometry]

Load a mesh or vectorized path into objects like Trimesh, Path2D, Path3D, Scene

Parameters:
  • file_obj (str, or file- like object) – The source of the data to be loadeded

  • file_type (str) – What kind of file type do we have (eg: ‘stl’)

  • resolver (trimesh.visual.Resolver) – Object to load referenced assets like materials and textures

  • force (None or str) – For ‘mesh’: try to coerce scenes into a single mesh For ‘scene’: try to coerce everything into a scene

  • kwargs (dict) – Passed to geometry __init__

Returns:

geometry – Loaded geometry as trimesh classes

Return type:

Trimesh, Path2D, Path3D, Scene

trimesh.load_mesh(file_obj: str | Path | IO | BytesIO | StringIO | BinaryIO | TextIO | dict | None, file_type: str | None = None, resolver: Resolver | dict | None = None, **kwargs) Geometry | list[Geometry]

Load a mesh file into a Trimesh object.

Parameters:
  • file_obj (str or file object) – File name or file with mesh data

  • file_type (str or None) – Which file type, e.g. ‘stl’

  • kwargs (dict) – Passed to Trimesh constructor

Returns:

Loaded geometry data.

Return type:

mesh

trimesh.load_path(file_obj, file_type: str | None = None, **kwargs)

Load a file to a Path file_object.

Parameters:
  • file_obj

    Accepts many types:
    • Path, Path2D, or Path3D file_objects

    • open file file_object (dxf or svg)

    • file name (dxf or svg)

    • shapely.geometry.Polygon

    • shapely.geometry.MultiLineString

    • dict with kwargs for Path constructor

    • (n, 2, (2|3)) float line segments

  • file_type – Type of file is required if file object is passed.

Returns:

path – Data as a native trimesh Path file_object

Return type:

Path, Path2D, Path3D file_object

trimesh.load_remote(url, **kwargs)

Load a mesh at a remote URL into a local trimesh object.

This must be called explicitly rather than automatically from trimesh.load to ensure users don’t accidentally make network requests.

Parameters:
  • url (string) – URL containing mesh file

  • **kwargs (passed to load)

Returns:

loaded – Loaded result

Return type:

Trimesh, Path, Scene

trimesh.transform_points(points: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes], matrix: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes], translate: bool = True) ndarray[tuple[int, ...], dtype[float64]]

Returns points rotated by a homogeneous transformation matrix.

If points are (n, 2) matrix must be (3, 3) If points are (n, 3) matrix must be (4, 4)

Parameters:
  • points ((n, dim) float) – Points where dim is 2 or 3.

  • matrix ((3, 3) or (4, 4) float) – Homogeneous rotation matrix.

  • translate (bool) – Apply translation from matrix or not.

Returns:

transformed – Transformed points.

Return type:

(n, dim) float

trimesh.unitize(vectors, check_valid=False, threshold=None)

Unitize a vector or an array or row-vectors.

Parameters:
  • vectors ((n,m) or (j) float) – Vector or vectors to be unitized

  • check_valid (bool) – If set, will return mask of nonzero vectors

  • threshold (float) – Cutoff for a value to be considered zero.

Returns:

  • unit ((n,m) or (j) float) – Input vectors but unitized

  • valid ((n,) bool or bool) – Mask of nonzero vectors returned if check_valid