Browse Source

Add collision detection in on-at-a-time iterator

Lipu Fei 6 years ago
parent
commit
d45d6add40
1 changed files with 42 additions and 3 deletions
  1. 42 3
      cura/OneAtATimeIterator.py

+ 42 - 3
cura/OneAtATimeIterator.py

@@ -6,7 +6,7 @@ import sys
 from shapely import affinity
 from shapely.geometry import Polygon
 
-from UM.Scene.Iterator import Iterator
+from UM.Scene.Iterator.Iterator import Iterator
 from UM.Scene.SceneNode import SceneNode
 
 
@@ -20,7 +20,7 @@ from UM.Scene.SceneNode import SceneNode
 #  |                                |
 #  |                                |          - Rectangle represents the complete print head including fans, etc.
 #  |       X                X       |    y     - X's are the nozzles
-#  |      (1)              (2)      |    |
+#  |      (1)              (2)      |    ^
 #  |                                |    |
 #  +--------------------------------+    +--> x
 #
@@ -31,12 +31,13 @@ from UM.Scene.SceneNode import SceneNode
 #
 # This iterator determines the print order following the rules above.
 #
-class OneAtATimeIterator(Iterator.Iterator):
+class OneAtATimeIterator(Iterator):
 
     def __init__(self, scene_node):
         from cura.CuraApplication import CuraApplication
         self._global_stack = CuraApplication.getInstance().getGlobalContainerStack()
         self._original_node_list = []
+
         super().__init__(scene_node)  # Call super to make multiple inheritance work.
 
     def getMachineNearestCornerToExtruder(self, global_stack):
@@ -65,6 +66,40 @@ class OneAtATimeIterator(Iterator.Iterator):
 
         return min_coord
 
+    def _checkForCollisions(self) -> bool:
+        all_nodes = []
+        for node in self._scene_node.getChildren():
+            if not issubclass(type(node), SceneNode):
+                continue
+            convex_hull = node.callDecoration("getConvexHullHead")
+            if not convex_hull:
+                continue
+
+            bounding_box = node.getBoundingBox()
+            from UM.Math.Polygon import Polygon
+            bounding_box_polygon = Polygon([[bounding_box.left, bounding_box.front],
+                                            [bounding_box.left, bounding_box.back],
+                                            [bounding_box.right, bounding_box.back],
+                                            [bounding_box.right, bounding_box.front]])
+
+            all_nodes.append({"node": node,
+                              "bounding_box": bounding_box_polygon,
+                              "convex_hull": convex_hull})
+
+        has_collisions = False
+        for i, node_dict in enumerate(all_nodes):
+            for j, other_node_dict in enumerate(all_nodes):
+                if i == j:
+                    continue
+                if node_dict["bounding_box"].intersectsPolygon(other_node_dict["convex_hull"]):
+                    has_collisions = True
+                    break
+
+            if has_collisions:
+                break
+
+        return has_collisions
+
     def _fillStack(self):
         min_coord = self.getMachineNearestCornerToExtruder(self._global_stack)
         transform_x = -int(round(min_coord[0] / abs(min_coord[0])))
@@ -81,6 +116,10 @@ class OneAtATimeIterator(Iterator.Iterator):
             tm2 = [1, 0, 0, -1, 0, 0]
             return affinity.affine_transform(affinity.translate(polygon, yoff = -machine_size[1]), tm2)
 
+        if self._checkForCollisions():
+            self._node_stack = []
+            return
+
         node_list = []
         for node in self._scene_node.getChildren():
             if not issubclass(type(node), SceneNode):