예제 #1
0
def test_apply_transformation_multiple_times(sx, sy, sz, doc1: 'Drawing'):
    def insert():
        return Insert.new(dxfattribs={
            'name': 'AXIS',
            'insert': (0, 0, 0),
            'xscale': 1,
            'yscale': 1,
            'zscale': 1,
            'rotation': 0,
        },
                          doc=doc1), [(0, 0, 0), X_AXIS, Y_AXIS, Z_AXIS]

    entity, vertices = insert()
    m = Matrix44.chain(
        Matrix44.scale(sx, sy, sz),
        Matrix44.z_rotate(math.radians(10)),
        Matrix44.translate(1, 1, 1),
    )

    for i in range(5):
        entity, vertices = synced_transformation(entity, vertices, m)
        points = list(vertices)
        for num, line in enumerate(entity.virtual_entities()):
            assert points[0].isclose(line.dxf.start, abs_tol=1e-9)
            assert points[num + 1].isclose(line.dxf.end, abs_tol=1e-9)
예제 #2
0
    def matrix44(self) -> Matrix44:
        """ Returns a transformation :class:`Matrix44` object to transform block
        entities into WCS.

        .. versionadded:: 0.13

        """
        dxf = self.dxf
        sx = dxf.xscale
        sy = dxf.yscale
        sz = dxf.zscale

        ocs = self.ocs()
        extrusion = ocs.uz
        ux = Vector(ocs.to_wcs(X_AXIS))
        uy = Vector(ocs.to_wcs(Y_AXIS))
        m = Matrix44.ucs(ux=ux * sx, uy=uy * sy, uz=extrusion * sz)

        angle = math.radians(dxf.rotation)
        if angle != 0.0:
            m = Matrix44.chain(m, Matrix44.axis_rotate(extrusion, angle))

        insert = ocs.to_wcs(dxf.get('insert', Vector()))

        block_layout = self.block()
        if block_layout is not None:
            # transform block base point into WCS without translation
            insert -= m.transform_direction(block_layout.block.dxf.base_point)

        # set translation
        m.set_row(3, insert.xyz)
        return m
예제 #3
0
def test_apply_transformation_multiple_times(sx, sy, sz, doc1: "Drawing"):
    def insert():
        return (
            Insert.new(
                dxfattribs={
                    "name": "AXIS",
                    "insert": (0, 0, 0),
                    "xscale": 1,
                    "yscale": 1,
                    "zscale": 1,
                    "rotation": 0,
                },
                doc=doc1,
            ),
            [(0, 0, 0), X_AXIS, Y_AXIS, Z_AXIS],
        )

    entity, vertices = insert()
    m = Matrix44.chain(
        Matrix44.scale(sx, sy, sz),
        Matrix44.z_rotate(math.radians(10)),
        Matrix44.translate(1, 1, 1),
    )

    for i in range(5):
        entity, vertices = synced_transformation(entity, vertices, m)
        points = list(vertices)
        for num, line in enumerate(entity.virtual_entities()):
            assert points[0].isclose(line.dxf.start, abs_tol=1e-6)
            assert points[num + 1].isclose(line.dxf.end, abs_tol=1e-6)
예제 #4
0
 def build():
     circle = Circle()
     vertices = list(circle.vertices(linspace(0, 360, vertex_count, endpoint=False)))
     m = Matrix44.chain(
         Matrix44.axis_rotate(axis=Vec3.random(), angle=random.uniform(0, math.tau)),
         Matrix44.translate(dx=random.uniform(-2, 2), dy=random.uniform(-2, 2), dz=random.uniform(-2, 2)),
     )
     return synced_transformation(circle, vertices, m)
예제 #5
0
def build(angle, dx, dy, dz, axis, start, end, count):
    ellipse = Ellipse.new(dxfattribs={
        'start_param': start,
        'end_param': end,
    })
    vertices = list(ellipse.vertices(ellipse.params(count)))
    m = Matrix44.chain(Matrix44.axis_rotate(axis=axis, angle=angle),
                       Matrix44.translate(dx=dx, dy=dy, dz=dz))
    return synced_transformation(ellipse, vertices, m)
예제 #6
0
def test_circle_default_ocs():
    circle = Circle.new(dxfattribs={'center': (2, 3, 4), 'thickness': 2})
    # 1. rotation - 2. scaling - 3. translation
    m = Matrix44.chain(Matrix44.scale(2, 2, 3), Matrix44.translate(1, 1, 1))
    # default extrusion is (0, 0, 1), therefore scale(2, 2, ..) is a uniform scaling in the xy-play of the OCS
    circle.transform(m)

    assert circle.dxf.center == (5, 7, 13)
    assert circle.dxf.extrusion == (0, 0, 1)
    assert circle.dxf.thickness == 6
예제 #7
0
 def build():
     arc = Arc.new(dxfattribs={
         'start_angle': random.uniform(0, 360),
         'end_angle': random.uniform(0, 360),
     })
     vertices = list(arc.vertices(arc.angles(vertex_count)))
     m = Matrix44.chain(
         Matrix44.axis_rotate(axis=Vec3.random(), angle=random.uniform(0, math.tau)),
         Matrix44.translate(dx=random.uniform(-2, 2), dy=random.uniform(-2, 2), dz=random.uniform(-2, 2)),
     )
     return synced_transformation(arc, vertices, m)
예제 #8
0
 def build():
     ellipse = Ellipse.new(dxfattribs={
         'start_param': start,
         'end_param': end,
     })
     vertices = list(ellipse.vertices(ellipse.params(vertex_count)))
     m = Matrix44.chain(
         Matrix44.axis_rotate(axis=Vec3.random(), angle=random.uniform(0, math.tau)),
         Matrix44.translate(dx=random.uniform(-2, 2), dy=random.uniform(-2, 2), dz=random.uniform(-2, 2)),
     )
     return synced_transformation(ellipse, vertices, m)
예제 #9
0
def main_multi_ellipse(layout):
    m = Matrix44.chain(
        Matrix44.scale(1.1, 1.3, 1),
        Matrix44.z_rotate(math.radians(10)),
        Matrix44.translate(1, 1, 0),
    )
    entity, vertices, axis_vertices = ellipse(start=math.pi / 2,
                                              end=-math.pi / 2)

    for index in range(5):
        entity, vertices = synced_transformation(entity, vertices, m)
        add(layout, entity, vertices)
예제 #10
0
def test_xline_transform():
    # same implementation for Ray()
    xline = XLine.new(dxfattribs={
        "start": (2, 3, 4),
        "unit_vector": (1, 0, 0)
    })
    # 1. scaling - 2. rotation - 3. translation
    m = Matrix44.chain(Matrix44.scale(2, 2, 3), Matrix44.translate(1, 1, 1))
    xline.transform(m)

    assert xline.dxf.start == (5, 7, 13)
    assert xline.dxf.unit_vector == (1, 0, 0)
예제 #11
0
def test_scale_and_reflexion(rx, ry, text2):
    insert = Vec3(0, 0, 0)
    m = Matrix44.chain(
        Matrix44.scale(2 * rx, 3 * ry, 1),
        Matrix44.z_rotate(math.radians(45)),
        Matrix44.translate(3 * rx, 3 * ry, 0),
    )

    text2.transform(m)
    check_point = m.transform(insert)
    ocs = text2.ocs()
    assert ocs.to_wcs(text2.dxf.insert).isclose(check_point)
    assert math.isclose(text2.dxf.height, 3.0)
    assert math.isclose(text2.dxf.width, 2.0 / 3.0)
예제 #12
0
def test_random_block_reference_transformation(sx, sy, sz, doc1: "Drawing"):
    def insert():
        return (
            Insert.new(
                dxfattribs={
                    "name": "AXIS",
                    "insert": (0, 0, 0),
                    "xscale": 1,
                    "yscale": 1,
                    "zscale": 1,
                    "rotation": 0,
                    "layer": "insert",
                },
                doc=doc1,
            ),
            [Vec3(0, 0, 0), X_AXIS, Y_AXIS, Z_AXIS],
        )

    def check(lines, chk):
        origin, x, y, z = chk
        l1, l2, l3 = lines
        assert origin.isclose(l1.dxf.start)
        assert x.isclose(l1.dxf.end)
        assert origin.isclose(l2.dxf.start)
        assert y.isclose(l2.dxf.end)
        assert origin.isclose(l3.dxf.start)
        assert z.isclose(l3.dxf.end)

    entity0, vertices0 = insert()
    entity0, vertices0 = synced_scaling(entity0, vertices0, 1, 2, 3)

    m = Matrix44.chain(
        # Transformation order is important: scale - rotate - translate
        # Because scaling after rotation leads to a non orthogonal
        # coordinate system, which can not represented by the
        # INSERT entity.
        Matrix44.scale(sx, sy, sz),
        Matrix44.axis_rotate(axis=Vec3.random(),
                             angle=random.uniform(0, math.tau)),
        Matrix44.translate(
            dx=random.uniform(-2, 2),
            dy=random.uniform(-2, 2),
            dz=random.uniform(-2, 2),
        ),
    )
    entity, vertices = synced_transformation(entity0, vertices0, m)
    lines = list(entity.virtual_entities())
    check(lines, vertices)
예제 #13
0
def test_arc_default_ocs():
    arc = Arc.new(dxfattribs={'center': (2, 3, 4), 'thickness': 2, 'start_angle': 30, 'end_angle': 60})
    # 1. rotation - 2. scaling - 3. translation
    m = Matrix44.chain(Matrix44.scale(2, 2, 3), Matrix44.translate(1, 1, 1))
    # default extrusion is (0, 0, 1), therefore scale(2, 2, ..) is a uniform scaling in the xy-play of the OCS
    arc.transform(m)

    assert arc.dxf.center == (5, 7, 13)
    assert arc.dxf.extrusion == (0, 0, 1)
    assert arc.dxf.thickness == 6
    assert math.isclose(arc.dxf.start_angle, 30, abs_tol=1e-9)
    assert math.isclose(arc.dxf.end_angle, 60, abs_tol=1e-9)

    arc.transform(Matrix44.z_rotate(math.radians(30)))
    assert math.isclose(arc.dxf.start_angle, 60, abs_tol=1e-9)
    assert math.isclose(arc.dxf.end_angle, 90, abs_tol=1e-9)
예제 #14
0
def main_ellipse_hatch(layout, spline=False):
    def draw_ellipse_axis(ellipse):
        center = ellipse.center
        major_axis = ellipse.major_axis
        msp.add_line(center, center + major_axis)

    entitydb = layout.doc.entitydb
    hatch = cast(Hatch, layout.add_hatch(color=1))
    path = hatch.paths.add_edge_path()
    path.add_line((0, 0), (5, 0))
    path.add_ellipse((2.5, 0), (2.5, 0),
                     ratio=.5,
                     start_angle=0,
                     end_angle=180,
                     ccw=1)
    if spline:
        hatch.paths.all_to_line_edges(spline_factor=4)

    chk_ellipse, chk_vertices, _ = ellipse((2.5, 0),
                                           ratio=0.5,
                                           start=0,
                                           end=math.pi)
    chk_ellipse, chk_vertices = synced_translation(chk_ellipse,
                                                   chk_vertices,
                                                   dx=2.5)

    m = Matrix44.chain(
        Matrix44.scale(1.1, 1.3, 1),
        Matrix44.z_rotate(math.radians(15)),
        Matrix44.translate(1, 1, 0),
    )
    for index in range(3):
        color = 2 + index

        hatch = hatch.copy()
        entitydb.add(hatch)
        hatch.dxf.color = color
        hatch.transform(m)
        layout.add_entity(hatch)

        ellipse_edge = hatch.paths[0].edges[1]
        if not spline:
            draw_ellipse_axis(ellipse_edge)

        chk_ellipse, chk_vertices = synced_transformation(
            chk_ellipse, chk_vertices, m)
        add(layout, chk_ellipse, chk_vertices)
예제 #15
0
def test_transform():
    point = Point.new(dxfattribs={
        'location': (2, 3, 4),
        'extrusion': (0, 1, 0),
        'thickness': 2
    })
    # 1. rotation - 2. scaling - 3. translation
    m = Matrix44.chain(Matrix44.scale(2, 3, 1), Matrix44.translate(1, 1, 1))
    point.transform(m)
    assert point.dxf.location == (5, 10, 5)
    assert point.dxf.extrusion == (0, 1, 0)
    assert point.dxf.thickness == 6

    angle = math.pi / 4
    point.transform(Matrix44.z_rotate(math.pi / 4))
    assert point.dxf.extrusion.isclose((-math.cos(angle), math.sin(angle), 0))
    assert math.isclose(point.dxf.thickness, 6)
예제 #16
0
def test_circle_user_ocs():
    center = (2, 3, 4)
    extrusion = (0, 1, 0)

    circle = Circle.new(
        dxfattribs={'center': center, 'extrusion': extrusion, 'thickness': 2})
    ocs = OCS(extrusion)
    v = ocs.to_wcs(center)  # (-2, 4, 3)
    v = Vector(v.x * 2, v.y * 4, v.z * 2)
    v += (1, 1, 1)
    # and back to OCS, extrusion is unchanged
    result = ocs.from_wcs(v)

    m = Matrix44.chain(Matrix44.scale(2, 4, 2), Matrix44.translate(1, 1, 1))
    circle.transform(m)
    assert circle.dxf.center == result
    assert circle.dxf.extrusion == (0, 1, 0)
    assert circle.dxf.thickness == 8  # in WCS y-axis
예제 #17
0
def main_non_uniform_hatch_polyline(layout, spline=False):
    entitydb = layout.doc.entitydb
    hatch, lwpolyline = hatch_polyline(layout)
    if spline:
        hatch.paths.all_to_spline_edges()

    m = Matrix44.chain(
        Matrix44.scale(-1.1, 1.1, 1),
        Matrix44.z_rotate(math.radians(10)),
        Matrix44.translate(1, 1, 1),
    )
    for index in range(4):
        color = 2 + index
        hatch = hatch.copy()
        entitydb.add(hatch)
        hatch.dxf.color = color
        hatch.transform(m)
        layout.add_entity(hatch)
예제 #18
0
    def test_reflections(self, s, e, rotation, sx, sy):
        m = Matrix44.chain(
            Matrix44.scale(sx, sy, 1),
            Matrix44.z_rotate(rotation),
        )
        expected_start = m.transform(Vec3.from_deg_angle(s))
        expected_end = m.transform(Vec3.from_deg_angle(e))
        expected_angle_span = arc_angle_span_deg(s, e)

        ocs = OCSTransform(Z_AXIS, m)
        new_s, new_e = ocs.transform_ccw_arc_angles_deg(s, e)
        wcs_start = ocs.new_ocs.to_wcs(Vec3.from_deg_angle(new_s))
        wcs_end = ocs.new_ocs.to_wcs(Vec3.from_deg_angle(new_e))
        assert arc_angle_span_deg(new_s, new_e) == pytest.approx(
            expected_angle_span
        )
        assert wcs_start.isclose(expected_start)
        assert wcs_end.isclose(expected_end)
예제 #19
0
def main_insert2(layout):
    entity, vertices = insert()
    m = Matrix44.chain(
        Matrix44.scale(-1.1, 1.1, 1),
        Matrix44.z_rotate(math.radians(10)),
        Matrix44.translate(1, 1, 1),
    )
    doc.layers.new('exploded axis', dxfattribs={'color': -7})

    for i in range(5):
        entity, vertices = synced_transformation(entity, vertices, m)
        layout.entitydb.add(entity)
        layout.add_entity(entity)

        origin, x, y, z = list(vertices)
        layout.add_line(origin,
                        x,
                        dxfattribs={
                            'color': 2,
                            'layer': 'new axis'
                        })
        layout.add_line(origin,
                        y,
                        dxfattribs={
                            'color': 4,
                            'layer': 'new axis'
                        })
        layout.add_line(origin,
                        z,
                        dxfattribs={
                            'color': 6,
                            'layer': 'new axis'
                        })

        for line in entity.virtual_entities():
            line.dxf.layer = 'exploded axis'
            line.dxf.color = 7
            layout.entitydb.add(line)
            layout.add_entity(line)
예제 #20
0
def main_uniform_hatch_polyline(layout):
    entitydb = layout.doc.entitydb
    hatch, lwpolyline = hatch_polyline(layout, edge_path=False)
    m = Matrix44.chain(
        Matrix44.scale(-1.1, 1.1, 1),
        Matrix44.z_rotate(math.radians(10)),
        Matrix44.translate(1, 1, 1),
    )
    for index in range(4):
        color = 2 + index

        hatch = hatch.copy()
        entitydb.add(hatch)
        hatch.dxf.color = color
        hatch.transform(m)

        lwpolyline = lwpolyline.copy()
        entitydb.add(lwpolyline)
        lwpolyline.dxf.color = color
        lwpolyline.transform(m)

        layout.add_entity(lwpolyline)
        layout.add_entity(hatch)
예제 #21
0
파일: text2path.py 프로젝트: mhenr18/ezdxf
 def get_transformation():
     """ Apply rotation, width factor, translation to the insertion point
     and if necessary transformation from OCS to WCS.
     """
     # TODO: text generation flags - mirror-x and mirror-y
     angle = math.radians(entity.dxf.rotation)
     width_factor = entity.dxf.width
     if align == 'LEFT':
         location = p1
     elif align in ('ALIGNED', 'FIT'):
         width_factor = 1.0  # text goes from p1 to p2, no stretching applied
         location = p1.lerp(p2, factor=0.5)
         angle = (p2 - p1).angle  # override stored angle
     else:
         location = p2
     m = Matrix44.chain(
         Matrix44.scale(width_factor, 1, 1),
         Matrix44.z_rotate(angle),
         Matrix44.translate(location.x, location.y, location.z),
     )
     ocs = entity.ocs()
     if ocs.transform:
         m *= ocs.matrix
     return m
예제 #22
0
def main_mtext(layout):
    content = '{}RSKNZQ'

    def mtext(num):
        height = 1.0
        width = 1.0
        p1 = Vector(0, 0, 0)

        t = MText.new(dxfattribs={
            'char_height': height,
            'width': width,
            'text_direction': (1, 0, 0),
            'attachment_point': 7,
            'layer': 'text',
        },
                      doc=doc)
        t.text = content.format(num)
        tlen = height * len(t.text) * width
        p2 = p1.replace(x=tlen)
        p3 = p2.replace(y=height)
        p4 = p1.replace(y=height)
        v = [p1, p2, p3, p4, p3.lerp(p4), p2.lerp(p3)]
        return t, v

    def add_box(vertices):
        p1, p2, p3, p4, center_top, center_right = vertices
        layout.add_line(p1, p2, dxfattribs={'color': 1, 'layer': 'rect'})
        layout.add_line(p2, p3, dxfattribs={'color': 3, 'layer': 'rect'})
        layout.add_line(p3, p4, dxfattribs={'color': 1, 'layer': 'rect'})
        layout.add_line(p4, p1, dxfattribs={'color': 3, 'layer': 'rect'})
        layout.add_line(center_right,
                        p1,
                        dxfattribs={
                            'color': 2,
                            'layer': 'rect'
                        })
        layout.add_line(center_right,
                        p4,
                        dxfattribs={
                            'color': 2,
                            'layer': 'rect'
                        })
        layout.add_line(center_top,
                        p1,
                        dxfattribs={
                            'color': 4,
                            'layer': 'rect'
                        })
        layout.add_line(center_top,
                        p2,
                        dxfattribs={
                            'color': 4,
                            'layer': 'rect'
                        })

    entity0, vertices0 = mtext(1)
    entity0, vertices0 = synced_rotation(entity0,
                                         vertices0,
                                         axis=Z_AXIS,
                                         angle=math.radians(30))
    entity0, vertices0 = synced_translation(entity0, vertices0, dx=3, dy=3)

    for i, reflexion in enumerate([(1, 2), (-1, 2), (-1, -2), (1, -2)]):
        rx, ry = reflexion
        m = Matrix44.chain(Matrix44.scale(rx, ry, 1), )
        entity, vertices = synced_transformation(entity0, vertices0, m)
        entity.text = content.format(i + 1)

        layout.add_entity(entity)
        add_box(vertices)
예제 #23
0
from ezdxf.math import UCS, Matrix44
from pathlib import Path

OUT_DIR = Path('~/Desktop/Outbox').expanduser()

doc = ezdxf.new('R2010')
msp = doc.modelspace()

# Using an UCS simplifies 3D operations, but UCS definition can happen later
# calculating corner points in local (UCS) coordinates without Vec3 class
angle = math.radians(360 / 5)
corners_ucs = [(math.cos(angle * n), math.sin(angle * n), 0) for n in range(5)]

# let's do some transformations
tmatrix = Matrix44.chain(  # creating a transformation matrix
    Matrix44.z_rotate(math.radians(15)),  # 1. rotation around z-axis
    Matrix44.translate(0, .333, .333),  # 2. translation
)
transformed_corners_ucs = tmatrix.transform_vertices(corners_ucs)

# transform UCS into WCS
ucs = UCS(
    origin=(0, 2, 2),  # center of pentagon
    ux=(1, 0, 0),  # x-axis parallel to WCS x-axis
    uz=(0, 1, 1),  # z-axis
)
corners_wcs = list(ucs.points_to_wcs(transformed_corners_ucs))

msp.add_polyline3d(
    points=corners_wcs,
    dxfattribs={
        'closed': True,
예제 #24
0
def tmatrix(dx, dy, sx=1, sy=1, angle=0):
    return Matrix44.chain(
        Matrix44.scale(sx=sx, sy=sy, sz=1),
        Matrix44.z_rotate(radians(angle)),
        Matrix44.translate(dx, dy, 0),
    )
예제 #25
0
def tmatrix(x, y, angle):
    return Matrix44.chain(
        Matrix44.z_rotate(radians(angle)),
        Matrix44.translate(x, y, 0),
    )
예제 #26
0
def m44():
    return Matrix44.chain(
        Matrix44.z_rotate(math.pi / 2),
        Matrix44.translate(1, 2, 0),
    )
예제 #27
0
 def matrix(self):
     return Matrix44.chain(
         Matrix44.x_rotate(0.75),
         Matrix44.translate(2, 3, 4),
     )
예제 #28
0
def main_text(layout):
    content = "{}RSKNZQ"

    def text(num):
        height = 1.0
        width = 1.0
        p1 = Vec3(0, 0, 0)

        t = Text.new(
            dxfattribs={
                "text":
                content.format(num),  # should easily show reflexion errors
                "height": height,
                "width": width,
                "rotation": 0,
                "layer": "text",
            },
            doc=doc,
        )
        t.set_pos(p1, align="LEFT")
        tlen = height * len(t.dxf.text) * width
        p2 = p1.replace(x=tlen)
        p3 = p2.replace(y=height)
        p4 = p1.replace(y=height)
        v = [p1, p2, p3, p4, p3.lerp(p4), p2.lerp(p3)]
        return t, v

    def add_box(vertices):
        p1, p2, p3, p4, center_top, center_right = vertices
        layout.add_line(p1, p2, dxfattribs={"color": 1, "layer": "rect"})
        layout.add_line(p2, p3, dxfattribs={"color": 3, "layer": "rect"})
        layout.add_line(p3, p4, dxfattribs={"color": 1, "layer": "rect"})
        layout.add_line(p4, p1, dxfattribs={"color": 3, "layer": "rect"})
        layout.add_line(center_right,
                        p1,
                        dxfattribs={
                            "color": 2,
                            "layer": "rect"
                        })
        layout.add_line(center_right,
                        p4,
                        dxfattribs={
                            "color": 2,
                            "layer": "rect"
                        })
        layout.add_line(center_top,
                        p1,
                        dxfattribs={
                            "color": 4,
                            "layer": "rect"
                        })
        layout.add_line(center_top,
                        p2,
                        dxfattribs={
                            "color": 4,
                            "layer": "rect"
                        })

    entity0, vertices0 = text(1)
    entity0, vertices0 = synced_rotation(entity0,
                                         vertices0,
                                         axis=Z_AXIS,
                                         angle=math.radians(30))
    entity0, vertices0 = synced_translation(entity0, vertices0, dx=3, dy=3)

    for i, reflexion in enumerate([(1, 2), (-1, 2), (-1, -2), (1, -2)]):
        rx, ry = reflexion
        m = Matrix44.chain(Matrix44.scale(rx, ry, 1), )
        entity, vertices = synced_transformation(entity0, vertices0, m)
        entity.dxf.text = content.format(i + 1)

        layout.add_entity(entity)
        add_box(vertices)