Repository: mikedh/trimesh
Pull request #2347 (2025-01-29 18:32:14)

Release: Kwarg Passthrough
- release #2343 
- release #2346 



Patch:
diff --git a/Dockerfile b/Dockerfile
index f864e423..7de3bf38 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -37,8 +37,9 @@ COPY --chown=499 pyproject.toml /home/user/
 # install trimesh into the venv
 RUN pip install /home/user[easy]
 
-# install FCL which currently has broken wheels on PyPi
-RUN pip install https://github.com/BerkeleyAutomation/python-fcl/releases/download/v0.7.0.7/python_fcl-0.7.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
+# install FCL from a hopefully temporary fork
+# as the original `python-fcl` currently has broken wheels on PyPi
+RUN pip install fclx
 
 ####################################
 ### Build output image most things should run on
diff --git a/docs/content/install.md b/docs/content/install.md
index 06e028f6..c121d543 100644
--- a/docs/content/install.md
+++ b/docs/content/install.md
@@ -18,11 +18,6 @@ If you\'d like most soft dependencies which should install cleanly on Mac, Windo
 pip install trimesh[easy]
 ```
 
-Or if you want the full experience, you can try the `all` extra which includes all the testing and recommended packages:
-```
-pip install trimesh[all]
-```
-
 
 ## Conda Packages
 
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 934ecbe7..44919076 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,11 +1,11 @@
-pypandoc==1.14
+pypandoc==1.15
 recommonmark==0.7.1
 jupyter==1.1.1
 
 # get sphinx version range from furo install
 furo==2024.8.6
 myst-parser==4.0.0
-pyopenssl==24.3.0
+pyopenssl==25.0.0
 autodocsumm==0.2.14
 jinja2==3.1.5
 matplotlib==3.10.0
diff --git a/pyproject.toml b/pyproject.toml
index 8d5892db..4f1970cd 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,7 +5,7 @@ requires = ["setuptools >= 61.0", "wheel"]
 [project]
 name = "trimesh"
 requires-python = ">=3.8"
-version = "4.6.0"
+version = "4.6.1"
 authors = [{name = "Michael Dawson-Haggerty", email = "mikedh@kerfed.com"}]
 license = {file = "LICENSE.md"}
 description = "Import, export, process, analyze and view triangular meshes."
@@ -96,7 +96,7 @@ recommend = [
     "scikit-image",
     "fast-simplification",
     # "python-fcl", # do collision checks # TODO : broken on numpy 2
-    "openctm", # load `CTM` compressed models
+    "openctm; platform_machine=='x86_64'", # load `CTM` compressed models
     "cascadio", # load `STEP` files
 ]
 
diff --git a/trimesh/exchange/load.py b/trimesh/exchange/load.py
index 3faba2f9..c0f57191 100644
--- a/trimesh/exchange/load.py
+++ b/trimesh/exchange/load.py
@@ -1,5 +1,6 @@
 import json
 import os
+from copy import deepcopy
 
 import numpy as np
 
@@ -210,7 +211,8 @@ def load_scene(
             )
         elif arg.file_type in mesh_loaders:
             # use mesh loader
-            loaded = _load_kwargs(
+            parsed = deepcopy(kwargs)
+            parsed.update(
                 mesh_loaders[arg.file_type](
                     file_obj=arg.file_obj,
                     file_type=arg.file_type,
@@ -219,6 +221,8 @@ def load_scene(
                     **kwargs,
                 )
             )
+            loaded = _load_kwargs(**parsed)
+
         elif arg.file_type in compressed_loaders:
             # for archives, like ZIP files
             loaded = _load_compressed(arg.file_obj, file_type=arg.file_type, **kwargs)
diff --git a/trimesh/visual/color.py b/trimesh/visual/color.py
index e511d867..85ebd0ba 100644
--- a/trimesh/visual/color.py
+++ b/trimesh/visual/color.py
@@ -924,12 +924,14 @@ def interpolate(
 
     # make input always float
     values = np.asanyarray(values, dtype=np.float64).ravel()
+
+    # get both minumium and maximum values for range normalization
+    v_min, v_max = values.min(), values.max()
     # offset to zero
-    values -= values.min()
-    # get the value range to avoid dividing by zero
-    values_ptp = np.ptp(values)
-    if values_ptp > 0.0:
-        values /= values_ptp
+    values -= v_min
+    # normalize to the 0.0 - 1.0 range
+    if v_min != v_max:
+        values /= v_max - v_min
 
     # scale values to 0.0 - 1.0 and get colors
     colors = cmap(values)


Test patch:
diff --git a/tests/test_bounds.py b/tests/test_bounds.py
index f4649be3..1e1680a4 100644
--- a/tests/test_bounds.py
+++ b/tests/test_bounds.py
@@ -21,8 +21,8 @@ class BoundsTest(g.unittest.TestCase):
 
         # Make sure oriented bound estimation runs within 30 seconds.
         assert (
-            stop - start < 30
-        ), f"Took {stop - start} seconds to estimate the oriented bounding box."
+            stop - start < 60
+        ), f"Took {stop - start}s to estimate the oriented bounding box."
 
     def test_obb_mesh(self):
         """
diff --git a/tests/test_loaded.py b/tests/test_loaded.py
index 09105545..cb6edb2a 100644
--- a/tests/test_loaded.py
+++ b/tests/test_loaded.py
@@ -31,6 +31,18 @@ class LoaderTest(g.unittest.TestCase):
         assert len(m.faces) > 0
         assert m.area > 1e-5
 
+    def test_load_mesh(self):
+        # test the influence of the parameter `process` for `load_mesh`
+        with open(g.os.path.join(g.dir_models, "featuretype.STL"), "rb") as file_obj:
+            mesh = g.trimesh.load_mesh(file_obj=file_obj, file_type="stl", process=False)
+            # check that number of vertices is not being reduced
+            assert len(mesh.vertices) == 10428
+
+        with open(g.os.path.join(g.dir_models, "featuretype.STL"), "rb") as file_obj:
+            mesh = g.trimesh.load_mesh(file_obj=file_obj, file_type="stl", process=True)
+            # check that number of vertices is being reduced
+            assert len(mesh.vertices) == 1722
+
     def test_fileobj(self):
         # make sure we don't close file objects that were passed
         # check load_mesh