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

github.com/Ultimaker/Cura.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGhostkeeper <rubend@tutanota.com>2019-08-29 15:56:49 +0300
committerGhostkeeper <rubend@tutanota.com>2019-08-29 15:57:55 +0300
commit1f534db50838b311d2ea6eff880df90634027c08 (patch)
treef7e3f1089c139bcba18d66754458e55371249b6a /plugins/TrimeshReader
parentcead90c5bacdb519c93b020fb1cce13d64706042 (diff)
Handle Trimesh returning scene of objects
These objects are added as a group node, if they are plural. Contributes to issue CURA-6739.
Diffstat (limited to 'plugins/TrimeshReader')
-rw-r--r--plugins/TrimeshReader/TrimeshReader.py58
1 files changed, 43 insertions, 15 deletions
diff --git a/plugins/TrimeshReader/TrimeshReader.py b/plugins/TrimeshReader/TrimeshReader.py
index d719e3dbc8..f0fd9bc023 100644
--- a/plugins/TrimeshReader/TrimeshReader.py
+++ b/plugins/TrimeshReader/TrimeshReader.py
@@ -3,6 +3,7 @@
# The _toMeshData function is taken from the AMFReader class which was built by fieldOfView.
+from typing import List, Union, TYPE_CHECKING
import numpy # To create the mesh data.
import os.path # To create the mesh name for the resulting mesh.
import trimesh # To load the files into a Trimesh.
@@ -10,12 +11,17 @@ import trimesh # To load the files into a Trimesh.
from UM.Mesh.MeshData import MeshData, calculateNormalsFromIndexedVertices # To construct meshes from the Trimesh data.
from UM.Mesh.MeshReader import MeshReader # The plug-in type we're extending.
from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType # To add file types that we can open.
+from UM.Scene.GroupDecorator import GroupDecorator # Added to the parent node if we load multiple nodes at once.
from cura.CuraApplication import CuraApplication
from cura.Scene.BuildPlateDecorator import BuildPlateDecorator # Added to the resulting scene node.
+from cura.Scene.ConvexHullDecorator import ConvexHullDecorator # Added to group nodes if we load multiple nodes at once.
from cura.Scene.CuraSceneNode import CuraSceneNode # To create a node in the scene after reading the file.
from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator # Added to the resulting scene node.
+if TYPE_CHECKING:
+ from UM.Scene.SceneNode import SceneNode
+
## Class that leverages Trimesh to import files.
class TrimeshReader(MeshReader):
def __init__(self) -> None:
@@ -34,21 +40,43 @@ class TrimeshReader(MeshReader):
# \param file_name The file path. This is assumed to be one of the file
# types that Trimesh can read. It will not be checked again.
# \return A scene node that contains the 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 _read(self, file_name: str) -> Union["SceneNode", List["SceneNode"]]:
+ mesh_or_scene = trimesh.load(file_name)
+ meshes = []
+ if isinstance(mesh_or_scene, trimesh.Trimesh):
+ meshes = [mesh_or_scene]
+ elif isinstance(mesh_or_scene, trimesh.Scene):
+ meshes = [mesh for mesh in mesh_or_scene.geometry.values()]
+
+ active_build_plate = CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate
+ nodes = []
+ for mesh in meshes:
+ if not isinstance(mesh, trimesh.Trimesh): # Trimesh can also receive point clouds, 2D paths, 3D paths or metadata. Skip those.
+ continue
+ 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 if len(meshes) == 1 else "{file_base_name} {counter}".format(file_base_name = file_base_name, counter = str(len(nodes) + 1)))
+ new_node.addDecorator(BuildPlateDecorator(active_build_plate))
+ new_node.addDecorator(SliceableObjectDecorator())
+ nodes.append(new_node)
+
+ if len(nodes) == 1:
+ return nodes[0]
+ # Add all nodes to a group so they stay together.
+ group_node = CuraSceneNode()
+ group_node.addDecorator(GroupDecorator())
+ group_node.addDecorator(ConvexHullDecorator())
+ group_node.addDecorator(BuildPlateDecorator(active_build_plate))
+ for node in nodes:
+ node.setParent(group_node)
+ return group_node
## Converts a Trimesh to Uranium's MeshData.
# \param tri_node A Trimesh containing the contents of a file that was