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)
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)