Browse Source

Modify arrange() to optionally create AddSceneNodeOperations

Then the MultiplyObjectsJob can use the arrange function instead of duplicating the code

CURA-7440
Kostas Karmas 4 years ago
parent
commit
f9bd5e3dcd
2 changed files with 19 additions and 36 deletions
  1. 7 2
      cura/Arranging/Nest2DArrange.py
  2. 12 34
      cura/MultiplyObjectsJob.py

+ 7 - 2
cura/Arranging/Nest2DArrange.py

@@ -2,10 +2,12 @@ import numpy
 from pynest2d import Point, Box, Item, NfpConfig, nest
 from typing import List, TYPE_CHECKING, Optional, Tuple
 
+from UM.Application import Application
 from UM.Math.Matrix import Matrix
 from UM.Math.Polygon import Polygon
 from UM.Math.Quaternion import Quaternion
 from UM.Math.Vector import Vector
+from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
 from UM.Operations.GroupedOperation import GroupedOperation
 from UM.Operations.RotateOperation import RotateOperation
 from UM.Operations.TranslateOperation import TranslateOperation
@@ -96,7 +98,7 @@ def findNodePlacement(nodes_to_arrange: List["SceneNode"], build_volume: "BuildV
     return found_solution_for_all, node_items
 
 
-def arrange(nodes_to_arrange: List["SceneNode"], build_volume: "BuildVolume", fixed_nodes: Optional[List["SceneNode"]] = None, factor = 10000) -> bool:
+def arrange(nodes_to_arrange: List["SceneNode"], build_volume: "BuildVolume", fixed_nodes: Optional[List["SceneNode"]] = None, factor = 10000, add_new_nodes_in_scene: bool = False) -> bool:
     """
     Find placement for a set of scene nodes, and move them by using a single grouped operation.
     :param nodes_to_arrange: The list of nodes that need to be moved.
@@ -104,14 +106,17 @@ def arrange(nodes_to_arrange: List["SceneNode"], build_volume: "BuildVolume", fi
     :param fixed_nodes: List of nods that should not be moved, but should be used when deciding where the others nodes
                         are placed.
     :param factor: The library that we use is int based. This factor defines how accuracte we want it to be.
+    :param add_new_nodes_in_scene: Whether to create new scene nodes before applying the transformations and rotations
     :return:
     """
-
+    scene_root = Application.getInstance().getController().getScene().getRoot()
     found_solution_for_all, node_items = findNodePlacement(nodes_to_arrange, build_volume, fixed_nodes, factor)
 
     not_fit_count = 0
     grouped_operation = GroupedOperation()
     for node, node_item in zip(nodes_to_arrange, node_items):
+        if add_new_nodes_in_scene:
+            grouped_operation.addOperation(AddSceneNodeOperation(node, scene_root))
 
         if node_item.binId() == 0:
             # We found a spot for it

+ 12 - 34
cura/MultiplyObjectsJob.py

@@ -4,24 +4,16 @@
 import copy
 from typing import List
 
+from UM.Application import Application
 from UM.Job import Job
-from UM.Math.Matrix import Matrix
-from UM.Math.Quaternion import Quaternion
-from UM.Math.Vector import Vector
-from UM.Operations.GroupedOperation import GroupedOperation
 from UM.Message import Message
-from UM.Operations.RotateOperation import RotateOperation
-from UM.Operations.TranslateOperation import TranslateOperation
 from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
 from UM.Scene.SceneNode import SceneNode
 from UM.i18n import i18nCatalog
-from cura.Arranging.Nest2DArrange import findNodePlacement
+from cura.Arranging.Nest2DArrange import arrange
 
 i18n_catalog = i18nCatalog("cura")
 
-from UM.Application import Application
-from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
-
 
 class MultiplyObjectsJob(Job):
     def __init__(self, objects, count, min_offset = 8):
@@ -31,8 +23,9 @@ 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()
 
@@ -71,30 +64,15 @@ class MultiplyObjectsJob(Job):
                     child.callDecoration("setBuildPlateNumber", build_plate_number)
 
                 nodes.append(new_node)
-        factor = 10000
-        found_solution_for_all, node_items = findNodePlacement(nodes, Application.getInstance().getBuildVolume(), fixed_nodes, factor = factor)
-        not_fit_count = 0
+
+        found_solution_for_all = True
         if nodes:
-            operation = GroupedOperation()
-            for new_node, node_item in zip(nodes, node_items):
-                operation.addOperation(AddSceneNodeOperation(new_node, root))
-
-                if node_item.binId() == 0:
-                    # We found a spot for it
-                    rotation_matrix = Matrix()
-                    rotation_matrix.setByRotationAxis(node_item.rotation(), Vector(0, -1, 0))
-                    operation.addOperation(RotateOperation(new_node, Quaternion.fromMatrix(rotation_matrix)))
-                    operation.addOperation(
-                        TranslateOperation(new_node, Vector(node_item.translation().x() / factor, 0,
-                                                            node_item.translation().y() / factor)))
-                else:
-                    # We didn't find a spot
-                    operation.addOperation(TranslateOperation(new_node, Vector(200, new_node.getWorldPosition().y, -not_fit_count * 20), set_position = True))
-                    not_fit_count += 1
-
-            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()