1.. module:: ezdxf.path
2
3Path
4====
5
6This module implements a geometric :class:`Path`, supported by several render
7backends, with the goal to create such paths from DXF entities like LWPOLYLINE,
8POLYLINE or HATCH and send them to the render backend,
9see :mod:`ezdxf.addons.drawing`.
10
11Minimum common interface:
12
13- matplotlib: `PathPatch`_
14    - matplotlib.path.Path() codes:
15    - MOVETO
16    - LINETO
17    - CURVE3 - quadratic Bèzier-curve
18    - CURVE4 - cubic Bèzier-curve
19
20- PyQt: `QPainterPath`_
21    - moveTo()
22    - lineTo()
23    - quadTo() - quadratic Bèzier-curve (converted to a cubic Bèzier-curve)
24    - cubicTo() - cubic Bèzier-curve
25
26- PyCairo: `Context`_
27    - move_to()
28    - line_to()
29    - no support for quadratic Bèzier-curve
30    - curve_to() - cubic Bèzier-curve
31
32- SVG: `SVG-Path`_
33    - "M" - absolute move to
34    - "L" - absolute line to
35    - "Q" - absolute quadratic Bèzier-curve
36    - "C" - absolute cubic Bèzier-curve
37
38ARC and ELLIPSE entities are approximated by multiple cubic Bézier-curves, which
39are close enough for display rendering. Non-rational SPLINES of 3rd degree can
40be represented exact as multiple cubic Bézier-curves, other B-splines will be
41approximated. The XLINE and the RAY entities are not supported, because of their
42infinite nature.
43
44This :class:`Path` class is a full featured 3D object, although the backends
45only support 2D paths.
46
47.. hint::
48
49    A :class:`Path` can not represent a point. A :class:`Path` with only a
50    start point yields no vertices!
51
52.. versionchanged:: 0.16
53    Refactored the module :mod:`ezdxf.render.path` into the subpackage
54    :mod:`ezdxf.path`.
55
56The usability of the :class:`Path` class expanded by the introduction
57of the reverse conversion from :class:`Path` to DXF entities (LWPOLYLINE,
58POLYLINE, LINE), and many other tools in `ezdxf` v0.16.
59To emphasize this new usability, the :class:`Path` class has got its own
60subpackage :mod:`ezdxf.path`.
61
62.. warning::
63
64    Always import from the top level :mod:`ezdxf.path`, never from the
65    sub-modules
66
67Factory Functions
68-----------------
69
70Functions to create :class:`Path` objects from other objects.
71
72.. function:: make_path(entity: DXFEntity) -> Path
73
74    Factory function to create a single :class:`Path` object from a DXF
75    entity. Supported DXF types:
76
77    - LINE
78    - CIRCLE
79    - ARC
80    - ELLIPSE
81    - SPLINE and HELIX
82    - LWPOLYLINE
83    - 2D and 3D POLYLINE
84    - SOLID, TRACE, 3DFACE
85    - IMAGE, WIPEOUT clipping path
86    - VIEWPORT clipping path
87
88    The HATCH entity consist of multiple boundary paths and is not convertible
89    into a single :class:`Path` object and therefore not supported by this
90    function.
91
92    :param entity: DXF entity
93    :param segments: minimal count of cubic Bézier-curves for elliptical arcs
94        like CIRCLE, ARC, ELLIPSE, see :meth:`Path.add_ellipse`
95    :param level: subdivide level for SPLINE approximation,
96        see :meth:`Path.add_spline`
97
98    :raises TypeError: for unsupported DXF types
99
100    .. versionadded:: 0.16
101
102
103.. autofunction:: from_hatch(hatch: Hatch) -> Iterable[Path]
104
105.. autofunction:: from_vertices(vertices: Iterable[Vertex], close=False) -> Path
106
107.. autofunction:: from_matplotlib_path(mpath, curves=True) -> Iterable[Path]
108
109.. autofunction:: from_qpainter_path(qpath) -> Iterable[Path]
110
111Render Functions
112----------------
113
114Functions to create DXF entities from paths and add them to the modelspace, a
115paperspace layout or a block definition.
116
117.. autofunction:: render_lwpolylines(layout: Layout, paths: Iterable[Path], *, distance: float = 0.01, segments: int = 4, extrusion: Vertex = (0, 0, 1),  dxfattribs: Dict = None) -> EntityQuery
118
119.. autofunction:: render_polylines2d(layout: Layout, paths: Iterable[Path], *, distance: float = 0.01, segments: int = 4, extrusion: Vertex = (0, 0, 1),  dxfattribs: Dict = None) -> EntityQuery
120
121.. autofunction:: render_hatches(layout: Layout, paths: Iterable[Path], *, edge_path = True, distance: float = 0.01, segments: int = 4, g1_tol: float = 1e-4, extrusion: Vertex = (0, 0, 1),  dxfattribs: Dict = None) -> EntityQuery
122
123.. autofunction:: render_polylines3d(layout: Layout, paths: Iterable[Path], *, distance: float = 0.01, segments: int = 4, dxfattribs: Dict = None) -> EntityQuery
124
125.. autofunction:: render_lines(layout: Layout, paths: Iterable[Path], *, distance: float = 0.01, segments: int = 4, dxfattribs: Dict = None) -> EntityQuery
126
127.. autofunction:: render_splines_and_polylines(layout: Layout, paths: Iterable[Path], *, g1_tol: float = 1e-4, dxfattribs: Dict = None) -> EntityQuery
128
129Entity Maker
130------------
131
132Functions to create DXF entities from paths.
133
134.. autofunction:: to_lwpolylines(paths: Iterable[Path], *, distance: float = 0.01, segments: int = 4, extrusion: Vertex = (0, 0, 1),  dxfattribs: Dict = None) -> Iterable[LWPolyline]
135
136.. autofunction:: to_polylines2d(paths: Iterable[Path], *, distance: float = 0.01, segments: int = 4, extrusion: Vertex = (0, 0, 1),  dxfattribs: Dict = None) -> Iterable[Polyline]
137
138.. autofunction:: to_hatches(paths: Iterable[Path], *, edge_path: True, distance: float = 0.01, segments: int = 4, g1_tol: float = 1e-4, extrusion: Vertex = (0, 0, 1),  dxfattribs: Dict = None) -> Iterable[Hatch]
139
140.. autofunction:: to_polylines3d(paths: Iterable[Path], *, distance: float = 0.01, segments: int = 4, dxfattribs: Dict = None) -> Iterable[Polyline]
141
142.. autofunction:: to_lines(paths: Iterable[Path], *, distance: float = 0.01, segments: int = 4, dxfattribs: Dict = None) -> Iterable[Line]
143
144.. autofunction:: to_splines_and_polylines(paths: Iterable[Path], *, g1_tol: float= 1e-4, dxfattribs: Dict = None) -> Iterable[Union[Spline, Polyline]]
145
146Tool Maker
147----------
148
149Functions to create construction tools.
150
151.. autofunction:: to_bsplines_and_vertices(path: Path, g1_tol: float = 1e-4) -> Iterable[Union[BSpline, List[Vec3]]]
152
153.. autofunction:: to_matplotlib_path(paths: Iterable[Path], extrusion = (0, 0, 1)) -> matplotlib.path.Path
154
155.. autofunction:: to_qpainter_path(paths: Iterable[Path], extrusion = (0, 0, 1)) -> PyQt5.QtGui.QPainterPath
156
157
158Utility Functions
159-----------------
160
161.. autofunction:: transform_paths(paths: Iterable[Path], m: Matrix44) -> List[Path]
162
163.. autofunction:: transform_paths_to_ocs(paths: Iterable[Path], ocs: OCS) -> List[Path]
164
165.. autofunction:: bbox(paths: Iterable[Path]) -> BoundingBox
166
167.. autofunction:: fit_paths_into_box(paths: Iterable[Path], size: Tuple[float, float, float], uniform = True, source_box: BoundingBox = None) -> List[Path]
168
169.. autofunction:: add_bezier3p(path: Path, curves: Iterable[Bezier3P])
170
171.. autofunction:: add_bezier4p(path: Path, curves: Iterable[Bezier4P])
172
173.. autofunction:: add_ellipse(path: Path,ellipse: ConstructionEllipse, segments=1)
174
175.. autofunction:: add_spline(path: Path, spline: BSpline, level=4)
176
177Basic Shapes
178------------
179
180.. autofunction:: unit_circle(start_angle: float = 0, end_angle: float = 2π, segments: int = 1, transform: Matrix44 = None) -> Path
181
182.. autofunction:: wedge(start_angle: float, end_angle: float, segments: int = 1, transform: Matrix44 = None) -> Path
183
184.. autofunction:: elliptic_transformation(center: Vertex = (0, 0, 0), radius: float = 1, ratio: float = 1, rotation: float = 0) -> Matrix44
185
186.. autofunction:: rect(width: float = 1, height: float = 1, transform: Matrix44 = None) -> Path
187
188.. autofunction:: ngon(count: int, length: float = None, radius: float = 1.0, transform: Matrix44 = None) -> Path
189
190.. autofunction:: star(count: int, r1: float, r2: float, transform: Matrix44 = None) -> Path
191
192.. autofunction:: gear(count: int, top_width: float, bottom_width: float, height: float, outside_radius: float, transform: Matrix44 = None) -> Path
193
194The :mod:`~ezdxf.addons.text2path` add-on provides additional functions to
195create paths from text strings and DXF text entities.
196
197
198The Path Class
199--------------
200
201.. class:: Path
202
203    .. autoattribute:: start
204
205    .. autoattribute:: end
206
207    .. autoattribute:: is_closed
208
209    .. autoattribute:: has_lines
210
211    .. autoattribute:: has_curves
212
213    .. automethod:: control_vertices
214
215    .. automethod:: has_clockwise_orientation
216
217    .. automethod:: line_to(location: Vec3)
218
219    .. automethod:: curve3_to(location: Vec3, ctrl: Vec3)
220
221    .. automethod:: curve4_to(location: Vec3, ctrl1: Vec3, ctrl2: Vec3)
222
223    .. automethod:: close
224
225    .. automethod:: clone() -> Path
226
227    .. automethod:: reversed() -> Path
228
229    .. automethod:: clockwise() -> Path
230
231    .. automethod:: counter_clockwise() -> Path
232
233    .. automethod:: transform(m: Matrix44) -> Path
234
235    .. automethod:: approximate(segments: int=20) -> Iterable[Vec3]
236
237    .. automethod:: flattening(distance: float, segments: int=16) -> Iterable[Vec3]
238
239.. _PathPatch: https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.patches.PathPatch.html#matplotlib.patches.PathPatch
240.. _QPainterPath: https://doc.qt.io/qt-5/qpainterpath.html
241.. _SVG-Path: https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths
242.. _Context: https://pycairo.readthedocs.io/en/latest/reference/context.html