diff options
author | Jack Ha <j.ha@ultimaker.com> | 2017-04-03 15:48:31 +0300 |
---|---|---|
committer | Jack Ha <j.ha@ultimaker.com> | 2017-04-03 15:48:31 +0300 |
commit | a83b1dd638567fc6f14897c0eb76207af4b5dd20 (patch) | |
tree | 4c4a005da399df94dd9c5148e6adbae2bad9579d /cura/Arrange.py | |
parent | d6cd37626b76db0e6e4e2287de4e8fc7f7736de2 (diff) |
Split ShapeArray from Arranger. CURA-3239
Diffstat (limited to 'cura/Arrange.py')
-rwxr-xr-x | cura/Arrange.py | 129 |
1 files changed, 18 insertions, 111 deletions
diff --git a/cura/Arrange.py b/cura/Arrange.py index ed683b3610..e0bd94b742 100755 --- a/cura/Arrange.py +++ b/cura/Arrange.py @@ -1,110 +1,15 @@ -import numpy -from UM.Math.Polygon import Polygon - - -## Polygon representation as an array -# -class ShapeArray: - def __init__(self, arr, offset_x, offset_y, scale = 1): - self.arr = arr - self.offset_x = offset_x - self.offset_y = offset_y - self.scale = scale - - @classmethod - def fromPolygon(cls, vertices, scale = 1): - # scale - vertices = vertices * scale - # flip y, x -> x, y - flip_vertices = numpy.zeros((vertices.shape)) - flip_vertices[:, 0] = vertices[:, 1] - flip_vertices[:, 1] = vertices[:, 0] - flip_vertices = flip_vertices[::-1] - # offset, we want that all coordinates have positive values - offset_y = int(numpy.amin(flip_vertices[:, 0])) - offset_x = int(numpy.amin(flip_vertices[:, 1])) - flip_vertices[:, 0] = numpy.add(flip_vertices[:, 0], -offset_y) - flip_vertices[:, 1] = numpy.add(flip_vertices[:, 1], -offset_x) - shape = [int(numpy.amax(flip_vertices[:, 0])), int(numpy.amax(flip_vertices[:, 1]))] - arr = cls.arrayFromPolygon(shape, flip_vertices) - return cls(arr, offset_x, offset_y) - - ## Return an offset and hull ShapeArray from a scenenode. - @classmethod - def fromNode(cls, node, min_offset, scale = 0.5): - # hacky way to undo transformation - transform = node._transformation - transform_x = transform._data[0][3] - transform_y = transform._data[2][3] - hull_verts = node.callDecoration("getConvexHull") - - offset_verts = hull_verts.getMinkowskiHull(Polygon.approximatedCircle(min_offset)) - 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.fromPolygon(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.fromPolygon(hull_points, scale = scale) # x, y - - return offset_shape_arr, hull_shape_arr - - - ## Create np.array with dimensions defined by shape - # Fills polygon defined by vertices with ones, all other values zero - # Only works correctly for convex hull vertices - # Originally from: http://stackoverflow.com/questions/37117878/generating-a-filled-polygon-inside-a-numpy-array - @classmethod - def arrayFromPolygon(cls, shape, vertices): - base_array = numpy.zeros(shape, dtype=float) # Initialize your array of zeros - - fill = numpy.ones(base_array.shape) * True # Initialize boolean array defining shape fill - - # Create check array for each edge segment, combine into fill array - for k in range(vertices.shape[0]): - fill = numpy.all([fill, cls._check(vertices[k - 1], vertices[k], base_array)], axis=0) - - # Set all values inside polygon to one - base_array[fill] = 1 - - return base_array - - ## Return indices that mark one side of the line, used by array_from_polygon - # Uses the line defined by p1 and p2 to check array of - # input indices against interpolated value - # Returns boolean array, with True inside and False outside of shape - # Originally from: http://stackoverflow.com/questions/37117878/generating-a-filled-polygon-inside-a-numpy-array - @classmethod - def _check(cls, p1, p2, base_array): - if p1[0] == p2[0] and p1[1] == p2[1]: - return - idxs = numpy.indices(base_array.shape) # Create 3D array of indices - - p1 = p1.astype(float) - p2 = p2.astype(float) - - if p2[0] == p1[0]: - sign = numpy.sign(p2[1] - p1[1]) - return idxs[1] * sign - - if p2[1] == p1[1]: - sign = numpy.sign(p2[0] - p1[0]) - return idxs[1] * sign - - # Calculate max column idx for each row idx based on interpolated line between two points - - max_col_idx = (idxs[0] - p1[0]) / (p2[0] - p1[0]) * (p2[1] - p1[1]) + p1[1] - sign = numpy.sign(p2[0] - p1[0]) - return idxs[1] * sign <= max_col_idx * sign - - from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Logger import Logger +from cura.ShapeArray import ShapeArray + +import numpy import copy +## 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 +# the same logic. class Arrange: def __init__(self, x, y, offset_x, offset_y, scale=1): self.shape = (y, x) @@ -166,16 +71,18 @@ class Arrange: ## Fill priority, take offset as center. lower is better def centerFirst(self): - # Distance x + distance y - #self._priority = np.fromfunction( - # lambda i, j: abs(self._offset_x-i)+abs(self._offset_y-j), self.shape, dtype=np.int32) - # Square distance - # self._priority = np.fromfunction( - # lambda i, j: abs(self._offset_x-i)**2+abs(self._offset_y-j)**2, self.shape, dtype=np.int32) + # Distance x + distance y: creates diamond shape + #self._priority = numpy.fromfunction( + # lambda i, j: abs(self._offset_x-i)+abs(self._offset_y-j), self.shape, dtype=numpy.int32) + # Square distance: creates a more round shape + self._priority = numpy.fromfunction( + lambda i, j: (self._offset_x - i) ** 2 + (self._offset_y - j) ** 2, self.shape, dtype=numpy.int32) + self._priority_unique_values = numpy.unique(self._priority) + self._priority_unique_values.sort() + + def backFirst(self): self._priority = numpy.fromfunction( - lambda i, j: abs(self._offset_x-i)**3+abs(self._offset_y-j)**3, self.shape, dtype=numpy.int32) - # self._priority = np.fromfunction( - # lambda i, j: max(abs(self._offset_x-i), abs(self._offset_y-j)), self.shape, dtype=np.int32) + lambda i, j: 10 * j + abs(self._offset_x - i), self.shape, dtype=numpy.int32) self._priority_unique_values = numpy.unique(self._priority) self._priority_unique_values.sort() |