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

Cannot read binary STL files in version #158

Closed yellowshippo closed 3 years ago

yellowshippo commented 3 years ago

With version 2.14.0, I cannot read binary STL files, while it was possible with version 2.13.0.

How to reproduce:

  1. Unzip and place the sample STL file (https://github.com/WoLpH/numpy-stl/files/5900440/out.stl.zip; in fact it is generated using numpy-stl 2.10.1, according to the header of the file) under your current directory
  2. Run the following script in your terminal: pip3 install -U numpy-stl && python3 -c "import stl; print([m.vectors for m in stl.Mesh.from_multi_file('out.stl')])" # Will result in RuntimeError
  3. If I use the previous version (2.13.0), it runs correctly with the following script: pip3 install -U numpy-stl==2.13.0 && python3 -c "import stl; print([m.vectors for m in stl.Mesh.from_multi_file('out.stl')])" # Runs correctly

Actual results (2.14.0)

$ pip3 install -U numpy-stl && python3 -c "import stl; print([m.vectors for m in stl.Mesh.from_multi_file('out.stl')])"  # Will result in RuntimeError
Requirement already satisfied: numpy-stl in /usr/local/var/pyenv/versions/3.7.3/lib/python3.7/site-packages (2.13.0)
Collecting numpy-stl
  Using cached numpy_stl-2.14.0-py3-none-any.whl
Requirement already satisfied: python-utils>=1.6.2 in /usr/local/var/pyenv/versions/3.7.3/lib/python3.7/site-packages (from numpy-stl) (2.3.0)
Requirement already satisfied: numpy in /Users/horie/.local/lib/python3.7/site-packages (from numpy-stl) (1.18.0)
Requirement already satisfied: six in /usr/local/var/pyenv/versions/3.7.3/lib/python3.7/site-packages (from python-utils>=1.6.2->numpy-stl) (1.15.0)
Installing collected packages: numpy-stl
  Attempting uninstall: numpy-stl
    Found existing installation: numpy-stl 2.13.0
    Uninstalling numpy-stl-2.13.0:
      Successfully uninstalled numpy-stl-2.13.0
Successfully installed numpy-stl-2.14.0
WARNING: You are using pip version 20.3.3; however, version 21.0.1 is available.
You should consider upgrading via the '/usr/local/var/pyenv/versions/3.7.3/bin/python3.7 -m pip install --upgrade pip' command.
got name b'-stl (2.10.1) 2019-12-24 17:56:46.326275 tests/data/stl/write/out.stl'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "<string>", line 1, in <listcomp>
  File "/usr/local/var/pyenv/versions/3.7.3/lib/python3.7/site-packages/stl/stl.py", line 400, in from_multi_file
    raw_data = cls.load(fh, mode=mode, speedups=speedups)
  File "/usr/local/var/pyenv/versions/3.7.3/lib/python3.7/site-packages/stl/stl.py", line 95, in load
    name, data = cls._load_ascii(fh, header, speedups=speedups)
  File "/usr/local/var/pyenv/versions/3.7.3/lib/python3.7/site-packages/stl/stl.py", line 237, in _load_ascii
    return name, numpy.fromiter(iterator, dtype=cls.dtype)
  File "/usr/local/var/pyenv/versions/3.7.3/lib/python3.7/site-packages/stl/stl.py", line 208, in _ascii_reader
    normals = get('facet normal')
  File "/usr/local/var/pyenv/versions/3.7.3/lib/python3.7/site-packages/stl/stl.py", line 182, in get
    '%r should start with %r' % (line, prefix))
RuntimeError: (False, "b'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x80a\\x00\\x00\\x80@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x80@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00a\\x00\\x00\\x00a\\x00\\x00\\x00a\\x00\\x00\\x80@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x80@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00a\\x00\\x00\\x00\\x00\\x00\\x00\\x80@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x80\\xc0\\x00\\x00\\x80\\xc0\\x00\\x00\\x80\\xc0\\x00\\x00\\x80@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x80\\xc0\\x00\\x00\\x00\\x00\\x00\\x00\\x80@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x00\\xc1\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x80@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x80@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x80@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x80@\\x00\\x00\\x80@\\x00\\x00\\x80@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x80@\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x80@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x80@\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x80\\xc0\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x80@\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00\\x00@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x00\\x00' should start with b'facet normal'")

Expected results (2.13.0)

$ pip3 install -U numpy-stl==2.13.0 && python3 -c "import stl; print([m.vectors for m in stl.Mesh.from_multi_file('out.stl')])"  # Runs correctly
Collecting numpy-stl==2.13.0
  Using cached numpy_stl-2.13.0-py3-none-any.whl
Requirement already satisfied: python-utils>=1.6.2 in /usr/local/var/pyenv/versions/3.7.3/lib/python3.7/site-packages (from numpy-stl==2.13.0) (2.3.0)
Requirement already satisfied: numpy in /Users/horie/.local/lib/python3.7/site-packages (from numpy-stl==2.13.0) (1.18.0)
Requirement already satisfied: six in /usr/local/var/pyenv/versions/3.7.3/lib/python3.7/site-packages (from python-utils>=1.6.2->numpy-stl==2.13.0) (1.15.0)
Installing collected packages: numpy-stl
  Attempting uninstall: numpy-stl
    Found existing installation: numpy-stl 2.14.0
    Uninstalling numpy-stl-2.14.0:
      Successfully uninstalled numpy-stl-2.14.0
Successfully installed numpy-stl-2.13.0
WARNING: You are using pip version 20.3.3; however, version 21.0.1 is available.
You should consider upgrading via the '/usr/local/var/pyenv/versions/3.7.3/bin/python3.7 -m pip install --upgrade pip' command.
[array([[[4., 0., 0.],
        [0., 4., 0.],
        [0., 0., 0.]],

       [[4., 0., 0.],
        [0., 4., 0.],
        [0., 2., 2.]],

       [[4., 0., 0.],
        [0., 0., 0.],
        [0., 0., 2.]],

       [[4., 0., 0.],
        [2., 0., 2.],
        [0., 2., 2.]],

       [[4., 0., 0.],
        [2., 0., 2.],
        [0., 0., 2.]],

       [[0., 4., 0.],
        [0., 0., 0.],
        [0., 0., 2.]],

       [[0., 4., 0.],
        [0., 2., 2.],
        [0., 0., 2.]],

       [[0., 0., 4.],
        [2., 0., 2.],
        [0., 2., 2.]],

       [[0., 0., 4.],
        [2., 0., 2.],
        [0., 0., 2.]],

       [[0., 0., 4.],
        [0., 2., 2.],
        [0., 0., 2.]]], dtype=float32)]

Versions

I am using Python with the following environment: Python 3.7.3 (default, Apr 22 2019, 02:40:09) [Clang 10.0.1 (clang-1001.0.46.4)]

wolph commented 3 years ago

I've yanked the release and I'll release a fixed version today. Apparently the tests don't cover all cases.

Thank you for the very detailed report!

yellowshippo commented 3 years ago

Thank you for the quick reply! I’m looking forward to the fix.

wolph commented 3 years ago

Honestly... this shouldn't work because multi-files are only supported as ascii files. But it indeed broke the old behaviour so I've fixed it :)

yellowshippo commented 3 years ago

Oh really? In that case, what method should I use to read binary files instead?

wolph commented 3 years ago

The from_file method :) That's actually easier because it returns a single mesh instead of a list of meshes:

import stl

print(stl.Mesh.from_file('out.stl').vectors)
yellowshippo commented 3 years ago

Thank you for the information! I will try it. Also, it would be nice if you support binary STLs for from_multi_file.

wolph commented 3 years ago

In any case it works again now :)

wolph commented 3 years ago

The problem is that there is no standard for binary multi-files. I could invent my own standard of course, but that wouldn't be compatible with anything else.

Even the multiple ascii STL files are not actually a standard, only a few bits of software support it.

yellowshippo commented 3 years ago

I confirmed from_multi_file works with the binary file (and also from_file, of course). I understand there are a lot of non-standards in STL...

Thank you for your kind support and help!