Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <bastien@blender.org>2020-08-07 17:38:40 +0300
committerBastien Montagne <bastien@blender.org>2020-08-07 17:38:40 +0300
commit04c0573ee77cc955cf585a0d7a61163375eb57cd (patch)
tree51e1adb31281c0595c1a6e36100b7a6cdb59a950
parent919541ffbeb34af259f2950c785d9cb7cc392f33 (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__.py4
-rw-r--r--io_mesh_ply/import_ply.py37
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: