mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-23 22:54:01 -06:00
CURA-5370 Small refactor for Arranger: make x and y consistent (numpy arrays start with y first in general), faster, cleanup, more unit tests, take actual build plate size in Arranger instances
This commit is contained in:
parent
310aee07ac
commit
f5bed242ed
8 changed files with 287 additions and 73 deletions
|
@ -4,9 +4,17 @@ from cura.Arranging.Arrange import Arrange
|
|||
from cura.Arranging.ShapeArray import ShapeArray
|
||||
|
||||
|
||||
def gimmeShapeArray():
|
||||
vertices = numpy.array([[-3, 1], [3, 1], [0, -3]])
|
||||
shape_arr = ShapeArray.fromPolygon(vertices)
|
||||
## Triangle of area 12
|
||||
def gimmeShapeArray(scale = 1.0):
|
||||
vertices = numpy.array([[-3, 1], [3, 1], [0, -3]], dtype=numpy.int32)
|
||||
shape_arr = ShapeArray.fromPolygon(vertices, scale = scale)
|
||||
return shape_arr
|
||||
|
||||
|
||||
## Boring square
|
||||
def gimmeShapeArraySquare(scale = 1.0):
|
||||
vertices = numpy.array([[-2, -2], [2, -2], [2, 2], [-2, 2]], dtype=numpy.int32)
|
||||
shape_arr = ShapeArray.fromPolygon(vertices, scale = scale)
|
||||
return shape_arr
|
||||
|
||||
|
||||
|
@ -20,6 +28,45 @@ def test_smoke_ShapeArray():
|
|||
shape_arr = gimmeShapeArray()
|
||||
|
||||
|
||||
## Test ShapeArray
|
||||
def test_ShapeArray():
|
||||
scale = 1
|
||||
ar = Arrange(16, 16, 8, 8, scale = scale)
|
||||
ar.centerFirst()
|
||||
|
||||
shape_arr = gimmeShapeArray(scale)
|
||||
print(shape_arr.arr)
|
||||
count = len(numpy.where(shape_arr.arr == 1)[0])
|
||||
print(count)
|
||||
assert count >= 10 # should approach 12
|
||||
|
||||
|
||||
## Test ShapeArray with scaling
|
||||
def test_ShapeArray_scaling():
|
||||
scale = 2
|
||||
ar = Arrange(16, 16, 8, 8, scale = scale)
|
||||
ar.centerFirst()
|
||||
|
||||
shape_arr = gimmeShapeArray(scale)
|
||||
print(shape_arr.arr)
|
||||
count = len(numpy.where(shape_arr.arr == 1)[0])
|
||||
print(count)
|
||||
assert count >= 40 # should approach 2*2*12 = 48
|
||||
|
||||
|
||||
## Test ShapeArray with scaling
|
||||
def test_ShapeArray_scaling2():
|
||||
scale = 0.5
|
||||
ar = Arrange(16, 16, 8, 8, scale = scale)
|
||||
ar.centerFirst()
|
||||
|
||||
shape_arr = gimmeShapeArray(scale)
|
||||
print(shape_arr.arr)
|
||||
count = len(numpy.where(shape_arr.arr == 1)[0])
|
||||
print(count)
|
||||
assert count >= 1 # should approach 3, but it can be inaccurate due to pixel rounding
|
||||
|
||||
|
||||
## Test centerFirst
|
||||
def test_centerFirst():
|
||||
ar = Arrange(300, 300, 150, 150)
|
||||
|
@ -32,13 +79,33 @@ def test_centerFirst():
|
|||
assert ar._priority[150][150] < ar._priority[130][130]
|
||||
|
||||
|
||||
## Test centerFirst
|
||||
def test_centerFirst_rectangular():
|
||||
ar = Arrange(400, 300, 200, 150)
|
||||
ar.centerFirst()
|
||||
assert ar._priority[150][200] < ar._priority[150][220]
|
||||
assert ar._priority[150][200] < ar._priority[170][200]
|
||||
assert ar._priority[150][200] < ar._priority[170][220]
|
||||
assert ar._priority[150][200] < ar._priority[180][150]
|
||||
assert ar._priority[150][200] < ar._priority[130][200]
|
||||
assert ar._priority[150][200] < ar._priority[130][180]
|
||||
|
||||
|
||||
## Test centerFirst
|
||||
def test_centerFirst_rectangular():
|
||||
ar = Arrange(10, 20, 5, 10)
|
||||
ar.centerFirst()
|
||||
print(ar._priority)
|
||||
assert ar._priority[10][5] < ar._priority[10][7]
|
||||
|
||||
|
||||
## Test backFirst
|
||||
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][150]
|
||||
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][150]
|
||||
assert ar._priority[150][150] > ar._priority[130][130]
|
||||
|
||||
|
||||
|
@ -55,6 +122,113 @@ def test_smoke_bestSpot():
|
|||
assert hasattr(best_spot, "priority")
|
||||
|
||||
|
||||
## Real life test
|
||||
def test_bestSpot():
|
||||
ar = Arrange(16, 16, 8, 8)
|
||||
ar.centerFirst()
|
||||
|
||||
shape_arr = gimmeShapeArray()
|
||||
best_spot = ar.bestSpot(shape_arr)
|
||||
assert best_spot.x == 0
|
||||
assert best_spot.y == 0
|
||||
ar.place(best_spot.x, best_spot.y, shape_arr)
|
||||
|
||||
# Place object a second time
|
||||
best_spot = ar.bestSpot(shape_arr)
|
||||
assert best_spot.x is not None # we found a location
|
||||
assert best_spot.x != 0 or best_spot.y != 0 # it can't be on the same location
|
||||
ar.place(best_spot.x, best_spot.y, shape_arr)
|
||||
|
||||
print(ar._occupied) # For debugging
|
||||
|
||||
|
||||
## Real life test rectangular build plate
|
||||
def test_bestSpot_rectangular_build_plate():
|
||||
ar = Arrange(16, 40, 8, 20)
|
||||
ar.centerFirst()
|
||||
|
||||
shape_arr = gimmeShapeArray()
|
||||
best_spot = ar.bestSpot(shape_arr)
|
||||
ar.place(best_spot.x, best_spot.y, shape_arr)
|
||||
assert best_spot.x == 0
|
||||
assert best_spot.y == 0
|
||||
|
||||
# Place object a second time
|
||||
best_spot2 = ar.bestSpot(shape_arr)
|
||||
assert best_spot2.x is not None # we found a location
|
||||
assert best_spot2.x != 0 or best_spot2.y != 0 # it can't be on the same location
|
||||
ar.place(best_spot2.x, best_spot2.y, shape_arr)
|
||||
|
||||
# Place object a 3rd time
|
||||
best_spot3 = ar.bestSpot(shape_arr)
|
||||
assert best_spot3.x is not None # we found a location
|
||||
assert best_spot3.x != best_spot.x or best_spot3.y != best_spot.y # it can't be on the same location
|
||||
assert best_spot3.x != best_spot2.x or best_spot3.y != best_spot2.y # it can't be on the same location
|
||||
ar.place(best_spot3.x, best_spot3.y, shape_arr)
|
||||
|
||||
best_spot_x = ar.bestSpot(shape_arr)
|
||||
ar.place(best_spot_x.x, best_spot_x.y, shape_arr)
|
||||
|
||||
best_spot_x = ar.bestSpot(shape_arr)
|
||||
ar.place(best_spot_x.x, best_spot_x.y, shape_arr)
|
||||
|
||||
best_spot_x = ar.bestSpot(shape_arr)
|
||||
ar.place(best_spot_x.x, best_spot_x.y, shape_arr)
|
||||
|
||||
print(ar._occupied) # For debugging
|
||||
|
||||
|
||||
## Real life test
|
||||
def test_bestSpot_scale():
|
||||
scale = 0.5
|
||||
ar = Arrange(16, 16, 8, 8, scale = scale)
|
||||
ar.centerFirst()
|
||||
|
||||
shape_arr = gimmeShapeArray(scale)
|
||||
best_spot = ar.bestSpot(shape_arr)
|
||||
assert best_spot.x == 0
|
||||
assert best_spot.y == 0
|
||||
ar.place(best_spot.x, best_spot.y, shape_arr)
|
||||
|
||||
print(ar._occupied)
|
||||
|
||||
# Place object a second time
|
||||
best_spot = ar.bestSpot(shape_arr)
|
||||
assert best_spot.x is not None # we found a location
|
||||
assert best_spot.x != 0 or best_spot.y != 0 # it can't be on the same location
|
||||
ar.place(best_spot.x, best_spot.y, shape_arr)
|
||||
|
||||
print(ar._occupied) # For debugging
|
||||
|
||||
|
||||
## Real life test
|
||||
def test_bestSpot_scale_rectangular():
|
||||
scale = 0.5
|
||||
ar = Arrange(16, 40, 8, 20, scale = scale)
|
||||
ar.centerFirst()
|
||||
|
||||
shape_arr = gimmeShapeArray(scale)
|
||||
|
||||
shape_arr_square = gimmeShapeArraySquare(scale)
|
||||
best_spot = ar.bestSpot(shape_arr_square)
|
||||
assert best_spot.x == 0
|
||||
assert best_spot.y == 0
|
||||
ar.place(best_spot.x, best_spot.y, shape_arr_square)
|
||||
|
||||
print(ar._occupied)
|
||||
|
||||
# Place object a second time
|
||||
best_spot = ar.bestSpot(shape_arr)
|
||||
assert best_spot.x is not None # we found a location
|
||||
assert best_spot.x != 0 or best_spot.y != 0 # it can't be on the same location
|
||||
ar.place(best_spot.x, best_spot.y, shape_arr)
|
||||
|
||||
best_spot = ar.bestSpot(shape_arr_square)
|
||||
ar.place(best_spot.x, best_spot.y, shape_arr_square)
|
||||
|
||||
print(ar._occupied) # For debugging
|
||||
|
||||
|
||||
## Try to place an object and see if something explodes
|
||||
def test_smoke_place():
|
||||
ar = Arrange(30, 30, 15, 15)
|
||||
|
@ -80,6 +254,20 @@ def test_checkShape():
|
|||
assert points3 > points
|
||||
|
||||
|
||||
## See of our center has less penalty points than out of the center
|
||||
def test_checkShape_rectangular():
|
||||
ar = Arrange(20, 30, 10, 15)
|
||||
ar.centerFirst()
|
||||
print(ar._priority)
|
||||
|
||||
shape_arr = gimmeShapeArray()
|
||||
points = ar.checkShape(0, 0, shape_arr)
|
||||
points2 = ar.checkShape(5, 0, shape_arr)
|
||||
points3 = ar.checkShape(0, 5, shape_arr)
|
||||
assert points2 > points
|
||||
assert points3 > points
|
||||
|
||||
|
||||
## Check that placing an object on occupied place returns None.
|
||||
def test_checkShape_place():
|
||||
ar = Arrange(30, 30, 15, 15)
|
||||
|
@ -104,6 +292,13 @@ def test_smoke_place_objects():
|
|||
ar.place(best_spot_x, best_spot_y, shape_arr)
|
||||
|
||||
|
||||
# Test some internals
|
||||
def test_compare_occupied_and_priority_tables():
|
||||
ar = Arrange(10, 15, 5, 7)
|
||||
ar.centerFirst()
|
||||
assert ar._priority.shape == ar._occupied.shape
|
||||
|
||||
|
||||
## Polygon -> array
|
||||
def test_arrayFromPolygon():
|
||||
vertices = numpy.array([[-3, 1], [3, 1], [0, -3]])
|
||||
|
@ -145,3 +340,5 @@ def test_check2():
|
|||
assert numpy.any(check_array)
|
||||
assert not check_array[3][0]
|
||||
assert check_array[3][4]
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue