Ë
    £èh¥…  ã                  óh  — d dl mZ d dlmZmZmZmZmZ d dlZd dl	Z
d dlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ d dl m!Z! d dl"m#Z# ddl$m%Z% dd	l&m'Z' dd
l(m)Z)m*Z* erd dl"m#Z# d dl+m,Z, g d¢Z-dZ.dZ/dZ0dZ1d<d„Z2d=d„Z3d>d„Z4d?d„Z5ddœd@d„Z6dAd„Z7	 	 dB	 	 	 	 	 	 	 	 	 dCd„Z8dDd„Z9dDd„Z:e.e/eddœ	 	 	 	 	 	 	 	 	 	 	 dEd„Z;ddeddœ	 	 	 	 	 	 	 	 	 	 	 dEd„Z<de.e/e0edd œ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dFd!„Z=e.e/eddœ	 	 	 	 	 	 	 	 	 	 	 dEd"„Z>e.e/dd#œ	 	 	 	 	 	 	 	 	 dGd$„Z?e.e/dd#œ	 	 	 	 	 	 	 	 	 dGd%„Z@e0dd&œ	 	 	 	 	 	 	 dHd'„ZA	 dI	 	 	 	 	 dJd(„ZBdKd)„ZCdLd*„ZD	 dM	 	 	 	 	 	 	 	 	 	 	 	 	 dNd+„ZEdOdPd,„ZFd-d.d/œ	 	 	 	 	 dQd0„ZGdRd1„ZHdRd2„ZIdSdTd3„ZJdUd4„ZKdVd5„ZLdWd6„ZMdXdYd7„ZNdZd8„ZOd[d9„ZP	 d\	 	 	 	 	 	 	 d]d:„ZQd^d_d;„ZRy)`é    )Úannotations)ÚTYPE_CHECKINGÚIterableÚIteratorÚOptionalÚSequenceN)ÚVec2ÚVec3ÚUVecÚZ_AXISÚOCSÚUCSÚMatrix44ÚBoundingBoxÚConstructionEllipseÚcubic_bezier_from_ellipseÚBezier4PÚBezier3PÚBSplineÚreverse_bezier_curvesÚbulge_to_arcÚlinear_vertex_spacingÚinscribe_circle_tangent_lengthÚcubic_bezier_arc_parametersÚcubic_bezier_bboxÚquadratic_bezier_bbox)Úmapbox_earcut_2d)ÚEntityQueryé   )ÚPath)ÚCommand)Ú	converterÚnesting)ÚGenericLayoutType)ÚbboxÚprecise_bboxÚfit_paths_into_boxÚtransform_pathsÚtransform_paths_to_ocsÚrender_lwpolylinesÚrender_polylines2dÚrender_polylines3dÚrender_linesÚrender_hatchesÚrender_mpolygonsÚrender_splines_and_polylinesÚadd_bezier4pÚadd_bezier3pÚadd_ellipseÚadd_2d_polylineÚ
add_splineÚto_multi_pathÚsingle_pathsÚhave_close_control_verticesÚlines_to_curve3Úlines_to_curve4ÚfilletÚpolygonal_filletÚchamferÚchamfer2ÚtriangulateÚis_rectangularç{®Gáz„?é   g-Cëâ6?g»½×Ùß|Û=c                óJ   — t        «       }| D ]  }|j                  |«       Œ |S )z€Returns a multi-path object from all given paths and their sub-paths.
    Ignores paths without any commands (empty paths).
    )r    Úextend_multi_path)ÚpathsÚ
multi_pathÚps      ú0lib/python3.12/site-packages/ezdxf/path/tools.pyr6   r6   U   s)   € ô “€JÛˆØ×$Ñ$ QÕ'ð àÐó    c              #  óp   K  — | D ]+  }|j                   r|j                  «       E d{  –—†  Œ(|–— Œ- y7 Œ­w)zBYields all given paths and their sub-paths as single path objects.N)Úhas_sub_pathsÚ	sub_paths)rE   rG   s     rH   r7   r7   _   s.   è ø€ ãˆØ�?Š?Ø—{‘{“}×$Ñ$à‹Gñ	 à$ús   ‚%6§4¨6c                óJ   — | D �cg c]  }|j                  |«      ‘Œ c}S c c}w )a  Transform multiple path objects at once by transformation
    matrix `m`. Returns a list of the transformed path objects.

    Args:
        paths: iterable of :class:`Path` or :class:`Path2d` objects
        m: transformation matrix of type :class:`~ezdxf.math.Matrix44`

    )Ú	transform)rE   ÚmrG   s      rH   r(   r(   h   s$   € ñ %*Ó*¡E˜qˆA�K‰K˜�N EÑ*Ð*ùÒ*s   … c                ón   — |j                   j                  «       }|j                  «        t        | |«      S )a  Transform multiple :class:`Path` objects at once from WCS to OCS.
    Returns a list of the transformed :class:`Path` objects.

    Args:
        paths: iterable of :class:`Path` or :class:`Path2d` objects
        ocs: OCS transformation of type :class:`~ezdxf.math.OCS`

    )ÚmatrixÚcopyÚ	transposer(   )rE   ÚocsÚts      rH   r)   r)   t   s*   € ð 	�
‰
�‰Ó€AØ‡K�K„MÜ˜5 !Ó$Ð$rI   F©Úfastc               óê   — t        «       }| D ]c  }|r |j                  |j                  «       «       Œ%t        |«      }|j                  sŒ=|j                  |j
                  |j                  f«       Œe |S )uU  Returns the :class:`~ezdxf.math.BoundingBox` for the given paths.

    Args:
        paths: iterable of :class:`Path` or :class:`Path2d` objects
        fast: calculates the precise bounding box of BÃ¨zier curves if
            ``False``, otherwise uses the control points of BÃ©zier curves to
            determine their bounding box.

    )r   ÚextendÚcontrol_verticesr&   Úhas_dataÚextminÚextmax)rE   rW   ÚboxrG   Úbbs        rH   r%   r%   ‚   s]   € ô ‹-€CÛˆÙØ�J‰J�q×)Ñ)Ó+Õ,ä˜a“ˆBØ�{‹{Ø—
‘
˜BŸI™I r§y¡yÐ1Õ2ð ð €JrI   c           	     ó¢  — t        | «      dk(  r
t        «       S | j                  }|g}| j                  «       D �]Š  }|j                  t
        j                  k(  r|j                  |j                  «       �nA|j                  t
        j                  k(  rmt        t        ||j                  |j                  |j                  f«      «      }|j                  |j                  «       |j                  |j                  «       n·|j                  t
        j                   k(  rbt#        t%        ||j&                  |j                  f«      «      }|j                  |j                  «       |j                  |j                  «       n8|j                  t
        j(                  k(  r|j                  |j                  «       |j                  }�Œ� t        |«      S )zIReturns the precise :class:`~ezdxf.math.BoundingBox` for the given paths.r   )Úlenr   ÚstartÚcommandsÚtyper!   ÚLINE_TOÚappendÚendÚ	CURVE4_TOr   r   Úctrl1Úctrl2r\   r]   Ú	CURVE3_TOr   r   ÚctrlÚMOVE_TO)Úpathrb   ÚpointsÚcmdr_   s        rH   r&   r&   —   s6  € ä
ˆ4ƒy�A‚~Ü‹}ÐØ�J‰J€EØ˜€FØ�}‰}�ˆØ�8‰8”w—‘Ò&Ø�M‰M˜#Ÿ'™'Ö"Ø�X‰Xœ×*Ñ*Ò*Ü"Ü˜% §¡¨C¯I©I°s·w±wÐ?Ó@óˆBð �M‰M˜"Ÿ)™)Ô$Ø�M‰M˜"Ÿ)™)Õ$Ø�X‰Xœ×*Ñ*Ò*Ü&¤x°¸¿¹À#Ç'Á'Ð0JÓ'KÓLˆBØ�M‰M˜"Ÿ)™)Ô$Ø�M‰M˜"Ÿ)™)Õ$Ø�X‰XœŸ™Ò(Ø�M‰M˜#Ÿ'™'Ô"Ø—‘Šð ô" �vÓÐrI   Tc                óœ  — t        | «      } t        | «      dk(  r| S |€t        | d¬«      }n|}|j                  r|j                  dk(  r| S t        |«      }|dk(  st        |«      dk  rt        d«      ‚|rt        |j                  |«      \  }}}nt        |j                  |«      \  }}}t        j                  |||«      }	t        | |	«      S )a  Scale the given `paths` to fit into a box of the given `size`,
    so that all path vertices are inside these borders.
    If `source_box` is ``None`` the default source bounding box is calculated
    from the control points of the `paths`.

    `Note:` if the target size has a z-size of 0, the `paths` are
    projected into the xy-plane, same is true for the x-size, projects into
    the yz-plane and the y-size, projects into and xz-plane.

    Args:
        paths: iterable of :class:`~ezdxf.path.Path` objects
        size: target box size as tuple of x-, y- and z-size values
        uniform: ``True`` for uniform scaling
        source_box: pass precalculated source bounding box, or ``None`` to
            calculate the default source bounding box from the control vertices

    r   TrV   )r   r   r   zinvalid target size)Úlistra   r%   r[   Úsizer
   ÚminÚ
ValueErrorÚ_get_uniform_scalingÚ_get_non_uniform_scalingr   Úscaler(   )
rE   rs   ÚuniformÚ
source_boxÚcurrent_boxÚtarget_sizeÚsxÚsyÚszrO   s
             rH   r'   r'   ±   sÊ   € ô. �‹K€EÜ
ˆ5ƒz�Q‚ØˆØÐÜ˜5 tÔ,‰à ˆØ×Ò ;×#3Ñ#3°yÒ#@ØˆÜ�t“*€KØ�iÒ¤3 {Ó#3°aÒ#7ÜÐ.Ó/Ð/áÜ)¨+×*:Ñ*:¸KÓH‰
ˆˆB‘ä-¨k×.>Ñ.>ÀÓL‰
ˆˆB�Ü�‰�r˜2˜rÓ"€AÜ˜5 !Ó$Ð$rI   c                ó€  — d}t         j                  }| j                  |kD  r(|j                  |kD  r|j                  | j                  z  }t         j                  }| j                  |kD  r(|j                  |kD  r|j                  | j                  z  }t         j                  }| j                  |kD  r(|j                  |kD  r|j                  | j                  z  }t        |||«      }|t         j                  u rt        d«      ‚|j                  |kD  r|nd}|j                  |kD  r|nd}|j                  |kD  r|nd}|||fS )Nç�íµ ÷Æ°>zinternal errorr   )ÚmathÚinfÚxÚyÚzrt   ÚArithmeticError)Úcurrent_sizer|   ÚTOLÚscale_xÚscale_yÚscale_zÚuniform_scales          rH   rv   rv   Ý   s  € Ø
€CÜ�h‰h€GØ‡~�~˜Ò §¡°Ò 3Ø—-‘- ,§.¡.Ñ0ˆÜ�h‰h€GØ‡~�~˜Ò §¡°Ò 3Ø—-‘- ,§.¡.Ñ0ˆÜ�h‰h€GØ‡~�~˜Ò §¡°Ò 3Ø—-‘- ,§.¡.Ñ0ˆä˜ ¨'Ó2€MØœŸ™Ñ ÜÐ.Ó/Ð/Ø*Ÿ}™}¨sÒ2‰m¸€GØ*Ÿ}™}¨sÒ2‰m¸€GØ*Ÿ}™}¨sÒ2‰m¸€GØ�G˜WÐ$Ð$rI   c                ó  — d}d}| j                   |kD  r|j                   | j                   z  }d}| j                  |kD  r|j                  | j                  z  }d}| j                  |kD  r|j                  | j                  z  }|||fS )Nr�   g      ð?)r„   r…   r†   )rˆ   r|   r‰   rŠ   r‹   rŒ   s         rH   rw   rw   ò   s}   € Ø
€CØ€GØ‡~�~˜ÒØ—-‘- ,§.¡.Ñ0ˆØ€GØ‡~�~˜ÒØ—-‘- ,§.¡.Ñ0ˆØ€GØ‡~�~˜ÒØ—-‘- ,§.¡.Ñ0ˆØ�G˜WÐ$Ð$rI   ©ÚdistanceÚsegmentsÚ	extrusionÚ
dxfattribsc          	     óŽ   — t        t        j                  |||||¬«      «      }|D ]  }| j                  |«       Œ t	        |«      S )uA  Render the given `paths` into `layout` as
    :class:`~ezdxf.entities.LWPolyline` entities.
    The `extrusion` vector is applied to all paths, all vertices are projected
    onto the plane normal to this extrusion vector. The default extrusion vector
    is the WCS z-axis. The plane elevation is the distance from the WCS origin
    to the start point of the first path.

    Args:
        layout: the modelspace, a paperspace layout or a block definition
        paths: iterable of :class:`Path` or :class:`Path2d` objects
        distance:  maximum distance, see :meth:`Path.flattening`
        segments: minimum segment count per BÃ©zier curve
        extrusion: extrusion vector for all paths
        dxfattribs: additional DXF attribs

    Returns:
        created entities in an :class:`~ezdxf.query.EntityQuery` object

    r�   )rr   r"   Úto_lwpolylinesÚ
add_entityr   )ÚlayoutrE   r�   r‘   r’   r“   ÚlwpolylinesÚ
lwpolylines           rH   r*   r*     óP   € ô8 Ü× Ñ ØØØØØ!ô	
ó€Kó "ˆ
Ø×Ñ˜*Õ%ð "ä�{Ó#Ð#rI   c          	     óŽ   — t        t        j                  |||||¬«      «      }|D ]  }| j                  |«       Œ t	        |«      S )uA  Render the given `paths` into `layout` as 2D
    :class:`~ezdxf.entities.Polyline` entities.
    The `extrusion` vector is applied to all paths, all vertices are projected
    onto the plane normal to this extrusion vector.The default extrusion vector
    is the WCS z-axis. The plane elevation is the distance from the WCS origin
    to the start point of the first path.

    Args:
        layout: the modelspace, a paperspace layout or a block definition
        paths: iterable of :class:`Path` or :class:`Path2d` objects
        distance:  maximum distance, see :meth:`Path.flattening`
        segments: minimum segment count per BÃ©zier curve
        extrusion: extrusion vector for all paths
        dxfattribs: additional DXF attribs

    Returns:
        created entities in an :class:`~ezdxf.query.EntityQuery` object

    r�   )rr   r"   Úto_polylines2dr–   r   )r—   rE   r�   r‘   r’   r“   Úpolylines2dÚ
polyline2ds           rH   r+   r+   -  rš   rI   ©Ú	edge_pathr�   r‘   Úg1_tolr’   r“   c               ó’   — t        t        j                  |||||||¬«      «      }|D ]  }	| j                  |	«       Œ t	        |«      S )u/  Render the given `paths` into `layout` as
    :class:`~ezdxf.entities.Hatch` entities.
    The `extrusion` vector is applied to all paths, all vertices are projected
    onto the plane normal to this extrusion vector. The default extrusion vector
    is the WCS z-axis. The plane elevation is the distance from the WCS origin
    to the start point of the first path.

    Args:
        layout: the modelspace, a paperspace layout or a block definition
        paths: iterable of :class:`Path` or :class:`Path2d`  objects
        edge_path: ``True`` for edge paths build of LINE and SPLINE edges,
            ``False`` for only LWPOLYLINE paths as boundary paths
        distance:  maximum distance, see :meth:`Path.flattening`
        segments: minimum segment count per BÃ©zier curve to flatten polyline paths
        g1_tol: tolerance for G1 continuity check to separate SPLINE edges
        extrusion: extrusion vector for all paths
        dxfattribs: additional DXF attribs

    Returns:
        created entities in an :class:`~ezdxf.query.EntityQuery` object

    rŸ   )rr   r"   Ú
to_hatchesr–   r   )
r—   rE   r    r�   r‘   r¡   r’   r“   ÚhatchesÚhatchs
             rH   r.   r.   W  sW   € ôB Ü×ÑØØØØØØØ!ô	
ó
€Gó ˆØ×Ñ˜%Õ ð ä�wÓÐrI   c          	     óŽ   — t        t        j                  |||||¬«      «      }|D ]  }| j                  |«       Œ t	        |«      S )uº  Render the given `paths` into `layout` as
    :class:`~ezdxf.entities.MPolygon` entities. The MPOLYGON entity supports
    only polyline boundary paths. All curves will be approximated.

    The `extrusion` vector is applied to all paths, all vertices are projected
    onto the plane normal to this extrusion vector. The default extrusion vector
    is the WCS z-axis. The plane elevation is the distance from the WCS origin
    to the start point of the first path.

    Args:
        layout: the modelspace, a paperspace layout or a block definition
        paths: iterable of :class:`Path` or :class:`Path2d` objects
        distance:  maximum distance, see :meth:`Path.flattening`
        segments: minimum segment count per BÃ©zier curve to flatten polyline paths
        extrusion: extrusion vector for all paths
        dxfattribs: additional DXF attribs

    Returns:
        created entities in an :class:`~ezdxf.query.EntityQuery` object

    r�   )rr   r"   Úto_mpolygonsr–   r   )r—   rE   r�   r‘   r’   r“   ÚpolygonsÚpolygons           rH   r/   r/   ˆ  sP   € ô< Ü×ÑØØØØØ!ô	
ó€Hó ˆØ×Ñ˜'Õ"ð ä�xÓ Ð rI   ©r�   r‘   r“   c               óŒ   — t        t        j                  ||||¬«      «      }|D ]  }| j                  |«       Œ t	        |«      S )uö  Render the given `paths` into `layout` as 3D
    :class:`~ezdxf.entities.Polyline` entities.

    Args:
        layout: the modelspace, a paperspace layout or a block definition
        paths: iterable of :class:`Path`or :class:`Path2d` objects
        distance:  maximum distance, see :meth:`Path.flattening`
        segments: minimum segment count per BÃ©zier curve
        dxfattribs: additional DXF attribs

    Returns:
        created entities in an :class:`~ezdxf.query.EntityQuery` object

    rª   )rr   r"   Úto_polylines3dr–   r   )r—   rE   r�   r‘   r“   Úpolylines3dÚ
polyline3ds          rH   r,   r,   ´  sM   € ô. Ü× Ñ ØØØØ!ô		
ó€Kó "ˆ
Ø×Ñ˜*Õ%ð "ä�{Ó#Ð#rI   c               óŒ   — t        t        j                  ||||¬«      «      }|D ]  }| j                  |«       Œ t	        |«      S )uï  Render the given `paths` into `layout` as
    :class:`~ezdxf.entities.Line` entities.

    Args:
        layout: the modelspace, a paperspace layout or a block definition
        paths: iterable of :class:`Path`or :class:`Path2d` objects
        distance:  maximum distance, see :meth:`Path.flattening`
        segments: minimum segment count per BÃ©zier curve
        dxfattribs: additional DXF attribs

    Returns:
        created entities in an :class:`~ezdxf.query.EntityQuery` object

    rª   )rr   r"   Úto_linesr–   r   )r—   rE   r�   r‘   r“   ÚlinesÚlines          rH   r-   r-   Ø  sM   € ô, Ü×ÑØØØØ!ô		
ó€Eó ˆØ×Ñ˜$Õð ä�uÓÐrI   ©r¡   r“   c               óŠ   — t        t        j                  |||¬«      «      }|D ]  }| j                  |«       Œ t	        |«      S )aÑ  Render the given `paths` into `layout` as :class:`~ezdxf.entities.Spline`
    and 3D :class:`~ezdxf.entities.Polyline` entities.

    Args:
        layout: the modelspace, a paperspace layout or a block definition
        paths: iterable of :class:`Path`or :class:`Path2d` objects
        g1_tol: tolerance for G1 continuity check
        dxfattribs: additional DXF attribs

    Returns:
        created entities in an :class:`~ezdxf.query.EntityQuery` object

    r³   )rr   r"   Úto_splines_and_polylinesr–   r   )r—   rE   r¡   r“   ÚentitiesÚentitys         rH   r0   r0   û  sJ   € ô( Ü×*Ñ*ØØØ!ô	
ó€Hó ˆØ×Ñ˜&Õ!ð ä�xÓ Ð rI   c                ó¤   — t        |j                  «      dk  ryt        | «      dk(  r|r|j                  | _        t        | t        ||«      «       y)uþ  Add an elliptical arc as multiple cubic BÃ¨zier-curves to the given
    `path`, use :meth:`~ezdxf.math.ConstructionEllipse.from_arc` constructor
    of class :class:`~ezdxf.math.ConstructionEllipse` to add circular arcs.

    Auto-detect the connection point to the given `path`, if neither the start-
    nor the end point of the ellipse is close to the path end point, a line from
    the path end point to the ellipse start point will be added automatically
    (see :func:`add_bezier4p`).

    By default, the start of an **empty** path is set to the start point of
    the ellipse, setting argument `reset` to ``False`` prevents this
    behavior.

    Args:
        path: :class:`~ezdxf.path.Path` object
        ellipse: ellipse parameters as :class:`~ezdxf.math.ConstructionEllipse`
            object
        segments: count of BÃ¨zier-curve segments, at least one segment for
            each quarter (pi/2), ``1`` for as few as possible.
        reset: set start point to start of ellipse if path is empty

    ç•Ö&è.>Nr   )ÚabsÚ
param_spanra   Ústart_pointrb   r1   r   )rn   Úellipser‘   Úresets       rH   r3   r3     sF   € ô2 ˆ7×ÑÓ Ò%ØÜ
ˆ4ƒy�A‚~™%Ø×(Ñ(ˆŒ
Ü�Ô0°¸(ÓCÕDrI   c                óÌ  — d}d}t        |«      }t        |«      sy|d   j                  d   }| j                  j	                  |«      rt        |«      }|D ]Œ  }|j                  \  }}}}|j	                  | j                  «      s| j                  |«       |j	                  |||¬«      r&|j	                  |||¬«      r| j                  |«       Œz| j                  |||«       ŒŽ y)u;  Add multiple cubic BÃ¨zier-curves to the given `path`.

    Auto-detect the connection point to the given `path`, if neither the start-
    nor the end point of the curves is close to the path end point, a line from
    the path end point to the start point of the first curve will be added
    automatically.

    çVçž¯Ò<ç        Néÿÿÿÿ©Úrel_tolÚabs_tol)rr   ra   Úcontrol_pointsrg   Úiscloser   Úline_toÚ	curve4_to)	rn   ÚcurvesrÄ   rÅ   rg   Úcurverb   ri   rj   s	            rH   r1   r1   ;  s×   € ð €GØ€GÜ�&‹\€FÜˆvŒ;ØØ
�‰*×
#Ñ
# BÑ
'€CØ‡x�x×Ñ˜Ôä& vÓ.ˆãˆØ#(×#7Ñ#7Ñ ˆˆu�e˜SØ�}‰}˜TŸX™XÔ&Ø�L‰L˜Ôð �=‰=˜¨¸ˆ=ÔAÀcÇkÁkØ˜7¨Gð GRô G
ð �L‰L˜Õà�N‰N˜3  uÕ-ñ rI   c                óÎ  — d}d}t        |«      }t        |«      sy|d   j                  d   }| j                  j	                  |«      rt        |«      }|D ]�  }|j                  \  }}}|j	                  | j                  ||¬«      s| j                  |«       |j	                  |||¬«      s|j	                  |||¬«      r| j                  |«       Œ|| j                  ||«       Œ� y)u?  Add multiple quadratic BÃ¨zier-curves to the given `path`.

    Auto-detect the connection point to the given `path`, if neither the start-
    nor the end point of the curves is close to the path end point, a line from
    the path end point to the start point of the first curve will be added
    automatically.

    rÀ   rÁ   NrÂ   rÃ   )rr   ra   rÆ   rg   rÇ   r   rÈ   Ú	curve3_to)rn   rÊ   rÄ   rÅ   rg   rË   rb   rl   s           rH   r2   r2   \  s×   € ð €GØ€GÜ�&‹\€FÜˆvŒ;ØØ
�‰*×
#Ñ
# BÑ
'€CØ‡x�x×Ñ˜Ôä& vÓ.ˆãˆØ ×/Ñ/Ñˆˆt�SØ�}‰}˜TŸX™X¨wÀˆ}ÔHØ�L‰L˜Ôà�=‰=˜ w¸ˆ=Ô@ÀCÇKÁKØ˜'¨7ð EPô E
ð �L‰L˜Õà�N‰N˜3 Õ%ñ rI   c                ó  ‡ — dˆ fd„}t        ‰ «      rt        d«      ‚d}d}|D ]S  \  }	}
}t        |«      dk  rd}t        |	|
«      }|€|‰ _        |}|}Œ1|r |||||«       n‰ j                  |«       |}|}ŒU |ri‰ j                  j                  ‰ j                  t        d¬«      s=|r  |‰ j                  ‰ j                  ||«       n‰ j                  ‰ j                  «       |j                  s|r‰ j                  ||«       yy)zYInternal API to add 2D polylines which may include bulges to an
    **empty** path.

    c                óÖ  •— | j                  |t        d¬«      ry t        j                  |dz  «      }t	        | ||«      \  }}}}|t        j
                  z  }|t        j
                  z  }||kD  r|t        j
                  z  }t        t        j                  |||dz   «      «      }	g }
t        |«      D ]q  }t        j                  ||t        t        j                  |	|   «      t        j                  |	|dz      «      «      }|
j                  t        t        |«      «      «       Œs |
d   }|j                   d   }|j                  |t        d¬«      rt#        |
«      }
t%        ‰|
«       y )Nr   rÃ   é   r   )rÇ   ÚIS_CLOSE_TOLr‚   Úceilr   Útaurr   ÚnpÚlinspaceÚranger   Úfrom_arcr   ÚdegreesrY   r   rÆ   r   r1   )Úp1Úp2Úbulger‘   Únum_bezÚcenterÚstart_angleÚ	end_angleÚradiusÚanglesrÊ   Úir½   Úcurve0Úcp0rn   s                  €rH   Úbulge_toz!add_2d_polyline.<locals>.bulge_to‰  s8  ø€ Ø�:‰:�b¤,¸ˆ:Ô:Øä—)‘)˜H q™LÓ)ˆÜ1=¸bÀ"ÀeÓ1LÑ.ˆ�˜Y¨à!¤D§H¡HÑ,ˆØ¤§¡Ñ(ˆ	Ø˜Ò"ØœŸ™Ñ!ˆIÜ”b—k‘k +¨y¸'ÀA¹+ÓFÓGˆØˆÜ�w–ˆAÜ)×2Ñ2ØØÜÜ—‘˜V A™YÓ'Ü—‘˜V A¨¡E™]Ó+óˆGð �M‰Mœ$Ô8¸ÓAÓBÕCð  ð ˜‘ˆØ×#Ñ# AÑ&ˆØ�;‰;�r¤<¸ˆ;Ô;Ü*¨6Ó2ˆFÜ�T˜6Õ"rI   zRequires an empty path.Nr   r�   rÃ   )rÙ   r
   rÚ   r
   rÛ   Úfloatr‘   Úint)ra   ru   rº   r
   rb   rÈ   rÇ   rg   rÑ   rN   Úto_wcs)rn   ro   ÚcloserT   Ú	elevationr‘   rå   Ú
prev_pointÚ
prev_bulger„   r…   rÛ   Úpoints   `            rH   r4   r4   |  sû   ø€ õ#ô8 ˆ4„yÜÐ2Ó3Ð3à!%€JØ€JÛ‰ˆˆ1ˆeäˆu‹:˜ÒØˆEÜ�Q˜“
ˆØÐØˆDŒJØˆJØˆJØáÙ�Z ¨
°HÕ=à�L‰L˜ÔØˆ
Ø‰
ð! ñ$ �T—Z‘Z×'Ñ'¨¯©¼,ÐPQÐ'ÔRÙÙ�T—X‘X˜tŸz™z¨:°xÕ@à�L‰L˜Ÿ™Ô$à
‡}‚}™	Ø�‰�C˜Õ#ð "rI   c                ó2  — t        | «      dk(  r|r|j                  d«      | _        |j                  dk(  r?|j                  s3|j
                  r'|j                  «       D �cg c]  }t        |«      ‘Œ }}n|j                  |¬«      }t        | |«       yc c}w )uÅ  Add a B-spline as multiple cubic BÃ¨zier-curves.

    Non-rational B-splines of 3rd degree gets a perfect conversion to
    cubic BÃ©zier curves with a minimal count of curve segments, all other
    B-spline require much more curve segments for approximation.

    Auto-detect the connection point to the given `path`, if neither the start-
    nor the end point of the B-spline is close to the path end point, a line
    from the path end point to the start point of the B-spline will be added
    automatically. (see :meth:`add_bezier4p`).

    By default, the start of an **empty** path is set to the start point of
    the spline, setting argument `reset` to ``False`` prevents this
    behavior.

    Args:
        path: :class:`~ezdxf.path.Path` object
        spline: B-spline parameters as :class:`~ezdxf.math.BSpline` object
        level: subdivision level of approximation segments
        reset: set start point to start of spline if path is empty

    r   rÐ   )ÚlevelN)
ra   rí   rb   ÚdegreeÚis_rationalÚ
is_clampedÚbezier_decompositionr   Úcubic_bezier_approximationr1   )rn   Úsplinerï   r¾   ro   rÊ   s         rH   r5   r5   Æ  sƒ   € ô. ˆ4ƒy�A‚~™%Ø—\‘\ !“_ˆŒ
à‡}�}˜Ò &×"4Ò"4¸×9JÒ9JØ17×1LÑ1LÔ1NÓOÑ1N v”(˜6Õ"Ð1NˆÑOà×2Ñ2¸Ð2Ó?ˆÜ��vÕùò Ps   Á Br¹   çê-�™—q=rÃ   c               ó|   ‡‡— t        ˆˆfd„t        | j                  «       |j                  «       «      D «       «      S )zBReturns ``True`` if the control vertices of given paths are close.c              3  óL   •K  — | ]  \  }}|j                  |‰‰¬ «      –— Œ y­w)rÃ   N)rÇ   )Ú.0Úcp_aÚcp_brÅ   rÄ   s      €€rH   Ú	<genexpr>z.have_close_control_vertices.<locals>.<genexpr>ë  s,   øè ø€ ð áI‰JˆD�$ð 	�‰�T 7°Gˆ×<ÙIùs   ƒ!$)ÚallÚziprZ   )ÚaÚbrÄ   rÅ   s     ``rH   r8   r8   ç  s8   ù€ ô ô ä˜a×0Ñ0Ó2°A×4FÑ4FÓ4HÔIóó ð rI   c                ó   — t        | d¬«      S )u^   Replaces all lines by quadratic BÃ©zier curves.
    Returns a new :class:`Path` instance.
    rÐ   ©Úcount©Ú_all_lines_to_curve©rn   s    rH   r9   r9   ñ  ó   € ô ˜t¨1Ô-Ð-rI   c                ó   — t        | d¬«      S )uZ   Replaces all lines by cubic BÃ©zier curves.
    Returns a new :class:`Path` instance.
    rB   r  r  r  s    rH   r:   r:   ø  r  rI   c                ó\  — |dk(  s|dk(  s
J d|› �«       ‚| j                  «       }t        |«      }|dk(  r
t        «       S | j                  }t        j
                  }t        | j                  «      }|D ]·  }|j                  |k(  r‰|j                  |j                  «      r|dk(  rz|j                  |«       |c S t        ||j                  |«      }|dk(  r|j                  |d   |d   ¬«       n/|j                  |d   |d   |d   ¬«       n|j                  |«       |j                  }Œ¹ |S )	NrB   rÐ   zinvalid count: r   r   é   )rl   )ri   rj   )rc   ra   r    rb   r!   re   rd   rÇ   rg   Úappend_path_elementr   rÍ   rÉ   )	rn   r  Úcmdsrs   rb   rÈ   Únew_pathrp   Úverticess	            rH   r  r  ÿ  s#  € Ø�AŠ:˜ !šÐ> °u°gÐ%>Ó>Ð#à�=‰=‹?€DÜˆt‹9€DØˆq‚yÜ‹vˆØ�J‰J€EÜ�o‰o€GÜ�D—J‘JÓ€HÛˆØ�8‰8�wÒØ�}‰}˜SŸW™WÔ%Ø˜1’9ð ×0Ñ0°Ô5Ø#’Oô 1°¸¿¹ÀÓG�Ø˜A’:Ø×&Ñ& x°¡{¸À!¹Ð&ÕEà×&Ñ&Ø  ™Ø& q™kØ& q™kð 'õ ð ×(Ñ(¨Ô-Ø—‘‰ð1 ð2 €OrI   c                ó¤  — | |z
  j                  «       }||z
  j                  «       }|j                  |«      s|j                  | «      rt        ‚|j                  |«      }t	        |||«      }|||z  z   }|j                  |«      }	|	j                  | «      j                  |«      }
||
z   }t        ||
 |	¬«      }|t        j                  |z
  |fS )N)ÚoriginÚuxÚuz)	Ú	normalizerÇ   ÚZeroDivisionErrorÚangle_betweenr   Úcrossr   r‚   Úpi)Úp0rÙ   rÚ   rà   Údir1Údir2ÚangleÚtangent_lengthÚarc_start_pointÚlocal_z_axisÚ
radius_vecÚ
arc_centerÚucss                rH   Ú_get_local_fillet_ucsr"  %  sÐ   € Ø�‰G×ÑÓ €DØ�‰G×ÑÓ €DØ‡|�|�DÔ˜TŸ\™\¨4¨%Ô0ÜÐð ×Ñ˜tÓ$€EÜ3°D¸$ÀÓG€Nà˜D >Ñ1Ñ2€Oð
 —:‘:˜dÓ#€Là×#Ñ# T EÓ*×4Ñ4°VÓ<€JØ  :Ñ-€JÜ
�Z Z K°LÔ
A€CØœDŸG™G e™O¨SÐ0Ð0rI   c                óX  ‡— t        | «      dk  rt        d«      ‚‰dk  rt        d‰› �«      ‚t        | | dd «      D ��cg c]	  \  }}||f‘Œ }}}t        | d   «      }t        ||dd «      D ]  \  \  }}\  }}	 t	        |||‰«      \  }}	}
|j                  |«       t        d|	«      D ]A  }t        |
j                  ˆfd„|D «       «      «      }|j                  |d   |d   |d	   «       ŒC Œ� |j                  | d   «       |S c c}}w # t
        $ r |j                  |«       Y Œºw xY w)
zÃReturns a :class:`Path` with circular fillets of given `radius` between
    straight line segments.

    Args:
        points: coordinates of the line segments
        radius: fillet radius

    rÐ   ú)at least 3 not coincident points requiredr   úinvalid radius: r   Nc              3  ó(   •K  — | ]	  }|‰z  –— Œ y ­w)N© )rù   Úvrà   s     €rH   rü   zfillet.<locals>.<genexpr>V  s   øè ø€ Ð0LÁVÀ°°VµÁVùs   ƒrÂ   r
  )ra   ru   rþ   r    r"  r  rÈ   r   ÚtupleÚpoints_to_wcsrÉ   )ro   rà   r  rÙ   r±   rG   rÚ   Úp3r¼   r  r!  ÚparamsÚ
bez_pointss    `           rH   r;   r;   <  s?  ø€ ô ˆ6ƒ{�Q‚ÜÐDÓEÐEØ�‚{ÜÐ+¨F¨8Ð4Ó5Ð5Ü$'¨°°q°r°
Ô$;Ô<Ñ$;™&˜"˜bˆb�"ŠXÐ$;€EÑ<ÜˆV�A‰Y‹€AÜ! %¨¨q¨r¨Ö3Ñ‰ˆˆR‘(�2�rð	Ü&;¸BÀÀBÈÓ&OÑ#ˆK˜ ð 	
�	‰	�+ÔÜ1°!°UÖ;ˆFä˜s×0Ñ0Ó0LÁVÓ0LÓLÓMˆJØ�K‰K˜
 2™¨
°1©°zÀ!±}ÕEñ <ð 4ð ‡I�Iˆf�R‰jÔØ€Hùó! =øô
 !ò 	Ø�I‰I�bŒMÙð	ús   Á DÁ;DÄD)Ä(D)c                ól   — t        d|«      }t        t        | t        j                  |z  z  «      d«      S )NrB   r   )Úmaxrç   r‚   rÓ   )r  r  s     rH   Ú_segment_countr0  \  s-   € Ü��5‹M€EÜŒs�5œDŸH™H uÑ,Ñ-Ó.°Ó2Ð2rI   c                óN  — t        | «      dk  rt        d«      ‚|dk  rt        d|› �«      ‚t        | | dd «      D ��cg c]	  \  }}||f‘Œ }}}t        | d   «      }t        ||dd «      D ]{  \  \  }}\  }}	 t	        ||||«      \  }	}
}t        |
|«      }|
|z  }t        |dz   «      D ];  }t        j                  ||z  |«      }|j                  |j                  |«      «       Œ= Œ} |j                  | d   «       |S c c}}w # t
        $ r |j                  |«       Y Œ¶w xY w)a`  
    Returns a :class:`Path` with polygonal fillets of given `radius` between
    straight line segments. The `count` argument defines the vertex count of the
    fillet for a full circle.

    Args:
        points: coordinates of the line segments
        radius: fillet radius
        count: polygon vertex count for a full circle, minimum is 4

    rÐ   r$  r   r%  r   NrÂ   )ra   ru   rþ   r    r"  r  rÈ   r0  rÖ   r
   Ú
from_anglerè   )ro   rà   r  r  rÙ   r±   rG   rÚ   r+  Ú_r  r!  r‘   Údeltarâ   r  s                   rH   r<   r<   a  s;  € ô ˆ6ƒ{�Q‚ÜÐDÓEÐEØ�‚{ÜÐ+¨F¨8Ð4Ó5Ð5Ü$'¨°°q°r°
Ô$;Ô<Ñ$;™&˜"˜bˆb�"ŠXÐ$;€EÑ<ÜˆV�A‰Y‹€AÜ! %¨¨q¨r¨Ö3Ñ‰ˆˆR‘(�2�rð	Ü1°"°b¸"¸fÓE‰MˆAˆu�cô " %¨Ó/ˆØ˜Ñ ˆä�x !‘|Ö$ˆAÜŸ™¨¨U©°FÓ;ˆJØ�I‰I�c—j‘j Ó,Õ-ñ %ð 4ð ‡I�Iˆf�R‰jÔØ€Hùó! =øô
 !ò 	Ø�I‰I�bŒMÙð	ús   ¿DÁ:DÄD$Ä#D$c                ó´  — t        | «      dk  rt        d«      ‚t        | | dd «      D ��cg c]	  \  }}||f‘Œ }}}t        | d   «      }t        ||dd «      D ]Á  \  \  }}\  }}	 ||z
  j	                  «       }||z
  j	                  «       }	|j                  |	«      s|j                  |	 «      rt        ‚|j                  |	«      dz  }
t        |dz  t        j                  |
«      z  «      }|j                  |||z  z   «       |j                  ||	|z  z   «       ŒÃ |j                  | d   «       |S c c}}w # t        $ r |j                  |«       Y Œüw xY w)zÁ
    Returns a :class:`Path` with chamfers of given `length` between
    straight line segments.

    Args:
        points: coordinates of the line segments
        length: chamfer length

    rÐ   r$  r   Nr   g       @rÂ   )ra   ru   rþ   r    r  rÇ   r  r  rº   r‚   ÚsinrÈ   )ro   Úlengthr  rÙ   r±   rG   rÚ   r+  r  r  r  rÿ   s               rH   r=   r=   „  sT  € ô ˆ6ƒ{�Q‚ÜÐDÓEÐEÜ$'¨°°q°r°
Ô$;Ô<Ñ$;™&˜"˜bˆb�"ŠXÐ$;€EÑ<ÜˆV�A‰Y‹€AÜ! %¨¨q¨r¨Ö3Ñ‰ˆˆR‘(�2�rð		Ø˜‘G×&Ñ&Ó(ˆDØ˜‘G×&Ñ&Ó(ˆDØ�|‰|˜DÔ! T§\¡\°4°%Ô%8Ü'Ð'Ø×&Ñ& tÓ,¨sÑ2ˆEÜ�V˜c‘\¤T§X¡X¨e£_Ñ4Ó5ˆAð 	
�	‰	�"˜˜q™‘/Ô"Ø	�	‰	�"˜˜q™‘/Õ"ð 4ð ‡I�Iˆf�R‰jÔØ€Hùó# =øô !ò 	Ø�I‰I�bŒMÙð	ús   ¬D4Á'BD:Ä:EÅEc                óF  — t        | «      dk  rt        d«      ‚t        | | dd «      D ��cg c]	  \  }}||f‘Œ }}}t        | d   «      }t        ||dd «      D ]Š  \  \  }}\  }}	 ||z
  j	                  «       }	||z
  j	                  «       }
|	j                  |
«      s|	j                  |
 «      rt        ‚	 |j                  ||	|z  z   «       |j                  ||
|z  z   «       ŒŒ |j                  | d   «       |S c c}}w # t        $ r |j                  |«       Y ŒÅw xY w)aQ  
    Returns a :class:`Path` with chamfers at the given distances `a` and `b`
    from the segment points between straight line segments.

    Args:
        points: coordinates of the line segments
        a: distance of the chamfer start point to the segment point
        b: distance of the chamfer end point to the segment point

    rÐ   z)at least 3 non-coincident points requiredr   Nr   rÂ   )ra   ru   rþ   r    r  rÇ   r  rÈ   )ro   rÿ   r   r  rÙ   r±   rG   rÚ   r+  r  r  s              rH   r>   r>   ¤  s)  € ô ˆ6ƒ{�Q‚ÜÐDÓEÐEÜ$'¨°°q°r°
Ô$;Ô<Ñ$;™&˜"˜bˆb�"ŠXÐ$;€EÑ<ÜˆV�A‰Y‹€AÜ! %¨¨q¨r¨Ö3Ñ‰ˆˆR‘(�2�rð	Ø˜‘G×&Ñ&Ó(ˆDØ˜‘G×&Ñ&Ó(ˆDØ�|‰|˜DÔ! T§\¡\°4°%Ô%8Ü'Ð'ð &9ð
 	
�	‰	�"˜˜q™‘/Ô"Ø	�	‰	�"˜˜q™‘/Õ"ð 4ð ‡I�Iˆf�R‰jÔØ€Hùó =øô !ò 	Ø�I‰I�bŒMÙð	ús   ¬C=Á'ADÄD ÄD c              #  óö   K  — t        j                  t        | «      «      D ]M  }|d   j                  ||«      }|dd D �cg c]  }|j                  ||«      ‘Œ }}t	        ||«      E d{  –—†  ŒO yc c}w 7 Œ­w)uÅ  Tessellate nested 2D paths into triangle-faces. For 3D paths the
    projection onto the xy-plane will be triangulated.

    Args:
        paths: iterable of nested Path instances
        max_sagitta: maximum distance from the center of the curve to the
            center of the line segment between two approximation points to determine if
            a segment should be subdivided.
        min_segments: minimum segment count per BÃ©zier curve

    r   r   N)r#   Úgroup_pathsr7   Ú
flatteningr   )rE   Úmax_sagittaÚmin_segmentsr©   ÚexteriorrG   Úholess          rH   r?   r?   Ã  ss   è ø€ ô ×&Ñ&¤|°EÓ':Ö;ˆØ˜1‘:×(Ñ(¨°lÓCˆØBIÈ!È"Á+ÓNÁ+¸Q�—‘˜k¨<Õ8À+ˆÐNÜ# H¨eÓ4×4Ñ4ñ <ùâNØ4ús   ‚>A9Á A2ÁA9Á*A7Á+A9c                óÈ  — | j                  «       }t        |«      dk  ry|d   j                  |d   «      r|j                  «        t        |«      dk7  ry|r<|d   |d   z
  }t	        |j
                  «      dk  st	        |j                  «      dk  sy|d   j                  |d   «      }|d   j                  |d   «      }t        j                  ||«      sy|d   j                  |d   «      }|d   j                  |d   «      }t        j                  ||«      sy|d   j                  |d   «      }|d   j                  |d   «      }t        j                  ||«      syy	)
zÌReturns ``True`` if `path` is a rectangular quadrilateral (square or
    rectangle). If the argument `aligned` is ``True`` all sides of the
    quadrilateral have to be parallel to the x- and y-axis.
    rB   Fr   rÂ   r   rö   r
  rÐ   T)	rZ   ra   rÇ   Úpoprº   r„   r…   r�   r‚   )rn   Úalignedro   Ú
first_sideÚv1Úv2s         rH   r@   r@   ×  sO  € ð
 ×"Ñ"Ó$€FÜ
ˆ6ƒ{�Q‚ØØˆa�y×Ñ˜ ™Ô$Ø�
‰
ŒÜ
ˆ6ƒ{�aÒØáØ˜A‘Y ¨¡Ñ*ˆ
Ü�J—L‘LÓ! EÒ)¬S°·±Ó->ÀÒ-FØð 
�‰×	Ñ	˜F 1™IÓ	&€BØ	�‰×	Ñ	˜F 1™IÓ	&€BÜ�<‰<˜˜BÔØà	�‰×	Ñ	˜F 1™IÓ	&€BØ	�‰×	Ñ	˜F 1™IÓ	&€BÜ�<‰<˜˜BÔØà	�‰×	Ñ	˜F 1™IÓ	&€BØ	�‰×	Ñ	˜F 1™IÓ	&€BÜ�<‰<˜˜BÔØàrI   )rE   úIterable[Path]Úreturnr    )rE   rF  rG  rF  )rE   rF  rO   r   rG  ú
list[Path])rE   rF  rT   r   rG  rH  )rE   rF  rG  r   )rn   r    rG  r   )TN)
rE   rF  rs   ztuple[float, float, float]ry   Úboolrz   zOptional[BoundingBox]rG  rH  )rˆ   r
   r|   r
   )r—   r$   rE   rF  r�   ræ   r‘   rç   r’   r   rG  r   )r—   r$   rE   rF  r    rI  r�   ræ   r‘   rç   r¡   ræ   r’   r   rG  r   )
r—   r$   rE   rF  r�   ræ   r‘   rç   rG  r   )r—   r$   rE   rF  r¡   ræ   rG  r   )r   T)rn   r    r½   r   rG  ÚNone)rn   r    rÊ   zIterable[Bezier4P]rG  rJ  )rn   r    rÊ   zIterable[Bezier3P]rG  rJ  )r   )rn   r    ro   zIterable[Sequence[float]]ré   rI  rT   r   rê   ræ   r‘   rç   rG  rJ  )rB   T)rn   r    rõ   r   rG  rJ  )rÿ   r    r   r    rG  rI  )rn   r    rG  r    )rB   )rn   r    r  rç   rG  r    )rG  ztuple[Vec3, float, UCS])ro   úSequence[Vec3]rà   ræ   rG  r    )r  ræ   r  rç   rG  rç   )é    )ro   rK  rà   ræ   r  rç   rG  r    )ro   rK  r7  ræ   rG  r    )ro   rK  rÿ   ræ   r   ræ   rG  r    )rA   é   )rE   rF  r<  ræ   r=  rç   rG  zIterator[Sequence[Vec2]])T)rn   r    rG  rI  )SÚ
__future__r   Útypingr   r   r   r   r   r‚   ÚnumpyrÔ   Ú
ezdxf.mathr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Úezdxf.math.triangulationr   Úezdxf.queryr   rn   r    rc   r!   Ú r"   r#   Úezdxf.eztypesr$   Ú__all__ÚMAX_DISTANCEÚMIN_SEGMENTSÚG1_TOLrÑ   r6   r7   r(   r)   r%   r&   r'   rv   rw   r*   r+   r.   r/   r,   r-   r0   r3   r1   r2   r4   r5   r8   r9   r:   r  r"  r;   r0  r<   r=   r>   r?   r@   r'  rI   rH   Ú<module>rZ     së  ðõ #÷õ ó Û ÷÷ ÷ ÷ ÷ ó õ, 6Ý #å Ý ß  áÝ'Ý/ò€ð> €Ø€Ø	€Ø€óóó	+ó%ð ).õ ó*ð: Ø(,ð	)%Øð)%à
$ð)%ð ð)%ð &ð	)%ð
 ó)%óX%ó*%ð* #Ø ØØñ'$Øð'$àð'$ð ð	'$ð
 ð'$ð ð'$ð ó'$ð\ ØØØñ'$Øð'$àð'$ð ð	'$ð
 ð'$ð ð'$ð ó'$ð\ Ø"Ø ØØØñ. Øð. àð. ð ð	. ð
 ð. ð ð. ð ð. ð ð. ð ó. ðj #Ø ØØñ)!Øð)!àð)!ð ð	)!ð
 ð)!ð ð)!ð ó)!ð` #Ø Øñ!$Øð!$àð!$ð ð	!$ð
 ð!$ð ó!$ðP #Ø Øñ Øð àð ð ð	 ð
 ð ð ó ðN Øñ!Øð!àð!ð ð	!ð ó!ðB AEðEØ
ðEØ,ðEà	óEó@.óB&ðL ðG$Ø
ðG$à%ðG$ð ðG$ð 
ð	G$ð
 ðG$ð ðG$ð 
óG$ôTðD "&¨uñØðØðà	óó.ó.ô#óL1ó.ó@3ô
 óFó@ð@ KMð5Øð5Ø(-ð5ØDGð5àó5õ("rI   