def test_upright_insert(): doc = ezdxf.new() blk = doc.blocks.new("example") blk.add_arc( center=(5, 0, 2), radius=3, start_angle=30, end_angle=150, ) blk.add_lwpolyline(POLYLINE_POINTS) msp = doc.modelspace() blk_ref = msp.add_blockref( name="example", insert=(0, 0, 4), dxfattribs={ "extrusion": (0, 0, -1), "rotation": -37, }, ) blk_ref_copy = blk_ref.copy() upright(blk_ref_copy) msp.add_entity(blk_ref_copy) assert blk_ref_copy.dxf.extrusion.isclose(Z_AXIS) for e0, e1 in zip(blk_ref.virtual_entities(), blk_ref_copy.virtual_entities()): assert e0.dxftype() == e1.dxftype(), "same DXF type expected" p0 = path.make_path(e0) assert len(p0) > 0, "source path cannot be empty" p1 = path.make_path(e1) assert len(p1) > 0, "upright path cannot be empty" assert path.have_close_control_vertices( p0, p1), "expected same WCS representation"
def test_upright_arc_geometry(arc): p0 = path.make_path(arc) upright(arc) # ARC angles are always in counter-clockwise orientation around the # extrusion vector, therefore a reversed path vertex order: p1 = path.make_path(arc).reversed() assert path.have_close_control_vertices(p0, p1)
def test_wcs_mirror_transformations_of_clockwise_oriented_curves(sx, sy, kind): hatch = Hatch() edge_path = hatch.paths.add_edge_path() # A closed loop is required to get a path! edge_path.add_line((15, 5), (5, 5)) if kind == "arc": edge_path.add_arc((10, 5), 5, start_angle=0, end_angle=180, ccw=False) elif kind == "ellipse": edge_path.add_ellipse( (10, 5), (5, 0), ratio=0.7, start_angle=0, end_angle=180, ccw=False ) else: pytest.fail(f"unknown kind: {kind}") src_path = make_path(hatch) assert len(src_path) > 1, "expected non empty path" m = Matrix44.scale(sx, sy, 1) transformed_hatch = transformed_copy(hatch, m) expected_path = src_path.transform(m) path_of_transformed_hatch = make_path(transformed_hatch) assert ( have_close_control_vertices(path_of_transformed_hatch, expected_path) is True )
def test_upright_circle_geometry(circle): circle.dxf.center = (0, 0) # required for rotation! p0 = path.make_path(circle) upright(circle) # IMPORTANT: Circle has a different WCS representation as Path object # Rotated around the z-axis by 180 degrees AND reversed order, because # the start point is always at 0 degrees, determined by the OCS x-axis! p1 = path.make_path(circle).transform(Matrix44.z_rotate(math.pi)) assert path.have_close_control_vertices(p0, p1.reversed())
def test_upright_polyline(factory): polyline = factory() p0 = path.make_path(polyline) assert p0.has_curves is True upright(polyline) assert polyline.dxf.extrusion.isclose(Z_AXIS) p1 = path.make_path(polyline) # vertex order do not change: assert path.have_close_control_vertices(p0, p1)
def mapping( entity: DXFGraphic, distance: float = MAX_FLATTENING_DISTANCE, force_line_string: bool = False, ) -> Dict: """Create the compiled ``__geo_interface__`` mapping as :class:`dict` for the given DXF `entity`, all coordinates are :class:`Vec3` objects and represents "Polygon" always as tuple (exterior, holes) even without holes. Internal API - result is **not** a valid ``_geo_interface__`` mapping! Args: entity: DXF entity distance: maximum flattening distance for curve approximations force_line_string: by default this function returns Polygon objects for closed geometries like CIRCLE, SOLID, closed POLYLINE and so on, by setting argument `force_line_string` to ``True``, this entities will be returned as LineString objects. """ dxftype = entity.dxftype() if isinstance(entity, Point): return {TYPE: POINT, COORDINATES: entity.dxf.location} elif isinstance(entity, Line): return line_string_mapping([entity.dxf.start, entity.dxf.end]) elif isinstance(entity, Polyline): if entity.is_3d_polyline or entity.is_2d_polyline: # May contain arcs as bulge values: path = make_path(entity) points = list(path.flattening(distance)) return _line_string_or_polygon_mapping(points, force_line_string) else: raise TypeError("Polymesh and Polyface not supported.") elif isinstance(entity, LWPolyline): # May contain arcs as bulge values: path = make_path(entity) points = list(path.flattening(distance)) return _line_string_or_polygon_mapping(points, force_line_string) elif dxftype in {"CIRCLE", "ARC", "ELLIPSE", "SPLINE"}: return _line_string_or_polygon_mapping( list(entity.flattening(distance)), force_line_string # type: ignore ) elif dxftype in {"SOLID", "TRACE", "3DFACE"}: return _line_string_or_polygon_mapping( entity.wcs_vertices(close=True), force_line_string # type: ignore ) elif isinstance(entity, DXFPolygon): return _hatch_as_polygon(entity, distance, force_line_string) else: raise TypeError(dxftype)
def test_upright_hatch_with_edge_path(all_edge_types_hatch): hatch = all_edge_types_hatch hatch.dxf.elevation = Vec3(0, 0, 4) hatch.dxf.extrusion = Vec3(0, 0, -1) assert hatch.dxf.extrusion.isclose(-Z_AXIS) 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_lwpolyline_lines(): from ezdxf.entities import LWPolyline pline = LWPolyline() pline.append_points([(1, 1), (2, 1), (2, 2)], format='xy') path = make_path(pline) assert path.start == (1, 1) assert path.end == (2, 2) assert len(path) == 2 pline.dxf.elevation = 1.0 path = make_path(pline) assert path.start == (1, 1, 1) assert path.end == (2, 2, 1)
def test_polyline_lines(): from ezdxf.entities import Polyline pline = Polyline() pline.append_formatted_vertices([(1, 1), (2, 1), (2, 2)], format='xy') path = make_path(pline) assert path.start == (1, 1) assert path.end == (2, 2) assert len(path) == 2 pline.dxf.elevation = (0, 0, 1) path = make_path(pline) assert path.start == (1, 1, 1) assert path.end == (2, 2, 1)
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 bundle_items(items: Iterable[DXFGraphic]) -> Iterable[Bundle]: paths: List[Path] = list() for entity in items: p = make_path(entity) p.user_data = entity paths.append(p) return build_bundles(paths)
def test_from_line(): start = Vec3(1, 2, 3) end = Vec3(4, 5, 6) line = factory.new("LINE", dxfattribs={"start": start, "end": end}) path = make_path(line) assert path.start.isclose(start) assert path.end.isclose(end)
def test_from_line(): start = Vec3(1, 2, 3) end = Vec3(4, 5, 6) line = factory.new('LINE', dxfattribs={'start': start, 'end': end}) path = make_path(line) assert path.start == start assert path.end == end
def draw_curve_entity(self, entity: DXFGraphic, properties: Properties) -> None: try: path = make_path(entity) except AttributeError: # API usage error raise TypeError(f"Unsupported DXF type {entity.dxftype()}") self.out.draw_path(path, properties)
def _convert_entity(self): e: 'Polyline' = cast('Polyline', self.entity) if e.is_2d_polyline or e.is_3d_polyline: self._path = make_path(e) else: m = MeshVertexMerger.from_polyface(e) self._mesh = MeshBuilder.from_builder(m)
def test_wcs_mirror_transformations_for_all_edge_types( sx, sy, all_edge_types_hatch ): hatch = all_edge_types_hatch src_path = make_path(hatch) assert len(src_path) > 1, "expected non empty path" m = Matrix44.scale(sx, sy, 1) transformed_hatch = transformed_copy(hatch, m) expected_path = src_path.transform(m) path_of_transformed_hatch = make_path(transformed_hatch) assert ( have_close_control_vertices(path_of_transformed_hatch, expected_path) is True )
def test_upright_quadrilaterals(cls): solid = cls.new( dxfattribs={ "vtx0": (1, 1), "vtx1": (2, 1), "vtx2": (2, 2), "vtx3": (1, 2), "extrusion": (0, 0, -1), }) p0 = path.make_path(solid) assert len(p0) == 4 upright(solid) assert solid.dxf.extrusion.isclose(Z_AXIS) p1 = path.make_path(solid) # same vertex order as source entity assert path.have_close_control_vertices(p0, p1)
def test_lwpolyline_s_shape(): from ezdxf.entities import LWPolyline pline = LWPolyline() pline.append_points(S_SHAPE, format='xyb') path = make_path(pline) assert path.start == (0, 0) assert path.end == (5, 2) # closed assert any(cmd.type == Command.CURVE4_TO for cmd in path)
def test_make_path_from_lwpolyline_with_bulges(): pline = LWPolyline() pline.closed = True pline.append_points(POINTS, format="xyb") path = make_path(pline) assert path.start == (0, 0) assert path.end == (0, 0) # closed assert any(cmd.type == Command.CURVE4_TO for cmd in path)
def test_3d_polyline(): from ezdxf.entities import Polyline pline = Polyline.new(dxfattribs={'flags': Polyline.POLYLINE_3D}) pline.append_vertices([(1, 1, 1), (2, 1, 3), (2, 2, 2)]) path = make_path(pline) assert path.start == (1, 1, 1) assert path.end == (2, 2, 2) assert len(path) == 2
def test_from_circle_with_zero_radius(): circle = factory.new('CIRCLE', dxfattribs={ 'center': (1, 0, 0), 'radius': 0, }) path = make_path(circle) assert len(path) == 0
def test_polyine_with_bulges(): from ezdxf.entities import Polyline pline = Polyline() pline.close(True) pline.append_formatted_vertices(POINTS, format='xyb') path = make_path(pline) assert path.start == (0, 0) assert path.end == (0, 0) # closed assert any(cmd.type == Command.CURVE4_TO for cmd in path)
def test_upright_ellipse(): ellipse = Ellipse.new( dxfattribs={ "center": (5, 5, 5), "major_axis": (5, 0, 0), "ratio": 0.5, "start_param": 0.5, "end_param": 1.5, "extrusion": (0, 0, -1), }) p0 = path.make_path(ellipse) assert p0.has_curves is True upright(ellipse) assert ellipse.dxf.extrusion.isclose(Z_AXIS) p1 = path.make_path(ellipse) # has reversed vertex order of source entity: assert path.have_close_control_vertices(p0, p1.reversed())
def test_from_quadrilateral_with_3_points(dxftype): entity = factory.new(dxftype) entity.dxf.vtx0 = (0, 0, 0) entity.dxf.vtx1 = (1, 0, 0) entity.dxf.vtx2 = (1, 1, 0) entity.dxf.vtx3 = (1, 1, 0) # last two points are equal path = make_path(entity) assert path.is_closed is True assert len(list(path.approximate())) == 4
def test_issue_224_end_points(ellipse): p = make_path(ellipse) assert ellipse.start_point.isclose(p.start) assert ellipse.end_point.isclose(p.end) # end point locations measured in BricsCAD: assert ellipse.start_point.isclose((2191.3054, -1300.8375), abs_tol=1e-4) assert ellipse.end_point.isclose((2609.7870, -1520.6677), abs_tol=1e-4)
def test_from_circle(radius): circle = factory.new('CIRCLE', dxfattribs={ 'center': (1, 0, 0), 'radius': radius, }) path = make_path(circle) assert path.start == (2, 0) assert path.end == (2, 0) assert path.is_closed is True
def test_make_path_from_full_circle_lwpolyline_issue_424(): pline = LWPolyline() pline.closed = True points = [ (39_482_129.9462793, 3_554_328.753243976, 1.0), (39_482_129.95781776, 3_554_328.753243976, 1.0), ] pline.append_points(points, format="xyb") path = make_path(pline) assert len(path) == 2
def _convert_entity(self): e: 'LWPolyline' = cast('LWPolyline', self.entity) if e.has_width: # use a mesh representation: tb = TraceBuilder.from_polyline(e) mb = MeshVertexMerger() # merges coincident vertices for face in tb.faces(): mb.add_face(Vec3.generate(face)) self._mesh = MeshBuilder.from_builder(mb) else: # use a path representation to support bulges! self._path = make_path(e)
def test_from_circle_with_zero_radius(): circle = factory.new( "CIRCLE", dxfattribs={ "center": (1, 0, 0), "radius": 0, }, ) path = make_path(circle) assert len(path) == 0
def test_from_arc(): arc = factory.new('ARC', dxfattribs={ 'center': (1, 0, 0), 'radius': 1, 'start_angle': 0, 'end_angle': 180, }) path = make_path(arc) assert path.start == (2, 0) assert path.end == (0, 0)