diff options
Diffstat (limited to 'cura/MultiplyObjectsJob.py')
-rw-r--r-- | cura/MultiplyObjectsJob.py | 71 |
1 files changed, 20 insertions, 51 deletions
diff --git a/cura/MultiplyObjectsJob.py b/cura/MultiplyObjectsJob.py index 134e579746..1ba78edacf 100644 --- a/cura/MultiplyObjectsJob.py +++ b/cura/MultiplyObjectsJob.py @@ -4,18 +4,15 @@ import copy from typing import List +from UM.Application import Application from UM.Job import Job -from UM.Operations.GroupedOperation import GroupedOperation from UM.Message import Message +from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Scene.SceneNode import SceneNode from UM.i18n import i18nCatalog -i18n_catalog = i18nCatalog("cura") - -from cura.Arranging.Arrange import Arrange -from cura.Arranging.ShapeArray import ShapeArray +from cura.Arranging.Nest2DArrange import arrange -from UM.Application import Application -from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation +i18n_catalog = i18nCatalog("cura") class MultiplyObjectsJob(Job): @@ -26,28 +23,27 @@ class MultiplyObjectsJob(Job): self._min_offset = min_offset def run(self) -> None: - status_message = Message(i18n_catalog.i18nc("@info:status", "Multiplying and placing objects"), lifetime=0, - dismissable=False, progress=0, title = i18n_catalog.i18nc("@info:title", "Placing Objects")) + status_message = Message(i18n_catalog.i18nc("@info:status", "Multiplying and placing objects"), lifetime = 0, + dismissable = False, progress = 0, + title = i18n_catalog.i18nc("@info:title", "Placing Objects")) status_message.show() scene = Application.getInstance().getController().getScene() - total_progress = len(self._objects) * self._count - current_progress = 0 - global_container_stack = Application.getInstance().getGlobalContainerStack() if global_container_stack is None: return # We can't do anything in this case. - machine_width = global_container_stack.getProperty("machine_width", "value") - machine_depth = global_container_stack.getProperty("machine_depth", "value") root = scene.getRoot() - scale = 0.5 - arranger = Arrange.create(x = machine_width, y = machine_depth, scene_root = root, scale = scale, min_offset = self._min_offset) + processed_nodes = [] # type: List[SceneNode] nodes = [] - not_fit_count = 0 - found_solution_for_all = False + fixed_nodes = [] + for node_ in DepthFirstIterator(root): + # Only count sliceable objects + if node_.callDecoration("isSliceable"): + fixed_nodes.append(node_) + for node in self._objects: # If object is part of a group, multiply group current_node = node @@ -58,31 +54,8 @@ class MultiplyObjectsJob(Job): continue processed_nodes.append(current_node) - node_too_big = False - if node.getBoundingBox().width < machine_width or node.getBoundingBox().depth < machine_depth: - offset_shape_arr, hull_shape_arr = ShapeArray.fromNode(current_node, min_offset = self._min_offset, scale = scale) - else: - node_too_big = True - - found_solution_for_all = True - arranger.resetLastPriority() for _ in range(self._count): - # We do place the nodes one by one, as we want to yield in between. new_node = copy.deepcopy(node) - solution_found = False - if not node_too_big: - if offset_shape_arr is not None and hull_shape_arr is not None: - solution_found = arranger.findNodePlacement(new_node, offset_shape_arr, hull_shape_arr) - else: - # The node has no shape, so no need to arrange it. The solution is simple: Do nothing. - solution_found = True - - if node_too_big or not solution_found: - found_solution_for_all = False - new_location = new_node.getPosition() - new_location = new_location.set(z = - not_fit_count * 20) - new_node.setPosition(new_location) - not_fit_count += 1 # Same build plate build_plate_number = current_node.callDecoration("getBuildPlateNumber") @@ -91,19 +64,15 @@ class MultiplyObjectsJob(Job): child.callDecoration("setBuildPlateNumber", build_plate_number) nodes.append(new_node) - current_progress += 1 - status_message.setProgress((current_progress / total_progress) * 100) - Job.yieldThread() - - Job.yieldThread() + found_solution_for_all = True if nodes: - operation = GroupedOperation() - for new_node in nodes: - operation.addOperation(AddSceneNodeOperation(new_node, current_node.getParent())) - operation.push() + found_solution_for_all = arrange(nodes, Application.getInstance().getBuildVolume(), fixed_nodes, + factor = 10000, add_new_nodes_in_scene = True) status_message.hide() if not found_solution_for_all: - no_full_solution_message = Message(i18n_catalog.i18nc("@info:status", "Unable to find a location within the build volume for all objects"), title = i18n_catalog.i18nc("@info:title", "Placing Object")) + no_full_solution_message = Message( + i18n_catalog.i18nc("@info:status", "Unable to find a location within the build volume for all objects"), + title = i18n_catalog.i18nc("@info:title", "Placing Object")) no_full_solution_message.show() |