Esempio n. 1
0
def test_constructor_functions():
    # does not check the math, because tis would just duplicate the implementation code
    origin = (3, 3, 3)
    axis = (1, 0, -1)
    def_point = (3, 10, 4)
    ucs = UCS.from_x_axis_and_point_in_xy(origin, axis=axis, point=def_point)
    assert ucs.is_cartesian
    assert isclose(ucs.from_wcs(def_point).z, 0)

    ucs = UCS.from_x_axis_and_point_in_xz(origin, axis=axis, point=def_point)
    assert ucs.is_cartesian
    assert isclose(ucs.from_wcs(def_point).y, 0)

    ucs = UCS.from_y_axis_and_point_in_xy(origin, axis=axis, point=def_point)
    assert ucs.is_cartesian
    assert isclose(ucs.from_wcs(def_point).z, 0)

    ucs = UCS.from_y_axis_and_point_in_yz(origin, axis=axis, point=def_point)
    assert ucs.is_cartesian
    assert isclose(ucs.from_wcs(def_point).x, 0)

    ucs = UCS.from_z_axis_and_point_in_xz(origin, axis=axis, point=def_point)
    assert ucs.is_cartesian
    assert isclose(ucs.from_wcs(def_point).y, 0)

    ucs = UCS.from_z_axis_and_point_in_yz(origin, axis=axis, point=def_point)
    assert ucs.is_cartesian
    assert isclose(ucs.from_wcs(def_point).x, 0)
Esempio n. 2
0
    def generate_geometry(self, vertices: List[Vec3]) -> None:
        """Regenerate the MLINE geometry for new reference line defined by
        `vertices`.
        """
        vertices = list(filter_close_vertices(vertices, abs_tol=1e-6))
        if len(vertices) == 0:
            self.clear()
            return
        elif len(vertices) == 1:
            self.vertices = [MLineVertex.new(vertices[0], X_AXIS, Y_AXIS)]
            return

        style = self.style
        assert style is not None, "valid MLINE style required"
        if len(style.elements) == 0:
            raise const.DXFStructureError(
                f"No line elements defined in {str(style)}."
            )

        def miter(dir1: Vec3, dir2: Vec3):
            return ((dir1 + dir2) * 0.5).normalize().orthogonal()

        ucs = UCS.from_z_axis_and_point_in_xz(
            origin=vertices[0],
            point=vertices[1],
            axis=self.dxf.extrusion,
        )
        # Transform given vertices into UCS and project them into the
        # UCS-xy-plane by setting the z-axis to 0:
        vertices = [v.replace(z=0) for v in ucs.points_from_wcs(vertices)]
        start_angle = style.dxf.start_angle
        end_angle = style.dxf.end_angle

        line_directions = [
            (v2 - v1).normalize() for v1, v2 in zip(vertices, vertices[1:])
        ]

        if self.is_closed:
            line_directions.append((vertices[0] - vertices[-1]).normalize())
            closing_miter = miter(line_directions[0], line_directions[-1])
            miter_directions = [closing_miter]
        else:
            closing_miter = None
            line_directions.append(line_directions[-1])
            miter_directions = [line_directions[0].rotate_deg(start_angle)]

        for d1, d2 in zip(line_directions, line_directions[1:]):
            miter_directions.append(miter(d1, d2))

        if closing_miter is None:
            miter_directions.pop()
            miter_directions.append(line_directions[-1].rotate_deg(end_angle))
        else:
            miter_directions.append(closing_miter)

        self.vertices = [
            MLineVertex.new(v, d, m)
            for v, d, m in zip(vertices, line_directions, miter_directions)
        ]
        self._update_parametrization()

        # reverse transformation into WCS
        for v in self.vertices:
            v.transform(ucs.matrix)