Skip to content
Snippets Groups Projects
Commit 04c0573e authored by Bastien Montagne's avatar Bastien Montagne
Browse files

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...
parent 919541ff
No related branches found
No related tags found
No related merge requests found
......@@ -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",
......
......@@ -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:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment