diff options
author | Bastien Montagne <bastien@blender.org> | 2020-08-07 17:38:40 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2020-08-07 17:38:40 +0300 |
commit | 04c0573ee77cc955cf585a0d7a61163375eb57cd (patch) | |
tree | 51e1adb31281c0595c1a6e36100b7a6cdb59a950 | |
parent | 919541ffbeb34af259f2950c785d9cb7cc392f33 (diff) |
Fix T78278: Cannot import some binary PLY file generated by Rhinos3D 6.0
Issue was that in binary file reading, python only recognize `'\n'`
character as line separator... PLY seems to allow (or at least, use)
other OS-related variants of lines terminators, so we have to implement
our own line iterator for those cases...
-rw-r--r-- | io_mesh_ply/__init__.py | 4 | ||||
-rw-r--r-- | io_mesh_ply/import_ply.py | 37 |
2 files changed, 36 insertions, 5 deletions
diff --git a/io_mesh_ply/__init__.py b/io_mesh_ply/__init__.py index 1a69c346..a3f08ebd 100644 --- a/io_mesh_ply/__init__.py +++ b/io_mesh_ply/__init__.py @@ -20,8 +20,8 @@ bl_info = { "name": "Stanford PLY format", - "author": "Bruce Merry, Campbell Barton", - "version": (2, 0, 0), + "author": "Bruce Merry, Campbell Barton", "Bastien Montagne" + "version": (2, 1, 0), "blender": (2, 90, 0), "location": "File > Import/Export", "description": "Import-Export PLY mesh data with UVs and vertex colors", diff --git a/io_mesh_ply/import_ply.py b/io_mesh_ply/import_ply.py index c118aa3c..d9d12d67 100644 --- a/io_mesh_ply/import_ply.py +++ b/io_mesh_ply/import_ply.py @@ -152,14 +152,45 @@ def read(filepath): invalid_ply = (None, None, None) with open(filepath, 'rb') as plyf: - signature = plyf.readline() + signature = plyf.peek(5) - if not signature.startswith(b'ply'): + if not signature.startswith(b'ply') or not len(signature) >= 5: print("Signature line was invalid") return invalid_ply + custom_line_sep = None + if signature[3] != ord(b'\n'): + if signature[3] != ord(b'\r'): + print("Unknown line separator") + return invalid_ply + if signature[4] == ord(b'\n'): + custom_line_sep = b"\r\n" + else: + custom_line_sep = b"\r" + + # Work around binary file reading only accepting "\n" as line separator. + plyf_header_line_iterator = lambda plyf: plyf + if custom_line_sep is not None: + def _plyf_header_line_iterator(plyf): + buff = plyf.peek(2**16) + while len(buff) != 0: + read_bytes = 0 + buff = buff.split(custom_line_sep) + for line in buff[:-1]: + read_bytes += len(line) + len(custom_line_sep) + if line.startswith(b'end_header'): + # Since reader code might (will) break iteration at this point, + # we have to ensure file is read up to here, yield, amd return... + plyf.read(read_bytes) + yield line + return + yield line + plyf.read(read_bytes) + buff = buff[-1] + plyf.peek(2**16) + plyf_header_line_iterator = _plyf_header_line_iterator + valid_header = False - for line in plyf: + for line in plyf_header_line_iterator(plyf): tokens = re.split(br'[ \r\n]+', line) if len(tokens) == 0: |