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...
This commit is contained in:
parent
919541ffbe
commit
04c0573ee7
Notes:
blender-bot
2023-02-14 18:53:21 +01:00
Referenced by issue #78278, Cannot import PLY file generated by Rhinos3D 6.0
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue