Exemple #1
0
def test_backFirst():
    ar = Arrange(300, 300, 150, 150, scale=1)
    ar.backFirst()
    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[130][150]
    assert ar._priority[150][150] > ar._priority[130][130]
Exemple #2
0
def test_centerFirst_rectangular():
    ar = Arrange(400, 300, 200, 150, scale=1)
    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]
Exemple #3
0
def test_centerFirst():
    ar = Arrange(300, 300, 150, 150, scale=1)
    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]
Exemple #4
0
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
Exemple #5
0
def test_smoke_bestSpot():
    ar = Arrange(30, 30, 15, 15, scale=1)
    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")
Exemple #6
0
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
Exemple #7
0
def test_bestSpot():
    ar = Arrange(16, 16, 8, 8, scale=1)
    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
Exemple #8
0
def test_checkShape_place():
    ar = Arrange(30, 30, 15, 15)
    ar.centerFirst()

    shape_arr = gimmeShapeArray()
    points = ar.checkShape(3, 6, shape_arr)
    ar.place(3, 6, shape_arr)
    points2 = ar.checkShape(3, 6, shape_arr)

    assert points2 is None
Exemple #9
0
def test_smoke_place_objects():
    ar = Arrange(20, 20, 10, 10, scale=1)
    ar.centerFirst()
    shape_arr = gimmeShapeArray()

    for i in range(5):
        best_spot_x, best_spot_y, score, prio = ar.bestSpot(shape_arr)
        ar.place(best_spot_x, best_spot_y, shape_arr)
Exemple #10
0
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)
Exemple #11
0
def test_checkShape():
    ar = Arrange(30, 30, 15, 15)
    ar.centerFirst()

    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
Exemple #12
0
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
Exemple #13
0
def test_centerFirst_rectangular2():
    ar = Arrange(10, 20, 5, 10, scale=1)
    ar.centerFirst()
    print(ar._priority)
    assert ar._priority[10][5] < ar._priority[10][7]
Exemple #14
0
def test_bestSpot_rectangular_build_plate():
    ar = Arrange(16, 40, 8, 20, scale=1)
    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
Exemple #15
0
def test_smoke_arrange():
    ar = Arrange.create(fixed_nodes=[])
Exemple #16
0
def test_compare_occupied_and_priority_tables():
    ar = Arrange(10, 15, 5, 7)
    ar.centerFirst()
    assert ar._priority.shape == ar._occupied.shape
Exemple #17
0
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
Exemple #18
0
 def add(self):
     new_arrange = Arrange.create(x = self._x, y = self._y, fixed_nodes = self._fixed_nodes)
     self._arrange.append(new_arrange)
     self._count += 1
     self._update_first_empty()
Exemple #19
0
    def run(self):
        status_message = Message(
            i18n_catalog.i18nc("@info:status",
                               "Finding new location for objects"),
            lifetime=0,
            dismissable=False,
            progress=0,
            title=i18n_catalog.i18nc("@info:title", "Finding Location"))
        status_message.show()
        global_container_stack = Application.getInstance(
        ).getGlobalContainerStack()
        machine_width = global_container_stack.getProperty(
            "machine_width", "value")
        machine_depth = global_container_stack.getProperty(
            "machine_depth", "value")

        arranger = Arrange.create(x=machine_width,
                                  y=machine_depth,
                                  fixed_nodes=self._fixed_nodes,
                                  min_offset=self._min_offset)

        # Collect nodes to be placed
        nodes_arr = [
        ]  # fill with (size, node, offset_shape_arr, hull_shape_arr)
        for node in self._nodes:
            offset_shape_arr, hull_shape_arr = ShapeArray.fromNode(
                node, min_offset=self._min_offset)
            if offset_shape_arr is None:
                Logger.log(
                    "w",
                    "Node [%s] could not be converted to an array for arranging...",
                    str(node))
                continue
            nodes_arr.append(
                (offset_shape_arr.arr.shape[0] * offset_shape_arr.arr.shape[1],
                 node, offset_shape_arr, hull_shape_arr))

        # Sort the nodes with the biggest area first.
        nodes_arr.sort(key=lambda item: item[0])
        nodes_arr.reverse()

        # Place nodes one at a time
        start_priority = 0
        last_priority = start_priority
        last_size = None
        grouped_operation = GroupedOperation()
        found_solution_for_all = True
        not_fit_count = 0
        for idx, (size, node, offset_shape_arr,
                  hull_shape_arr) in enumerate(nodes_arr):
            # For performance reasons, we assume that when a location does not fit,
            # it will also not fit for the next object (while what can be untrue).
            if last_size == size:  # This optimization works if many of the objects have the same size
                start_priority = last_priority
            else:
                start_priority = 0
            best_spot = arranger.bestSpot(hull_shape_arr,
                                          start_prio=start_priority)
            x, y = best_spot.x, best_spot.y
            node.removeDecorator(ZOffsetDecorator)
            if node.getBoundingBox():
                center_y = node.getWorldPosition().y - node.getBoundingBox(
                ).bottom
            else:
                center_y = 0
            if x is not None:  # We could find a place
                last_size = size
                last_priority = best_spot.priority

                arranger.place(
                    x, y, offset_shape_arr)  # take place before the next one
                grouped_operation.addOperation(
                    TranslateOperation(node,
                                       Vector(x, center_y, y),
                                       set_position=True))
            else:
                Logger.log("d", "Arrange all: could not find spot!")
                found_solution_for_all = False
                grouped_operation.addOperation(
                    TranslateOperation(node,
                                       Vector(200, center_y,
                                              -not_fit_count * 20),
                                       set_position=True))
                not_fit_count += 1

            status_message.setProgress((idx + 1) / len(nodes_arr) * 100)
            Job.yieldThread()

        grouped_operation.push()

        status_message.hide()

        if not found_solution_for_all:
            no_full_solution_message = Message(i18n_catalog.i18nc(
                "@info:status",
                "Unable to find a location within the build volume for all objects"
            ),
                                               title=i18n_catalog.i18nc(
                                                   "@info:title",
                                                   "Can't Find Location"))
            no_full_solution_message.show()

        self.finished.emit(self)
Exemple #20
0
    def run(self):
        status_message = Message(
            i18n_catalog.i18nc("@info:status",
                               "Multiplying and placing objects"),
            lifetime=0,
            dismissable=False,
            progress=0,
            title=i18n_catalog.i18nc("@info:title", "Placing Object"))
        status_message.show()
        scene = Application.getInstance().getController().getScene()

        total_progress = len(self._objects) * self._count
        current_progress = 0

        global_container_stack = Application.getInstance(
        ).getGlobalContainerStack()
        machine_width = global_container_stack.getProperty(
            "machine_width", "value")
        machine_depth = global_container_stack.getProperty(
            "machine_depth", "value")

        root = scene.getRoot()
        scale = 0.5
        arranger = Arrange.create(x=machine_width,
                                  y=machine_depth,
                                  scene_root=root,
                                  scale=scale,
                                  min_offset=self._min_offset)
        processed_nodes = []
        nodes = []

        not_fit_count = 0

        for node in self._objects:
            # If object is part of a group, multiply group
            current_node = node
            while current_node.getParent() and (
                    current_node.getParent().callDecoration("isGroup")
                    or current_node.getParent().callDecoration("isSliceable")):
                current_node = current_node.getParent()

            if current_node in processed_nodes:
                continue
            processed_nodes.append(current_node)

            node_too_big = False
            if node.getBoundingBox(
            ).width < machine_width or node.getBoundingBox(
            ).depth < machine_depth:
                offset_shape_arr, hull_shape_arr = ShapeArray.fromNode(
                    current_node, min_offset=self._min_offset, scale=scale)
            else:
                node_too_big = True

            found_solution_for_all = True
            arranger.resetLastPriority()
            for i in range(self._count):
                # We do place the nodes one by one, as we want to yield in between.
                new_node = copy.deepcopy(node)
                solution_found = False
                if not node_too_big:
                    solution_found = arranger.findNodePlacement(
                        new_node, offset_shape_arr, hull_shape_arr)

                if node_too_big or not solution_found:
                    found_solution_for_all = False
                    new_location = new_node.getPosition()
                    new_location = new_location.set(z=-not_fit_count * 20)
                    new_node.setPosition(new_location)
                    not_fit_count += 1

                # Same build plate
                build_plate_number = current_node.callDecoration(
                    "getBuildPlateNumber")
                new_node.callDecoration("setBuildPlateNumber",
                                        build_plate_number)
                for child in new_node.getChildren():
                    child.callDecoration("setBuildPlateNumber",
                                         build_plate_number)

                nodes.append(new_node)
                current_progress += 1
                status_message.setProgress(
                    (current_progress / total_progress) * 100)
                Job.yieldThread()

            Job.yieldThread()

        if nodes:
            op = GroupedOperation()
            for new_node in nodes:
                op.addOperation(
                    AddSceneNodeOperation(new_node, current_node.getParent()))
            op.push()
        status_message.hide()

        if not found_solution_for_all:
            no_full_solution_message = Message(i18n_catalog.i18nc(
                "@info:status",
                "Unable to find a location within the build volume for all objects"
            ),
                                               title=i18n_catalog.i18nc(
                                                   "@info:title",
                                                   "Placing Object"))
            no_full_solution_message.show()