def draw_polyline_entity(self, entity: DXFGraphic): dxftype = entity.dxftype() if dxftype == 'POLYLINE': e = cast(Polyface, entity) if e.is_polygon_mesh or e.is_poly_face_mesh: self.draw_mesh_builder_entity( MeshBuilder.from_polyface(e), self._resolve_properties(entity), ) return entity = cast(Union[LWPolyline, Polyline], entity) if not entity.has_arc: properties = self._resolve_properties(entity) if dxftype == 'LWPOLYLINE': self.out.draw_line_string(Vector.generate( entity.vertices_in_wcs()), close=entity.closed, properties=properties) else: # POLYLINE if entity.is_2d_polyline: ocs = entity.ocs() elevation = Vector(entity.dxf.elevation).z vertices = ocs.points_to_wcs( Vector(p[0], p[1], elevation) for p in entity.points()) else: vertices = Vector.generate(entity.points()) self.out.draw_line_string(vertices, close=entity.is_closed, properties=properties) return self.parent_stack.append(entity) self.out.set_current_entity(entity, tuple(self.parent_stack)) # todo: end points of virtual entities are not in correct order # can't use self.out.start_path() for child in entity.virtual_entities(): # all child entities have the same properties as the parent, # no visibility check required: self.draw_entity(child) # self.out.end_path() self.parent_stack.pop() self.out.set_current_entity(None)
def transform(self, m: Matrix44) -> 'Bezier4P': """ General transformation interface, returns a new :class:`Bezier4p` curve and it is always a 3D curve. Args: m: 4x4 transformation matrix (:class:`ezdxf.math.Matrix44`) .. versionadded:: 0.14 """ if len(self._control_points[0]) == 2: defpoints = Vector.generate(self._control_points) else: defpoints = self._control_points defpoints = tuple(m.transform_vertices(defpoints)) return Bezier4P(defpoints)
def add_vertices(self, vertices: Iterable['Vertex']) -> Sequence[int]: """ Add new vertices to the mesh, each vertex is a ``(x, y, z)`` tuple or a :class:`~ezdxf.math.Vector` object, returns the indices of the `vertices` added to the :attr:`vertices` list. e.g. adding 4 vertices to an empty mesh, returns the indices ``(0, 1, 2, 3)``, adding additional 4 vertices returns the indices ``(4, 5, 6, 7)``. Args: vertices: list of vertices, vertex as ``(x, y, z)`` tuple or :class:`~ezdxf.math.Vector` objects Returns: tuple: indices of the `vertices` added to the :attr:`vertices` list """ start_index = len(self.vertices) self.vertices.extend(Vector.generate(vertices)) return tuple(range(start_index, len(self.vertices)))
def draw_polyline_entity(self, entity: DXFGraphic, properties: Properties): dxftype = entity.dxftype() if dxftype == 'POLYLINE': e = cast(Polyface, entity) if e.is_polygon_mesh or e.is_poly_face_mesh: # draw 3D mesh or poly-face entity self.draw_mesh_builder_entity( MeshBuilder.from_polyface(e), properties, ) return entity = cast(Union[LWPolyline, Polyline], entity) is_lwpolyline = dxftype == 'LWPOLYLINE' if entity.has_width: # draw banded 2D polyline elevation = 0.0 ocs = entity.ocs() transform = ocs.transform if transform: if is_lwpolyline: # stored as float elevation = entity.dxf.elevation else: # stored as vector (0, 0, elevation) elevation = Vector(entity.dxf.elevation).z trace = TraceBuilder.from_polyline( entity, segments=self.circle_approximation_count // 2 ) for polygon in trace.polygons(): # polygon is a sequence of Vec2() if transform: points = ocs.points_to_wcs( Vector(v.x, v.y, elevation) for v in polygon ) else: points = Vector.generate(polygon) # Set default SOLID filling for LWPOLYLINE properties.filling = Filling() self.out.draw_filled_polygon(points, properties) return path = Path.from_lwpolyline(entity) \ if is_lwpolyline else Path.from_polyline(entity) self.out.draw_path(path, properties)
def fit_points(self, points: Iterable['Vertex']) -> None: self._fit_points = VertexArray( chain.from_iterable(Vector.generate(points)))
def test_distance_point_line_3d(points, expected): p, a, b = Vector.generate(points) assert distance_point_line_3d(p, a, b) == pytest.approx(expected)