コード例 #1
0
    def test_draw_border(self):
        """ Tests that the border is drawn if requested
        """

        generator = WorkingAreaGenerator(self.to_uu, "wId")
        generator.set_size(400, 300)

        root = etree.Element("root")
        generator.upsert(root)
        border_index = len(root[0]) # border is added at the end of the list of children

        border = Border([[(40, 20), (160, 200)]], 0)
        painter = BorderPainter(border)

        painter.paint(generator)

        self.assertEqual(root[0][border_index].tag, "rect")
        self.assertEqual(root[0][border_index].get("x"), "10.0")
        self.assertEqual(root[0][border_index].get("y"), "5.0")
        self.assertEqual(root[0][border_index].get("width"), "30.0")
        self.assertEqual(root[0][border_index].get("height"), "45.0")
        self.assertEqual(root[0][border_index].get("style"), ("stroke-width:0.0625;"
                                                              "stroke-miterlimit:4;"
                                                              "stroke-dasharray:0.25,0.25;"
                                                              "stroke-dashoffset:0;"
                                                              "fill:none"))
コード例 #2
0
    def test_skip_initial_path(self):
        """ Tests that an empty paths as the first path is skipped
        """

        border = Border([[], [(30, 15), (20, 20), (25, 40)], [(90, 30), (30, 90)]], 10)

        self.assertEqual(border.width(), 90)
        self.assertEqual(border.height(), 95)
        self.assertEqual(border.left(), 10)
        self.assertEqual(border.right(), 100)
        self.assertEqual(border.top(), 100)
        self.assertEqual(border.bottom(), 5)
コード例 #3
0
    def test_skip_empty_paths(self):
        """ Tests that empty paths are skipped
        """

        border = Border([[(30, 15), (20, 20), (25, 40)], [], [(90, 30), (30, 90)], []], 10)

        self.assertEqual(border.width(), 90)
        self.assertEqual(border.height(), 95)
        self.assertEqual(border.left(), 10)
        self.assertEqual(border.right(), 100)
        self.assertEqual(border.top(), 100)
        self.assertEqual(border.bottom(), 5)
コード例 #4
0
    def test_build_border_with_multiple_paths(self): # pylint: disable=invalid-name
        """ Tests that Border instance is correctly build when multiple paths are present
        """

        border = Border([[(30, 15), (20, 20), (25, 40)], [(90, 30), (30, 90)]], 10)

        self.assertEqual(border.width(), 90)
        self.assertEqual(border.height(), 95)
        self.assertEqual(border.left(), 10)
        self.assertEqual(border.right(), 100)
        self.assertEqual(border.top(), 100)
        self.assertEqual(border.bottom(), 5)
コード例 #5
0
    def test_build_border_with_one_path(self):
        """ Tests that Border instance is correctly build when one path is present
        """

        border = Border([[(30, 15), (20, 20), (25, 40)]], 10)

        self.assertEqual(border.width(), 30)
        self.assertEqual(border.height(), 45)
        self.assertEqual(border.left(), 10)
        self.assertEqual(border.right(), 40)
        self.assertEqual(border.top(), 50)
        self.assertEqual(border.bottom(), 5)
コード例 #6
0
    def test_build_border_with_empty_path(self): # pylint: disable=invalid-name
        """ Tests that Border instance is correctly built when no path is present
        """

        border = Border([[]], 10)

        self.assertEqual(border.width(), 0)
        self.assertEqual(border.height(), 0)
        self.assertEqual(border.left(), 0)
        self.assertEqual(border.right(), 0)
        self.assertEqual(border.top(), 0)
        self.assertEqual(border.bottom(), 0)
コード例 #7
0
    def test_build_border_with_one_path_one_point(self): # pylint: disable=invalid-name
        """ Tests that Border instance is correctly built when one path with one point is present
        """

        border = Border([[(10, 20)]], 10)

        self.assertEqual(border.width(), 20)
        self.assertEqual(border.height(), 20)
        self.assertEqual(border.left(), 0)
        self.assertEqual(border.right(), 20)
        self.assertEqual(border.top(), 30)
        self.assertEqual(border.bottom(), 10)
コード例 #8
0
    def test_build_border_with_no_path(self):
        """ Tests that Border instance is correctly built when no path is present
        """

        border = Border([], 10)

        self.assertEqual(border.width(), 0)
        self.assertEqual(border.height(), 0)
        self.assertEqual(border.left(), 0)
        self.assertEqual(border.right(), 0)
        self.assertEqual(border.top(), 0)
        self.assertEqual(border.bottom(), 0)
コード例 #9
0
    def test_border_vertices(self):
        """ Tests that Border reports its vertices correctly
        """

        border = Border([[(30, 15), (20, 20), (25, 40)]], 10)

        self.assertEqual(border.bottom_left(), (10, 5))
        self.assertEqual(border.bottom_right(), (40, 5))
        self.assertEqual(border.top_left(), (10, 50))
        self.assertEqual(border.top_right(), (40, 50))
コード例 #10
0
    def test_border_with_margin(self):
        """ Tests that commands to square the piece with a margin are added if requested

        Path starts with the point nearest to the bottom left border point
        """

        border = Border([[(2, 2), (8, 18)]], 0)
        path = [(5, 7), (3, 4), (5, 9), (1, 1), (2.1, 2.1), (8, 2), (5, 7)]

        generator = CuttingToolPathsGenerator(path, 1, border)
        generator.generate()

        # Same initial and final point (the one closest to (0, 0) and (5, 7) not repeated
        expected_path = [(0, 0), (2, 2), (2.1, 2.1), (8, 2), (5, 7), (3, 4), (5, 9), (1, 1),
                         (2.1, 2.1), (2, 2), (8, 2), (8, 18), (2, 18), (2, 2), (0, 0)]

        self.assertEqual(generator.path(), expected_path)
コード例 #11
0
    def test_border_with_no_margin(self):
        """ Tests that commands to square the piece are added if requested

        Margin is 0, path starts from the point nearest to (0, 0)
        """

        border = Border([[(0, 0), (10, 20)]], 0)
        path = [(5, 7), (3, 4), (5, 9), (1, 1), (8, 2), (5, 7)]

        generator = CuttingToolPathsGenerator(path, 1, border)
        generator.generate()

        # Same initial and final point (the one closest to (0, 0) and (5, 7) not repeated
        expected_path = [(0, 0), (1, 1), (8, 2), (5, 7), (3, 4), (5, 9), (1, 1), (0, 0), (10, 0),
                         (10, 20), (0, 20), (0, 0)]

        self.assertEqual(generator.path(), expected_path)
コード例 #12
0
    def test_do_not_draw_border_if_equal_working_area(self): # pylint: disable=invalid-name
        """ Tests that no border is drawn if border is coincident with the working area
        """

        generator = WorkingAreaGenerator(self.to_uu, "wId")
        generator.set_size(400, 300)

        root = etree.Element("root")
        generator.upsert(root)
        num_initial_root_children = len(root[0])

        border = Border([[(0, 0), (400, 300)]], 0)
        painter = BorderPainter(border)

        painter.paint(generator)

        self.assertEqual(len(root[0]), num_initial_root_children)
コード例 #13
0
    def effect(self):
        """ Main function
        """

        # First of all generating the machine instance and checking piece dimensions fit
        machine = machine_factory(self.options.machine_type)
        if machine:
            valid_dimensions = machine.piece_dimensions_allowed(
                self.options.dim_x, self.options.dim_y)
            if not valid_dimensions:
                raise InvalidWorkpieceDimensions(machine.working_area_width(),
                                                 machine.working_area_height())

        # A function to convert to millimiters
        to_mm = lambda value: self.uutounit(value, 'mm')
        # A function to convert to user units. This must be used to write units in the svg
        to_uu = lambda value: self.unittouu(str(value) + "mm")

        # Draw the working area
        working_area_generator = WorkingAreaGenerator(to_uu, WORKING_AREA_ID)
        working_area_generator.set_size(self.options.dim_x, self.options.dim_y)
        working_area_generator.upsert(self.document.getroot())

        if not self.options.ids:
            # print info and exit
            inkex.debug(
                _(("No path was seletect, only the working area was generated. Now draw a "
                   "path inside the working area and select it to generate the g-code"
                   )))
        else:
            # Extracting paths in machine coordinates
            paths_extractor = PathsExtractor(
                self.selected.values(), to_mm, WORKING_AREA_ID,
                FlattenBezier(self.options.flatness),
                self.options.auto_close_path)
            paths_extractor.extract()

            # The border to use. This is None if no border is requested. If border is present, also
            # draws it
            border = None
            if self.options.square:
                border = Border(paths_extractor.paths(), self.options.margin)
                painter = BorderPainter(border)
                painter.paint(working_area_generator)

            # Joining paths. This will also check that all paths are closed
            paths_joiner = PathsJoiner(paths_extractor.paths(), CLOSE_DISTANCE)
            paths_joiner.unite()

            # Generate tool positions
            tool_path_generator = CuttingToolPathsGenerator(
                paths_joiner.union_path(), CLOSE_DISTANCE, border)
            tool_path_generator.generate()

            # The object drawing the tool path
            painter = ToolPathPainter(tool_path_generator.path())

            # Draw tool path on original svg if requested
            if self.options.draw_toolpath:
                painter.paint(working_area_generator.get_element(),
                              working_area_generator.get_factor(), "255,0,0")

            # Generating g-code
            gcode_generator = CuttingGCodeGenerator(tool_path_generator.path(),
                                                    self.options.speed)
            gcode_generator.generate()

            # Computing information about path
            generic_filename = base_filename(self.options.shapename,
                                             self.gcode_file_path)
            info = PathInfo(tool_path_generator.path(), self.options,
                            generic_filename)

            # Writing gcode to file
            write_file(
                os.path.join(self.gcode_file_path, info.gcode_filename()),
                lambda f: f.write(gcode_generator.gcode()))

            # Writing svg to file
            doc = generate_path_svg(painter)
            write_file(os.path.join(self.gcode_file_path, info.svg_filename()),
                       lambda f: doc.write(f))

            # Writing metainfo to file
            write_file(
                os.path.join(self.gcode_file_path, info.metainfo_filename()),
                lambda f: f.write(json.dumps(info.metainfo(), indent=2)))

            message = (_("The generate g-code has been saved to ") +
                       info.gcode_filename() +
                       _(". Estimated working time: ") +
                       str(info.working_time_min()) + _(" minutes"))
            if not info.is_path_inside_workpiece():
                message += _(
                    ". WARNING: some points are outside the workpiece")

            inkex.debug(message)