trimesh 5.0.0rc0 documentation (original) (raw)

trimesh


Github Actions codecov Docker Image Version (latest by date) PyPI version

Trimesh is a pure Python 3.10+ library for loading and using triangular meshes with an emphasis on watertight surfaces. The goal of the library is to provide a full featured and well tested Trimesh object which allows for easy manipulation and analysis, in the style of the Polygon object in theShapely library.

The API is mostly stable, but this should not be relied on and is not guaranteed: install a specific version if you plan on deploying something using trimesh.

Pull requests are appreciated and responded to promptly! If you’d like to contribute, here a quick development and contributing guide.

Basic Installation

Keeping trimesh easy to install is a core goal, thus the only hard dependency is `numpy <http://www.numpy.org/>`__. Installing other packages adds functionality but is not required. For the easiest install with just numpy:

The minimal install can load many supported formats (STL, PLY, OBJ, GLTF/GLB) into numpy.ndarray values. More functionality is available when soft dependencies are installed, including convex hulls (scipy), graph operations (networkx), fast ray queries (embreex), vector path handling (shapely andrtree), XML formats like 3DXML/XAML/3MF (lxml), preview windows (pyglet), faster cache checks (xxhash), etc.

To install trimesh with the soft dependencies that generally install cleanly from binaries on Linux x86_64, MacOS ARM, and Windows x86_64 using pip:

pip install trimesh[easy]

If you are supporting a different platform or are freezing dependencies for an application we recommend you do not use extras, i.e. depend ontrimesh scipy versus trimesh[easy]. Further information is available in the advanced installation documentation.

Quick Start

Here is an example of loading a mesh from file and colorizing its faces (nicely formatted notebook version of this example.

import numpy as np import trimesh

attach to logger so trimesh messages will be printed to console

trimesh.util.attach_to_log()

mesh objects can be created from existing faces and vertex data

mesh = trimesh.Trimesh(vertices=[[0, 0, 0], [0, 0, 1], [0, 1, 0]], faces=[[0, 1, 2]])

by default, Trimesh will do a light processing, which will

remove any NaN values and merge vertices that share position

if you want to not do this on load, you can pass process=False

mesh = trimesh.Trimesh(vertices=[[0, 0, 0], [0, 0, 1], [0, 1, 0]], faces=[[0, 1, 2]], process=False)

some formats like glb represent multiple meshes with multiple instances

and load_mesh will concatenate irreversibly, load it as a Scene

if you need instance information:

scene = trimesh.load_scene('models/CesiumMilkTruck.glb')

mesh = trimesh.load_mesh('models/CesiumMilkTruck.glb')

is the current mesh watertight?

mesh.is_watertight

what's the euler number for the mesh?

mesh.euler_number

the convex hull is another Trimesh object that is available as a property

lets compare the volume of our mesh with the volume of its convex hull

print(mesh.volume / mesh.convex_hull.volume)

since the mesh is watertight it means there is a volume

with a center of mass calculated from a surface integral approach

which we can set as the origin for our mesh. It's perfectly fine to

alter the vertices directly:

mesh.vertices -= mesh.center_mass

although this will completely clear the cache including face normals

as we don't know that they're still valid. Using the translation

method will try to save cached values that are still valid:

mesh.apply_translation(-mesh.center_mass)

what's the (3, 3) moment of inertia for the mesh?

mesh.moment_inertia

if there are multiple bodies in the mesh we can split the mesh by

connected components of face adjacency

since this example mesh is a single watertight body we get a list of one mesh

mesh.split()

facets are groups of coplanar adjacent faces

set each facet to a random color

colors are 8 bit RGBA by default (n, 4) np.uint8

for facet in mesh.facets: mesh.visual.face_colors[facet] = trimesh.visual.random_color()

preview mesh in an opengl window if you installed pyglet and scipy with pip

mesh.show()

transform method can be passed a (4, 4) matrix and will cleanly apply the transform

mesh.apply_transform(trimesh.transformations.random_rotation_matrix())

axis aligned bounding box is available

mesh.bounding_box.extents

a minimum volume oriented bounding box also available

primitives are subclasses of Trimesh objects which automatically generate

faces and vertices from data stored in the 'primitive' attribute

mesh.bounding_box_oriented.primitive.extents mesh.bounding_box_oriented.primitive.transform

show the mesh appended with its oriented bounding box

the bounding box is a trimesh.primitives.Box object, which subclasses

Trimesh and lazily evaluates to fill in vertices and faces when requested

(press w in viewer to see triangles)

(mesh + mesh.bounding_box_oriented).show()

bounding spheres and bounding cylinders of meshes are also

available, and will be the minimum volume version of each

except in certain degenerate cases, where they will be no worse

than a least squares fit version of the primitive.

print(mesh.bounding_box_oriented.volume, mesh.bounding_cylinder.volume, mesh.bounding_sphere.volume)

Features

Additional Notes

Links

Install

Examples

Geometry Formats

Contributing

Docker

API Reference