
    OgՉ              
      
   U d Z ddlmZ ddlmZmZmZmZmZ ddl	m
Z
 ddlZddl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 ddlm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& g dZ'dZ(dZ)dZ*ejV                  Z+ejX                  dUd       Z-e-j]                  ej^                        dVd       Z0e-j]                  ejb                        dWd       Z2e-j]                  ejf                        dXd       Z4e-j]                  ejj                        dYd       Z6e-j]                  ejn                        dZd       Z8e-j]                  ejr                        d[d       Z:e-j]                  ejv                        d\d       Z<e-j]                  ejz                        e-j]                  ej|                        d]d              Z?ejX                  dUd       Z@e@j]                  ej                        d^d       ZBe@j]                  ejb                        e@j]                  ej^                        d_d              ZCe@j]                  ejf                        dXd       ZDe@j]                  ejj                        dYd       ZEe@j]                  ejn                        dZd       ZFe@j]                  ejr                        d[d       ZGe@j]                  ejv                        d\d        ZHe@j]                  ejz                        e@j]                  ej|                        d]d!              ZId`d"ZJd`d#ZKd`d$ZLdad%ZMejX                  e+d&dbd'       ZNeNj]                  ej                        e+d&dcd(       ZOeNj]                  ej^                        e+d&ddd)       ZPeNj]                  ejf                        e+d&ded*       ZQeNj]                  ejj                        e+d&dfd+       ZReNj]                  ejn                        e+d&dgd,       ZSeNj]                  ejr                        e+d&dhd-       ZTe+d&	 	 	 did.ZUe+d&djd/ZVdd0d1	 	 	 	 	 	 	 dkd2ZWdd0d1	 	 	 	 	 	 	 dld3ZXeYeZee[f      Z\d4e]d5<   dmd6Z^	 	 	 	 	 	 	 	 dnd7Z_dod8Z`dod9Zadpd:Zbdqd;Zcdod<Zddod=Zedod>Zfdrd?Zgdsd@Zhej^                  e`ejf                  eaejj                  edejn                  eeejr                  efiZidtdAZjd0dBdCdD	 	 	 	 	 	 	 dudEZkd0dCdF	 	 	 	 	 	 	 dvdGZl	 	 	 	 	 	 	 	 dwdHZm	 	 	 	 	 	 	 	 	 	 dxdIZn	 	 	 	 	 	 	 	 	 	 dydJZo	 	 	 	 	 	 	 	 dzdKZpd{dLZq	 	 	 	 	 	 	 	 	 	 d|dMZrd}dNZs G dO dPe      Ztd~dQZu	 d	 	 	 	 	 	 	 ddRZve+d&	 	 	 	 	 ddSZwe+d&ddTZxy)z
EdgeSmith
=========

A module for creating entities like polylines and hatch boundary paths from linked edges.

The complementary module to ezdxf.edgeminer.

    )annotations)IteratorIterableSequenceAny
NamedTuple)	TypeAliasN)
itemgetter)	edgeminerentities)path)boundary_paths)upright_all)UVecVec2Vec3arc_angle_span_degellipse_param_spanbulge_from_arc_angleZ_AXISMatrix44intersection_line_line_2dis_point_in_polygon_2dBoundingBox2darea)bounding_box_2dchain_verticesedge_path_from_chainedges_from_entities_2dfilter_2d_entitiesfilter_edge_entitiesfilter_open_edgesintersecting_edges_2dis_closed_entityis_inside_polygon_2dis_pure_2d_entity	loop_arealwpolyline_from_chainmake_edge_2dpath2d_from_chainpolyline2d_from_chainpolyline_path_from_chaing&.>gHz>c                     y)aE  Returns ``True`` if the given entity represents a closed loop.

    Tests the following DXF entities:

        - CIRCLE (radius > 0)
        - ARC
        - ELLIPSE
        - SPLINE
        - LWPOLYLINE
        - POLYLINE
        - HATCH
        - SOLID
        - TRACE

    Returns ``False`` for all other DXF entities.
    F entitys    T/var/www/html/public_html/myphp/venv/lib/python3.12/site-packages/ezdxf/edgesmith.pyr%   r%   E   s    $     c                   t        | j                  j                        }| j                  j                  }| j                  j                  }t        ||      }t        |      t        kD  xr t        j                  |dt              S )Ng     v@abs_tol)	absdxfradiusstart_angle	end_angler   LEN_TOLmathisclose)r1   r9   r:   r;   
angle_spans        r2   _is_closed_arcr@   Z   sa    ""#F**((K

$$I#K;Jv; UT\\*eW%UUr3   c                N    t        | j                  j                        t        kD  S N)r7   r8   r9   r<   r0   s    r2   _is_closed_circlerC   c   s    vzz  !G++r3   c                    | j                   j                  }| j                   j                  }t        ||      }t	        j
                  |t        j                  t              syy)Nr5   FT)r8   start_param	end_paramr   r=   r>   tauRAD_TOL)r1   rE   rF   spans       r2   _is_closed_ellipserJ   h   sF    **((K

$$Ik95D<<dhh8r3   c                    	 | j                         }|j                  }t        |      dk  ry|d   }|d   }|j	                  |t
              S # t        $ r Y yw xY w)NF   r   r5   )construction_tool
ValueErrorcontrol_pointslenr>   r<   )r1   bsplinerP   startends        r2   _is_closed_splinerU   r   sm    **, ++N
>Q1E

C==g=..  s   A 	AAc                    t        |       dk  ry| j                  du ryt        | j                  d   d d       }t        | j                  d   d d       }|j	                  |t
              S )N   FTr      rM   r5   )rQ   closedr   lwpointsr>   r<   )r1   rS   rT   s      r2   _is_closed_lwpolyliner[      sf    
6{Q}}#BQ'(E
vr"2A&
'C==g=..r3   c                   | j                   s| j                  rr| j                  }t        |      dk  ry| j                  ry|d   j
                  j                  }|d   j
                  j                  }|j                  |t              ryy)NrX   FTr   rM   r5   )	is_2d_polylineis_3d_polylineverticesrQ   	is_closedr8   locationr>   r<   )r1   r_   p0p1s       r2   _is_closed_polyline2drd      sw     5 5 ??x=1A;??++B<##,,::b':*r3   c                >    t        t        | j                              S rB   )boolrQ   pathsr0   s    r2   _is_closed_hatchrh      s    FLL!""r3   c                     y)NTr/   r0   s    r2   _is_closed_solidrj      s     r3   c                     y)a  Returns ``True`` if the given entity represents a pure 2D entity in the
    xy-plane of the WCS.

    - All vertices must be in the xy-plane of the WCS.
    - Thickness must be 0.
    - The extrusion vector must be (0, 0, 1).
    - Entities with inverted extrusions vectors (0, 0, -1) are **not** pure 2D entities.
      The ezdxf.upright module can be used to revert inverted extrusion vectors
      back to (0, 0, 1).

    Tests the following DXF entities:

        - LINE
        - CIRCLE
        - ARC
        - ELLIPSE
        - SPLINE
        - LWPOLYLINE
        - POLYLINE
        - HATCH
        - SOLID
        - TRACE

    Returns ``False`` for all other DXF entities.

    Fr/   r0   s    r2   r'   r'      s    8 r3   c                   t        j                  | j                  j                        syt	        | j                  j
                        t        kD  ryt	        t        | j                  j                        j                        t        kD  ryt	        t        | j                  j                        j                        t        kD  ryyNFT)r   r>   r8   	extrusionr7   	thicknessr<   r   rS   zrT   r0   s    r2   _is_pure_2d_entityrq      s    >>&**../
6:: 7*
4

  !##$w.
4

!!"W,r3   c                h   t        j                  | j                  j                        syt	        t        | j                  j                        j                        t        kD  ryt	        | j                  j                        t        kD  ryt	        | j                  j                        t        kD  ryyrm   )r   r>   r8   rn   r7   r   centerrp   r<   	elevationro   r0   s    r2   _is_pure_2d_arcru      sy     >>&**../
4

!!"$$%/
6:: 7*
6:: 7*r3   c                    t        j                  | j                  j                        syt	        t        | j                  j                        j                        t        kD  ryyrm   )	r   r>   r8   rn   r7   r   rs   rp   r<   r0   s    r2   _is_pure_2d_ellipserw      sC    >>&**../
4

!!"$$%/r3   c                    t        j                  | j                  j                        sy	 | j	                         }t        d |j                  D              ryy# t
        $ r Y yw xY w)NFc              3  T   K   | ]   }t        |j                        t        kD   " y wrB   r7   rp   r<   .0vs     r2   	<genexpr>z%_is_pure_2d_spline.<locals>.<genexpr>   s     
9!3qss8g
9   &(T)r   r>   r8   rn   rN   rO   anyrP   )r1   cts     r2   _is_pure_2d_spliner      s^    >>&**../%%' 
9r'8'8
99	  s   A 	A&%A&c                    t        j                  | j                  j                        syt	        | j                  j
                        t        kD  ryt	        | j                  j                        t        kD  ryyrm   )r   r>   r8   rn   r7   rt   r<   ro   r0   s    r2   _is_pure_2d_lwpolyliner      sR    >>&**../
6:: 7*
6:: 7*r3   c                    | j                   s| j                  ryt        d | j                         D              ryt	        | j
                  j                        t        kD  ryy)NFc              3  T   K   | ]   }t        |j                        t        kD   " y wrB   rz   r{   s     r2   r~   z'_is_pure_2d_polyline.<locals>.<genexpr>  s     
>!3qss8g
>r   T)is_polygon_meshis_poly_face_meshr   points_in_wcsr7   r8   ro   r<   r0   s    r2   _is_pure_2d_polyliner     sM    !9!9

>v';';'=
>>
6:: 7*r3   c                    t        j                  | j                  j                        syt	        t        | j                  j                        j                        t        kD  ryyrm   )	r   r>   r8   rn   r7   r   rt   rp   r<   r0   s    r2   _is_pure_2d_hatchr     sC    >>&**../
4

$$%''(72r3   c                6   t        j                  | j                  j                        syt	        | j                  j
                        t        kD  ryt	        | j                  j                        t        kD  ryt        d | j                         D              ryy)NFc              3  T   K   | ]   }t        |j                        t        kD   " y wrB   rz   r{   s     r2   r~   z$_is_pure_2d_solid.<locals>.<genexpr>   s     
=!3qss8g
=r   T)
r   r>   r8   rn   r7   rt   r<   ro   r   wcs_verticesr0   s    r2   _is_pure_2d_solidr     sn     >>&**../
6:: 7*
6:: 7*

=v':':'<
==r3   c                    d | D        S )a'  Returns all entities that can be used to build edges in the context of
    :mod:`ezdxf.edgeminer`.

    Returns the following DXF entities:

        - LINE
        - ARC
        - ELLIPSE
        - SPLINE
        - LWPOLYLINE
        - POLYLINE

    .. note::

        - CIRCLE, TRACE and SOLID are closed shapes by definition and cannot be used as
          edge in the context of :mod:`ezdxf.edgeminer` or :mod:`ezdxf.edgesmith`.
        - This filter is not limited to pure 2D entities!
        - Does not test if the entity is a closed loop!

    c           
   3     K   | ]l  }t        |t        j                  t        j                  t        j                  t        j
                  t        j                  t        j                  f      r| n y wrB   )
isinstanceetLineArcEllipseSpline
LWPolylinePolyline)r|   r1   s     r2   r~   z'filter_edge_entities.<locals>.<genexpr>:  sR      

		

 	s   A2A4r/   r   s    r2   r"   r"   %  s    * r3   c                    d | D        S )zReturns all pure 2D entities, ignores all entities placed outside or extending
    beyond the xy-plane of the :ref:`WCS`. See :func:`is_pure_2d_entity` for more
    information.

    c              3  8   K   | ]  }t        |      r|  y wrB   )r'   r|   es     r2   r~   z%filter_2d_entities.<locals>.<genexpr>Q  s     <!'8';A<   r/   r   s    r2   r!   r!   K  s     =x<<r3   c                *    t        |       }d |D        S )aQ  Returns all open linear entities usable as edges in the context of
    :mod:`ezdxf.edgeminer` or :mod:`ezdxf.edgesmith`.

    Ignores all entities that represent closed loops like circles, closed arcs, closed
    ellipses, closed splines and closed polylines.

    .. note::

        This filter is not limited to pure 2D entities!

    c              3  8   K   | ]  }t        |      r|  y wrB   )r%   r   s     r2   r~   z$filter_open_edges.<locals>.<genexpr>a  s     8!$4Q$7A8r   )r"   )r   edgess     r2   r#   r#   T  s     !*E8u88r3   c                x    | j                   j                  | j                        |k  ry | j                  |k  ry | S rB   )rS   distancerT   length)edgegap_tols     r2   _validate_edger   d  s4    zz488$w.{{WKr3   r   c                    y)aB  Makes an Edge instance from the following DXF entity types:

        - LINE (length accurate)
        - ARC (length accurate)
        - ELLIPSE (length approximated)
        - SPLINE (length approximated as straight lines between control points)
        - LWPOLYLINE (length of bulges as straight line from start- to end point)
        - POLYLINE (length of bulges as straight line from start- to end point)

    The start- and end points of the edge is projected onto the xy-plane. Returns
    ``None`` if the entity has a closed shape or cannot be represented as an edge.
    Nr/   )r1   r   s     r2   r*   r*   m  s     r3   c                   t        | j                  j                        }t        | j                  j                        }|j	                  |      }t        t        j                  ||||       |      S )Npayload)r   r8   rS   rT   r   r   em	make_edge)r1   r   rS   rT   r   s        r2   _edge_from_liner   ~  sT     !!"E
vzz~~
C^^C F",,uc66JGTTr3   c                  t        | j                  j                        }|t        k  ry | j                  j                  }| j                  j
                  }t        ||      }||z  dz  t        j                  z  }| j                  ||f      \  }}t        t        j                  t        |      t        |      ||       |      S )Ng     f@r   )r7   r8   r9   r<   r:   r;   r   r=   pir_   r   r   r   r   )	r1   r   r9   r:   r;   span_degr   speps	            r2   _edge_from_arcr     s    ""#F**((K

$$I!+y9Hh&0F__k956FB
T"XtBx@ r3   c          	        	 | j                         }|j                  j                  t        k  s|j
                  j                  t        k  ry t        |j                  |j                        }t        dt        |dz              }t        j                  |j                  |j                  |                  }t        d t!        ||dd        D              }t#        t%        j&                  |d   |d   ||       |      S # t        $ r Y y w xY w)NrL   gtV?c              3  D   K   | ]  \  }}|j                  |        y wrB   r   r|   abs      r2   r~   z%_edge_from_ellipse.<locals>.<genexpr>       C41aAC    rW   r   rM   r   )rN   rO   
major_axis	magnituder<   
minor_axisr   rE   rF   maxroundr   listr_   paramssumzipr   r   r   )r1   r   ct1rI   numpointsr   s          r2   _edge_from_ellipser     s    &&( ~~')S^^-E-E-Ocoos}}=D
atf}%
&C YYs||CJJsO45FC3vvabz+BCCF
VAYr
FFCW   s   D   	DDc          	     d   	 | j                         }t        |j                  d         }t        |j                  d         }t        j                  |j                        }t        d t        ||dd        D              }t        t        j                  ||||       |      S # t        $ r Y y w xY w)Nr   rM   c              3  D   K   | ]  \  }}|j                  |        y wrB   r   r   s      r2   r~   z$_edge_from_spline.<locals>.<genexpr>  r   r   rW   r   )
rN   rO   r   rP   r   r   r   r   r   r   )r1   r   ct2rS   rT   r   r   s          r2   _edge_from_spliner     s    &&( ##A&'E
s!!"%
&CYYs))*FC3vvabz+BCCF",,uc66JGTT  s   B# #	B/.B/c          	        t        |       ry t        j                  | j                               }t	        |      dk  ry |d   }|d   }t        d t        ||dd        D              }t        t        j                  ||||       |      S )NrX   r   rM   c              3  D   K   | ]  \  }}|j                  |        y wrB   r   r   s      r2   r~   z(_edge_from_lwpolyline.<locals>.<genexpr>  r   r   rW   r   )
r[   r   r   vertices_in_wcsrQ   r   r   r   r   r   r1   r   r   rS   rT   r   s         r2   _edge_from_lwpolyliner     s}    V$YYv--/0F
6{Q1IE
*CC3vvabz+BCCF",,uc66JGTTr3   c          	     H   | j                   s| j                  sy t        |       ry t        j                  | j                               }t        |      dk  ry |d   }|d   }t        d t        ||dd        D              }t        t        j                  ||||       |      S )NrX   r   rM   c              3  D   K   | ]  \  }}|j                  |        y wrB   r   r   s      r2   r~   z&_edge_from_polyline.<locals>.<genexpr>  r   r   rW   r   )r]   r^   rd   r   r   r   rQ   r   r   r   r   r   r   s         r2   _edge_from_polyliner     s    !!V%:%:V$YYv++-.F
6{Q1IE
*CC3vvabz+BCCF",,uc66JGTTr3   c             #  B   K   | D ]  }t        ||      }||  yw)zYields all DXF entities as 2D edges in the xy-plane of the :ref:`WCS`.

    Skips all entities that have a closed shape or can not be represented as edge.
    r   N)r*   )r   r   r1   r   s       r2   r    r      s.       FG4Js   c                  | s
t               S | d   j                  g}| D ]]  }t        j                  |d   |j                  |      s|j	                  |j                         |j	                  |j
                         _ |S )zReturns all vertices from a sequence of connected edges.

    Adds line segments between edges when the gap is bigger than `gap_tol`.
    r   rM   r   )tuplerS   r   r>   appendrT   )r   r   r_   r   s       r2   r   r     sl    
 w!!HNN+H "zz(2,

GDOODJJ'!" Or3   rM   )
dxfattribsmax_sagittac                   t         j                  j                  |      }t        |       dk(  r|S |j	                  t        | |      d       |S )a  Returns a new virtual :class:`~ezdxf.entities.LWPolyline` entity.

    This function assumes the building blocks as simple DXF entities attached as payload
    to the edges. The edges are processed in order of the input sequence and the start-
    and end points of the edges should be connected. The output polyline is projected
    onto the xy-plane of the :ref:`WCS`.

        - :class:`~ezdxf.entities.Line` as line segment
        - :class:`~ezdxf.entities.Arc` as bulge
        - :class:`~ezdxf.entities.Ellipse` as bulge or as flattened line segments
        - :class:`~ezdxf.entities.Spline` as flattened line segments
        - :class:`~ezdxf.entities.LWPolyline` and :class:`~ezdxf.entities.Polyline`
          will be merged
        - Everything else will be added as line segment from :attr:`Edge.start` to
          :attr:`Edge.end`
        - Gaps between edges are connected by line segments.

    r   r   vbformat)r   r   newrQ   
set_points_make_polyline_pointsr   r   r   polylines       r2   r)   r)     sK    0 }}  J 7H
5zQ-e[A$OOr3   c                   t         j                  j                  |      }t        |       dk(  r|S |j	                  t        | |      d       |S )a~  Returns a new virtual :class:`Polyline` entity.

    This function assumes the building blocks as simple DXF entities attached as payload
    to the edges. The edges are processed in order of the input sequence and the start-
    and end points of the edges should be connected. The output polyline is projected
    onto the xy-plane of the :ref:`WCS`.

        - :class:`~ezdxf.entities.Line` as line segment
        - :class:`~ezdxf.entities.Arc` as bulge
        - :class:`~ezdxf.entities.Ellipse` as bulge or as flattened line segments
        - :class:`~ezdxf.entities.Spline` as flattened line segments
        - :class:`~ezdxf.entities.LWPolyline` and :class:`~ezdxf.entities.Polyline`
          will be merged
        - Everything else will be added as line segment from :attr:`Edge.start` to
          :attr:`Edge.end`
        - Gaps between edges are connected by line segments.

    r   r   r   r   )r   r   r   rQ   append_formatted_verticesr   r   s       r2   r,   r,     sN    * {{*5H
5zQ&&e[1$ '  Or3   r	   BulgePointsc                    | dk  r|dz  } | S Nr   g      Y@r/   )r   r   s     r2   _adjust_max_sagittar   7  s    Qunr3   c                   g }	 t        j                  |       }t        ||      }|t        kD  r:|j                  d t        j                  |j                  |            D               |r|j                          |S # t        $ r |cY S w xY w)Nc              3  $   K   | ]  }|d f 
 yw        Nr/   r|   ps     r2   r~   z%_flatten_3d_entity.<locals>.<genexpr>G  s     W1q#hWs   )
r   	make_path	TypeErrorr   r<   extendr   r   
flatteningreverse)r1   r   r   
is_reverser   entity_paths         r2   _flatten_3d_entityr   =  s     FnnV, &k6:KWW		+2H2H2U(VWW 	M  s   A< <B
	B
c                   | j                   }t        j                  |j                  j                        rt        |j                  j                  |j                  j                        }d}|t        kD  r-t        t        j                  |            }| j                  r| }t        | j                        |ft        | j                        dfgS t!        || j"                  || j                        S )Nr   )r   r   r>   r8   rn   r   r:   r;   DEG_TOLr   r=   radiansr   r   rS   rT   r   r   )r   r   arcrI   bulges        r2   _arc_to_bulge_pointsr  O  s    ,,C~~cgg''(!#''"5"5sww7H7HI'>(d);<E$**u%$((^S!
 	

 c4;;T__MMr3   c                (   | j                   }t        |j                  j                        }t	        |j                  j
                  |j                  j                        }t        j                  |d      r|t        j                  |j                  j                        rSd}|t        kD  rt        |      }| j                  r| }t        | j                        |ft        | j                         dfgS t#        || j$                  || j                        S )N      ?r   )r   r7   r8   ratior   rE   rF   r=   r>   r   rn   rH   r   r   r   rS   rT   r   r   )r   r   ellipser  rI   r   s         r2   _ellipse_to_bulge_pointsr  `  s    ,,G!!"Egkk55w{{7L7LMD||E3FNN7;;3H3H$I'>(.E$**u%$((^S!
 	

 gt{{KQQr3   c           	     ^    t        |       dk  ryt        d t        | | dd        D              S )NrX   r   c              3  D   K   | ]  \  }}|j                  |        y wrB   r   )r|   rb   rc   s      r2   r~   z!_sum_distances.<locals>.<genexpr>u  s     I62rr{{2Ir   rW   )rQ   r   r   )r_   s    r2   _sum_distancesr	  r  s/    
8}qIS8AB<-HIIIr3   c                ,    | dkD  r| S t        |      dz  S r   )r	  )r   rP   s     r2   _max_sagitta_spliner  x  s    Q.)E11r3   c                *   | j                   }g }	 |j                         }t        ||j                        }|t
        kD  r'|j                  d |j                  |      D               | j                  r|j                          |S # t        $ r |cY S w xY w)Nc              3  6   K   | ]  }t        |      d f  ywr   )r   r   s     r2   r~   z*_spline_to_bulge_points.<locals>.<genexpr>  s     ItAwnIs   )
r   rN   rO   r  rP   r<   r   r   r   r   )r   r   spliner   r   s        r2   _spline_to_bulge_pointsr  ~  s    FF%%' &k23D3DEKWIbmmK.HII 	M  s   B BBc           	     V   | j                   }t        j                  |j                  j                        rL|j                  d      D cg c]  \  }}}t        ||      |f }}}}| j                  rt        |      S |S t        || j                  || j                        S c c}}}w )Nxybr   )r   r   r>   r8   rn   
get_pointsr   r   _revert_bulge_pointsr   r   )r   r   plxyr   r   s          r2   _lwpolyline_to_bulge_pointsr    s    B~~bff&&'13e1LMMgaA41:q/MM??'//b$++{DOOLL	 Ns   B$c                   | j                   }|j                  rt        j                  |j                  j
                        re|j                  D cg c]7  }t        |j                  j                        |j                  j                  f9 }}| j                  rt        |      S |S t        || j                  || j                        S c c}w rB   )r   r]   r   r>   r8   rn   r_   r   ra   r   r   r  r   r   )r   r   r  r}   r   s        r2   _polyline2d_to_bulge_pointsr    s    llB	V^^BFF,<,<=?A{{K!4'5KK??'//b$++{DOOLL	 Ls   <C	c                   t        |       dk  r| S | j                          | D cg c]  }|d   	 }}t        |      r>|j                  d      }|j	                  |       t        t        d | D        |            S | S c c}w )NrX   rW   r   c              3  &   K   | ]	  }|d      yw)r   Nr/   )r|   pnts     r2   r~   z'_revert_bulge_points.<locals>.<genexpr>  s     /CQ/s   )rQ   r   r   popr   r   r   )ptsr  bulgesfirsts       r2   r  r    st    
3x!|
KKM #$c!f$F$
6{

1eC/3/899J %s   A>c                    t        |      dk  r| S 	 | d   \  }}|d   \  }}|j                  |      t        k  r| j                          | j                  |       | S # t        $ r | j                  |       | cY S w xY w)NrX   rM   r   )rQ   
IndexErrorr   r   r<   r  )r   	extensioncurrent_end_connection_points        r2   _extend_bulge_pointsr'    s    
9~Q
 $A,a,-7


MM)M  i s   A A<;A<c                2   g }g }| D ]  }|j                          t        j                  t        |j                              }|r	 |||      }t        |      dk  r.t        |j                        dft        |j                        dfg}t        ||      } |S )zKReturns the polyline points to create a LWPolyline or a 2D Polyline entity.rX   r   )
clearPOLYLINE_CONVERTERSgettyper   rQ   r   rS   rT   r'  )r   r   r   r#  r   	converters         r2   r   r     s    FI 
9'++D,>?	!$4Iy>Adjj!3'dhh%I &fi8
9 Mr3   TrW   )r   r`   flagsc          	     @   t        j                         }t        |      |_        |xj                  |z  c_        t        |       dk(  r|S t        | |      }|j                  |D cg c]  \  }}|j                  |j                  |f  c}}       d|_        |S c c}}w )a  Returns a new :class:`~ezdxf.entities.PolylinePath` for :class:`~ezdxf.entities.Hatch`
    entities.

    This function assumes the building blocks as simple DXF entities attached as payload
    to the edges. The edges are processed in order of the input sequence and the start-
    and end points of the edges should be connected. The output path is projected onto
    the xy-plane of the :ref:`WCS`.

        - :class:`~ezdxf.entities.Line` as line segment
        - :class:`~ezdxf.entities.Arc` as bulge
        - :class:`~ezdxf.entities.Ellipse` as bulge or flattened line segments
        - :class:`~ezdxf.entities.Spline` as flattened line segments
        - :class:`~ezdxf.entities.LWPolyline` and :class:`~ezdxf.entities.Polyline` are
          merged
        - Everything else will be added as line segment from :attr:`Edge.start` to
          :attr:`Edge.end`
        - Gaps between edges are connected by line segments.

    Args:
        edges: Sequence of :class:`~ezdxf.edgeminer.Edge` instances with DXF primitives
            attached as payload
        max_sagitta (float): curve flattening parameter
        is_closed (bool): ``True`` if path is implicit closed
        flags (int): default(0), external(1), derived(4), textbox(8) or outermost(16)

    r   T)
bpPolylinePathrf   r`   path_type_flagsrQ   r   set_verticesr  r  )r   r   r`   r.  polyline_pathbulge_pointsr   r   s           r2   r-   r-     s    : OO%M"9oM!!U*!
5zQ(<L,G$!Qacc1GH"M  Hs   &#B
)r   r.  c                  t        j                         }|xj                  |z  c_        t        |       dk(  r|S | D ]  }|j                  }t        ||j                        }|j                  }t        |t        j                        rt        |||       Zt        |t        j                        rt        ||||       t        |t        j                        rt        ||||       t        |t        j                         rt#        |||       t        |t        j$                        r?|j&                  s|j(                  r't+        |t-        |j/                               ||       -t        |t        j0                        r't+        |t-        |j/                               ||       n|j3                  |j4                  |j6                          |j9                  t:               |S )aY  Returns a new :class:`~ezdxf.entities.EdgePath` for :class:`~ezdxf.entities.Hatch`
    entities.

    This function assumes the building blocks as simple DXF entities attached as payload
    to the edges. The edges are processed in order of the input sequence and the start-
    and end points of the edges should be connected. The output path is projected onto
    the xy-plane of the :ref:`WCS`.

        - :class:`~ezdxf.entities.Line` as :class:`~ezdxf.entities.LineEdge`
        - :class:`~ezdxf.entities.Arc` as :class:`~ezdxf.entities.ArcEdge`
        - :class:`~ezdxf.entities.Ellipse` as :class:`~ezdxf.entities.EllipseEdge`
        - :class:`~ezdxf.entities.Spline` as :class:`~ezdxf.entities.SplineEdge`
        - :class:`~ezdxf.entities.LWPolyline` and :class:`~ezdxf.entities.Polyline` will
          be exploded and added as :class:`~ezdxf.entities.LineEdge` and
          :class:`~ezdxf.entities.ArcEdge`
        - Everything else will be added as line segment from :attr:`Edge.start` to
          :attr:`Edge.end`
        - Gaps between edges are connected by line segments.

    Args:
        edges: Sequence of :class:`~ezdxf.edgeminer.Edge` instances with DXF primitives
            attached as payload
        max_sagitta (float): curve flattening parameter
        flags (int): default(0), external(1), derived(4), textbox(8) or outermost(16)

    r   )r0  EdgePathr2  rQ   r   r   r   r   r   r   r   _add_line_to_edge_path_2dr   _add_arc_to_edge_path_2dr   _add_ellipse_to_edge_path_2dr   _add_spline_to_edge_path_2dr   r]   r^    _add_polyline_parts_to_edge_pathr   virtual_entitiesr   add_linerS   rT   
close_gapsr<   )r   r   r.  	edge_pathr   r1   r   r   s           r2   r   r     sk   : I&
5zQ 5&{DKK@//fbgg&%iA'$YJ

+(FGXN		*'	67C,!!V%:%:,4 7 7 9:G[ .,4 7 7 9:G[ tzz4884/50 !r3   c                    t        |j                  j                        }t        |j                  j                        }|r||}}| j	                  ||       y rB   )r   r8   rS   rT   r>  )r@  liner   rS   rT   s        r2   r8  r8  C  sD      E
txx||
C%suc"r3   c                   t        j                  |j                  j                        rq| j	                  t        |j                  j                        |j                  j                  |j                  j                  |j                  j                  |        y t        j                  |j                  |            }|r|j                          t        | |       y )N)rs   r9   r:   r;   ccw)r   r>   r8   rn   add_arcr   rs   r9   r:   r;   r   r   r   _add_vertices_to_edge_path_2d)r@  r   r   r   r_   s        r2   r9  r9  M  s     ~~cgg''('77>>++gg'' 	 	
 99S^^K89%i:r3   c           	         t        j                  |j                  j                        r	 |j	                         }| j                  t        |j                        t        |j                        |j                  t        j                  |j                        t        j                  |j                        |        y t        j                  |j!                  |            }|r|j#                          t%        | |       y # t
        $ r Y y w xY w)N)rs   r   r  r:   r;   rD  )r   r>   r8   rn   rN   rO   add_ellipser   rs   r   r  r=   degreesrE   rF   r   r   r   rF  )r@  r  r   r   r   r_   s         r2   r:  r:  _  s     ~~gkk++,	**,B 			?BMM*((R^^4ll2<<0 	 	
 99W//<=%i:  		s   D 	DDc                   	 |j                         }t        j                  |j                        }t        |j                               }t        |j                               }|r0|j                          |j                          |j                          | j                  |||r|nd |j                         y # t        $ r Y y w xY w)N)rP   knot_valuesweightsdegree)
rN   rO   r   r   rP   knotsrL  r   
add_splinerM  )r@  r  r   r   rP   rN  rL  s          r2   r;  r;  v  s    %%' YYr001NE2::< G %"yy	    s   B9 9	CCc                V    t        ||dd        D ]  \  }}| j                  ||        y )NrW   )r   r>  )r@  r_   rS   rT   s       r2   rF  rF    s2    (HQRL1 '
s5#&'r3   c                   t        |       t        t        |            }t        t        j                  |            }|rt        j
                  |      }|D ]  }|j                  }t        |t        j                        rt        | ||j                         At        |t        j                        s\t        ||j                        }t        | ||j                  |        y rB   )r   r   r    r   find_sequential_chainreverse_chainr   r   r   r   r8  r   r   r   r   r9  )r@  r   r   r   r   r   r1   r   s           r2   r<  r<    s      '12E))%01E  ' Sfbgg&%iI'*;DH$YRSr3   c                p   t        j                         }t        |       dk(  r|S t        j                  ddd      }| D ]`  }	 t        j
                  |j                        }|j                  |      }|j                  r|j                         }|j                  |       b |S # t        t        f$ r Y vw xY w)u  Returns a new :class:`ezdxf.path.Path` entity.

    This function assumes the building blocks as simple DXF entities attached as payload
    to the edges. The edges are processed in order of the input sequence and the start-
    and end points of the edges should be connected. The output is a 2D path projected
    onto the xy-plane of the :ref:`WCS`.

        - :class:`~ezdxf.entities.Line` as line segment
        - :class:`~ezdxf.entities.Arc` as cubic Bézier curves
        - :class:`~ezdxf.entities.Ellipse` as cubic Bézier curves
        - :class:`~ezdxf.entities.Spine` cubic Bézier curves
        - :class:`~ezdxf.entities.LWPolyline` and :class:`~ezdxf.entities.Polyline`
          as line segments and cubic Bézier curves
        - Everything else will be added as line segment from :attr:`Edge.start` to
          :attr:`Edge.end`
        - Gaps between edges are connected by line segments.

    r   r  r   )r   PathrQ   r   scaler   r   rO   r   	transformr   reversedappend_path)r   	main_pathmr   sub_paths        r2   r+   r+     s    & 		I
5zQ 	sC%A (	~~dll3H %%a(??((*Hh'(  I& 		s   B##B54B5c                  "    e Zd ZU ded<   ded<   y)IntersectingEdgeem.Edger   floatr   N)__name__
__module____qualname____annotations__r/   r3   r2   r^  r^    s    
MOr3   r^  c                Z    t        d | D              }|j                  d | D               |S )zNReturns the :class:`~ezdxf.math.BoundingBox2d` of all start- and end vertices.c              3  4   K   | ]  }|j                     y wrB   rS   r   s     r2   r~   z"bounding_box_2d.<locals>.<genexpr>  s     0Q0   c              3  4   K   | ]  }|j                     y wrB   )rT   r   s     r2   r~   z"bounding_box_2d.<locals>.<genexpr>  s     %!%rh  )r   r   )r   bboxs     r2   r   r     s)    0%00DKK%u%%Kr3   c           	        g }t        |       dk(  r|S t        |      }|9t        |       }t        |j                  j                  dz   |j
                        }nt        |      }||f}| D ]i  }t        |j                        }	t        |j                        }
t        ||	|
fd      }|@|j                  t        ||j                  |                   k |j                  t        d             |S )a  Returns all edges that intersect a line from point `p1` to point `p2`.

    If `p2` is ``None`` an arbitrary point outside the bounding box of all start- and
    end vertices beyond extmax.x will be chosen.
    The edges are handled as straight lines from start- to end vertex, projected onto
    the xy-plane of the :ref:`WCS`. The result is sorted by the distance from
    intersection point to point `p1`.
    r   r  F)virtualrW   )key)rQ   r   r   extmaxr  r  rS   rT   r   r   r^  r   sortr
   )r   rc   p2intersectionsinner_pointrj  outer_point	test_liner   rS   rT   ips               r2   r$   r$     s     -/M
5zQr(K	zu%4;;==3.>2hk*I STZZ 488n&y5#,N>  !1$8L8LR8P!QRS :a=)r3   c                   t        j                  | |      st        d      t        j                  d | D              }t        t        |      |      dk\  S )a   Returns ``True`` when `point` is inside the polygon.

    The edges must be a closed loop. The polygon is build from edges as straight lines
    from start- to end vertex, independently whatever the edges really represent.
    A point at a boundary line is inside the polygon.

    Args:
        edges: sequence of :class:`~ezdxf.edgeminer.Edge` representing a closed loop
        point: point to test
        gap_tol: maximum vertex distance to consider two edges as connected

    Raises:
        ValueError: edges are not a closed loop

    r   edges are not a closed loopc              3  4   K   | ]  }|j                     y wrB   rg  r   s     r2   r~   z'is_inside_polygon_2d.<locals>.<genexpr>  s     /A/rh  r   )r   is_looprO   r   r   r   )r   pointr   polygons       r2   r&   r&     sH    $ ::eW-677ii///G!$u+w73>>r3   c               j    t        j                  | |      st        d      t        d | D              S )zeReturns the area of a closed loop.

    Raises:
        ValueError: edges are not a closed loop

    r   rw  c              3  4   K   | ]  }|j                     y wrB   rg  r   s     r2   r~   zloop_area.<locals>.<genexpr>  s     'A'rh  )r   ry  rO   r   )r   r   s     r2   r(   r(     s/     ::eW-677''''r3   )r1   et.DXFEntityreturnrf   )r1   et.Arcr  rf   )r1   z	et.Circler  rf   )r1   
et.Ellipser  rf   )r1   	et.Spliner  rf   )r1   et.LWPolyliner  rf   )r1   et.Polyliner  rf   )r1   zet.Hatchr  rf   )r1   zet.Solid | et.Tracer  rf   )r1   et.Liner  rf   )r1   zet.Circle | et.Arcr  rf   )r   Iterable[et.DXFEntity]r  zIterator[et.DXFEntity])r   r_  r   r`  r  em.Edge | None)r1   r~  r  r  )r1   r  r  r  )r1   r  r  r  )r1   r  r  r  )r1   r  r  r  )r1   r  r  r  )r1   r  r  r  )r   r  r  zIterator[em.Edge])r   Sequence[em.Edge]r  Sequence[Vec3])r   r  r   r   r   r`  r  r  )r   r  r   r   r   r`  r  r  )r   r`  r   r`  r  r`  )r   r`  r   r`  r   rf   r  r   )r   r_  r   r`  r  r   )r_   r  r  r`  )r   r`  rP   r  )r  r   r  r   )r   r   r#  r   r  r   )r   r  r   r`  r  r   )r   r  r   r`  r.  intr  zbp.PolylinePath)r   r  r   r`  r.  r  r  bp.EdgePath)r@  r  rB  r  r   rf   r  None)
r@  r  r   r  r   rf   r   r`  r  r  )
r@  r  r  r  r   rf   r   r`  r  r  )r@  r  r  r  r   rf   r  r  )r@  r  r_   z
list[Vec2]r  r  )
r@  r  r   zlist[et.DXFGraphic]r   rf   r   r`  r  r  )r   r  r  z	path.Path)r   r  r  r   rB   )r   r  rc   r   rp  zUVec | Noner  zlist[IntersectingEdge])r   r  rz  r   r  rf   )r   r  r  r`  )y__doc__
__future__r   typingr   r   r   r   r   typing_extensionsr	   r=   	functoolsoperatorr
   ezdxfr   r   r   r   r   ezdxf.entitiesr   r0  ezdxf.uprightr   
ezdxf.mathr   r   r   r   r   r   r   r   r   r   r   r   __all__r<   r   rH   GAP_TOLsingledispatchr%   registerr   r@   CirclerC   r   rJ   r   rU   r   r[   r   rd   Hatchrh   TraceSolidrj   r'   r   rq   ru   rw   r   r   r   r   r   r"   r!   r#   r   r*   r   r   r   r   r   r   r    r   r)   r,   r   r   r`  r   rd  r   r   r  r  r	  r  r  r  r  r  r'  r*  r   r-   r   r8  r9  r:  r;  rF  r<  r+   r^  r   r$   r&   r(   r/   r3   r2   <module>r     s   # @ @ '    !    / %   * 


**  ( 266"V #V 299%, &, 2::& ' 299%
/ &
/ 2==)/ */ 2;;' (  288$# %# 288$288$ % %
  < BGG$	 %	 BII&BFF#	 $ '	 BJJ' ( BII&	 '	 BMM* + BKK( ) BHH% & BHH%BHH%	 & &	#L=9  29    rww07 U  U rvv.5    rzz"6=  #$ ryy!4; U "U r}}%<C U &U r{{#8? U $U$ 29
$

 9@ $ 	  	
 @ 48b-0FK< eD%K01Y 1(-;?$N"R$J2$MM
" FF JJ(II&MM.KK, & 79DWX%%.3%QT%%R 79q;;.3;AD;;|##")#48#	#;;!';26;EJ;	;$;;%/;:>;MR;	;.$-8<	.'
SS!S S 	S
 
S0"Jz 
 ;?"&,7D 7>??%)?	?2 4; 	(r3   