mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-05-03 01:04:35 +08:00
Tuned arranger a bit, good enough for proof of concept. CURA-3239
This commit is contained in:
parent
bf08d30e7d
commit
f357dea086
@ -12,20 +12,17 @@ class ShapeArray:
|
||||
def from_polygon(cls, vertices, scale = 1):
|
||||
# scale
|
||||
vertices = vertices * scale
|
||||
# flip x, y
|
||||
# flip y, x -> x, y
|
||||
flip_vertices = np.zeros((vertices.shape))
|
||||
flip_vertices[:, 0] = vertices[:, 1]
|
||||
flip_vertices[:, 1] = vertices[:, 0]
|
||||
flip_vertices = flip_vertices[::-1]
|
||||
# offset
|
||||
# offset, we want that all coordinates have positive values
|
||||
offset_y = int(np.amin(flip_vertices[:, 0]))
|
||||
offset_x = int(np.amin(flip_vertices[:, 1]))
|
||||
# offset to 0
|
||||
flip_vertices[:, 0] = np.add(flip_vertices[:, 0], -offset_y)
|
||||
flip_vertices[:, 1] = np.add(flip_vertices[:, 1], -offset_x)
|
||||
shape = [int(np.amax(flip_vertices[:, 0])), int(np.amax(flip_vertices[:, 1]))]
|
||||
#from UM.Logger import Logger
|
||||
#Logger.log("d", " Vertices: %s" % str(flip_vertices))
|
||||
arr = cls.array_from_polygon(shape, flip_vertices)
|
||||
return cls(arr, offset_x, offset_y)
|
||||
|
||||
@ -85,6 +82,7 @@ class Arrange:
|
||||
def __init__(self, x, y, offset_x, offset_y, scale=1):
|
||||
self.shape = (y, x)
|
||||
self._priority = np.zeros((x, y), dtype=np.int32)
|
||||
self._priority_unique_values = []
|
||||
self._occupied = np.zeros((x, y), dtype=np.int32)
|
||||
self._scale = scale # convert input coordinates to arrange coordinates
|
||||
self._offset_x = offset_x
|
||||
@ -92,8 +90,12 @@ class Arrange:
|
||||
|
||||
## Fill priority, take offset as center. lower is better
|
||||
def centerFirst(self):
|
||||
#self._priority = np.fromfunction(
|
||||
# lambda i, j: abs(self._offset_x-i)+abs(self._offset_y-j), self.shape)
|
||||
self._priority = np.fromfunction(
|
||||
lambda i, j: abs(self._offset_x-i)+abs(self._offset_y-j), self.shape)
|
||||
lambda i, j: abs(self._offset_x-i)**2+abs(self._offset_y-j)**2, self.shape, dtype=np.int32)
|
||||
self._priority_unique_values = np.unique(self._priority)
|
||||
self._priority_unique_values.sort()
|
||||
|
||||
## Return the amount of "penalty points" for polygon, which is the sum of priority
|
||||
# 999999 if occupied
|
||||
@ -115,24 +117,14 @@ class Arrange:
|
||||
offset_x:offset_x + shape_arr.arr.shape[1]]
|
||||
return np.sum(prio_slice[np.where(shape_arr.arr == 1)])
|
||||
|
||||
## Slower but better (it tries all possible locations)
|
||||
def bestSpot2(self, shape_arr):
|
||||
best_x, best_y, best_points = None, None, None
|
||||
min_y = max(-shape_arr.offset_y, 0) - self._offset_y
|
||||
max_y = self.shape[0] - shape_arr.arr.shape[0] - self._offset_y
|
||||
min_x = max(-shape_arr.offset_x, 0) - self._offset_x
|
||||
max_x = self.shape[1] - shape_arr.arr.shape[1] - self._offset_x
|
||||
for y in range(min_y, max_y):
|
||||
for x in range(min_x, max_x):
|
||||
penalty_points = self.check_shape(x, y, shape_arr)
|
||||
if best_points is None or penalty_points < best_points:
|
||||
best_points = penalty_points
|
||||
best_x, best_y = x, y
|
||||
return best_x, best_y, best_points
|
||||
|
||||
## Faster
|
||||
## Find "best" spot
|
||||
def bestSpot(self, shape_arr, start_prio = 0):
|
||||
for prio in range(start_prio, 300):
|
||||
start_idx_list = np.where(self._priority_unique_values == start_prio)
|
||||
if start_idx_list:
|
||||
start_idx = start_idx_list[0]
|
||||
else:
|
||||
start_idx = 0
|
||||
for prio in self._priority_unique_values[start_idx:]:
|
||||
tryout_idx = np.where(self._priority == prio)
|
||||
for idx in range(len(tryout_idx[0])):
|
||||
x = tryout_idx[0][idx]
|
||||
|
@ -848,7 +848,9 @@ class CuraApplication(QtApplication):
|
||||
|
||||
## Testing, prepare arranger for use
|
||||
def _prepareArranger(self, fixed_nodes = None):
|
||||
arranger = Arrange(215, 215, 107, 107) # TODO: fill in dimensions
|
||||
#arranger = Arrange(215, 215, 107, 107) # TODO: fill in dimensions
|
||||
scale = 0.5
|
||||
arranger = Arrange(250, 250, 125, 125, scale = scale) # TODO: fill in dimensions
|
||||
arranger.centerFirst()
|
||||
|
||||
if fixed_nodes is None:
|
||||
@ -864,13 +866,14 @@ class CuraApplication(QtApplication):
|
||||
|
||||
vertices = fixed_node.callDecoration("getConvexHull")
|
||||
points = copy.deepcopy(vertices._points)
|
||||
shape_arr = ShapeArray.from_polygon(points)
|
||||
shape_arr = ShapeArray.from_polygon(points, scale=scale)
|
||||
arranger.place(0, 0, shape_arr)
|
||||
Logger.log("d", "Current buildplate: \n%s" % str(arranger._occupied[::10, ::10]))
|
||||
return arranger
|
||||
|
||||
@classmethod
|
||||
def _nodeAsShapeArr(cls, node, min_offset):
|
||||
scale = 0.5
|
||||
# hacky way to undo transformation
|
||||
transform = node._transformation
|
||||
transform_x = transform._data[0][3]
|
||||
@ -881,12 +884,12 @@ class CuraApplication(QtApplication):
|
||||
offset_points = copy.deepcopy(offset_verts._points) # x, y
|
||||
offset_points[:, 0] = numpy.add(offset_points[:, 0], -transform_x)
|
||||
offset_points[:, 1] = numpy.add(offset_points[:, 1], -transform_y)
|
||||
offset_shape_arr = ShapeArray.from_polygon(offset_points)
|
||||
offset_shape_arr = ShapeArray.from_polygon(offset_points, scale = scale)
|
||||
|
||||
hull_points = copy.deepcopy(hull_verts._points)
|
||||
hull_points[:, 0] = numpy.add(hull_points[:, 0], -transform_x)
|
||||
hull_points[:, 1] = numpy.add(hull_points[:, 1], -transform_y)
|
||||
hull_shape_arr = ShapeArray.from_polygon(hull_points) # x, y
|
||||
hull_shape_arr = ShapeArray.from_polygon(hull_points, scale = scale) # x, y
|
||||
|
||||
return offset_shape_arr, hull_shape_arr
|
||||
|
||||
@ -913,7 +916,6 @@ class CuraApplication(QtApplication):
|
||||
transformation._data[0][3] = 200
|
||||
transformation._data[2][3] = -100 + i * 20
|
||||
|
||||
# new_node.setTransformation(transformation)
|
||||
nodes.append(new_node)
|
||||
return nodes
|
||||
|
||||
@ -922,7 +924,7 @@ class CuraApplication(QtApplication):
|
||||
# count: number of copies
|
||||
# min_offset: minimum offset to other objects.
|
||||
@pyqtSlot("quint64", int)
|
||||
def multiplyObject(self, object_id, count, min_offset = 5):
|
||||
def multiplyObject(self, object_id, count, min_offset = 8):
|
||||
node = self.getController().getScene().findObject(object_id)
|
||||
|
||||
if not node and object_id != 0: # Workaround for tool handles overlapping the selected object
|
||||
@ -1063,7 +1065,7 @@ class CuraApplication(QtApplication):
|
||||
## Testing: arrange selected objects or all objects
|
||||
@pyqtSlot()
|
||||
def arrange(self):
|
||||
min_offset = 5
|
||||
min_offset = 8
|
||||
|
||||
if Selection.getAllSelectedObjects():
|
||||
nodes = Selection.getAllSelectedObjects()
|
||||
@ -1374,9 +1376,8 @@ class CuraApplication(QtApplication):
|
||||
self._currently_loading_files.remove(filename)
|
||||
|
||||
arranger = self._prepareArranger()
|
||||
min_offset = 5
|
||||
min_offset = 8
|
||||
total_time = 0
|
||||
import time
|
||||
|
||||
for node in nodes:
|
||||
node.setSelectable(True)
|
||||
@ -1403,13 +1404,8 @@ class CuraApplication(QtApplication):
|
||||
node.addDecorator(ConvexHullDecorator())
|
||||
|
||||
# find node location
|
||||
if 1:
|
||||
start_time = time.time()
|
||||
offset_shape_arr, hull_shape_arr = self._nodeAsShapeArr(node, min_offset = min_offset)
|
||||
nodes = self._findNodePlacements(arranger, node, offset_shape_arr, hull_shape_arr, count = 1)
|
||||
total_time += (time.time() - start_time)
|
||||
else:
|
||||
nodes = [node]
|
||||
offset_shape_arr, hull_shape_arr = self._nodeAsShapeArr(node, min_offset = min_offset)
|
||||
nodes = self._findNodePlacements(arranger, node, offset_shape_arr, hull_shape_arr, count = 1)
|
||||
|
||||
for new_node in nodes:
|
||||
op = AddSceneNodeOperation(new_node, scene.getRoot())
|
||||
@ -1417,8 +1413,6 @@ class CuraApplication(QtApplication):
|
||||
|
||||
scene.sceneChanged.emit(node)
|
||||
|
||||
Logger.log("d", "Placement of %s objects took %.1f seconds" % (len(nodes), total_time))
|
||||
|
||||
def addNonSliceableExtension(self, extension):
|
||||
self._non_sliceable_extensions.append(extension)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user