wolph / numpy-stl

Simple library to make working with STL files (and 3D objects in general) fast and easy.
http://numpy-stl.readthedocs.org/
BSD 3-Clause "New" or "Revised" License
605 stars 103 forks source link

2.15 update breaks ASCII file read in a specific case #161

Closed bbrelje closed 3 years ago

bbrelje commented 3 years ago

Our lab uses numpy-stl as part of our regression testing framework and we've (so far) left numpy-stl unpinned. The 2.15 update broke one of our test cases and it seems to be related to ASCII file parsing. For now we will pin to 2.14.2 so a hotfix isn't urgent, but I think it's a legitimate bug.

I developed a Docker container which illustrates the issue and can be pulled from Dockerhub as benjaminbrelje/numpystlbug. It's basically a vanilla ubuntu image with python3, pip3, git, and numpy-stl installed along with the stl file in question (bwb.stl). It also fails across a variety of Ubuntu and Centos 7 setups in our build matrix.

The following Python console action should work (and does work in 2.14.2) but errors out as of 2.15. From the host: $ docker run -it benjaminbrelje/numpystlbug In the container:

root@52e18fd1544c:/# cd ~
root@52e18fd1544c:~# dir
bwb.stl
root@52e18fd1544c:~# python3
Python 3.8.5 (default, Jul 28 2020, 12:59:40) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from stl import mesh
>>> a = mesh.Mesh.from_file('bwb.stl')
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/stl/stl.py", line 218, in _ascii_reader
    assert get().lower() == b('endloop')
AssertionError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/stl/stl.py", line 71, in load
    name, data = cls._load_ascii(
  File "/usr/local/lib/python3.8/dist-packages/stl/stl.py", line 241, in _load_ascii
    return name, numpy.fromiter(iterator, dtype=cls.dtype)
  File "/usr/local/lib/python3.8/dist-packages/stl/stl.py", line 223, in _ascii_reader
    raise RuntimeError(recoverable[0], e)
RuntimeError: (False, AssertionError())

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/dist-packages/stl/stl.py", line 378, in from_file
    name, data = cls.load(
  File "/usr/local/lib/python3.8/dist-packages/stl/stl.py", line 90, in load
    name, data = cls._load_binary(fh, header,
  File "/usr/local/lib/python3.8/dist-packages/stl/stl.py", line 110, in _load_binary
    assert count < MAX_COUNT, ('File too large, got %d triangles which '
AssertionError: File too large, got 1970216992 triangles which exceeds the maximum of 100000000
>>> 

Downgrading to 2.14.2 fixes the problem:

root@52e18fd1544c:~# pip3 install numpy-stl==2.14.2
Collecting numpy-stl==2.14.2
  Downloading numpy-stl-2.14.2.tar.gz (480 kB)
     |████████████████████████████████| 480 kB 1.2 MB/s 
Requirement already satisfied: numpy in /usr/local/lib/python3.8/dist-packages (from numpy-stl==2.14.2) (1.20.1)
Requirement already satisfied: python-utils>=1.6.2 in /usr/local/lib/python3.8/dist-packages (from numpy-stl==2.14.2) (2.5.6)
Requirement already satisfied: six in /usr/local/lib/python3.8/dist-packages (from python-utils>=1.6.2->numpy-stl==2.14.2) (1.15.0)
Building wheels for collected packages: numpy-stl
  Building wheel for numpy-stl (setup.py) ... done
  Created wheel for numpy-stl: filename=numpy_stl-2.14.2-py3-none-any.whl size=18323 sha256=2d888f6d40e7ed838d335cd4b6378ec3ac422003d975ba0bf94ed61b8b05c26b
  Stored in directory: /root/.cache/pip/wheels/cd/f3/f2/8cf0e851670675a91b4a4116b76993d467ed77331c2cd4f9a0
Successfully built numpy-stl
Installing collected packages: numpy-stl
  Attempting uninstall: numpy-stl
    Found existing installation: numpy-stl 2.15.0
    Uninstalling numpy-stl-2.15.0:
      Successfully uninstalled numpy-stl-2.15.0
Successfully installed numpy-stl-2.14.2
root@52e18fd1544c:~# python3
Python 3.8.5 (default, Jul 28 2020, 12:59:40) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from stl import mesh
>>> a = mesh.Mesh.from_file('bwb.stl')
>>> dir(a)
['_Logged__get_name', '__abstractmethods__', '__class__', '__contains__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__setitem__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_abc_impl', '_areas', '_ascii_reader', '_get_or_update', '_load_ascii', '_load_binary', '_set', '_write_ascii', '_write_binary', 'areas', 'attr', 'check', 'data', 'debug', 'dtype', 'error', 'exception', 'from_file', 'from_files', 'from_multi_file', 'get', 'get_header', 'get_mass_properties', 'get_mass_properties_with_density', 'get_unit_normals', 'info', 'is_closed', 'items', 'keys', 'load', 'log', 'logger', 'max_', 'min_', 'name', 'normals', 'points', 'remove_duplicate_polygons', 'remove_empty_areas', 'rotate', 'rotate_using_matrix', 'rotation_matrix', 'save', 'speedups', 'transform', 'translate', 'units', 'update_areas', 'update_max', 'update_min', 'update_normals', 'update_units', 'v0', 'v1', 'v2', 'values', 'vectors', 'warning', 'x', 'y', 'z']
>>> 

The stl file in question is located here: https://github.com/mdolab/pygeo/blob/master/tests/inputFiles/bwb.stl

Thank you for providing this useful package!

wolph commented 3 years ago

I believe I've fixed it in 2.15.1 but please let me know if you're still experiencing issues :)

I've included your file as one of the tests so it shouldn't give issues in the future.

bbrelje commented 3 years ago

That was quick! Thank you!