Пример #1
0
    def create(cls, scene_root = None, fixed_nodes = None, scale = 0.5):
        arranger = Arrange(220, 220, 110, 110, scale = scale)
        arranger.centerFirst()

        if fixed_nodes is None:
            fixed_nodes = []
            for node_ in DepthFirstIterator(scene_root):
                # Only count sliceable objects
                if node_.callDecoration("isSliceable"):
                    fixed_nodes.append(node_)

        # Place all objects fixed nodes
        for fixed_node in fixed_nodes:
            vertices = fixed_node.callDecoration("getConvexHull")
            if not vertices:
                continue
            points = copy.deepcopy(vertices._points)
            shape_arr = ShapeArray.fromPolygon(points, scale = scale)
            arranger.place(0, 0, shape_arr)

        # If a build volume was set, add the disallowed areas
        if Arrange.build_volume:
            disallowed_areas = Arrange.build_volume.getDisallowedAreas()
            for area in disallowed_areas:
                points = copy.deepcopy(area._points)
                shape_arr = ShapeArray.fromPolygon(points, scale = scale)
                arranger.place(0, 0, shape_arr)
        return arranger
Пример #2
0
    def create(cls, scene_root=None, fixed_nodes=None, scale=0.5):
        arranger = Arrange(220, 220, 110, 110, scale=scale)
        arranger.centerFirst()

        if fixed_nodes is None:
            fixed_nodes = []
            for node_ in DepthFirstIterator(scene_root):
                # Only count sliceable objects
                if node_.callDecoration("isSliceable"):
                    fixed_nodes.append(node_)

        # Place all objects fixed nodes
        for fixed_node in fixed_nodes:
            vertices = fixed_node.callDecoration("getConvexHull")
            points = copy.deepcopy(vertices._points)
            shape_arr = ShapeArray.fromPolygon(points, scale=scale)
            arranger.place(0, 0, shape_arr)

        # If a build volume was set, add the disallowed areas
        if Arrange.build_volume:
            disallowed_areas = Arrange.build_volume.getDisallowedAreas()
            for area in disallowed_areas:
                points = copy.deepcopy(area._points)
                shape_arr = ShapeArray.fromPolygon(points, scale=scale)
                arranger.place(0, 0, shape_arr)
        return arranger
Пример #3
0
    def run(self):
        status_message = Message(i18n_catalog.i18nc(
            "@info:status", "Multiplying and placing objects"),
                                 lifetime=0,
                                 dismissable=False,
                                 progress=0)
        status_message.show()
        scene = Application.getInstance().getController().getScene()
        node = scene.findObject(self._object_id)

        if not node and self._object_id != 0:  # Workaround for tool handles overlapping the selected object
            node = Selection.getSelectedObject(0)

        # If object is part of a group, multiply group
        current_node = node
        while current_node.getParent() and current_node.getParent(
        ).callDecoration("isGroup"):
            current_node = current_node.getParent()

        root = scene.getRoot()
        arranger = Arrange.create(scene_root=root)
        node_too_big = False
        if node.getBoundingBox().width < 300 or node.getBoundingBox(
        ).depth < 300:
            offset_shape_arr, hull_shape_arr = ShapeArray.fromNode(
                current_node, min_offset=self._min_offset)
        else:
            node_too_big = True
        nodes = []
        found_solution_for_all = True
        for i in range(self._count):
            # We do place the nodes one by one, as we want to yield in between.
            if not node_too_big:
                node, solution_found = arranger.findNodePlacement(
                    current_node, offset_shape_arr, hull_shape_arr)
            if node_too_big or not solution_found:
                found_solution_for_all = False
                new_location = node.getPosition()
                new_location = new_location.set(z=100 - i * 20)
                node.setPosition(new_location)

            nodes.append(node)
            Job.yieldThread()
            status_message.setProgress((i + 1) / self._count * 100)

        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"
                ))
            no_full_solution_message.show()
Пример #4
0
def test_check2():
    base_array = numpy.zeros([5, 5], dtype=float)
    p1 = numpy.array([0, 3])
    p2 = numpy.array([4, 3])
    check_array = ShapeArray._check(p1, p2, base_array)
    assert numpy.any(check_array)
    assert not check_array[3][0]
    assert check_array[3][4]
Пример #5
0
def test_check2():
    base_array = numpy.zeros([5, 5], dtype=float)
    p1 = numpy.array([0, 3])
    p2 = numpy.array([4, 3])
    check_array = ShapeArray._check(p1, p2, base_array)
    assert numpy.any(check_array)
    assert not check_array[3][0]
    assert check_array[3][4]
Пример #6
0
    def run(self):
        status_message = Message(i18n_catalog.i18nc("@info:status", "Finding new location for objects"), lifetime = 0, dismissable=False, progress = 0)
        status_message.show()
        arranger = Arrange.create(fixed_nodes = self._fixed_nodes)

        # 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)
            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
        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).
            # We also skip possibilities by slicing through the possibilities (step = 10)
            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(offset_shape_arr, start_prio=start_priority, step=10)
            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, hull_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, - idx * 20), set_position = True))

            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"))
            no_full_solution_message.show()
Пример #7
0
    def run(self):
        status_message = Message(i18n_catalog.i18nc("@info:status", "Finding new location for objects"), lifetime = 0, dismissable=False, progress = 0)
        status_message.show()
        arranger = Arrange.create(fixed_nodes = self._fixed_nodes)

        # 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)
            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
        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).
            # We also skip possibilities by slicing through the possibilities (step = 10)
            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(offset_shape_arr, start_prio=start_priority, step=1)
            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, hull_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, - idx * 20), set_position = True))

            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"))
            no_full_solution_message.show()
Пример #8
0
    def create(cls, scene_root=None, fixed_nodes=None, scale=1.0):
        global_stack = Application.getInstance().getGlobalContainerStack()
        machine_width = int(global_stack.getProperty("machine_width", "value"))
        machine_depth = int(global_stack.getProperty("machine_depth", "value"))
        arranger = Arrange(machine_depth,
                           machine_width,
                           int(machine_width / 2),
                           int(machine_depth / 2),
                           scale=scale)
        arranger.centerFirst()

        if fixed_nodes is None:
            fixed_nodes = []
            for node_ in DepthFirstIterator(scene_root):
                # Only count sliceable objects
                if node_.callDecoration("isSliceable") and not isinstance(
                        node_, DuplicatedNode):
                    fixed_nodes.append(node_)

        # Place all objects fixed nodes
        for fixed_node in fixed_nodes:
            arrange_align = Preferences.getInstance().getValue(
                "mesh/arrange_align")
            if arrange_align:
                bb = fixed_node.getBoundingBox()
                points = numpy.array(
                    [[bb.right, bb.back], [bb.left, bb.back],
                     [bb.left, bb.front], [bb.right, bb.front]],
                    dtype=numpy.float32)
            else:
                vertices = fixed_node.callDecoration("getConvexHull")
                points = copy.deepcopy(vertices._points)

            shape_arr = ShapeArray.fromPolygon(points, scale=scale)
            arranger.place(0, 0, shape_arr)

        # If a build volume was set, add the disallowed areas
        if Arrange.build_volume:
            disallowed_areas = Arrange.build_volume.getDisallowedAreas()
            for area in disallowed_areas:
                points = copy.deepcopy(area._points)
                shape_arr = ShapeArray.fromPolygon(points, scale=scale)
                arranger.place(0, 0, shape_arr)
        return arranger
Пример #9
0
    def _onPrintModeChanged(self):
        if self._global_stack:
            self._restoreSettingsValue()
            print_mode = self._global_stack.getProperty("print_mode", "value")
            if print_mode != "regular":
                nodes = self._scene.getRoot().getChildren()
                max_offset = 0
                machine_head_with_fans_polygon = self._global_stack.getProperty(
                    "machine_head_with_fans_polygon", "value")
                machine_head_size = abs(machine_head_with_fans_polygon[0][0] -
                                        machine_head_with_fans_polygon[2][0])
                margin = Application.getInstance().getBuildVolume().margin
                if print_mode == "mirror":
                    margin += machine_head_size / 2
                sliceable_nodes = []
                for node in nodes:
                    self._setActiveExtruder(node)
                    if (node.callDecoration("isSliceable") or
                            node.callDecoration("isGroup")) and not isinstance(
                                node, DuplicatedNode):
                        sliceable_nodes.append(node)
                        offset_shape_arr, hull_shape_arr = ShapeArray.fromNode(
                            node, 4)
                        position = node.getPosition()
                        max_offset = max(
                            abs(offset_shape_arr.offset_x) + position.x +
                            margin, max_offset)

                for node in sliceable_nodes:
                    position = node.getPosition()
                    offset = position.x - max_offset
                    node.setPosition(Vector(offset, position.y, position.z))

                if self._old_material == "":
                    self._old_material = ExtruderManager.getInstance(
                    ).getExtruderStack(1).material
                    material = ExtruderManager.getInstance().getExtruderStack(
                        0).material
                    ExtruderManager.getInstance().getExtruderStack(
                        1).setMaterial(material)
                    variant = ExtruderManager.getInstance().getExtruderStack(
                        0).variant
                    ExtruderManager.getInstance().getExtruderStack(
                        1).setVariant(variant)
                    Preferences.getInstance().setValue(
                        "cura/old_material", self._old_material.getId())
                self.renderDuplicatedNodes()
            else:
                self.removeDuplicatedNodes()
                if self._old_material != "":
                    ExtruderManager.getInstance().getExtruderStack(
                        1).setMaterial(self._old_material)
                    self._old_material = ""
                    Preferences.getInstance().setValue("cura/old_material", "")
Пример #10
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

        root = scene.getRoot()
        arranger = Arrange.create(scene_root=root)
        nodes = []
        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"):
                current_node = current_node.getParent()

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

            found_solution_for_all = True
            for i in range(self._count):
                # We do place the nodes one by one, as we want to yield in between.
                if not node_too_big:
                    node, solution_found = arranger.findNodePlacement(current_node, offset_shape_arr, hull_shape_arr)
                if node_too_big or not solution_found:
                    found_solution_for_all = False
                    new_location = node.getPosition()
                    new_location = new_location.set(z = 100 - i * 20)
                    node.setPosition(new_location)

                nodes.append(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()
Пример #11
0
    def run(self):
        status_message = Message(i18n_catalog.i18nc("@info:status", "Multiplying and placing objects"), lifetime=0,
                                 dismissable=False, progress=0)
        status_message.show()
        scene = Application.getInstance().getController().getScene()
        node = scene.findObject(self._object_id)

        if not node and self._object_id != 0:  # Workaround for tool handles overlapping the selected object
            node = Selection.getSelectedObject(0)

        # If object is part of a group, multiply group
        current_node = node
        while current_node.getParent() and current_node.getParent().callDecoration("isGroup"):
            current_node = current_node.getParent()

        root = scene.getRoot()
        arranger = Arrange.create(scene_root=root)
        offset_shape_arr, hull_shape_arr = ShapeArray.fromNode(current_node, min_offset=self._min_offset)
        nodes = []
        found_solution_for_all = True
        for i in range(self._count):
            # We do place the nodes one by one, as we want to yield in between.
            node, solution_found = arranger.findNodePlacement(current_node, offset_shape_arr, hull_shape_arr)
            if not solution_found:
                found_solution_for_all = False
                new_location = node.getPosition()
                new_location = new_location.set(z = 100 - i * 20)
                node.setPosition(new_location)

            nodes.append(node)
            Job.yieldThread()
            status_message.setProgress((i + 1) / self._count * 100)

        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"))
            no_full_solution_message.show()
Пример #12
0
    def run(self):
        status_message = Message(i18n_catalog.i18nc(
            "@info:status", "Multiplying and placing objects"),
                                 lifetime=0,
                                 dismissable=False,
                                 progress=0)
        status_message.show()
        scene = Application.getInstance().getController().getScene()

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

        root = scene.getRoot()
        arranger = Arrange.create(scene_root=root)
        nodes = []
        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"):
                current_node = current_node.getParent()

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

            found_solution_for_all = True
            for i in range(self._count):
                # We do place the nodes one by one, as we want to yield in between.
                if not node_too_big:
                    node, solution_found = arranger.findNodePlacement(
                        current_node, offset_shape_arr, hull_shape_arr)
                if node_too_big or not solution_found:
                    found_solution_for_all = False
                    new_location = node.getPosition()
                    new_location = new_location.set(z=100 - i * 20)
                    node.setPosition(new_location)

                nodes.append(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:
                print_mode_enabled = Application.getInstance(
                ).getGlobalContainerStack().getProperty(
                    "print_mode", "enabled")
                if print_mode_enabled:
                    node_dup = DuplicatedNode(new_node)
                    op.addOperation(
                        AddNodesOperation(node_dup, current_node.getParent()))
                else:
                    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"
                ))
            no_full_solution_message.show()
Пример #13
0
def gimmeShapeArray():
    vertices = numpy.array([[-3, 1], [3, 1], [0, -3]])
    shape_arr = ShapeArray.fromPolygon(vertices)
    return shape_arr
Пример #14
0
def test_arrayFromPolygon2():
    vertices = numpy.array([[-3, 1], [3, 1], [2, -3]])
    array = ShapeArray.arrayFromPolygon([5, 5], vertices)
    assert numpy.any(array)
Пример #15
0
def gimmeShapeArray():
    vertices = numpy.array([[-3, 1], [3, 1], [0, -3]])
    shape_arr = ShapeArray.fromPolygon(vertices)
    return shape_arr
Пример #16
0
def test_arrayFromPolygon2():
    vertices = numpy.array([[-3, 1], [3, 1], [2, -3]])
    array = ShapeArray.arrayFromPolygon([5, 5], vertices)
    assert numpy.any(array)