
    'jՉ              
      H
   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j+        Z+ej,        dd            Z-e-.                    ej/                  dd            Z0e-.                    ej1                  dd            Z2e-.                    ej3                  dd            Z4e-.                    ej5                  dd            Z6e-.                    ej7                  dd            Z8e-.                    ej9                  dd             Z:e-.                    ej;                  dd"            Z<e-.                    ej=                  e-.                    ej>                  dd$                        Z?ej,        dd%            Z@e@.                    ejA                  dd'            ZBe@.                    ej1                  e@.                    ej/                  dd)                        ZCe@.                    ej3                  dd*            ZDe@.                    ej5                  dd+            ZEe@.                    ej7                  dd,            ZFe@.                    ej9                  dd-            ZGe@.                    ej;                  dd.            ZHe@.                    ej=                  e@.                    ej>                  dd/                        ZIdd3ZJdd4ZKdd5ZLdd;ZMej,        e+d<dd=            ZNeN.                    ejA                  e+d<dd>            ZOeN.                    ej/                  e+d<dd?            ZPeN.                    ej3                  e+d<dd@            ZQeN.                    ej5                  e+d<ddA            ZReN.                    ej7                  e+d<ddB            ZSeN.                    ej9                  e+d<ddC            ZTe+d<ddEZUe+d<ddIZVddJdKddOZWddJdKddPZXeYeZee[f                  Z\dQe]dR<   ddTZ^ddVZ_ddWZ`ddXZaddZZbdd\Zcdd]Zddd^Zedd_ZfddaZgdddZhej/        e`ej3        eaej5        edej7        eeej9        efiZiddeZjdJdfdgdhddlZkdJdgdmddoZlddtZmddvZnddxZoddzZpdd|Zqdd~ZrddZs G d de          ZtddZu	 dddZve+d<ddZwe+d<ddZxdS )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>entityet.DXFEntityreturnboolc                    dS )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 r.   s    I/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/edgesmith.pyr%   r%   E   s	    $ 5    et.Arcc                    t          | j        j                  }| j        j        }| j        j        }t          ||          }t          |          t          k    ot          j        |dt                    S )Ng     v@abs_tol)	absdxfradiusstart_angle	end_angler   LEN_TOLmathisclose)r.   r=   r>   r?   
angle_spans        r5   _is_closed_arcrD   Z   s^    "##F*(K
$I#K;;Jv;; UT\*eW%U%U%UUr6   	et.Circlec                F    t          | j        j                  t          k    S N)r;   r<   r=   r@   r4   s    r5   _is_closed_circlerH   c   s    vz !!G++r6   
et.Ellipsec                    | j         j        }| j         j        }t          ||          }t	          j        |t          j        t                    sdS dS )Nr9   FT)r<   start_param	end_paramr   rA   rB   tauRAD_TOL)r.   rK   rL   spans       r5   _is_closed_ellipserP   h   sJ    *(K
$Ik955D<dh888 u4r6   	et.Splinec                    	 |                                  }n# t          $ r Y dS w xY w|j        }t          |          dk     rdS |d         }|d         }|                    |t
                    S )NF   r   r9   )construction_tool
ValueErrorcontrol_pointslenrB   r@   )r.   bsplinerW   startends        r5   _is_closed_spliner\   r   s    **,,   uu+N
>Qu1E

C==g=...    
%%et.LWPolylinec                   t          |           dk     rdS | j        du rdS t          | j        d         d d                   }t          | j        d         d d                   }|                    |t
                    S )N   FTr      rT   r9   )rX   closedr   lwpointsrB   r@   )r.   rZ   r[   s      r5   _is_closed_lwpolylinerd      sx    
6{{Qu}t#BQB'((E
vr"2A2&
'
'C==g=...r6   et.Polylinec                    | j         s| j        rg| j        }t          |          dk     rdS | j        rdS |d         j        j        }|d         j        j        }|                    |t                    rdS dS )Nra   FTr   rT   r9   )	is_2d_polylineis_3d_polylineverticesrX   	is_closedr<   locationrB   r@   )r.   ri   p0p1s       r5   _is_closed_polyline2drn      s      5  ?x==15 	4A;?+B<#,::b':** 	45r6   et.Hatchc                D    t          t          | j                            S rG   )r1   rX   pathsr4   s    r5   _is_closed_hatchrr      s    FL!!"""r6   et.Solid | et.Tracec                    dS )NTr3   r4   s    r5   _is_closed_solidru      s	     4r6   c                    dS )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.

    Fr3   r4   s    r5   r'   r'      s	    8 5r6   et.Linec                f   t          j        | j        j                  sdS t	          | j        j                  t          k    rdS t	          t          | j        j                  j	                  t          k    rdS t	          t          | j        j
                  j	                  t          k    rdS dS NFT)r   rB   r<   	extrusionr;   	thicknessr@   r   rZ   zr[   r4   s    r5   _is_pure_2d_entityr}      s    >&*.// u
6:  7**u
4
 !!#$$w..u
4
!""W,,u4r6   et.Circle | et.Arcc                B   t          j        | j        j                  sdS t	          t          | j        j                  j                  t          k    rdS t	          | j        j	                  t          k    rdS t	          | j        j
                  t          k    rdS dS ry   )r   rB   r<   rz   r;   r   centerr|   r@   	elevationr{   r4   s    r5   _is_pure_2d_arcr      s     >&*.// u
4
!""$%%//u
6:  7**u
6:  7**u4r6   c                    t          j        | j        j                  sdS t	          t          | j        j                  j                  t          k    rdS dS ry   )	r   rB   r<   rz   r;   r   r   r|   r@   r4   s    r5   _is_pure_2d_ellipser      sK    >&*.// u
4
!""$%%//u4r6   c                    t          j        | j        j                  sdS 	 |                                 }n# t
          $ r Y dS w xY wt          d |j        D                       rdS dS )NFc              3  P   K   | ]!}t          |j                  t          k    V  "d S rG   r;   r|   r@   .0vs     r5   	<genexpr>z%_is_pure_2d_spline.<locals>.<genexpr>   s/      
9
9!3qs88g
9
9
9
9
9
9r6   T)r   rB   r<   rz   rU   rV   anyrW   )r.   cts     r5   _is_pure_2d_spliner      s    >&*.// u%%''   uu

9
9r'8
9
9
999 u4s   7 
AAc                    t          j        | j        j                  sdS t	          | j        j                  t          k    rdS t	          | j        j                  t          k    rdS dS ry   )r   rB   r<   rz   r;   r   r@   r{   r4   s    r5   _is_pure_2d_lwpolyliner      s]    >&*.// u
6:  7**u
6:  7**u4r6   c                    | j         s| j        rdS t          d |                                 D                       rdS t	          | j        j                  t          k    rdS dS )NFc              3  P   K   | ]!}t          |j                  t          k    V  "d S rG   r   r   s     r5   r   z'_is_pure_2d_polyline.<locals>.<genexpr>  s/      
>
>!3qs88g
>
>
>
>
>
>r6   T)is_polygon_meshis_poly_face_meshr   points_in_wcsr;   r<   r{   r@   r4   s    r5   _is_pure_2d_polyliner     sn     !9 u

>
>v';';'='=
>
>
>>> u
6:  7**u4r6   c                    t          j        | j        j                  sdS t	          t          | j        j                  j                  t          k    rdS dS ry   )	r   rB   r<   rz   r;   r   r   r|   r@   r4   s    r5   _is_pure_2d_hatchr     sK    >&*.// u
4
$%%'((722u4r6   c                0   t          j        | j        j                  sdS t	          | j        j                  t          k    rdS t	          | j        j                  t          k    rdS t          d | 	                                D                       rdS dS )NFc              3  P   K   | ]!}t          |j                  t          k    V  "d S rG   r   r   s     r5   r   z$_is_pure_2d_solid.<locals>.<genexpr>   s/      
=
=!3qs88g
=
=
=
=
=
=r6   T)
r   rB   r<   rz   r;   r   r@   r{   r   wcs_verticesr4   s    r5   _is_pure_2d_solidr     s     >&*.// u
6:  7**u
6:  7**u

=
=v':':'<'<
=
=
=== u4r6   r   Iterable[et.DXFEntity]Iterator[et.DXFEntity]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   | ]X}t          |t          j        t          j        t          j        t          j        t          j        t          j        f          T|V  Yd S rG   )
isinstanceetLineArcEllipseSpline
LWPolylinePolyline)r   r.   s     r5   r   z'filter_edge_entities.<locals>.<genexpr>:  sl        
	

 

     r6   r3   r   s    r5   r"   r"   %  s#    *    r6   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          |          |V  d S rG   )r'   r   es     r5   r   z%filter_2d_entities.<locals>.<genexpr>Q  s0      <<!'8';';<A<<<<<<r6   r3   r   s    r5   r!   r!   K  s     =<x<<<<r6   c                8    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          |          |V  d S rG   )r%   r   s     r5   r   z$filter_open_edges.<locals>.<genexpr>a  s0      88!$4Q$7$78A888888r6   )r"   )r   edgess     r5   r#   r#   T  s%     !**E88u8888r6   edgeem.Edgegap_tolfloatem.Edge | Nonec                j    | j                             | j                  |k     rd S | j        |k     rd S | S rG   )rZ   distancer[   length)r   r   s     r5   _validate_edger   d  s;    z48$$w..t{WtKr6   r   c                   dS )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.
    Nr3   )r.   r   s     r5   r*   r*   m  s	     4r6   c                   t          | j        j                  }t          | j        j                  }|                    |          }t          t          j        ||||           |          S )Npayload)r   r<   rZ   r[   r   r   em	make_edge)r.   r   rZ   r[   r   s        r5   _edge_from_liner   ~  s[     !""E
vz~

C^^C  F",uc66JJJGTTTr6   c               |   t          | j        j                  }|t          k     rd S | j        j        }| j        j        }t          ||          }||z  dz  t          j        z  }| 	                    ||f          \  }}t          t          j        t          |          t          |          ||           |          S )Ng     f@r   )r;   r<   r=   r@   r>   r?   r   rA   piri   r   r   r   r   )	r.   r   r=   r>   r?   span_degr   speps	            r5   _edge_from_arcr     s    "##Ft*(K
$I!+y99Hh&0F__k9566FB
T"XXtBxx@@@  r6   c          	     R   	 |                                  }n# t          $ r Y d S w xY w|j        j        t          k     s|j        j        t          k     rd S t          |j        |j                  }t          dt          |dz                      }t          j        |                    |                    |                              }t          d t!          ||dd                    D                       }t#          t%          j        |d         |d         ||           |          S )NrS   gtV?c              3  F   K   | ]\  }}|                     |          V  d S rG   r   r   abs      r5   r   z%_edge_from_ellipse.<locals>.<genexpr>  0      CC41aACCCCCCr6   r`   r   rT   r   )rU   rV   
major_axis	magnituder@   
minor_axisr   rK   rL   maxroundr   listri   paramssumzipr   r   r   )r.   r   ct1rO   numpointsr   s          r5   _edge_from_ellipser     s   &&((   tt
~'))S^-E-O-Otcos}==D
atf}%%
&
&C Ys||CJJsOO4455FCC3vvabbz+B+BCCCCCF
VAYr
FFCCCW  r]   c          	        	 |                                  }n# t          $ r Y d S w xY wt          |j        d                   }t          |j        d                   }t          j        |j                  }t          d t          ||dd                    D                       }t          t          j	        ||||           |          S )Nr   rT   c              3  F   K   | ]\  }}|                     |          V  d S rG   r   r   s      r5   r   z$_edge_from_spline.<locals>.<genexpr>  r   r6   r`   r   )
rU   rV   r   rW   r   r   r   r   r   r   )r.   r   ct2rZ   r[   r   r   s          r5   _edge_from_spliner     s    &&((   tt #A&''E
s!"%
&
&CYs)**FCC3vvabbz+B+BCCCCCF",uc66JJJGTTTr]   c          	     d   t          |           rd S t          j        |                                           }t	          |          dk     rd S |d         }|d         }t          d t          ||dd                    D                       }t          t          j	        ||||           |          S )Nra   r   rT   c              3  F   K   | ]\  }}|                     |          V  d S rG   r   r   s      r5   r   z(_edge_from_lwpolyline.<locals>.<genexpr>  r   r6   r`   r   )
rd   r   r   vertices_in_wcsrX   r   r   r   r   r   r.   r   r   rZ   r[   r   s         r5   _edge_from_lwpolyliner     s    V$$ tYv--//00F
6{{Qt1IE
*CCC3vvabbz+B+BCCCCCF",uc66JJJGTTTr6   c          	        | j         s	| j        sd S t          |           rd S t          j        |                                           }t          |          dk     rd S |d         }|d         }t          d t          ||dd                    D                       }t          t          j        ||||           |          S )Nra   r   rT   c              3  F   K   | ]\  }}|                     |          V  d S rG   r   r   s      r5   r   z&_edge_from_polyline.<locals>.<genexpr>  r   r6   r`   r   )rg   rh   rn   r   r   r   rX   r   r   r   r   r   r   s         r5   _edge_from_polyliner     s    ! V%: tV$$ tYv++--..F
6{{Qt1IE
*CCC3vvabbz+B+BCCCCCF",uc66JJJGTTTr6   Iterator[em.Edge]c             #  B   K   | D ]}t          ||          }||V  dS )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   r.   r   s       r5   r    r      sC         FG444JJJ r6   r   Sequence[em.Edge]Sequence[Vec3]c                   | st                      S | d         j        g}| D ]X}t          j        |d         |j        |          s|                    |j                   |                    |j                   Y|S )zReturns all vertices from a sequence of connected edges.

    Adds line segments between edges when the gap is bigger than `gap_tol`.
    r   rT   r   )tuplerZ   r   rB   appendr[   )r   r   ri   r   s       r5   r   r     s    
  ww!!HN+H " "z(2,
GDDD 	(OODJ'''!!!!Or6   rT   )
dxfattribsmax_sagittar   r   r   c                   t           j                            |          }t          |           dk    r|S |                    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   newrX   
set_points_make_polyline_pointsr   r   r   polylines       r5   r)   r)     sY    0 }  J 77H
5zzQ-e[AA$OOOOr6   c                   t           j                            |          }t          |           dk    r|S |                    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   rX   append_formatted_verticesr   r   s       r5   r,   r,     s`    * {*55H
5zzQ&&e[11$ '    Or6   r	   BulgePointsr   c                    | dk     r|dz  } | S Nr   g      Y@r3   )r   r   s     r5   _adjust_max_sagittar   7  s    Qunr6   
is_reversec                D   g }	 t          j        |           }n# t          $ r |cY S w xY wt          ||          }|t          k    rD|                    d t          j        |                    |                    D                        |r|	                                 |S )Nc              3     K   | ]}|d fV  	dS         Nr3   r   ps     r5   r   z%_flatten_3d_entity.<locals>.<genexpr>G  s&      WW1q#hWWWWWWr6   )
r   	make_path	TypeErrorr   r@   extendr   r   
flatteningreverse)r.   r   r   r   r   entity_paths         r5   _flatten_3d_entityr  =  s     FnV,,   %k6::KWWW	+2H2H2U2U(V(VWWWWWW  	Ms    ((c                   | j         }t          j        |j        j                  rt          |j        j        |j        j                  }d}|t          k    r+t          t          j        |                    }| j        r| }t          | j                  |ft          | j                  dfgS t!          || j        || j                  S )Nr  )r   r   rB   r<   rz   r   r>   r?   DEG_TOLr   rA   radiansr   r   rZ   r[   r  r   )r   r   arcrO   bulges        r5   _arc_to_bulge_pointsr  O  s    ,C~cg'(( 

!#'"5sw7HII'>>(d););<<E $*u%$(^^S!
 	

 c4;T_MMMr6   c                   | j         }t          |j        j                  }t	          |j        j        |j        j                  }t          j        |d          rpt          j        |j        j
                  rRd}|t          k    rt          |          }| j        r| }t          | j                  |ft          | j                  dfgS t#          || j        || j                  S )N      ?r  )r   r;   r<   ratior   rK   rL   rA   rB   r   rz   rN   r   r   r   rZ   r[   r  r   )r   r   ellipser  rO   r  s         r5   _ellipse_to_bulge_pointsr  `  s    ,G!""Egk5w{7LMMD|E3 	
FN7;3H$I$I 	
'>>(..E $*u%$(^^S!
 	

 gt{KQQQr6   ri   c           	         t          |           dk     rdS t          d t          | | dd                    D                       S )Nra   r  c              3  F   K   | ]\  }}|                     |          V  d S rG   r   )r   rl   rm   s      r5   r   z!_sum_distances.<locals>.<genexpr>u  s0      II62rr{{2IIIIIIr6   r`   )rX   r   r   )ri   s    r5   _sum_distancesr  r  sG    
8}}qsIIS8ABB<-H-HIIIIIIr6   rW   c                6    | dk    r| S t          |          dz  S r   )r  )r   rW   s     r5   _max_sagitta_spliner  x  s$    Q.))E11r6   c                B   | j         }g }	 |                                }n# t          $ r |cY S w xY wt          ||j                  }|t
          k    r2|                    d |                    |          D                        | j        r|	                                 |S )Nc              3  8   K   | ]}t          |          d fV  dS r  r   r  s     r5   r   z*_spline_to_bulge_points.<locals>.<genexpr>  s,      IItAwwnIIIIIIr6   )
r   rU   rV   r  rW   r@   r	  r
  r   r  )r   r   spliner   r   s        r5   _spline_to_bulge_pointsr"  ~  s    FF%%''    &k23DEEKWIIbmmK.H.HIIIIII  	Ms     //c                    | j         }t          j        |j        j                  r8d |                    d          D             }| j        rt          |          S |S t          || j	        || j                  S )Nc                :    g | ]\  }}}t          ||          |fS r3   r   )r   xyr   s       r5   
<listcomp>z/_lwpolyline_to_bulge_points.<locals>.<listcomp>  s*    MMMgaA41::q/MMMr6   xybr   )
r   r   rB   r<   rz   
get_pointsr   _revert_bulge_pointsr  r   r   r   plr   s       r5   _lwpolyline_to_bulge_pointsr-    sv    B~bf&'' MMe1L1LMMM? 	0'///b$+{DOLLLr6   c                    | j         }|j        rGt          j        |j        j                  r)d |j        D             }| j        rt          |          S |S t          || j
        || j                  S )Nc                X    g | ]'}t          |j        j                  |j        j        f(S r3   )r   r<   rk   r  r   s     r5   r'  z/_polyline2d_to_bulge_points.<locals>.<listcomp>  s-    KKK!4''5KKKr6   )r   rg   r   rB   r<   rz   ri   r   r*  r  r   r+  s       r5   _polyline2d_to_bulge_pointsr0    st    lB	 V^BF,<== KKr{KKK? 	0'///b$+{DOLLLr6   ptsc                0   t          |           dk     r| S |                                  d | D             }t          |          rQ|                    d          }|                    |           t          t          d | D             |                    S | S )Nra   c                    g | ]
}|d          S )r`   r3   r   pnts     r5   r'  z(_revert_bulge_points.<locals>.<listcomp>  s    $$$c!f$$$r6   r   c              3  &   K   | ]}|d          V  dS )r   Nr3   r4  s     r5   r   z'_revert_bulge_points.<locals>.<genexpr>  s&      //CQ//////r6   )rX   r  r   popr   r   r   )r1  bulgesfirsts      r5   r*  r*    s    
3xx!||
KKMMM$$$$$F
6{{ :

1eC//3///88999Jr6   r   	extensionc                <   t          |          dk     r| S 	 | d         \  }}n'# t          $ r |                     |           | cY S w xY w|d         \  }}|                    |          t          k     r|                                  |                     |           | S )Nra   rT   r   )rX   
IndexErrorr	  r   r@   r7  )r   r:  current_end_connection_points        r5   _extend_bulge_pointsr@    s    
9~~QQ   i    $A,a,--77


MM)Ms   # !AAc                R   g }g }| D ]}|                                  t                              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.ra   r  )
clearPOLYLINE_CONVERTERSgettyper   rX   r   rZ   r[   r@  )r   r   r   r:  r   	converters         r5   r   r     s    FI 
9 
9'++D,>,>??	 	5!	$44Iy>>Adj!!3'dh%I &fi88Mr6   Tr`   )r   rj   flagsrG  intbp.PolylinePathc               
   t          j                    }t          |          |_        |xj        |z  c_        t          |           dk    r|S t          | |          }|                    d |D                        d|_        |S )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   c                2    g | ]\  }}|j         |j        |fS r3   )r%  r&  )r   r  r   s      r5   r'  z,polyline_path_from_chain.<locals>.<listcomp>   s&    GGG$!Qac1GGGr6   T)bpPolylinePathr1   rj   path_type_flagsrX   r   set_vertices)r   r   rj   rG  polyline_pathbulge_pointss         r5   r-   r-     s    : O%%M"9ooM!!U*!!
5zzQ(<<LGG,GGGHHH"Mr6   )r   rG  bp.EdgePathc                  t          j                    }|xj        |z  c_        t          |           dk    r|S | D ]}|j        }t          ||j                  }|j        }t          |t          j
                  rt          |||           Rt          |t          j                  rt          ||||           t          |t          j                  rt          ||||           t          |t          j                  rt#          |||           t          |t          j                  rA|j        s|j        r3t+          |t-          |                                          ||           3t          |t          j                  r3t+          |t-          |                                          ||           |                    |j        |j                   |                    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   )rL  EdgePathrN  rX   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   rg   rh    _add_polyline_parts_to_edge_pathr   virtual_entitiesr   add_linerZ   r[   
close_gapsr@   )r   r   rG  	edge_pathr   r.   r   r  s           r5   r   r     s   : I&
5zzQ 5 5&{DK@@/fbg&& 	5%iAAAA'' 	5$YJJJJ
++ 	5(FGXNNNN	** 	5'	67CCCC,, 	5!	5%+%:	5 -4 7 7 9 9::G[    .. 	5,4 7 7 9 9::G[    tz484444!!!r6   r]  liner  Nonec                    t          |j        j                  }t          |j        j                  }|r||}}|                     ||           d S rG   )r   r<   rZ   r[   r[  )r]  r^  r  rZ   r[   s        r5   rU  rU  C  sS       E
tx|

C  %suc"""""r6   r  c                   t          j        |j        j                  rR|                     t          |j        j                  |j        j        |j        j        |j        j	        |            d S t          j
        |                    |                    }|r|                                 t          | |           d S )N)r   r=   r>   r?   ccw)r   rB   r<   rz   add_arcr   r   r=   r>   r?   r   r
  r  _add_vertices_to_edge_path_2d)r]  r  r  r   ri   s        r5   rV  rV  M  s     ~cg'(( ;''7>+g' 	 	
 	
 	
 	
 	
 9S^^K8899 	%i:::::r6   r  c           	        t          j        |j        j                  r	 |                                }n# t
          $ r Y d S w xY w|                     t          |j                  t          |j	                  |j
        t          j        |j                  t          j        |j                  |            d S t          j        |                    |                    }|r|                                 t%          | |           d S )N)r   r   r  r>   r?   rb  )r   rB   r<   rz   rU   rV   add_ellipser   r   r   r  rA   degreesrK   rL   r   r
  r  rd  )r]  r  r  r   r   ri   s         r5   rW  rW  _  s    ~gk+,, ;	**,,BB 	 	 	FF		??BM**(R^44l2<00 	 	
 	
 	
 	
 	
 9W//<<== 	%i:::::s   5 
AAr!  c                   	 |                                 }n# t          $ r Y d S w xY wt          j        |j                  }t          |                                          }t          |                                          }|r<|                                 |                                 |                                 |                     |||r|nd |j	                   d S )N)rW   knot_valuesweightsdegree)
rU   rV   r   r   rW   knotsrj  r  
add_splinerk  )r]  r!  r  r   rW   rl  rj  s          r5   rX  rX  v  s    %%''   Yr011NE2::<<  G    %",y	      r]   
list[Vec2]c                n    t          ||dd                    D ]\  }}|                     ||           d S )Nr`   )r   r[  )r]  ri   rZ   r[   s       r5   rd  rd    sJ    (HQRRL11 ' '
s5#&&&&' 'r6   list[et.DXFGraphic]c                   t          |           t          t          |                    }t          t          j        |                    }|rt          j        |          }|D ]}|j        }t          |t          j	                  rt          | ||j                   :t          |t          j                  r,t          ||j                  }t          | ||j        |           d S rG   )r   r   r    r   find_sequential_chainreverse_chainr   r   r   r   rU  r   r   r   r   rV  )r]  r   r  r   r   r   r.   r   s           r5   rY  rY    s      '1122E)%0011E ( '' S Sfbg&& 	S%iIIII'' 	S*;DDH$YRRRS Sr6   	path.Pathc                z   t          j                    }t          |           dk    r|S t          j        ddd          }| D ]y}	 t          j        |j                  }n# t          t          f$ r Y 0w xY w|	                    |          }|j
        r|                                }|                    |           z|S )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   PathrX   r   scaler  r   rV   r  	transformr   reversedappend_path)r   	main_pathmr   sub_paths        r5   r+   r+     s    & 	I
5zzQ 	sC%%A ( (	~dl33HHI& 	 	 	H	%%a((? 	+((**Hh''''s   AA21A2c                  $    e Zd ZU ded<   ded<   dS )IntersectingEdger   r   r   r   N)__name__
__module____qualname____annotations__r3   r6   r5   r  r    s"         MMMOOOOOr6   r  r   c                v    t          d | D                       }|                    d | D                        |S )zNReturns the :class:`~ezdxf.math.BoundingBox2d` of all start- and end vertices.c              3  $   K   | ]}|j         V  d S rG   rZ   r   s     r5   r   z"bounding_box_2d.<locals>.<genexpr>  s$      00Q000000r6   c              3  $   K   | ]}|j         V  d S rG   )r[   r   s     r5   r   z"bounding_box_2d.<locals>.<genexpr>  s$      %%!%%%%%%r6   )r   r	  )r   bboxs     r5   r   r     sD    00%00000DKK%%u%%%%%%Kr6   rm   r   p2UVec | Nonelist[IntersectingEdge]c           	        g }t          |           dk    r|S t          |          }|2t          |           }t          |j        j        dz   |j                  }nt          |          }||f}| D ]v}t          |j                  }	t          |j                  }
t          ||	|
fd          }|6|	                    t          ||                    |                               w|                    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   Nr  F)virtualr`   )key)rX   r   r   extmaxr%  r&  rZ   r[   r   r   r  r   sortr
   )r   rm   r  intersectionsinner_pointr  outer_point	test_liner   rZ   r[   ips               r5   r$   r$     s    -/M
5zzQr((K	zu%%4;=3.>>2hhk*I S STZ  48nn&y5#,NNN>  !1$8L8LR8P8P!Q!QRRR:a==)))r6   pointc                   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  $   K   | ]}|j         V  d S rG   r  r   s     r5   r   z'is_inside_polygon_2d.<locals>.<genexpr>  s$      //A//////r6   r  )r   is_looprV   r   r   r   )r   r  r   polygons       r5   r&   r&     sc    $ :eW--- 86777i///////G!$u++w773>>r6   c               ~    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   r  c              3  $   K   | ]}|j         V  d S rG   r  r   s     r5   r   zloop_area.<locals>.<genexpr>  s$      ''A''''''r6   )r   r  rV   r   )r   r   s     r5   r(   r(     sG     :eW--- 86777''''''''r6   )r.   r/   r0   r1   )r.   r7   r0   r1   )r.   rE   r0   r1   )r.   rI   r0   r1   )r.   rQ   r0   r1   )r.   r^   r0   r1   )r.   re   r0   r1   )r.   ro   r0   r1   )r.   rs   r0   r1   )r.   rw   r0   r1   )r.   r~   r0   r1   )r   r   r0   r   )r   r   r   r   r0   r   )r.   r/   r0   r   )r.   rw   r0   r   )r.   r7   r0   r   )r.   rI   r0   r   )r.   rQ   r0   r   )r.   r^   r0   r   )r.   re   r0   r   )r   r   r0   r   )r   r   r0   r   )r   r   r   r   r   r   r0   r^   )r   r   r   r   r   r   r0   re   )r   r   r   r   r0   r   )r   r   r   r   r   r1   r0   r   )r   r   r   r   r0   r   )ri   r   r0   r   )r   r   rW   r   )r1  r   r0   r   )r   r   r:  r   r0   r   )r   r   r   r   r0   r   )r   r   r   r   rG  rH  r0   rI  )r   r   r   r   rG  rH  r0   rR  )r]  rR  r^  rw   r  r1   r0   r_  )
r]  rR  r  r7   r  r1   r   r   r0   r_  )
r]  rR  r  rI   r  r1   r   r   r0   r_  )r]  rR  r!  rQ   r  r1   r0   r_  )r]  rR  ri   rn  r0   r_  )
r]  rR  r   rp  r  r1   r   r   r0   r_  )r   r   r0   rt  )r   r   r0   r   rG   )r   r   rm   r   r  r  r0   r  )r   r   r  r   r0   r1   )r   r   r0   r   )y__doc__
__future__r   typingr   r   r   r   r   typing_extensionsr	   rA   	functoolsoperatorr
   ezdxfr   r   r   r   r   ezdxf.entitiesr   rL  ezdxf.uprightr   
ezdxf.mathr   r   r   r   r   r   r   r   r   r   r   r   __all__r@   r  rN   GAP_TOLsingledispatchr%   registerr   rD   CirclerH   r   rP   r   r\   r   rd   r   rn   Hatchrr   TraceSolidru   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   r   r   r  r   r  r  r  r  r  r"  r-  r0  r*  r@  rC  r   r-   r   rU  rV  rW  rX  rd  rY  r+   r  r   r$   r&   r(   r3   r6   r5   <module>r     s
     # " " " " " @ @ @ @ @ @ @ @ @ @ @ @ @ @ ' ' ' ' ' '            ! ! ! ! ! !                   / / / / / / % % % % % %                             * 


*    ( 26""V V V #"V 29%%, , , &%, 2:&&   '& 29%%
/ 
/ 
/ &%
/ 2=))/ / / *)/ 2;''   ('  28$$# # # %$# 28$$28$$   %$ %$
    < BG$$	 	 	 %$	 BI&&BF##	 	 	 $# '&	 BJ''   (' BI&&	 	 	 '&	 BM**   +* BK((   )( BH%%   &% BH%%BH%%	 	 	 &% &%	# # # #L= = = =9 9 9 9     29        rw07 U U U U U  U rv.5        rz""6=      #"$ ry!!4; U U U U U "!U r}%%<C U U U U U &%U r{##8? U U U U U $#U$ 29
 
 
 
 
 
 9@      $ 	     @ 48b     < eD%K01 1 1 1 1      $N N N N"R R R R$J J J J2 2 2 2   $M M M MM M M M
 
 
 
   " F J(I&M.K,    & 79DWX% % % % % %R 79q; ; ; ; ; ;|# # # #; ; ; ;$; ; ; ;.   .' ' ' '
S S S S0" " " "J    z   
    ;?    D 7>? ? ? ? ? ?2 4; 	( 	( 	( 	( 	( 	( 	( 	(r6   