Browse Source

Added first arranger tests, small refactors. CURA-3239

Jack Ha 8 years ago
parent
commit
d1b9078657
3 changed files with 88 additions and 4 deletions
  1. 10 3
      cura/Arrange.py
  2. 3 1
      cura/CuraApplication.py
  3. 75 0
      tests/TestArrange.py

+ 10 - 3
cura/Arrange.py

@@ -2,10 +2,15 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
 from UM.Logger import Logger
 from cura.ShapeArray import ShapeArray
 
+from collections import namedtuple
+
 import numpy
 import copy
 
 
+##  Return object for  bestSpot
+LocationSuggestion = namedtuple("LocationSuggestion", ["x", "y", "penalty_points", "priority"])
+
 ##  The Arrange classed is used together with ShapeArray. The class tries to find
 #   good locations for objects that you try to put on a build place.
 #   Different priority schemes can be defined so it alters the behavior while using
@@ -54,7 +59,7 @@ class Arrange:
         for i in range(count):
             new_node = copy.deepcopy(node)
 
-            x, y, penalty_points, start_prio = self.bestSpot(
+            x, y = self.bestSpot(
                 offset_shape_arr, start_prio = start_prio, step = step)
             transformation = new_node._transformation
             if x is not None:  # We could find a place
@@ -80,6 +85,7 @@ class Arrange:
         self._priority_unique_values = numpy.unique(self._priority)
         self._priority_unique_values.sort()
 
+    ##
     def backFirst(self):
         self._priority = numpy.fromfunction(
             lambda i, j: 10 * j + abs(self._offset_x - i), self.shape, dtype=numpy.int32)
@@ -107,6 +113,7 @@ class Arrange:
         return numpy.sum(prio_slice[numpy.where(shape_arr.arr == 1)])
 
     ##  Find "best" spot for ShapeArray
+    #   Return namedtuple with properties x, y, penalty_points, priority
     def bestSpot(self, shape_arr, start_prio = 0, step = 1):
         start_idx_list = numpy.where(self._priority_unique_values == start_prio)
         if start_idx_list:
@@ -124,8 +131,8 @@ class Arrange:
                 # array to "world" coordinates
                 penalty_points = self.checkShape(projected_x, projected_y, shape_arr)
                 if penalty_points != 999999:
-                    return projected_x, projected_y, penalty_points, prio
-        return None, None, None, prio  # No suitable location found :-(
+                    return LocationSuggestion(x = projected_x, y = projected_y, penalty_points = penalty_points, priority = prio)
+        return LocationSuggestion(x = None, y = None, penalty_points = None, priority = prio)  # No suitable location found :-(
 
     ##  Place the object
     def place(self, x, y, shape_arr):

+ 3 - 1
cura/CuraApplication.py

@@ -1043,8 +1043,10 @@ class CuraApplication(QtApplication):
         for size, node, offset_shape_arr, hull_shape_arr in nodes_arr:
             # we assume that when a location does not fit, it will also not fit for the next
             # object (while what can be untrue). That saves a lot of time.
-            x, y, penalty_points, start_prio = arranger.bestSpot(
+            best_spot = arranger.bestSpot(
                 offset_shape_arr, start_prio = start_prio)
+            x, y = best_spot.x, best_spot.y
+            start_prio = best_spot.priority
             if x is not None:  # We could find a place
                 arranger.place(x, y, hull_shape_arr)  # take place before the next one
 

+ 75 - 0
tests/TestArrange.py

@@ -0,0 +1,75 @@
+import pytest
+import numpy
+import time
+
+from cura.Arrange import Arrange
+from cura.ShapeArray import ShapeArray
+
+
+def gimmeShapeArray():
+    vertices = numpy.array([[-3, 1], [3, 1], [0, -3]])
+    shape_arr = ShapeArray.fromPolygon(vertices)
+    return shape_arr
+
+
+def test_smoke_arrange():
+    ar = Arrange.create(fixed_nodes = [])
+
+
+def test_centerFirst():
+    ar = Arrange(300, 300, 150, 150)
+    ar.centerFirst()
+    assert ar._priority[150][150] < ar._priority[170][150]
+    assert ar._priority[150][150] < ar._priority[150][170]
+    assert ar._priority[150][150] < ar._priority[170][170]
+    assert ar._priority[150][150] < ar._priority[130][150]
+    assert ar._priority[150][150] < ar._priority[150][130]
+    assert ar._priority[150][150] < ar._priority[130][130]
+
+
+def test_backFirst():
+    ar = Arrange(300, 300, 150, 150)
+    ar.backFirst()
+    assert ar._priority[150][150] < ar._priority[150][170]
+    assert ar._priority[150][150] < ar._priority[170][170]
+    assert ar._priority[150][150] > ar._priority[150][130]
+    assert ar._priority[150][150] > ar._priority[130][130]
+
+
+def test_smoke_bestSpot():
+    ar = Arrange(30, 30, 15, 15)
+    ar.centerFirst()
+
+    shape_arr = gimmeShapeArray()
+    best_spot = ar.bestSpot(shape_arr)
+    assert hasattr(best_spot, "x")
+    assert hasattr(best_spot, "y")
+    assert hasattr(best_spot, "penalty_points")
+    assert hasattr(best_spot, "priority")
+
+
+def test_smoke_place():
+    ar = Arrange(30, 30, 15, 15)
+    ar.centerFirst()
+
+    shape_arr = gimmeShapeArray()
+
+    assert not numpy.any(ar._occupied)
+    ar.place(0, 0, shape_arr)
+    assert numpy.any(ar._occupied)
+
+
+def test_place_objects():
+    ar = Arrange(20, 20, 10, 10)
+    ar.centerFirst()
+    shape_arr = gimmeShapeArray()
+    print(shape_arr)
+
+    now = time.time()
+    for i in range(5):
+        best_spot_x, best_spot_y, score, prio = ar.bestSpot(shape_arr)
+        print(best_spot_x, best_spot_y, score)
+        ar.place(best_spot_x, best_spot_y, shape_arr)
+        print(ar._occupied)
+
+    print(time.time() - now)