NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #1243 most downloaded on PyPI
Import, export, process, analyze and view triangular meshes.
Last release 2 days ago
02 Oct 2026
Ships fairly regularly
a new release about every 4 weeks
Most releases are documented
notes for 41 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
11 years old
1026 releases · first in 2015
Fix microinch conversion factor (was 1000x too large) by @dylanpulver in #2596
percent docstring in simplify_quadric_decimation by @MushiSenpai in #2605z reset did not move the camera by @guhou-hvi in #2608Full Changelog: 5.1.0...5.1.1
One column per quarter.
perf(curvature): batch the r-tree query in discrete_mean_curvature_measure by @dexhunter in #2584
Full Changelog: 5.0.0...5.1.0
Drop support for Python 3.8 and 3.9 (EOL) by @jorenham in https://github.com/mikedh/trimesh/pull/2525
trimesh.util: fix typing errors and add missing annotations by @jorenham in https://github.com/mikedh/trimesh/pull/2541Full Changelog: https://github.com/mikedh/trimesh/compare/4.12.2...5.0.0
trimesh.util: fix typing errors and add missing annotations by @jorenham in #2541Full Changelog: 4.12.2...5.0.0
Feature: Test Coverage by @mikedh in https://github.com/mikedh/trimesh/pull/2567
Full Changelog: https://github.com/mikedh/trimesh/compare/5.0.0rc0...5.0.0rc1
Full Changelog: 5.0.0rc0...5.0.0rc1
Drop support for Python 3.8 and 3.9 (EOL) by @jorenham in https://github.com/mikedh/trimesh/pull/2525
trimesh.util: fix typing errors and add missing annotations by @jorenham in https://github.com/mikedh/trimesh/pull/2541Full Changelog: https://github.com/mikedh/trimesh/compare/4.12.2...5.0.0rc0
trimesh.util: fix typing errors and add missing annotations by @jorenham in #2541Full Changelog: 4.12.2...5.0.0rc0
Release: Mesh.contains fix by @mikedh in https://github.com/mikedh/trimesh/pull/2535
Full Changelog: https://github.com/mikedh/trimesh/compare/4.12.1...4.12.2
In test_rps, use embreex only if it is installed by @musicinmybrain in https://github.com/mikedh/trimesh/pull/2531
Full Changelog: https://github.com/mikedh/trimesh/compare/4.12.0...4.12.1
Full Changelog: 4.12.0...4.12.1
Fix duplicate ray hits in pyembree intersects_id (#2504) by @AmenLemiesa in https://github.com/mikedh/trimesh/pull/2524
_get_colors by @strophy in https://github.com/mikedh/trimesh/pull/2526Full Changelog: https://github.com/mikedh/trimesh/compare/4.11.5...4.12.0
_get_colors by @strophy in #2526Full Changelog: 4.11.5...4.12.0
Release: Fix fill_holes with face attributes
Release: Fix fill_holes with face attributes (#2518)
Trimesh.fill_holes was adding new faces but haphazardly managing the
bookkeeping: it broke len(mesh.faces) == len(mesh.face_attributes[n])
if there were any holes filled.
Trimesh.extend_faces which moves the bookkeeping of "preserve
cached face normals to avoid recalculating, pad face colors, pad face
attributes" to a generic mesh attribute in the same vein as
mesh.update_faces.repair.fill_holes to use
triangulate_quads which implemented the hole filling logic but better.
Switch the winding search to a numpy indexing trick for new faces.geometry.triangulate_quads use the preexisting
util.triangle_fan_to_faces which uses numpy instead of a list
comprehension and is heavily used and tested in the codebase.Also:
Even if we can't fully support other endian platforms, imports and exports should explicitly set endian-ness of outputs.
Release: Simple endian tests (#2512)
Even if we can't fully support other endian platforms, imports and exports should explicitly set endian-ness of outputs.
make test-arch which runs a subset of test on qemu/docker to
catch simple problems on little-endian and 32bit platforms
Line.closed setter to
auto-close polylines when passed.np.einsum/np.dot from good discussion in #2514. My
conclusion was that numpy.dot is probably not the culprit and too core
to avoid. As part of looking into this I benchmarked our other uses of
np.einsum against simple numpy operations, it was on average ~2x
slower. I also tried the `np.einsum(... optimize=True) as discussed in
this interesting
post
but for the trimesh use cases of very simple expressions this was
substantially slower in every case I measured.switch while loop to bounded for loop in the traversals logic
Release: Fix For Open Paths (#2507)
while loop to bounded for loop in the traversals logicFix for new ruff rule in 0.15.0 blocking release.
Hotfix for new ruff release (#2503)
Fix for new ruff rule in 0.15.0 blocking release.
Release: Fix WebP Export (#2499) - test and release #2498
Release: Fix WebP Export (#2499)
moves trimesh/exchange/gltf.py to trimesh/exchange/gltf/__init__.py which is identical for import users, but lets us add the additional extensions.py
Release: Extensions (#2497)
trimesh/exchange/gltf.py to
trimesh/exchange/gltf/__init__.py which is identical for import users,
but lets us add the additional extensions.py next to it.Release: Projected Precise Mode
Release: Projected Precise Mode (#2491)
projected(... precise=True)trimesh.grouping.group_distance to be more coherent.this applies the March 2024 deprecation removing Trimesh.remove_degenerate_faces and Trimesh.remove_duplicate_faces.
Release: Collision Name (#2479)
Trimesh.remove_degenerate_faces and Trimesh.remove_duplicate_faces.SceneViewer control instructions from the README to print
on the h keypress, and make the default window caption include h for helppsutil from dependencies. It was only used to check if a
scipy.spatial.cdist call was going to use more than 50% of free system
memory before falling back to a more memory-efficient but slower loop.
This now falls back to a looping method if the cdist call is going to
use more than a fixed 4 GB of memory,Cylinder) mostly override area and
volume by checking that their primitive area/volume is not exactly
floating point equal to their meshed volume. This caught that Capsule
didn't return analytical volume/area which was also fixed. We could
probably make Primitive a multiple inheritance ABC that requires certain
properties but since Primitive already inherits from Trimesh that seems
unnecessary and confusing.Be more flexible in getting unit hints from file names since it was a little silly that 20mm-xyz-cube did not resolve as mm.
Release: Unit Hints (#2468)
20mm-xyz-cube did not resolve as mm.macos-15-intel image.trimesh.scene.lighting.autolight crashing on empty
scenes by checking scene.bounds is NonePBRMaterial.to_simple using the same conversion function for the
linear baseColorFactor to RGB, but don't actually apply the change as
it seems likely to be a source of user confusion.Path2D.convex_hull to match every other geometry method.test_scene.py to pytest styleLiteral type for VoxelizationMethodsType rather
than a "loose string".deprecate trimesh.viewer.widget since glooey hasn't been updated since 2021, and the widget module isn't tested.
Release: Partially update notebook viewer (#2465)
trimesh.resources.viewer.zip artifact. The
latest version of three.js is 180 but would require re-factoring the
notebook viewer which probably should be done at some point.BooleanEngineType,
BooleanOperationType, and GraphEngineType, and apply them to boolean
and graph functions that allow different engine options.repair keyword argument from Trimesh.split to
partially fix #2460trimesh.viewer.widget since glooey hasn't been updated
since 2021, and the widget module isn't tested.process=True on the outputs of manifold3d to fix #2466trimesh.path.polygons.sample_polygonis_volume in mesh booleans to fix #2458trimesh scipy vs trimesh[easy]remove Trimesh.smoothed, which has been long-deprecated and scheduled for removal no earlier than March 2024. Trimesh.smooth_shaded has been recommend…
Release: Docstrings + Docker UV (#2455)
linear_color_mapuv to install Python, and add an alias
for pip->uv pip so the images continue to behave similarly.Trimesh.smoothed, which has been long-deprecated and
scheduled for removal no earlier than March 2024.
Trimesh.smooth_shaded has been recommended for the entire deprecation
period via a warning.trimesh.Path3D) and face data (Trimesh). We now load both into the
kwargs, but the exchange entry point picks only the faces. It should
probably be returning a Scene which has both the mesh and path.lin2srgb/srgb2lin ->
trimesh.visual.color.linear_to_srgb and add a round-trip testrelease #2450 to avoid storing the locals in ExceptionWrapper.
Release: ExceptionWrapper (#2451)
Release: PathSample Fixes + Viridis
Release: PathSample Fixes + Viridis (#2444)
viridis the default color map in
trimesh.visual.color.interpolate and enables linear interpolation with
more than two values in trimesh.visual.color.linear_color_map. This
adds a 20kb JSON copy of the lookup table for viridis rather than
depending on matplotlib to avoid the 50mb of added dependencies. Fixes
#2446gzip files in trimesh.resources.get_json. gzip
won the decompress-speed benchmark by a fair bit on my machine compared
to bz2 and lzma although it had worse compression.GLTF files with a node named "world" were warning, which is not necessary. This changes the warning to a debug.
Hotfix: Remove a warning (#2440)
GLTF files with a node named "world" were warning, which is not necessary. This changes the warning to a debug.
Release: Parent Loggers + Numpy Dtype Hotfix
Release: Parent Loggers + Numpy Dtype Hotfix (#2430)
In trimesh.util.attach_to_log(only_parent=True) if there exist loggers
for project, project.other, project.other2, this will only attach
to project. By default it is off so it shouldn't change upstream
behavior.
We should also probably be doing instead of from .util import log,
log = getLogger(__name__) everywhere.
|u8 instead of <u8, which we
need to strip for the GLTF lookup table.vertex_attributes. That would be a large change and I'm not sure it's
possible to do without breaking the API.adds a type hint to scene.show with a Literal to fix #2426
Release: Scene Type Hints (#2427)
Literal to fix #2426typing.Literal from trimesh.typed
does not work with ruff.> trimesh.interfaces.gmsh is deprecated and will be removed January 2025! There are *many* gmsh options on PyPi: scikit-gmsh gmsh pygmsh gmsh-sdk, use…
Release: Remove GMSH (#2422)
Trimesh's interface to gmsh has been scheduled for removal and has been printing this warning for more than a year:
trimesh.interfaces.gmshis deprecated and will be removed January 2025! There are many gmsh options on PyPi:scikit-gmshgmshpygmshgmsh-sdk, users should pick one of those and use it directly. If STEP loading is the only thing needed you may wantpip install cascadiowhich uses OpenCASCADE more directly and will immediately enable STEP as a loadable format in trimesh.
Changes in this release:
trimesh.interfaces.gmshRelease: Layer Filter For Path.copy
Release: Layer Filter For Path.copy (#2418)
path.copy(layers={1, 2}) to only copy particular
layers.trimesh.primitives.Extrusion(..., mid_plane: bool) option as a
helper to produce extrusions that are centered at the origin.test_extrude and test_primitives to pytest style, and
remove the outdated test skip if triangle isn't installed.metadata = None keyword argument.trimesh.exchange.gltf._mesh_to_materials function.fix minimum Python version in readme
Release: Docstrings + IMC (#2417)
deprecate OpenCTM as it is abandoned, fully superseded by Google's Draco, and was causing maintenance burden for upstream packaging teams. Discussion…
Release: Don't Copy Embree Scenes (#2411)
preserve OBJ material names through a roundtrip mentioned in #2349
Release: More SVG Fixes (#2406)
release #2401 which tests and fixes #2253
Release: SVG Fixes (#2397)
identifier_hash to the abstract base class parent.Geometrytrimesh.inertia.points_inertia to calculate the tensor of an
array of point masses to use as a simple identifier for the PointCloud.
points_inertia is also useful for approximating a moment of inertia
from samples, which we test by sampling the volume of a random box.do another release with the PyPi trusted publisher now that everything is set up.
Release: Fix Typo (#2393)
Release: Trusted Publisher (#2391) - release #2387 - release #2389
Release: Trusted Publisher (#2391)
Nothing published for this version
Face normals were being recomputed unnecessarily for Box primitives.
Release: Box Normals (#2371)
Box primitives.support most of the basic shapes in SVG imports rather than just path strings. Unsupported are ellipses and rounded rectangles. Fixes #2361
Release: SVG Shapes (#2363)
remove setuptools from trimesh[easy] as it was a legacy thing from before pyproject.toml to fix #2359
Release: Remove Setuptools (#2360)
trimesh[easy] as it was a legacy thing from
before pyproject.toml to fix #2359fixes mesh.face_normals for (n, 2) vertices (to always be 3D +Z), rather than crashing
Release: Face normal fix (#2354)
mesh.face_normals for (n, 2) vertices (to always be 3D +Z),
rather than crashingRelease: Kwarg Passthrough
Release: Kwarg Passthrough (#2347)
This was the original load entry point and is deprecated, but there are no current plans to remove it. It has been modified into a thin wrapper for lo…
Release: Refactor Load Types (#2241)
A very common source of annoyance and confusion is that trimesh.load
can return lots of different types depending on what type of file was
passed (i.e. #2239). This refactor changes the return types for the
loading functions to:
trimesh.load_scene -> SceneScene, the most general container which can hold
any loadable type. Most people should probably use this to load
geometry.trimesh.load_mesh -> TrimeshTrimesh object.
This potentially has to drop information and irreversibly concatenate
multiple meshes.Scene.to_mesh rather than load.trimesh.load_path -> PathPath2D or Path3D which both inherit from
Pathtrimesh.load -> Geometryload_scene that attempts to match the behavior of the
previous loader for backwards compatibility. In my testing against the
current main branch it was returning the same types 99.8% of the
time
although there may be other subtle differences.trimesh.load(..., force='mesh') will emit a deprecation warning in
favor of load_meshtrimesh.load(..., force='scene') will emit a deprecation warning in
favor of load_sceneAdditional changes:
Geometry.metadata['file_path'] in favor of
Geometry.source.file_path. Everything that inherits from Geometry
should now have a .source attribute which is a typed dataclass. This
was something of a struggle as file_path was populated into metadata
on load, but we also try to make sure metadata is preserved through
round-trips if at all possible. And so the load inserted different
keys into the metadata. Making it first-class information rather than a
loose key seems like an improvement, but users will have to replace
mesh.metadata["file_name"] with mesh.source.file_name.WebResolver so it can be more easily
gated by allow_remote.trimesh.resources.get in favor of the
typed alternatives (get_json, get_bytes, etc).Scene.deduplicated in favor of a very
short list comprehension on Scene.duplicate_nodestrimesh.graph.smoothed in favor of
trimesh.graph.smooth_shaded.Path3D.to_planar -> Path3D.to_2D to be consistent
with Path2D.to_3D.Merge pull request #2319 from mikedh/test/iteration
Merge pull request #2319 from mikedh/test/iteration
Release: Iteration Tests
Merge pull request #2312 from mikedh/units/xaml
Merge pull request #2312 from mikedh/units/xaml
Release: Boolean Tests
Merge pull request #2300 from mikedh/followup/3mf
Merge pull request #2300 from mikedh/followup/3mf
Release Followup: Tuning 3MF loading
Merge pull request #2290 from mikedh/release/revolve
Merge pull request #2290 from mikedh/release/revolve
Release: Revolve Caps
Merge pull request #2278 from mikedh/fix/scene
Merge pull request #2278 from mikedh/fix/scene
Release: Scene Transform
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →