Skip to content

Commit ffe3c35

Browse files
authored
Release: Collision Name (#2479)
- release #2475 - release #2474 - release #2483 - release #2481 - release #2486 - release #2480 - this applies the March 2024 deprecation removing `Trimesh.remove_degenerate_faces` and `Trimesh.remove_duplicate_faces`. - moves the `SceneViewer` control instructions from the README to print on the `h` keypress, and make the default window caption include `h for help` - remove `psutil` 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, - add check that primitives (i.e. `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. - clean up references to OpenCTM, which [was deprecated](trimesh/openctm#5) for low use, being unmaintained, and inflicting a burden on upstream package management. - docker images now build with 3.14
2 parents 76b6dd1 + 4202422 commit ffe3c35

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1141
-711
lines changed

Makefile

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ NAME=trimesh/trimesh
1919
REPO=docker.io
2020
IMAGE=$(REPO)/$(NAME)
2121

22+
# the dockerfile location
23+
DOCKERFILE=helpers/Dockerfile
24+
2225
# the tags we'll be applying
2326
TAG_LATEST=$(IMAGE):latest
2427
TAG_GIT_SHA=$(IMAGE):$(GIT_SHA)
@@ -34,12 +37,18 @@ help: ## Print usage help
3437
# force amd64 builds on non-amd64 hosts (e.g. Apple Silicon)
3538
export DOCKER_DEFAULT_PLATFORM=linux/amd64
3639

40+
# docker build arguments common to all build paths
41+
# NEEDS_BUILDCHAIN can probably be false once 3.14 matures a little more
42+
# `--build-arg=NEEDS_BUILDCHAIN=true`
43+
44+
DOCKER_BUILD_ARGS=--progress=plain --file $(DOCKERFILE)
45+
3746
# build the output stage image using buildkit
3847
.PHONY: build
3948
build: ## Build the docker images
4049
DOCKER_BUILDKIT=1 \
4150
docker build \
42-
--progress=plain \
51+
$(DOCKER_BUILD_ARGS) \
4352
--target output \
4453
--tag $(TAG_LATEST) \
4554
--tag $(TAG_VERSION) \
@@ -51,9 +60,9 @@ build: ## Build the docker images
5160
tests: ## Run unit tests inside docker images.
5261
DOCKER_BUILDKIT=1 \
5362
docker build \
63+
$(DOCKER_BUILD_ARGS) \
5464
--target tests \
55-
--progress=plain \
56-
--build-arg "CODECOV_TOKEN=$(CODECOV_TOKEN)" \
65+
--secret id=codecov_token,env=CODECOV_TOKEN \
5766
.
5867

5968
# build the docs inside our image and eject the contents
@@ -62,8 +71,8 @@ tests: ## Run unit tests inside docker images.
6271
docs: ## Build trimesh's sphinx docs
6372
DOCKER_BUILDKIT=1 \
6473
docker build \
74+
$(DOCKER_BUILD_ARGS) \
6575
--target docs \
66-
--progress=plain \
6776
--output html \
6877
.
6978

README.md

Lines changed: 44 additions & 111 deletions
Large diffs are not rendered by default.

docker/openctm.bash

Lines changed: 0 additions & 22 deletions
This file was deleted.

docs/content/contributing.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Contributing To Trimesh
22
=======================
33

4-
Pull requests are always super welcome! Trimesh is a relatively small open source project and really benefits from the bugfixes, features, and other stuff the 100+ contributors have PR'd, so thanks!
4+
Pull requests are always super welcome! Trimesh is a relatively small open source project and really benefits from the bugfixes, features, and other stuff the 200+ contributors have PR'd, so thanks!
55

66

77
## Developer Quick Start
@@ -19,6 +19,7 @@ Then when you open a new terminal you can verify it got the right environment wi
1919
```
2020
mikedh@orion:trimesh$ which python
2121
/home/mikedh/venv/bin/python
22+
2223
mikedh@orion:trimesh$ which pip
2324
/home/mikedh/venv/bin/pip
2425
```
@@ -82,6 +83,20 @@ ruff format
8283
Trimesh uses the [Sphinx Numpy-style](https://www.sphinx-doc.org/en/master/usage/extensions/example_numpy.html#example-numpy) docstrings which get parsed into the API reference page.
8384

8485

86+
## Deprecations
87+
88+
We try to add a somewhat helpful `DeprecationWarning` one year in advance of a major API change:
89+
90+
```python
91+
warnings.warn(
92+
"`remove_duplicate_faces` is deprecated "
93+
+ "and will be removed in March 2024: "
94+
+ "replace with `mesh.update_faces(mesh.unique_faces())`",
95+
category=DeprecationWarning,
96+
stacklevel=2,
97+
)
98+
```
99+
85100
## General Tips
86101

87102
Python can be fast but only when you use it as little as possible. In general, if you ever have a block which loops through faces and vertices it will be basically unusable with even moderately sized meshes. All operations on face or vertex arrays should be vectorized numpy operations unless absolutely unavoidable. Profiling helps figure out what is slow, but some general advice:

docs/content/formats.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
Mesh Formats
2+
=======================
3+
4+
There's lots of mesh formats out there!
5+
6+
7+
## Which Mesh Format Should I Use?
8+
9+
Quick recommendation: `GLB`. If you're looking for "the simplest possible ASCII format because I have to write an importer in another language" you should take a look at `OFF`.
10+
11+
GLTF is nice because it has a [well defined specification](https://github.com/KhronosGroup/glTF/tree/main/specification/2.0), supports most things people would want, and is very fast to load. It's fast because the format has a small JSON header which defines the layout of a packed binary blob, so the arrays can be loaded with `numpy.frombuffer` which is extremely fast. As a counterpoint a format like `3MF` defines each vertex as an `<vertex><x>"1.0123312"</x> ...`, which is almost as far from fast as it is possible to get.
12+
13+
A very popular format is Wavefront `OBJ`. It's supported across many tools, although it lacks a specification and has an internal data structure that requires some pretty heavy conversion to the `trimesh` flat-array format which can lead to some confusion: for example `f 1/2/3 4/5/6 7//7 9/9/9` is a valid face. It's not a bad choice, but going with GLB is probably advisable in most cases.
14+
15+
## Supported Formats
16+
17+
No dependencies indicates a minimal install of just `trimesh` and `numpy` can load the format. If you are working with the textures, images are handled using `pip install pillow`.
18+
19+
| Format | Dependencies | Notes |
20+
| ------ | ------------ | ----- |
21+
| `GLB`/`GLTF` | | A scene format with flat arrays (i.e. very quick loading), wide support, and a well defined specification. Most people should use this is possible. It also supports most things you'd want including texture, point clouds, etc. |
22+
| `STL` | | Has both ASCII and binary representations, both of which are supported. This is a very basic format, and it consists of a "triangle soup" with no shared vertices. This format is the reason why `trimesh` has the default `process=True` which merges vertices since an unindexed triangle soup isn't super useful. |
23+
| `PLY` | | Has both ASCII and Binary representations, both are supported. It has indexed triangles, and a header format that supports named properties. [Overview](https://paulbourke.net/dataformats/ply/index.html)
24+
| `OBJ` | | Wavefront OBJ, relatively slow to parse and may require re-indexing to match the `trimesh` "matching arrays" data structure. |
25+
| `OFF` | | Text format that is just vertices and faces in ASCII |
26+
| `3MF` | `lxml`, `networkx` | An XML based 3D printing focused mesh format. It |
27+
| `3DXML` | `lxml`, `networkx`, `PIL` | Dassault's XML format from CATIA/SolidWorks, the easiest way to get from Solidworks to a nice 3D scene. |
28+
| `DAE`/`ZAE` | `lxml`, `PIL`, `pycollada` | COLLADA, an XML-based scene format that supports everything. |
29+
| `STEP`/`STP` | `cascadio` | The only boundary representation format with open-source loaders available. `cascadio` uses OpenCASCADE to convert to GLB before loading. |
30+
| `XAML` | `lxml` | Microsoft's 3D XAML format which exports from Solidworks |
31+
| `DXF` | | AutoCAD's drawing format, we only support the ASCII version with 2D geometry. |
32+
| `SVG` | `svg.path` | We import 2D paths as `trimesh.Path2D` from these, discarding pretty much all visual information other than the curves. |
33+
| `XYZ` | | Simple ASCII point cloud format with just one coordinate per line. |

docs/content/index.rst

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,20 @@ Install
1212

1313
install.md
1414

15+
Examples
16+
==========
17+
.. toctree::
18+
:maxdepth: 1
19+
20+
Examples <examples.rst>
21+
22+
Geometry Formats
23+
==========
24+
.. toctree::
25+
:maxdepth: 1
26+
27+
Geometry Formats <formats.md>
28+
1529
Contributing
1630
==========
1731
.. toctree::
@@ -25,13 +39,6 @@ Docker
2539
:maxdepth: 1
2640

2741
Docker <docker.md>
28-
29-
Examples
30-
==========
31-
.. toctree::
32-
:maxdepth: 1
33-
34-
Examples <examples.rst>
3542

3643
API Reference
3744
=============

docs/content/install.md

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,39 @@ Installation
44
The only thing required to install `trimesh` is
55
[numpy](http://www.numpy.org/).
66

7-
All other dependencies are \'soft,\' or trimesh will raise the exceptions (usually but not always an `ImportError`) at runtime if a function is called that requires a package that isn\'t installed. If you do the most basic install of `trimesh` it will only install `numpy`:
7+
All other dependencies are \"soft,\"or `trimesh` will raise the import exceptions (typically an `ImportError`) at runtime if a function is called that requires a package that isn\'t installed. If you do the most basic install of `trimesh` it will only install `numpy`:
88

99
```
1010
pip install trimesh
1111
```
1212

13-
This will enable you to load most formats into numpy arrays: STL, PLY, OBJ, GLB, GLTF.
14-
15-
If you\'d like most soft dependencies which should install cleanly on Mac, Windows, and Linux, you can use the `easy` pip extra:
13+
This will enable you to load most [formats](/formats.html) into numpy arrays: STL, PLY, OBJ, GLB, GLTF.
1614

15+
To install `trimesh` with the soft dependencies that generally install cleanly on Linux (x86_64), MacOS (ARM), and Windows (x86_64), you can use the `easy` install extra using `pip`:
1716
```
1817
pip install trimesh[easy]
1918
```
2019

2120

21+
## What makes a dependency `easy`?
22+
23+
"`pip install` always works." What this translates to has changed over time (specifically since MacOS went ARM). The current definition is:
24+
25+
- Using a [current](https://devguide.python.org/versions/) version of CPython.
26+
- Without a build toolchain installed. So `sdist` that requires compilation is not `easy`: binary wheels are required.
27+
- On the latest version of your operating system:
28+
- MacOS ARM. ARM took a long time to support because upstream Github Actions runners and `cibuildwheel` had to support it first, but after a few years it has stabilized. MacOS x86_64 wheels will be continued to be built for most projects until [Github turn the lights out in August 2027](https://github.com/actions/runner-images/issues/13045)
29+
- Windows x86_64
30+
- Linux x86_64 non-MUSL.
31+
32+
33+
## Freezing Dependencies
34+
35+
If you are freezing your dependencies with one of the many methods (version range in `pyproject.toml`, `requirements.txt`, `uv.lock`, etc), we recommend that you do not hard-code extras: i.e. depend on `trimesh scipy` versus `trimesh[easy]`.
36+
37+
Trimesh's test matrix runs with the latest version of the packages, so you may get functionality mis-matches by using the extra. And if you're relying on one of the smaller more specialized dependencies (`vhacdx`, etc) it is much easier to diagnose a fault with the specific package.
38+
39+
2240
## Conda Packages
2341

2442
If you prefer a `conda` environment, `trimesh` is available on `conda-forge` ([trimesh-feedstock repo](https://github.com/conda-forge/trimesh-feedstock))
@@ -42,8 +60,8 @@ Trimesh has a lot of soft-required upstream packages, and we try to make sure th
4260
| `lxml` | Parse XML documents. We use this over the built-in ones as it was slightly faster, and there was a format implemented which was extremely annoying to handle without the ability to get parent nodes (which `lxml` has but built-in XML doesn't). | Standard library's XML | `easy` |
4361
| `networkx` | Pure Python graph library that's reasonably fast and has a nice API. `scipy.sparse.csgraph` is way faster in most cases but is hard to understand and doesn't implement as many algorithms. | `graph-tool`, `scipy.sparse.csgraph` | `easy` |
4462
| `shapely` | Bindings to `GEOS` for 2D spatial stuff: "set-theoretic analysis and manipulation of planar features" which lets you offset, union, and query polygons. | `clipper` | `easy` |
45-
| `rtree` | Query ND rectangles with a spatial tree for a "broad phase" intersection. Used in polygon generation ("given N closed curves which curve contains the other curve?") and as the broad-phase for the built-in-numpy slow ray query engine. | `fcl` maybe? | `easy` |
46-
|`httpx`| Do network queries in `trimesh.exchange.load_remote`, will *only* make network requests when asked | `requests`, `aiohttp` | `easy`|
63+
| `rtree` | Query ND rectangles with a spatial tree for a "broad phase" intersection. Used in polygon generation ("given N closed curves which curve contains the other curve?") and as the broad-phase for the built-in-numpy slow ray query engine. | | `easy` |
64+
|`httpx`| Do network queries in `trimesh.exchange.load_remote`, we will *only* make network requests when asked | `requests`, `aiohttp` | `easy`|
4765
|`sympy`| Evaluate symbolic algebra | | `recommend`|
4866
|`xxhash`| Quickly hash arrays, used for our cache checking | | `easy`|
4967
|`charset-normalizer`| When we fail to decode text as UTF-8 we then check with charset-normalizer which guesses an encoding, letting us load files even with weird encodings. | | `easy`|
@@ -55,7 +73,6 @@ Trimesh has a lot of soft-required upstream packages, and we try to make sure th
5573
|`pyglet<2`| OpenGL bindings for our simple debug viewer. | | `recommend`|
5674
|`xatlas`| Unwrap meshes to generate UV coordinates quickly and well. | | `recommend`|
5775
|`python-fcl`| Do collision queries between meshes | | `recommend`|
58-
|`glooey`| Provide a viewer with widgets. | | `recommend`|
5976
|`meshio`| Load additional mesh formats. | | `recommend`|
6077
|`scikit-image`| Used in voxel ops | | `recommend`|
6178
|`mapbox-earcut`| Triangulate 2D polygons | `triangle` which has an unusual license | `easy`|
@@ -66,7 +83,6 @@ Trimesh has a lot of soft-required upstream packages, and we try to make sure th
6683
|`pyinstrument`| A sampling based profiler for performance tweaking. | | `test`|
6784
|`vhacdx`| A binding for VHACD which provides convex decompositions | | `recommend`|
6885
|`manifold3d`| A binding for the Manifold mesh boolean engine | | `recommend`|
69-
|`openctm`| A binding for OpenCTM loaders enabling `.ctm` loading | | `recommend`|
7086
|`cascadio`| A binding for OpenCASCADE enabling `.STEP` loading | | `recommend`|
7187

7288
## Adding A Dependency

docs/requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
pypandoc==1.15
1+
pypandoc==1.16.2
22
recommonmark==0.7.1
33
jupyter==1.1.1
44

55
# get sphinx version range from furo install
6-
furo==2025.7.19
6+
furo==2025.9.25
77
myst-parser==4.0.1
88
pyopenssl==25.3.0
99
autodocsumm==0.2.14
1010
jinja2==3.1.6
11-
matplotlib==3.10.6
11+
matplotlib==3.10.7
1212
nbconvert==7.16.6
1313

Dockerfile renamed to helpers/Dockerfile

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
# Stage 1: Build uv
3-
FROM ghcr.io/astral-sh/uv:0.8.16 AS uv
3+
FROM ghcr.io/astral-sh/uv:0.9.8 AS uv
44

55
# use a vanilla Debian base image
66
FROM debian:trixie-slim AS base
@@ -23,7 +23,9 @@ WORKDIR /home/user
2323
# but if you use Debian methods like `update-alternatives`
2424
# it won't provide a `pip` which works easily and it isn't
2525
# easy to know how system packages interact with pip packages
26-
RUN uv venv --python=python3.13 venv
26+
27+
ARG PYTHON_VERSION="3.14.0"
28+
RUN uv venv --python=python${PYTHON_VERSION} venv
2729

2830
# Add `pip` script install location to $PATH
2931
ENV PATH="/home/user/venv/bin:$PATH"
@@ -34,19 +36,33 @@ RUN echo '#!/bin/sh' > /home/user/venv/bin/pip && \
3436
chmod +x /home/user/venv/bin/pip
3537

3638
# Install helper script to PATH.
37-
COPY --chmod=755 docker/trimesh-setup /home/user/venv/bin
39+
COPY --chmod=755 helpers/trimesh-setup /home/user/venv/bin
3840

3941
#######################################
4042
## install things that need building
4143
FROM base AS build
4244

45+
# the `easy` extra shouldn't need a build chain
46+
# unless we're on a brand new Python release
47+
ARG NEEDS_BUILDCHAIN="false"
48+
USER root
49+
# install build dependencies
50+
RUN if [ "$NEEDS_BUILDCHAIN" = "true" ]; then trimesh-setup --install build; fi
51+
USER user
52+
4353
# copy in essential files
4454
COPY --chown=499 trimesh/ /home/user/trimesh
4555
COPY --chown=499 pyproject.toml /home/user/
4656

4757
# install trimesh into the venv
4858
RUN pip install /home/user[easy]
4959

60+
# recursively delete tests installed with libraries
61+
# these are about 30mb for no particular reason, and
62+
# if we break something we are doing this BEFORE tests
63+
RUN cd /home/user/venv && \
64+
find . -type d -name tests -exec rm -rf {} + || true
65+
5066
####################################
5167
### Build output image most things should run on
5268
FROM base AS output
@@ -71,14 +87,16 @@ USER root
7187
RUN trimesh-setup --install=test,gmsh,gltf_validator,llvmpipe,binvox,blender,build
7288
USER user
7389

74-
RUN blender --version
90+
RUN bash -c "ldconfig & blender --version"
7591

7692
# install things like pytest and make sure we're on Numpy 2.X
7793
RUN pip install .[all] && \
7894
python -c "import numpy as n; assert(n.__version__.startswith('2'))"
7995

80-
# check for lint problems
81-
RUN ruff check trimesh
96+
# check for lint problems and print the current python version
97+
RUN ruff check trimesh && \
98+
python --version && \
99+
python -c "from beartype import __version__ as v; print(v)"
82100

83101
# run pytest wrapped with xvfb for simple viewer tests
84102
# print more columns so the short summary is usable
@@ -90,11 +108,11 @@ RUN COLUMNS=240 xvfb-run pytest \
90108
-p no:cacheprovider tests
91109

92110

93-
# set codecov token as a build arg to upload
94-
ARG CODECOV_TOKEN=""
95-
RUN curl -Os https://uploader.codecov.io/latest/linux/codecov && \
96-
chmod +x codecov && \
97-
./codecov -t ${CODECOV_TOKEN}
111+
# use BuildKit secrets to access codecov token securely
112+
RUN --mount=type=secret,id=codecov_token \
113+
curl -Os https://uploader.codecov.io/latest/linux/codecov && \
114+
chmod +x codecov && \
115+
./codecov -t $(cat /run/secrets/codecov_token || echo "")
98116

99117
################################
100118
### Build Sphinx Docs
File renamed without changes.

0 commit comments

Comments
 (0)