Ejemplo n.º 1
0
def make_hatches_from_str(s: str,
                          font: fonts.FontFace,
                          size: float = 1.0,
                          align: str = 'LEFT',
                          length: float = 0,
                          segments: int = 4,
                          dxfattribs: Dict = None,
                          m: Matrix44 = None) -> List[Hatch]:
    """ Convert a single line string `s` into a list of virtual
    :class:`~ezdxf.entities.Hatch` entities.
    The text `size` is the height of the uppercase letter "X" (cap height).
    The paths are aligned about the insertion point at (0, 0).
    The HATCH entities are aligned to this insertion point. BASELINE means the
    bottom of the letter "X".

    Args:
         s: text to convert
         font: font face definition
         size: text size (cap height) in drawing units
         align: alignment as string, default is "LEFT"
         length: target length for the "ALIGNED" and "FIT" alignments
         segments: minimal segment count per Bézier curve
         dxfattribs: additional DXF attributes
         m: transformation :class:`~ezdxf.math.Matrix44`

    """
    font_properties, font_measurements = _get_font_data(font)
    # scale cap_height for 1 drawing unit!
    scaled_size = size / font_measurements.cap_height
    scaled_fm = font_measurements.scale_from_baseline(scaled_size)
    paths = _str_to_paths(s, font_properties, scaled_size)

    # HATCH is an OCS entity, transforming just the polyline paths
    # is not correct! The Hatch has to be created in the xy-plane!
    hatches = []
    dxfattribs = dxfattribs or dict()
    dxfattribs.setdefault('solid_fill', 1)
    dxfattribs.setdefault('pattern_name', 'SOLID')
    dxfattribs.setdefault('color', 7)

    for contour, holes in group_contour_and_holes(paths):
        hatch = Hatch.new(dxfattribs=dxfattribs)
        # Vec2 removes the z-axis, which would be interpreted as bulge value!
        hatch.paths.add_polyline_path(
            Vec2.generate(contour.flattening(1, segments=segments)), flags=1)
        for hole in holes:
            hatch.paths.add_polyline_path(
                Vec2.generate(hole.flattening(1, segments=segments)), flags=0)
        hatches.append(hatch)

    halign, valign = const.TEXT_ALIGN_FLAGS[align.upper()]
    bbox = path.bbox(paths, precise=False)
    matrix = get_alignment_transformation(scaled_fm, bbox, halign, valign)
    if m is not None:
        matrix *= m

    # Transform HATCH entities as a unit:
    return [hatch.transform(matrix) for hatch in hatches]
def test_polyline_path_transform_interface(m44):
    hatch = Hatch.new()
    vertices = list(box(1.0, 2.0))
    path = hatch.paths.add_polyline_path(vertices)

    hatch.transform(m44)
    chk = m44.transform_vertices(vertices)
    for v, c in zip(path.vertices, chk):
        assert c.isclose(v)
def closed_edge_hatch(request):
    _hatch = Hatch.new()
    _path = _hatch.paths.add_edge_path()
    if request.param == "arc":
        _path.add_arc((0, 0), radius=1, start_angle=0, end_angle=360, ccw=1)
    elif request.param == "ellipse":
        _path.add_ellipse(
            (0, 0), major_axis=(5, 0), ratio=0.2, start_angle=0, end_angle=360
        )
    return _hatch
Ejemplo n.º 4
0
def test_upright_hatch_with_polyline_path():
    hatch = Hatch.new(dxfattribs={
        "elevation": (0, 0, 4),
        "extrusion": (0, 0, -1),
    })
    hatch.paths.add_polyline_path([(x, y, b)
                                   for x, y, s, e, b in POLYLINE_POINTS])
    p0 = path.make_path(hatch)
    assert p0.has_curves is True

    upright(hatch)
    assert hatch.dxf.extrusion.isclose(Z_AXIS)
    p1 = path.make_path(hatch)
    assert path.have_close_control_vertices(p0, p1)
def test_edge_path_transform_interface(m44):
    hatch = Hatch.new()
    path = hatch.paths.add_edge_path()
    path.add_line((0, 0), (10, 0))
    path.add_arc((10, 5), radius=5, start_angle=270, end_angle=450, ccw=1)
    path.add_ellipse(
        (5, 10), major_axis=(5, 0), ratio=0.2, start_angle=0, end_angle=180
    )
    spline = path.add_spline(
        [(1, 1), (2, 2), (3, 3), (4, 4)], degree=3, periodic=1
    )
    # the following values do not represent a mathematically valid spline
    spline.control_points = [(1, 1), (2, 2), (3, 3), (4, 4)]
    spline.knot_values = [1, 2, 3, 4, 5, 6]
    spline.weights = [4, 3, 2, 1]
    spline.start_tangent = (10, 1)
    spline.end_tangent = (2, 20)

    chk = list(
        m44.transform_vertices(
            [
                Vec3(0, 0),
                Vec3(10, 0),
                Vec3(10, 5),
                Vec3(5, 10),
                Vec3(1, 1),
                Vec3(2, 2),
                Vec3(3, 3),
                Vec3(4, 4),
            ]
        )
    )

    hatch.transform(m44)
    line = path.edges[0]
    assert chk[0].isclose(line.start)
    assert chk[1].isclose(line.end)
    arc = path.edges[1]
    assert chk[2].isclose(arc.center)
    ellipse = path.edges[2]
    assert chk[3].isclose(ellipse.center)
    spline = path.edges[3]
    for c, v in zip(chk[4:], spline.control_points):
        assert c.isclose(v)
    for c, v in zip(chk[4:], spline.fit_points):
        assert c.isclose(v)
    assert m44.transform_direction((10, 1, 0)).isclose(spline.start_tangent)
    assert m44.transform_direction((2, 20, 0)).isclose(spline.end_tangent)
Ejemplo n.º 6
0
def _hatch_converter(paths: Iterable[Path],
                     add_boundary: Callable[[Hatch, Path, int], None],
                     extrusion: 'Vertex' = Z_AXIS,
                     dxfattribs: Optional[Dict] = None) -> Iterable[Hatch]:
    if isinstance(paths, Path):
        paths = [paths]
    else:
        paths = list(paths)
    if len(paths) == 0:
        return []

    extrusion = Vec3(extrusion)
    reference_point = paths[0].start
    dxfattribs = dxfattribs or dict()
    if not extrusion.isclose(Z_AXIS):
        ocs, elevation = _get_ocs(extrusion, reference_point)
        paths = tools.transform_paths_to_ocs(paths, ocs)
        dxfattribs['elevation'] = Vec3(0, 0, elevation)
        dxfattribs['extrusion'] = extrusion
    elif reference_point.z != 0:
        dxfattribs['elevation'] = Vec3(0, 0, reference_point.z)
    dxfattribs.setdefault('solid_fill', 1)
    dxfattribs.setdefault('pattern_name', 'SOLID')
    dxfattribs.setdefault('color', const.BYLAYER)

    for group in group_paths(paths):
        if len(group) == 0:
            continue
        hatch = Hatch.new(dxfattribs=dxfattribs)
        external = group[0]
        external.close()
        add_boundary(hatch, external, 1)
        for hole in group[1:]:
            hole.close()
            add_boundary(hatch, hole, 0)
        yield hatch
Ejemplo n.º 7
0
def all_edge_types_hatch(elevation, extrusion):
    hatch = Hatch.new(dxfattribs={
        "layer": "original",
        "color": 2,
        "elevation": (0.0, 0.0, elevation),
        "extrusion": extrusion,
        "pattern_name": "SOLID",
        "solid_fill": 1,
        "associative": 0,
        "hatch_style": 0,
        "pattern_type": 1,
    }, )
    # edge-path contains all supported edge types:
    ep = hatch.paths.add_edge_path(flags=1)
    ep.add_arc(  # clockwise oriented ARC
        center=(0.0, 13.0),
        radius=3.0,
        start_angle=-90.0,
        end_angle=90.0,
        ccw=False,
    )
    ep.add_ellipse(  # clockwise oriented ELLIPSE
        center=(0.0, 5.0),
        major_axis=(0.0, 5.0),
        ratio=0.6,
        start_angle=180.0,
        end_angle=360.0,
        ccw=False,
    )
    ep.add_line((0.0, 0.0), (10.0, 0.0))  # LINE
    ep.add_ellipse(  # counter-clockwise oriented ELLIPSE
        center=(10.0, 5.0),
        major_axis=(0.0, -5.0),
        ratio=0.6,
        start_angle=0.0,
        end_angle=180.0,
        ccw=True,
    )
    ep.add_arc(  # counter-clockwise oriented ARC
        center=(10.0, 13.0),
        radius=3.0,
        start_angle=270.0,
        end_angle=450.0,
        ccw=True,
    )
    ep.add_spline(  # SPLINE
        control_points=[
            Vec2(10.0, 16.0),
            Vec2(9.028174684192452, 16.0),
            Vec2(6.824943218065775, 12.14285714285714),
            Vec2(3.175056781934232, 19.85714285714287),
            Vec2(0.9718253158075516, 16.0),
            Vec2(0, 16.0),
        ],
        knot_values=[
            0.0,
            0.0,
            0.0,
            0.0,
            2.91547594742265,
            8.746427842267952,
            11.6619037896906,
            11.6619037896906,
            11.6619037896906,
            11.6619037896906,
        ],
        degree=3,
        periodic=0,
    )
    return hatch
Ejemplo n.º 8
0
 def hatch(self):
     return Hatch.new(dxfattribs={
         "elevation": (0, 0, 4),
         "extrusion": (0, 0, -1),
     })
Ejemplo n.º 9
0
def hatch():
    return Hatch.new()
def test_full_circle_edge_scaling():
    _hatch = Hatch.new()
    _path = _hatch.paths.add_edge_path()
    _arc = _path.add_arc((0, 0), radius=1, start_angle=0, end_angle=360, ccw=1)
    _hatch.transform(Matrix44.scale(0.5, 0.5, 0.5))
    assert _arc.radius == pytest.approx(0.5)