def test_upsert_adds_working_area_group(self):  # pylint: disable=invalid-name
        """ Tests that the upsert function inserts the working area with the correct id
        """
        generator = WorkingAreaGenerator(self.to_uu, "wId")
        root = etree.Element("root")

        generator.upsert(root)

        self.assertEqual(root[0].tag, "svg")
        self.assertEqual(root[0].get("id"), "wId")
    def test_add_working_area_style(self):
        """ Test that the added working area has the correct style
        """

        generator = WorkingAreaGenerator(self.to_uu, "wId")
        root = etree.Element("root")

        generator.upsert(root)

        self.assertEqual(root[0].get("style"),
                         "fill:none;stroke-width:0.25;stroke:rgb(0,0,0)")
    def test_upsert_does_not_create_duplicated_working_area(self):  # pylint: disable=invalid-name
        """ Tests that upsert does not insert a new working area if it is already present
        """
        generator = WorkingAreaGenerator(self.to_uu, "wId")
        root = etree.Element("root")
        etree.SubElement(root, "svg", {"id": "wId"})

        generator.upsert(root)

        self.assertEqual(len(root), 1)
        self.assertEqual(root[0].tag, "svg")
        self.assertEqual(root[0].get("id"), "wId")
    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"))
    def test_add_working_area_view_box_rectangular_area(self):  # pylint: disable=invalid-name
        """ Tests that the added working area has the correct viewBox in case of rectangular areas
        """

        generator = WorkingAreaGenerator(self.to_uu, "wId")
        generator.set_size(500, 400)
        root = etree.Element("root")

        generator.upsert(root)

        self.assertEqual(root[0].get("viewBox"), "0 0 100 80.0")
    def test_add_working_area_view_box_and_scaling_policy(self):  # pylint: disable=invalid-name
        """ Tests that the added working area has the correct viewBox and scaling policy
        """

        generator = WorkingAreaGenerator(self.to_uu, "wId")
        generator.set_size(500, 500)
        root = etree.Element("root")

        generator.upsert(root)

        self.assertEqual(root[0].get("viewBox"), "0 0 100 100.0")
        self.assertEqual(root[0].get("preserveAspectRatio"), "none")
    def test_add_working_area_position(self):
        """ Tests that the added working area has the correct position
        """

        generator = WorkingAreaGenerator(self.to_uu, "wId")
        generator.set_size(1323, 876)
        root = etree.Element("root")

        generator.upsert(root)

        self.assertEqual(root[0].get("x"), "0.0")
        self.assertEqual(root[0].get("y"), "0.0")
    def test_add_working_area_size(self):
        """ Tests that the added working area has the correct size
        """

        generator = WorkingAreaGenerator(self.to_uu, "wId")
        generator.set_size(1323, 876)
        root = etree.Element("root")

        generator.upsert(root)

        self.assertEqual(root[0].get("width"), "2646.0")
        self.assertEqual(root[0].get("height"), "1752.0")
    def test_use_translate_transform(self):
        """ Tests that the transformation of the element is taken into account when a translation
        """

        generator = WorkingAreaGenerator(self.to_uu, "wId")
        generator.set_size(400, 200)
        root = etree.Element("root", {'transform': "translate(10,-30)"})

        generator.upsert(root)

        self.assertEqual(root[0].get("x"), "-20.0")
        self.assertEqual(root[0].get("y"), "60.0")
    def test_add_cross(self):
        """ Tests that a cross is added
        """

        generator = WorkingAreaGenerator(self.to_uu, "wId")
        generator.set_size(400, 200)
        root = etree.Element("root")

        generator.upsert(root)

        self.assertEqual(root[0][1].tag, "path")
        self.assertEqual(root[0][1].get("d"),
                         "M -2.5,0 L 2.5,0 M 0,-2.5 L 0,2.5")
    def test_add_the_rectangle(self):
        """ Tests that a rectangle is added
        """

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

        generator.upsert(root)

        self.assertEqual(root[0][0].tag, "rect")
        self.assertEqual(root[0][0].get("x"), "0")
        self.assertEqual(root[0][0].get("y"), "0")
        self.assertEqual(root[0][0].get("width"), "100")
        self.assertEqual(root[0][0].get("height"), "75.0")
    def test_add_origin_coordinates_text(self):  # pylint: disable=invalid-name
        """ Tests that coordinates at the orgin are added
        """

        generator = WorkingAreaGenerator(self.to_uu, "wId")
        generator.set_size(400, 200)
        root = etree.Element("root")

        generator.upsert(root)

        self.assertEqual(root[0][2].tag, "text")
        self.assertEqual(root[0][2].get("x"), "-7.0")
        self.assertEqual(root[0][2].get("y"), "-2.5")
        self.assertEqual(root[0][2].get("font-family"), "Verdana")
        self.assertEqual(root[0][2].get("font-size"), "2.5")
        self.assertEqual(root[0][2].text, "(0, 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)
Beispiel #14
0
    def effect(self):
        """ Main function
        """

        # 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
            # Using error message even if this it not really an error...
            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(FLATNESS))
            paths_extractor.extract()

            # Generate tool positions and orientations
            tool_path_generator = EngravingToolPathsGenerator(paths_extractor.paths(),
                                                              self.options.depth_z, MIN_DISTANCE,
                                                              DISCRETIZATION_STEP)
            tool_path_generator.generate()

            # Generating g-code
            gcode_generator = EngravingGCodeGenerator(tool_path_generator.paths(), MM_PER_DEGREE,
                                                      SAFE_Z, SMALL_DISTANCE, SMALL_ANGLE)
            gcode_generator.generate()

            # Writing to file
            filename = base_filename(self.options.filename, self.gcode_file_path) + ".gcode"
            write_file(filename, lambda f: f.write(gcode_generator.gcode()))

            inkex.debug(_("The generate g-code has been save to ") + filename)
    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)