From 6274a58158bea8059bfb3c5de425a07a556423f6 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 29 Aug 2019 13:23:19 +0200 Subject: [PATCH] Add plug-in to read PLY files Seems to work fine. Contributes to issue CURA-6739. --- plugins/PLYReader/PLYReader.py | 76 ++++++++++++++++++++++++++++++++++ plugins/PLYReader/__init__.py | 21 ++++++++++ plugins/PLYReader/plugin.json | 7 ++++ 3 files changed, 104 insertions(+) create mode 100644 plugins/PLYReader/PLYReader.py create mode 100644 plugins/PLYReader/__init__.py create mode 100644 plugins/PLYReader/plugin.json diff --git a/plugins/PLYReader/PLYReader.py b/plugins/PLYReader/PLYReader.py new file mode 100644 index 0000000000..6f3abfd59d --- /dev/null +++ b/plugins/PLYReader/PLYReader.py @@ -0,0 +1,76 @@ +# Copyright (c) 2019 Ultimaker B.V., fieldOfView +# Cura is released under the terms of the LGPLv3 or higher. + +# The _toMeshData function is taken from the AMFReader class which was built by fieldOfView. + +import numpy # To create the mesh data. +import os.path # To create the mesh name for the resulting mesh. +import trimesh # To load the PLY files into a Trimesh. + +from UM.Mesh.MeshData import MeshData, calculateNormalsFromIndexedVertices +from UM.Mesh.MeshReader import MeshReader +from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType + +from cura.CuraApplication import CuraApplication +from cura.Scene.BuildPlateDecorator import BuildPlateDecorator +from cura.Scene.CuraSceneNode import CuraSceneNode +from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator + +## Class that leverages Trimesh to read PLY files (Stanford Triangle Format). +class PLYReader(MeshReader): + def __init__(self) -> None: + super().__init__() + + self._supported_extensions = [".ply"] + MimeTypeDatabase.addMimeType( + MimeType( + name = "application/x-ply", # Wikipedia lists the MIME type as "text/plain" but that won't do as it's not unique to PLY files. + comment = "Stanford Triangle Format", + suffixes = ["ply"] + ) + ) + + ## Reads the PLY file. + # \param file_name The file path of the PLY file. This is assumed to be a + # PLY file; it's not checked again. + # \return A scene node that contains the PLY file's contents. + def _read(self, file_name: str) -> CuraSceneNode: + mesh = trimesh.load(file_name) + mesh.merge_vertices() + mesh.remove_unreferenced_vertices() + mesh.fix_normals() + mesh_data = self._toMeshData(mesh) + + file_base_name = os.path.basename(file_name) + new_node = CuraSceneNode() + new_node.setMeshData(mesh_data) + new_node.setSelectable(True) + new_node.setName(file_base_name) + new_node.addDecorator(BuildPlateDecorator(CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate)) + new_node.addDecorator(SliceableObjectDecorator()) + return new_node + + def _toMeshData(self, tri_node: trimesh.base.Trimesh) -> MeshData: + tri_faces = tri_node.faces + tri_vertices = tri_node.vertices + + indices = [] + vertices = [] + + index_count = 0 + face_count = 0 + for tri_face in tri_faces: + face = [] + for tri_index in tri_face: + vertices.append(tri_vertices[tri_index]) + face.append(index_count) + index_count += 1 + indices.append(face) + face_count += 1 + + vertices = numpy.asarray(vertices, dtype = numpy.float32) + indices = numpy.asarray(indices, dtype = numpy.int32) + normals = calculateNormalsFromIndexedVertices(vertices, indices, face_count) + + mesh_data = MeshData(vertices = vertices, indices = indices, normals = normals) + return mesh_data \ No newline at end of file diff --git a/plugins/PLYReader/__init__.py b/plugins/PLYReader/__init__.py new file mode 100644 index 0000000000..05a6c8004d --- /dev/null +++ b/plugins/PLYReader/__init__.py @@ -0,0 +1,21 @@ +# Copyright (c) 2019 Ultimaker +# Cura is released under the terms of the LGPLv3 or higher. + +from . import PLYReader + +from UM.i18n import i18nCatalog +i18n_catalog = i18nCatalog("uranium") + + +def getMetaData(): + return { + "mesh_reader": [ + { + "extension": "ply", + "description": i18n_catalog.i18nc("@item:inlistbox", "PLY File") + } + ] + } + +def register(app): + return {"mesh_reader": PLYReader.PLYReader()} diff --git a/plugins/PLYReader/plugin.json b/plugins/PLYReader/plugin.json new file mode 100644 index 0000000000..b295b08780 --- /dev/null +++ b/plugins/PLYReader/plugin.json @@ -0,0 +1,7 @@ +{ + "name": "PLY Reader", + "author": "Ultimaker B.V.", + "version": "1.0.0", + "description": "Provides support for reading PLY files.", + "api": "6.0.0" +}