diff --git a/io_mesh_ply/__init__.py b/io_mesh_ply/__init__.py index 28de08bebff1841905cbeed15d289394ae02eb93..c9a79e1f639f5bc2b9ac95e82632d8c008bd96f3 100644 --- a/io_mesh_ply/__init__.py +++ b/io_mesh_ply/__init__.py @@ -24,7 +24,7 @@ bl_info = { "version": (1, 1, 0), "blender": (2, 82, 0), "location": "File > Import-Export", - "description": "Import-Export PLY mesh data with UV's and vertex colors", + "description": "Import-Export PLY mesh data with UVs and vertex colors", "wiki_url": "https://docs.blender.org/manual/en/latest/addons/io_mesh_ply.html", "support": 'OFFICIAL', "category": "Import-Export", diff --git a/io_mesh_ply/export_ply.py b/io_mesh_ply/export_ply.py index cd50dbaf88f5c0689c0b3bc8a7aef1abec3087e1..812aeb54713244ca2dc9e6b3a69a151648a43e08 100644 --- a/io_mesh_ply/export_ply.py +++ b/io_mesh_ply/export_ply.py @@ -34,44 +34,26 @@ def save_mesh(filepath, mesh, use_normals=True, use_uv_coords=True, use_colors=T def rvec2d(v): return round(v[0], 6), round(v[1], 6) - has_uv = bool(mesh.uv_layers) - has_vcol = bool(mesh.vertex_colors) - - if not has_uv: + if use_uv_coords and mesh.uv_layers: + active_uv_layer = mesh.uv_layers.active.data + else: use_uv_coords = False - if not has_vcol: - use_colors = False - if not use_uv_coords: - has_uv = False - if not use_colors: - has_vcol = False - - if has_uv: - active_uv_layer = mesh.uv_layers.active - if not active_uv_layer: - use_uv_coords = False - has_uv = False - else: - active_uv_layer = active_uv_layer.data - - if has_vcol: - active_col_layer = mesh.vertex_colors.active - if not active_col_layer: - use_colors = False - has_vcol = False - else: - active_col_layer = active_col_layer.data + if use_colors and mesh.vertex_colors: + active_col_layer = mesh.vertex_colors.active.data + else: + use_colors = False # in case color = uvcoord = uvcoord_key = normal = normal_key = None - mesh_verts = mesh.vertices # save a lookup - ply_verts = [] # list of dictionaries + mesh_verts = mesh.vertices # vdict = {} # (index, normal, uv) -> new index vdict = [{} for i in range(len(mesh_verts))] + ply_verts = [] ply_faces = [[] for f in range(len(mesh.polygons))] vert_count = 0 + for i, f in enumerate(mesh.polygons): smooth = not use_normals or f.use_smooth @@ -79,12 +61,12 @@ def save_mesh(filepath, mesh, use_normals=True, use_uv_coords=True, use_colors=T normal = f.normal[:] normal_key = rvec3d(normal) - if has_uv: + if use_uv_coords: uv = [ active_uv_layer[l].uv[:] for l in range(f.loop_start, f.loop_start + f.loop_total) ] - if has_vcol: + if use_colors: col = [ active_col_layer[l].color[:] for l in range(f.loop_start, f.loop_start + f.loop_total) @@ -98,11 +80,11 @@ def save_mesh(filepath, mesh, use_normals=True, use_uv_coords=True, use_colors=T normal = v.normal[:] normal_key = rvec3d(normal) - if has_uv: + if use_uv_coords: uvcoord = uv[j][0], uv[j][1] uvcoord_key = rvec2d(uvcoord) - if has_vcol: + if use_colors: color = col[j] color = ( int(color[0] * 255.0), @@ -115,7 +97,7 @@ def save_mesh(filepath, mesh, use_normals=True, use_uv_coords=True, use_colors=T vdict_local = vdict[vidx] pf_vidx = vdict_local.get(key) # Will be None initially - if pf_vidx is None: # same as vdict_local.has_key(key) + if pf_vidx is None: # Same as vdict_local.has_key(key) pf_vidx = vdict_local[key] = vert_count ply_verts.append((vidx, normal, uvcoord, color)) vert_count += 1 @@ -136,13 +118,11 @@ def save_mesh(filepath, mesh, use_normals=True, use_uv_coords=True, use_colors=T ) fw(f"element vertex {len(ply_verts)}\n") - fw( "property float x\n" "property float y\n" "property float z\n" ) - if use_normals: fw( "property float nx\n" @@ -164,6 +144,7 @@ def save_mesh(filepath, mesh, use_normals=True, use_uv_coords=True, use_colors=T fw(f"element face {len(mesh.polygons)}\n") fw("property list uchar uint vertex_indices\n") + fw("end_header\n") # Vertex data diff --git a/io_mesh_ply/import_ply.py b/io_mesh_ply/import_ply.py index 943f50a34a58a0a41adc11d40af0bfee5db2b131..2bf914422b9bd689e2fc72b4bdb1ad3867d7c1f3 100644 --- a/io_mesh_ply/import_ply.py +++ b/io_mesh_ply/import_ply.py @@ -19,7 +19,7 @@ # <pep8 compliant> -class element_spec(object): +class ElementSpec: __slots__ = ( "name", "count", @@ -43,7 +43,7 @@ class element_spec(object): return -1 -class property_spec(object): +class PropertySpec: __slots__ = ( "name", "list_type", @@ -102,7 +102,7 @@ class property_spec(object): return self.read_format(format, 1, self.numeric_type, stream)[0] -class object_spec(object): +class ObjectSpec: __slots__ = ("specs",) def __init__(self): @@ -113,15 +113,16 @@ class object_spec(object): return dict([(i.name, [i.load(format, stream) for j in range(i.count)]) for i in self.specs]) # Longhand for above LC - - # answer = {} - # for i in self.specs: - # answer[i.name] = [] - # for j in range(i.count): - # if not j % 100 and meshtools.show_progress: - # Blender.Window.DrawProgressBar(float(j) / i.count, 'Loading ' + i.name) - # answer[i.name].append(i.load(format, stream)) - # return answer + """ + answer = {} + for i in self.specs: + answer[i.name] = [] + for j in range(i.count): + if not j % 100 and meshtools.show_progress: + Blender.Window.DrawProgressBar(float(j) / i.count, 'Loading ' + i.name) + answer[i.name].append(i.load(format, stream)) + return answer + """ def read(filepath): @@ -154,7 +155,7 @@ def read(filepath): b'double': 'd', b'string': 's', } - obj_spec = object_spec() + obj_spec = ObjectSpec() invalid_ply = (None, None, None) with open(filepath, 'rb') as plyf: @@ -206,15 +207,15 @@ def read(filepath): if len(tokens) < 3: print("Invalid element line") return invalid_ply - obj_spec.specs.append(element_spec(tokens[1], int(tokens[2]))) + obj_spec.specs.append(ElementSpec(tokens[1], int(tokens[2]))) elif tokens[0] == b'property': if not len(obj_spec.specs): print("Property without element") return invalid_ply if tokens[1] == b'list': - obj_spec.specs[-1].properties.append(property_spec(tokens[4], type_specs[tokens[2]], type_specs[tokens[3]])) + obj_spec.specs[-1].properties.append(PropertySpec(tokens[4], type_specs[tokens[2]], type_specs[tokens[3]])) else: - obj_spec.specs[-1].properties.append(property_spec(tokens[2], None, type_specs[tokens[1]])) + obj_spec.specs[-1].properties.append(PropertySpec(tokens[2], None, type_specs[tokens[1]])) if not valid_header: print("Invalid header ('end_header' line not found!)") return invalid_ply @@ -373,7 +374,7 @@ def load_ply_mesh(filepath, ply_name): if texture and uvindices: pass - # XXX28: add support for using texture. + # TODO add support for using texture. # import os # import sys