Added first arranger tests, small refactors. CURA-3239

This commit is contained in:
Jack Ha 2017-04-03 16:36:48 +02:00
parent a83b1dd638
commit d1b9078657
3 changed files with 88 additions and 4 deletions

View file

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

View file

@ -1043,8 +1043,10 @@ class CuraApplication(QtApplication):
for size, node, offset_shape_arr, hull_shape_arr in nodes_arr: 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 # 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. # 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) 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 if x is not None: # We could find a place
arranger.place(x, y, hull_shape_arr) # take place before the next one arranger.place(x, y, hull_shape_arr) # take place before the next one

75
tests/TestArrange.py Executable file
View file

@ -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)