
    Og                    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{Gz?   g-C6?g|=c                J    t               }| D ]  }|j                  |        |S )zReturns 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      U/var/www/html/public_html/myphp/venv/lib/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   _   s3      ??{{}$$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      %**qAKKN***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KKM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%      sb     -C 3JJq))+,aB{{

BIIryy123 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&      s;   
4yA~}JJEF}} 88w&MM#''"XX***"%CIIsww?@B MM"))$MM"))$XX***&x#''0J'KLBMM"))$MM"))$XX(MM#''"" 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    . KE
5zQ5t, ;#3#3y#@t*Ki3{#3a#7.//)+*:*:KH
B-k.>.>L
Br2r"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hhG~~ 3--,..0hhG~~ 3--,..0hhG~~ 3--,..0'2M .//*}}s2mG*}}s2mG*}}s2mGGW$$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GW$$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*     U    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  s\    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/     sU    < !	
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,     sR    .   !		
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-     sR    , !		
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     sO    ( **!	
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%
4yA~%((
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xx&v. .#(#7#7 ueS}}TXX&LL ===Ackk7G GR G
 LLNN3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xx&v. 
& //tS}}TXXw}HLL==w=@CKK'7 EP E
 LLNN3%
&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  s?   ::b,::))HqL)1=b"e1L.Y!DHH,(	"!Ibkk+y'A+FGw 	DA)22VAY'VAE]+G MM$8ABC	D ##A&;;r<;;*62FT6"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 4y233!%JJ 1eu:EQ
DJJJZ
H=LL

!$ TZZ'',PQ'RTXXtzz:x@LL$
}}	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    . 4yA~%\\!_
}}&"4"49J9J171L1L1NOv(6"O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,      D$ 	T7G<s   !$)allziprZ   )abr   r   s     ``rH   r8   r8     s8      a002A4F4F4H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          t1--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:!>ug%>>#==?Dt9DqyvJJEooGDJJH 88w}}SWW%19 005#O 1GA:&&x{!&E&& &qk&qk '  ((-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3D$GND>12O
 ::d#L##TE*44V<J :-J
ZZKL
ACDGGeOS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)
zReturns 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0Ls   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;   <  sJ    6{QDEE{+F8455$'qr
$;<&"bb"X<E<VAYA!%qr3 FR(2r	&;BB&O#K 	
		+1!U; 	FFs000LV0LLMJKK
2
1z!}E	FF IIfRjH! =
 ! 	IIbM	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-    5MEs5DHHu,-.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  sB    6{QDEE{+F8455$'qr
$;<&"bb"X<E<VAYA!%qr3 .R(2r	1"b"fEMAuc "%/ x!|$ 	.AUF;JIIcjj,-	.. IIfRjH! =
 ! 	IIbM	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=     sV    6{QDEE$'qr
$;<&"bb"X<E<VAYA!%qr3 #R(2r		G&&(DG&&(D||D!T\\4%%8''&&t,s2EVc\TXXe_45A 	
		"q/"			"q/"# IIfRjH# = ! 	IIbM	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$'qr
$;<&"bb"X<E<VAYA!%qr3 #R(2r	G&&(DG&&(D||D!T\\4%%8'' &9
 	
		"q/"			"q/"# IIfRjH = ! 	IIbM	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?     sw      &&|E':; 51:((lCBI!"+NQk<8NN#He4445N4s   >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	)
zReturns ``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ay$


6{aAY*
JLL!E)S->-F 
		F1I	&B			F1I	&B<<B			F1I	&B			F1I	&B<<B			F1I	&B			F1I	&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(-5DG55("rI   