From af637d5acc34ffff87cf0ef3f6e2a7c3cffe1821 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 19 Mar 2018 11:33:17 +0100 Subject: [PATCH 1/8] Don't explode all nested groups when ungrouping groups of groups --- cura/CuraApplication.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 6056745c75..2e641f145a 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1401,6 +1401,10 @@ class CuraApplication(QtApplication): group_parent = node.getParent() children = node.getChildren().copy() for child in children: + # Ungroup only 1 level deep + if child.getParent() != node: + continue + # Set the parent of the children to the parent of the group-node op.addOperation(SetParentOperation(child, group_parent)) From ba678511052ddcb7822390b1687c77140d658cc5 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 19 Mar 2018 12:08:18 +0100 Subject: [PATCH 2/8] Don't add a SettingOverrideDecorator twice CuraSceneNodes get a SettingOverrideDecorator automatically when constructed --- plugins/SupportEraser/SupportEraser.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/SupportEraser/SupportEraser.py b/plugins/SupportEraser/SupportEraser.py index 3332b4181d..cdb1c28414 100644 --- a/plugins/SupportEraser/SupportEraser.py +++ b/plugins/SupportEraser/SupportEraser.py @@ -108,12 +108,10 @@ class SupportEraser(Tool): node.setPosition(position) active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate - - node.addDecorator(SettingOverrideDecorator()) node.addDecorator(BuildPlateDecorator(active_build_plate)) node.addDecorator(SliceableObjectDecorator()) - stack = node.callDecoration("getStack") # created by SettingOverrideDecorator + stack = node.callDecoration("getStack") # created by SettingOverrideDecorator that is automatically added to CuraSceneNode settings = stack.getTop() definition = stack.getSettingDefinition("anti_overhang_mesh") From e861a8a11234e9c65aad74df83963551ddbac4ea Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 19 Mar 2018 12:32:52 +0100 Subject: [PATCH 3/8] Add children to correct buildplate when multiplying --- cura/MultiplyObjectsJob.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cura/MultiplyObjectsJob.py b/cura/MultiplyObjectsJob.py index 441d4c96c3..b9f37ec6f8 100644 --- a/cura/MultiplyObjectsJob.py +++ b/cura/MultiplyObjectsJob.py @@ -33,6 +33,7 @@ class MultiplyObjectsJob(Job): root = scene.getRoot() arranger = Arrange.create(scene_root=root) nodes = [] + for node in self._objects: # If object is part of a group, multiply group current_node = node @@ -49,18 +50,20 @@ class MultiplyObjectsJob(Job): for i in range(self._count): # We do place the nodes one by one, as we want to yield in between. if not node_too_big: - node, solution_found = arranger.findNodePlacement(current_node, offset_shape_arr, hull_shape_arr) + new_node, solution_found = arranger.findNodePlacement(current_node, offset_shape_arr, hull_shape_arr) if node_too_big or not solution_found: found_solution_for_all = False - new_location = node.getPosition() + new_location = new_node.getPosition() new_location = new_location.set(z = 100 - i * 20) - node.setPosition(new_location) + new_node.setPosition(new_location) # Same build plate build_plate_number = current_node.callDecoration("getBuildPlateNumber") - node.callDecoration("setBuildPlateNumber", build_plate_number) + new_node.callDecoration("setBuildPlateNumber", build_plate_number) + for child in new_node.getChildren(): + child.callDecoration("setBuildPlateNumber", build_plate_number) - nodes.append(node) + nodes.append(new_node) current_progress += 1 status_message.setProgress((current_progress / total_progress) * 100) Job.yieldThread() From 91e1ae69ec52c954b2ad9c20b1254a32c0ed55c1 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 19 Mar 2018 14:35:08 +0100 Subject: [PATCH 4/8] Don't reparent nodes that are children of a selected node when grouping selection --- cura/CuraApplication.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 2e641f145a..6351d43c79 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1383,6 +1383,12 @@ class CuraApplication(QtApplication): group_node.setPosition(center) group_node.setCenterPosition(center) + # Remove nodes that are directly parented to another selected node from the selection so they remain parented + selected_nodes = Selection.getAllSelectedObjects().copy() + for node in selected_nodes: + if node.getParent() in selected_nodes and not node.getParent().callDecoration("isGroup"): + Selection.remove(node) + # Move selected nodes into the group-node Selection.applyOperation(SetParentOperation, group_node) From 4fc3c00e1d2a18b80592cbafa89acc7727db109d Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 19 Mar 2018 15:46:43 +0100 Subject: [PATCH 5/8] Fix position of added anti support meshes in group --- plugins/SupportEraser/SupportEraser.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/plugins/SupportEraser/SupportEraser.py b/plugins/SupportEraser/SupportEraser.py index cdb1c28414..7884ca30c7 100644 --- a/plugins/SupportEraser/SupportEraser.py +++ b/plugins/SupportEraser/SupportEraser.py @@ -19,10 +19,8 @@ from cura.Scene.CuraSceneNode import CuraSceneNode from cura.PickingPass import PickingPass -from UM.Operations.GroupedOperation import GroupedOperation from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation -from cura.Operations.SetParentOperation import SetParentOperation from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator from cura.Scene.BuildPlateDecorator import BuildPlateDecorator @@ -105,7 +103,6 @@ class SupportEraser(Tool): mesh = MeshBuilder() mesh.addCube(10,10,10) node.setMeshData(mesh.build()) - node.setPosition(position) active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate node.addDecorator(BuildPlateDecorator(active_build_plate)) @@ -120,13 +117,9 @@ class SupportEraser(Tool): new_instance.resetState() # Ensure that the state is not seen as a user state. settings.addInstance(new_instance) - root = self._controller.getScene().getRoot() - - op = GroupedOperation() - # First add the node to the scene, so it gets the expected transform - op.addOperation(AddSceneNodeOperation(node, root)) - op.addOperation(SetParentOperation(node, parent)) + op = AddSceneNodeOperation(node, parent) op.push() + node.setPosition(position, CuraSceneNode.TransformSpace.World) Application.getInstance().getController().getScene().sceneChanged.emit(node) From fff0a2519a885ed5edbd0915c793948ec392dd02 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 19 Mar 2018 17:28:09 +0100 Subject: [PATCH 6/8] Don't add a SettingOverrideDecorator twice --- plugins/3MFReader/ThreeMFReader.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index 3a1298bdba..9b7b979e8a 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -16,7 +16,6 @@ from UM.Mesh.MeshBuilder import MeshBuilder from UM.Mesh.MeshReader import MeshReader from UM.Scene.GroupDecorator import GroupDecorator -from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator from cura.Settings.ExtruderManager import ExtruderManager from cura.Scene.CuraSceneNode import CuraSceneNode from cura.Scene.BuildPlateDecorator import BuildPlateDecorator @@ -81,7 +80,7 @@ class ThreeMFReader(MeshReader): active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate - um_node = CuraSceneNode() + um_node = CuraSceneNode() # This adds a SettingOverrideDecorator um_node.addDecorator(BuildPlateDecorator(active_build_plate)) um_node.setName(node_name) transformation = self._createMatrixFromTransformationString(savitar_node.getTransformation()) @@ -110,8 +109,6 @@ class ThreeMFReader(MeshReader): # Add the setting override decorator, so we can add settings to this node. if settings: - um_node.addDecorator(SettingOverrideDecorator()) - global_container_stack = Application.getInstance().getGlobalContainerStack() # Ensure the correct next container for the SettingOverride decorator is set. From 5a9bcf446e9b34db6d54127e8847126f696a6ba5 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 19 Mar 2018 17:52:40 +0100 Subject: [PATCH 7/8] Do not select parented nodes when selecting all --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 6351d43c79..98c682a8a3 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1105,7 +1105,7 @@ class CuraApplication(QtApplication): continue if not node.getMeshData() and not node.callDecoration("isGroup"): continue # Node that doesnt have a mesh and is not a group. - if node.getParent() and node.getParent().callDecoration("isGroup"): + if node.getParent() and node.getParent().callDecoration("isGroup") or node.getParent().callDecoration("isSliceable"): continue # Grouped nodes don't need resetting as their parent (the group) is resetted) if not node.isSelectable(): continue # i.e. node with layer data From d123efd3eb97b9cef8d97d98b9c1a482c7f839b9 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Mon, 19 Mar 2018 18:25:40 +0100 Subject: [PATCH 8/8] Fix loading parented objects from 3mf files --- cura/Scene/BuildPlateDecorator.py | 2 +- plugins/3MFReader/ThreeMFReader.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Scene/BuildPlateDecorator.py b/cura/Scene/BuildPlateDecorator.py index c2fd3145dd..dfb465b7ad 100644 --- a/cura/Scene/BuildPlateDecorator.py +++ b/cura/Scene/BuildPlateDecorator.py @@ -15,7 +15,7 @@ class BuildPlateDecorator(SceneNodeDecorator): self._build_plate_number = nr if isinstance(self._node, CuraSceneNode): self._node.transformChanged() # trigger refresh node without introducing a new signal - if self._node and self._node.callDecoration("isGroup"): + if self._node: for child in self._node.getChildren(): child.callDecoration("setBuildPlateNumber", nr) diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index 9b7b979e8a..6c2fb9a59d 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -137,7 +137,7 @@ class ThreeMFReader(MeshReader): continue setting_container.setProperty(key, "value", setting_value) - if len(um_node.getChildren()) > 0: + if len(um_node.getChildren()) > 0 and um_node.getMeshData() is None: group_decorator = GroupDecorator() um_node.addDecorator(group_decorator) um_node.setSelectable(True)