
    hC                        % S r SSKJr  SSKJrJrJrJrJrJ	r	J
r
  SSKJr  SSKJr  SSKJr  SSKJr  / SQr\
" S	\S
9r\\\\S      4   rS\S'   \" SS5      rSS jr    SS jrSS jrSS jrg)a  
This module provides "nested Polygon" detection for multiple paths.

Terminology
-----------

exterior
    creates a filled area, has counter-clockwise (ccw) winding
    exterior := Path

hole
    creates an unfilled area, has clockwise winding (cw),
    hole := Polygon

polygon
    list of nested paths:
    polygon without a hole: [path]
    polygon with 1 hole: [path, [path]]
    polygon with 2 separated holes: [path, [path], [path]]
    polygon with 2 nested holes: [path, [path, [path]]]

    polygon := [exterior, *hole]

The result is a list of polygons:

1 polygon returns: [[ext-path]]
2 separated polygons returns: [[ext-path], [ext-path, [hole-path]]]

A hole is just another polygon, some render backends may require a distinct winding
order for nested paths like: ccw-cw-ccw-cw...

[Exterior-ccw,
    [Hole-Exterior-cw,
        [Sub-Hole-ccw],
        [Sub-Hole-ccw],
    ],
    [Hole-Exterior-cw],
    [Hole-Exterior-cw],
]

The implementation has to do some expensive tests, like check if a path is
inside of another path or if paths do overlap. A goal is to reduce this costs
by using proxy objects:

Bounding Box Proxy
------------------

This implementation uses the bounding box of the path as proxy object, this is very fast
but not accurate, but can handle most of the real world scenarios, in the assumption
that most HATCHES are created from non-overlapping boundary paths.
Overlap detection and resolving is not possible.

The input paths have to implement the SupportsBoundingBox protocol, which requires
only a method bbox() that returns a BoundingBox2d instance for the path.

Sort by Area
------------

It is not possible for a path to contain another path with a larger area.

    )annotations)TupleOptionalListIterableSequenceIteratorTypeVar)	TypeAlias)
namedtuple)AbstractBoundingBox)SupportsBoundingBox)make_polygon_structurewinding_deconstructiongroup_pathsflatten_polygonsT)boundPolygonr   	BoxStructz
bbox, pathc                  ^^^ SS jn      SS jmSUU4S jjmS	U4S jjm/ nU  H@  nUR                  5       nUR                  (       d  M&  UR                  [        XC5      5        MB     UR	                  US9  T" T" U5      5      $ )
zpReturns a recursive polygon structure from iterable `paths`, uses 2D
bounding boxes as fast detection objects.

c                `    U R                   R                  nUR                  UR                  -  $ N)bboxsizexy)itemr   s     D/var/www/html/env/lib/python3.13/site-packages/ezdxf/path/nesting.pyarea$make_polygon_structure.<locals>.areae   s!    yy~~vv    c                    / n/ nU H@  nU R                  UR                  R                  5      (       a  UOUR                  U5        MB     X#4$ r   )insider   centerappend)exterior
candidatesholesoutside	candidates        r   separate(make_polygon_structure.<locals>.separatei   sM     "$#%#Iooinn&;&;<<U'QQ $
 ~r"   c                   > / nU (       aQ  U R                  5       nT" UR                  U 5      u  p0U(       a  T" U5      nUR                  U/UQ5        U (       a  MQ  U$ r   )popr   r&   )r*   polygonsr'   r)   polygon_structurer,   s       r   r1   1make_polygon_structure.<locals>.polygon_structureu   s[    {{}H &hmmW=NE *%0OOX../ g r"   c                   > U  Vs/ s H,  n[        U[        5      (       a  UR                  OT" U5      PM.     sn$ s  snf r   )
isinstancer   path)r0   polygonas_nested_pathss     r   r7   /make_polygon_structure.<locals>.as_nested_paths   sE     $
# 'w	::GLLPW@XX#
 	
 
s   3<)key)r   r   returnfloat)r'   r   r(   list[BoxStruct]r:   z'tuple[list[BoxStruct], list[BoxStruct]])r*   r<   r:   z
list[list])r:   list)r   has_datar&   r   sort)pathsr    boxed_pathsr5   r   r7   r1   r,   s        @@@r   r   r   ^   s    
%
3B
	0
 
 Kyy{===y45  ,[9::r"   c                :   ^^^ UUU4S jm/ m/ mT" U S5        TT4$ )a	  Flatten the nested polygon structure in a tuple of two lists,
the first list contains the paths which should be counter-clockwise oriented
and the second list contains the paths which should be clockwise oriented.

The paths are not converted to this orientation.

c                   > U  HB  n[        U[        5      (       a  T" X!S-   5        M%  US-  (       a  TOTR                  U5        MD     g )N      )r4   r   r&   )	polygons_levelr6   	ccw_pathscw_pathsdeconstructs      r   rJ   +winding_deconstruction.<locals>.deconstruct   s>     G'8,,GQY/  %qyx??H !r"   r    )r0   rH   rI   rJ   s    @@@r   r   r      s*    I HI!hr"   c              #  ~   #    U  H1  n[        U[        5      (       a  [        U5       Sh  vN   M-  Uv   M3     g N7f)z9Yield a flat representation of the given nested polygons.N)r4   r   r   )r0   r6   s     r   r   r      s2     gx(('000M	 0s   )=;=c                l    [        U 5      nU Vs/ s H  n[        [        U5      5      PM     sn$ s  snf )z:Group separated paths and their inner holes as flat lists.)r   r=   r   )r@   r0   r6   s      r   r   r      s/    %e,H;CD8D!'*+8DDDs   1N)r@   Iterable[T]r:   list[Polygon])r0   rP   r:   ztuple[list[T], list[T]])r0   r   r:   zIterator[T])r@   rO   r:   zlist[list[T]])__doc__
__future__r   typingr   r   r   r   r   r	   r
   typing_extensionsr   collectionsr   
ezdxf.mathr   ezdxf.protocolsr   __all__r   r   __annotations__r   r   r   r   r   rL   r"   r   <module>rZ      s   <z #   ( " * / C*+1htI778 8{L1	2;j4Er"   