From 196891a84f93a3647e6110d8f4b352c336ac0ac0 Mon Sep 17 00:00:00 2001 From: Michael Dawson-Haggerty Date: Thu, 11 Jul 2024 12:43:05 -0400 Subject: [PATCH 1/2] remove int32 speedup which is squirrly on numpy2 --- pyproject.toml | 2 +- trimesh/grouping.py | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5892e7f0c..ff24cf28e 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.4.2" +version = "4.4.3" authors = [{name = "Michael Dawson-Haggerty", email = "mikedh@kerfed.com"}] license = {file = "LICENSE.md"} description = "Import, export, process, analyze and view triangular meshes." diff --git a/trimesh/grouping.py b/trimesh/grouping.py index ef36d3c99..d5cccfb20 100644 --- a/trimesh/grouping.py +++ b/trimesh/grouping.py @@ -198,7 +198,7 @@ def hashable_rows( d_min, d_max = as_int.min(), as_int.max() # since we are quantizing the data down we need every value # to fit in a partial integer so we have to check against extrema - threshold = 2 ** (precision - 1) + threshold = (2 ** (precision - 1)) - 1 # if the data is within the range of our precision threshold if d_max < threshold and d_min > -threshold: @@ -206,7 +206,7 @@ def hashable_rows( hashable = np.zeros(len(as_int), dtype=np.uint64) # offset to the middle of the unsigned integer range # this array should contain only positive values - bitbang = as_int.astype(np.uint64).T + threshold + bitbang = (as_int.T + (threshold + 1)).astype(np.uint64) # loop through each column and bitwise xor to combine # make sure as_int is int64 otherwise bit offset won't work for offset, column in enumerate(bitbang): @@ -223,7 +223,7 @@ def hashable_rows( return result -def float_to_int(data, digits: Optional[Integer] = None): +def float_to_int(data, digits: Optional[Integer] = None) -> NDArray[np.int64]: """ Given a numpy array of float/bool/int, return as integers. @@ -244,8 +244,10 @@ def float_to_int(data, digits: Optional[Integer] = None): # we can early-exit if we've been passed data that is already # an integer, unsigned integer, boolean, or empty - if data.dtype.kind in "iub" or data.size == 0: + if data.dtype == np.int64: return data + elif data.dtype.kind in "iub" or data.size == 0: + return data.astype(np.int64) elif data.dtype.kind != "f": # if it's not a floating point try to make it one data = data.astype(np.float64) @@ -256,16 +258,10 @@ def float_to_int(data, digits: Optional[Integer] = None): elif not isinstance(digits, (int, np.integer)): raise TypeError("Digits must be `None` or `int`, not `{type(digits)}`") - # see if we can use a smaller integer - d_extrema = max(abs(data.min()), abs(data.max())) * 10**digits - - # compare against `np.iinfo(np.int32).max` - dtype = [np.int32, np.int64][int(d_extrema > 2147483646)] - # multiply by requested power of ten # then subtract small epsilon to avoid "go either way" rounding # then do the rounding and convert to integer - return np.round((data * 10**digits) - 1e-6).astype(dtype) + return np.round((data * 10**digits) - 1e-6).astype(np.int64) def unique_ordered(data, return_index=False, return_inverse=False): From f3949b4fb721046c23b10a5d562f84b7c30e2d11 Mon Sep 17 00:00:00 2001 From: Michael Dawson-Haggerty Date: Thu, 11 Jul 2024 12:49:20 -0400 Subject: [PATCH 2/2] since numpy2 released we don't need a prerelease --- Dockerfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index ddfde738c..0859e6f53 100644 --- a/Dockerfile +++ b/Dockerfile @@ -72,10 +72,8 @@ USER root RUN trimesh-setup --install=test,gmsh,gltf_validator,llvmpipe,binvox USER user -# install things like pytest -# install prerelease for tests and make sure we're on Numpy 2.X +# install things like pytest and make sure we're on Numpy 2.X RUN pip install .[all] && \ - pip install --pre --upgrade --force-reinstall numpy && \ python -c "import numpy as n; assert(n.__version__.startswith('2'))" # check for lint problems