
    'j<                    ~   d dl mZ d dlmZmZmZmZmZmZm	Z	 d dl
Z
d dlmZmZmZmZmZmZ d dlmZmZ e	rd dlmZ g dZ G d d	e
j                  Z G d
 de          Z G d d          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z ddZ!d dZ"dS )!    )annotations)OptionalIterableIteratorSequence
NamedTupleCallableTYPE_CHECKINGN)Matrix44Vec2BoundingBox2dUVecis_convex_polygon_2dis_axes_aligned_rectangle_2d)NumpyPath2dNumpyPoints2d)Clipping)ClippingShapeClippingPortalClippingRectConvexClippingPolygonInvertedClippingPolygon	MultiClipfind_best_clipping_shapemake_inverted_clipping_shapec                  D   e Zd ZdZej        dd            Zej        dd            Zej        dd            Zej        d d            Z	ej        d!d            Z
ej        d"d            Zej        d"d            Zej        d#d            Zej        d#d            ZdS )$r   a  The ClippingShape defines a single clipping path and executes the clipping on
    basic geometries:

    - point: a single point
    - line: a line between two vertices
    - polyline: open polyline with one or more straight line segments
    - polygon: closed shape with straight line as edges
    - path: open shape with straight lines and Bezier-curves as segments
    - filled-path: closed shape with straight lines and Bezier-curves as edges

    Difference between open and closed shapes:

        - an open shape is treated as a linear shape without a filling
        - clipping an open shape returns one or more open shapes
        - a closed shape is treated as a filled shape, where the first vertex is
          coincident to the last vertex.
        - clipping a closed shape returns one or more closed shapes

    Notes:

        An arbitrary clipping polygon can split any basic geometry (except point) into
        multiple parts.

        All current implemented clipping algorithms flatten Bezier-curves into polylines.

    returnr   c                    d S N selfs    U/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/tools/clipping_portal.pybboxzClippingShape.bboxD   s    %(S    otherboolc                    d S r   r    r"   r&   s     r#   is_completely_insidez"ClippingShape.is_completely_insideG   s    BE#r%   c                    d S r   r    r)   s     r#   is_completely_outsidez#ClippingShape.is_completely_outsideL   s    CF3r%   pointr   Optional[Vec2]c                    d S r   r    )r"   r-   s     r#   
clip_pointzClippingShape.clip_pointO   s    9<r%   startendSequence[tuple[Vec2, Vec2]]c                    d S r   r    r"   r1   r2   s      r#   	clip_linezClippingShape.clip_lineR   s    PSPSr%   pointsr   Sequence[NumpyPoints2d]c                    d S r   r    r"   r7   s     r#   clip_polylinezClippingShape.clip_polylineU   s    ORsr%   c                    d S r   r    r:   s     r#   clip_polygonzClippingShape.clip_polygonX   s    NQcr%   pathsIterable[NumpyPath2d]max_sagittafloatIterator[NumpyPath2d]c                    d S r   r    r"   r>   r@   s      r#   
clip_pathszClippingShape.clip_paths[   	     !$r%   c                    d S r   r    rD   s      r#   clip_filled_pathszClippingShape.clip_filled_paths`   rF   r%   Nr   r   r&   r   r   r'   r-   r   r   r.   r1   r   r2   r   r   r3   r7   r   r   r8   r>   r?   r@   rA   r   rB   )__name__
__module____qualname____doc__abcabstractmethodr$   r*   r,   r0   r6   r;   r=   rE   rH   r    r%   r#   r   r   (   s        6 	((( (EEE E 	FFF F<<< <SSS SRRR RQQQ Q$ $ $ $ 	$ $ $ $ $ $r%   r   c                  $    e Zd ZU ded<   ded<   dS )ClippingStager   portalMatrix44 | None	transformN)rO   rP   rQ   __annotations__r    r%   r#   rV   rV   f   s*         r%   rV   c                      e Zd ZdZd(dZed)d            Zd*dZd(dZd+dZ	d,dZ
d-dZd.dZd.dZd/d"Zd/d#Zd0d&Zd'S )1r   z1The ClippingPortal manages a clipping path stack.r   Nonec                    g | _         d S r   _stagesr!   s    r#   __init__zClippingPortal.__init__n   s    ,.r%   r'   c                *    t          | j                  S r   )r'   r_   r!   s    r#   	is_activezClippingPortal.is_activeq   s    DL!!!r%   rW   r   rY   rX   c                V    | j                             t          ||                     d S r   )r_   appendrV   )r"   rW   rY   s      r#   pushzClippingPortal.pushu   s(    M&)<<=====r%   c                J    | j         r| j                                          d S d S r   )r_   popr!   s    r#   rg   zClippingPortal.popx   s0    < 	L	 	r%   commandCallable[[ClippingStage], bool]c                H    | j         d d d         D ]} ||          s d S d S Nr^   )r"   rh   stages      r#   foreach_stagezClippingPortal.foreach_stage|   sD    \$$B$' 	 	E75>> 	 	r%   r-   r   r.   c                B    |dfd}|                      |           S )Nrm   rV   r   r'   c                    J | j         r't          | j                                                  | j                                      d uS r   )rY   r   rW   r0   )rm   results    r#   doz%ClippingPortal.clip_point.<locals>.do   sW    %%% Aeo77??@@\,,V44F%%r%   rm   rV   r   r'   rn   )r"   r-   rr   rq   s      @r#   r0   zClippingPortal.clip_point   sA    #	& 	& 	& 	& 	& 	& 	2r%   r1   r2   list[tuple[Vec2, Vec2]]c                H    dfd}||fg|                      |           S )Nrm   rV   r   r'   c                    t                    }                                 |D ]Y\  }}| j        r| j                            ||f          \  }}                    | j                            ||                     Zt                    S r   )listclearrY   fast_2d_transformextendrW   r6   r'   )rm   linesserq   s       r#   rr   z$ClippingPortal.clip_line.<locals>.do   s    LLELLNNN < <1? E ?<<aVDDDAqel44Q::;;;;<<r%   rs   rt   )r"   r1   r2   rr   rq   s       @r#   r6   zClippingPortal.clip_line   sG    	  	  	  	  	  	  #,2r%   r7   r   list[NumpyPoints2d]c                D    dfd}|g|                      |           S )Nrm   rV   r   r'   c                   t                    }                                 |D ]P}| j        r|                    | j                                       | j                            |                     Qt                    S r   )rx   ry   rY   transform_inplacer{   rW   r;   r'   )rm   	polylinespolylinerq   s      r#   rr   z(ClippingPortal.clip_polyline.<locals>.do   s~    VILLNNN% D D? @..u???el88BBCCCC<<r%   rs   rt   r"   r7   rr   rq   s      @r#   r;   zClippingPortal.clip_polyline   C    	  	  	  	  	  	  2r%   c                D    dfd}|g|                      |           S )Nrm   rV   r   r'   c                   t                    }                                 |D ]P}| j        r|                    | j                                       | j                            |                     Qt                    S r   )rx   ry   rY   r   r{   rW   r=   r'   )rm   polygonspolygonrq   s      r#   rr   z'ClippingPortal.clip_polygon.<locals>.do   s}    F||HLLNNN# B B? ?--eo>>>el77@@AAAA<<r%   rs   rt   r   s      @r#   r=   zClippingPortal.clip_polygon   r   r%   r>   r?   r@   rA   list[NumpyPath2d]c                `    dfd}t          |          |                     |           S )Nrm   rV   r   r'   c                   t                    }                                 |D ]#}| j        r|                    | j                   $                    | j                            |                     t                    S r   )rx   ry   rY   r   r{   rW   rE   r'   rm   r>   pathr@   rq   s      r#   rr   z%ClippingPortal.clip_paths.<locals>.do   s{    LLELLNNN < <? <**5?;;;MM%,11%EEFFF<<r%   rs   rx   rn   r"   r>   r@   rr   rq   s     ` @r#   rE   zClippingPortal.clip_paths   M    	  	  	  	  	  	  	  e2r%   c                `    dfd}t          |          |                     |           S )Nrm   rV   r   r'   c                   t                    }                                 |D ]#}| j        r|                    | j                   $                    | j                            |                     t                    S r   )rx   ry   rY   r   r{   rW   rH   r'   r   s      r#   rr   z,ClippingPortal.clip_filled_paths.<locals>.do   s{    LLELLNNN < <? <**5?;;;MM%,88LLMMM<<r%   rs   r   r   s     ` @r#   rH   z ClippingPortal.clip_filled_paths   r   r%   mr   c                @    | j         d d d         D ]\  }}|||z  }|S rk   r^   )r"   r   _rY   s       r#   transform_matrixzClippingPortal.transform_matrix   s7     L2. 	 	LAy$Yr%   N)r   r\   )r   r'   )rW   r   rY   rX   r   r\   )rh   ri   r   r\   rK   )r1   r   r2   r   r   ru   )r7   r   r   r   )r>   r?   r@   rA   r   r   )r   r   r   r   )rO   rP   rQ   rR   r`   propertyrb   re   rg   rn   r0   r6   r;   r=   rE   rH   r   r    r%   r#   r   r   k   s       ;;/ / / / " " " X"> > > >      
                         r%   r   c                  R    e Zd ZdZddZd d	Zd!dZd"dZd#dZd#dZ	d$dZ
d$dZdS )%ClippingPolygonzpRepresents an arbitrary polygon as clipping shape.  Removes the geometry
    outside the clipping polygon.

    r$   r   clipperr   r   r\   c                N    |j         st          d          || _        || _        d S )Nclipping box not detectable)has_data
ValueError_bboxr   )r"   r$   r   s      r#   r`   zClippingPolygon.__init__   s-    } 	<:;;;
r%   c                    | j         S r   )r   r!   s    r#   r$   zClippingPolygon.bbox   s
    zr%   r-   r   r.   c                \    | j                             t          |                    }|sd S |S r   )r   	is_insider   )r"   r-   r   s      r#   r0   zClippingPolygon.clip_point   s/    L**4;;77	 	4r%   r1   r2   r3   c                8    | j                             ||          S r   )r   r6   r5   s      r#   r6   zClippingPolygon.clip_line   s    |%%eS111r%   r7   r   r8   c                l   | j         }t          |          dk    rt                      S t          |                                          }|                     |          rt                      S |                     |          r|fS d |                    |                                          D             S )Nr   c                R    g | ]$}t          |          d k    t          |          %S r   lenr   .0parts     r#   
<listcomp>z1ClippingPolygon.clip_polyline.<locals>.<listcomp>  7     
 
 
4yy1}} $}}r%   )	r   r   tupler   extentsr,   r*   r;   vertices)r"   r7   r   polyline_bboxs       r#   r;   zClippingPolygon.clip_polyline   s    ,v;;!77N%fnn&6&677%%m44 	77N$$]33 	9
 
--foo.?.?@@
 
 
 	
r%   c                l   | j         }t          |          dk     rt                      S t          |                                          }|                     |          rt                      S |                     |          r|fS d |                    |                                          D             S )N   c                R    g | ]$}t          |          d k    t          |          %S r   r   r   s     r#   r   z0ClippingPolygon.clip_polygon.<locals>.<listcomp>  r   r%   )	r   r   r   r   r   r,   r*   r=   r   )r"   r7   r   polygon_bboxs       r#   r=   zClippingPolygon.clip_polygon  s    ,v;;??77N$V^^%5%566%%l33 	77N$$\22 	9
 
,,V__->->??
 
 
 	
r%   r>   r?   r@   rA   rB   c              #    K   | j         }|D ]}|                                D ]}t          |                                          }|j        s+|                     |          r|V  E|                     |          r[t          j        |	                    |d                    }|
                    |          D ]-}t          |          dk    rt          j        |d          V  .Ȍd S )N   segmentsr   Fclose)r   	sub_pathsr   control_verticesr   r*   r,   r   rx   
flatteningr;   r   r   from_vertices)	r"   r>   r@   r   r   sub_path	path_bboxr   r   s	            r#   rE   zClippingPolygon.clip_paths  s"      , 	K 	KD NN,, K K)(*C*C*E*EFF	 ) ,,Y77 "NNN--i88 9X%8%8q%8%Q%QRR#11(;; K KD4yy1}})7EJJJJJJKK	K 	Kr%   c           
   #    K   | j         }|D ]}|                                D ]}t          |          dk     rt          |                                          }|                     |          r|V  Q|                     |          rg|                    t          j	        |
                    |d                              D ]-}t          |          dk    rt          j        |d          V  .Ҍd S )Nr   r   r   r   Tr   )r   r   r   r   r   r*   r,   r=   r   rx   r   r   r   )r"   r>   r@   r   r   r   r   r   s           r#   rH   z!ClippingPolygon.clip_filled_paths)  s*      , 	J 	JD NN,, J Jx==1$$)(*C*C*E*EFF	,,Y77 "NNN--i88 #00Ih11+1JJKK  J JD 4yy1}})7DIIIIII	JJ	J 	Jr%   N)r$   r   r   r   r   r\   rI   rK   rL   rM   rN   )rO   rP   rQ   rR   r`   r$   r0   r6   r;   r=   rE   rH   r    r%   r#   r   r      s         
         2 2 2 2
 
 
 

 
 
 
K K K K&J J J J J Jr%   r   c                  x     e Zd ZdZd  fdZd!d
Zd!dZd" fdZd#dZd$ fdZ	d$ fdZ
d% fdZd% fdZ xZS )&r   zRepresents a rectangle as clipping shape where the edges are parallel to
    the x- and  y-axis of the coordinate system.  Removes the geometry outside the
    clipping rectangle.

    r   Iterable[UVec]r   r\   c                0   ddl m} t          j        |          }t	          |          }|j        st          d          |j        }|j        |j	        z  dk     | _
        t                                          | ||j        |j                             d S )Nr   )ClippingRect2dr   g&.>)ezdxf.math.clippingr   r   rx   r   r   r   sizexy
remove_allsuperr`   extminextmax)r"   r   r   r   r$   r   	__class__s         r#   r`   zClippingRect.__init__E  s    666666)H%%W%%} 	<:;;;Y&46/D0~~dk4;GGHHHHHr%   r&   r   r'   c                6    | j                             |          S r   )r   containsr)   s     r#   r*   z!ClippingRect.is_completely_insideQ  s    z""5)))r%   c                8    | j                             |           S r   r   has_intersectionr)   s     r#   r,   z"ClippingRect.is_completely_outsideT      :..u5555r%   r-   r   r.   c                X    | j         rd S t                                          |          S r   )r   r   r0   )r"   r-   r   s     r#   r0   zClippingRect.clip_pointW  s*    ? 	4ww!!%(((r%   r1   r2   r3   c                b    | j         rt                      S | j                            ||          S r   )r   r   r   r6   r5   s      r#   r6   zClippingRect.clip_line\  s-    ? 	77N|%%eS111r%   r7   r   r8   c                    | j         rt          t                                fS t                                          |          S r   )r   r   r   r   r;   r"   r7   r   s     r#   r;   zClippingRect.clip_polylinea  s:    ? 	-!%''**,,ww$$V,,,r%   c                    | j         rt          t                                fS t                                          |          S r   )r   r   r   r   r=   r   s     r#   r=   zClippingRect.clip_polygonf  s:    ? 	-!%''**,,ww##F+++r%   r>   r?   r@   rA   rB   c                    | j         rt          t                                S t                                          ||          S r   )r   iterr   r   rE   r"   r>   r@   r   s      r#   rE   zClippingRect.clip_pathsk  s9     ? 	!== ww!!%555r%   c                    | j         rt          t                                S t                                          ||          S r   )r   r   r   r   rH   r   s      r#   rH   zClippingRect.clip_filled_pathsr  s9     ? 	!== ww((<<<r%   r   r   r   r\   rJ   rK   rL   rM   rN   )rO   rP   rQ   rR   r`   r*   r,   r0   r6   r;   r=   rE   rH   __classcell__r   s   @r#   r   r   >  s        
I 
I 
I 
I 
I 
I* * * *6 6 6 6) ) ) ) ) )
2 2 2 2
- - - - - -
, , , , , ,
6 6 6 6 6 6= = = = = = = = = =r%   r   c                  4     e Zd ZdZd fdZdd
ZddZ xZS )r   zwRepresents an arbitrary convex polygon as clipping shape.  Removes the geometry
    outside the clipping polygon.

    r   r   r   r\   c                    ddl m} t          j        |          }t	                                          t          |           ||                     d S )Nr   )ConvexClippingPolygon2d)r   r   r   rx   r   r`   r   )r"   r   r   r   r   s       r#   r`   zConvexClippingPolygon.__init__  sX    ??????)H%%w//1H1H1Q1QRRRRRr%   r&   r   r'   c                    dS NFr    r)   s     r#   r*   z*ConvexClippingPolygon.is_completely_inside      ur%   c                8    | j                             |           S r   r   r)   s     r#   r,   z+ConvexClippingPolygon.is_completely_outside  r   r%   r   rJ   rO   rP   rQ   rR   r`   r*   r,   r   r   s   @r#   r   r   z  su         
S S S S S S   6 6 6 6 6 6 6 6r%   r   c                  4     e Zd ZdZd fdZdd
ZddZ xZS )ConcaveClippingPolygonzxRepresents an arbitrary concave polygon as clipping shape.  Removes the geometry
    outside the clipping polygon.

    r   r   r   r\   c                    ddl m} t          j        |          }t	                                          t          |           ||                     d S )Nr   )ConcaveClippingPolygon2d)r   r   r   rx   r   r`   r   )r"   r   r   r   r   s       r#   r`   zConcaveClippingPolygon.__init__  sX    @@@@@@)H%%w//1I1I'1R1RSSSSSr%   r&   r   r'   c                    dS r   r    r)   s     r#   r*   z+ConcaveClippingPolygon.is_completely_inside  r   r%   c                8    | j                             |           S r   r   r)   s     r#   r,   z,ConcaveClippingPolygon.is_completely_outside  r   r%   r   rJ   r   r   s   @r#   r   r     su         
T T T T T T   6 6 6 6 6 6 6 6r%   r   c                  4     e Zd ZdZd fdZddZddZ xZS )r   zRepresents an arbitrary inverted clipping polygon.  Removes the geometry
    inside the clipping polygon.

    .. Important:: 
    
        The `outer_bounds` must be larger than the content to clip to work correctly.

    r   r   outer_boundsr   r   r\   c                    ddl m} t          j        |          }t	                                          | |||                     d S )Nr   )InvertedClippingPolygon2d)r   r   r   rx   r   r`   )r"   r   r   r   r   r   s        r#   r`   z InvertedClippingPolygon.__init__  sR    AAAAAA)H%%'@'@,'W'WXXXXXr%   r&   r'   c                    dS r   r    r)   s     r#   r*   z,InvertedClippingPolygon.is_completely_inside  s    ur%   c                8    | j                             |           S r   r   r)   s     r#   r,   z-InvertedClippingPolygon.is_completely_outside  r   r%   )r   r   r   r   r   r\   rJ   r   r   s   @r#   r   r     su         Y Y Y Y Y Y   6 6 6 6 6 6 6 6r%   r   r   r   r   c                    t          j        |           }t          |          rt          |          S t	          |d          rt          |          S t          |          S )a  Returns the best clipping shape for the given clipping polygon.

    The function analyses the given polygon (rectangular, convex or concave polygon, ...)
    and returns the optimized (fastest) clipping shape.

    Args:
        polygon: clipping polygon as iterable vertices

    F)strict)r   rx   r   r   r   r   r   )r   r7   s     r#   r   r     sb     YwF#F++ -F###	fU	3	3	3 -$V,,,!&)))r%   r   r   c                "    t          | |          S )zReturns an inverted clipping shape that removes the geometry inside the clipping
    polygon and beyond the outer bounds.

    Args:
        polygon: clipping polygon as iterable vertices
        outer_bounds: outer bounds of the clipping shape

    )r   )r   r   s     r#   r   r     s     #7L999r%   )r   r   r   r   )r   r   r   r   r   r   )#
__future__r   typingr   r   r   r   r   r	   r
   rS   
ezdxf.mathr   r   r   r   r   r   ezdxf.npshapesr   r   r   r   __all__ABCr   rV   r   r   r   r   r   r   r   r   r    r%   r#   <module>r     s   # " " " " "                  


                6 5 5 5 5 5 5 5 -,,,,,,	 	 	;$ ;$ ;$ ;$ ;$CG ;$ ;$ ;$|    J   
r r r r r r r rj[J [J [J [J [Jm [J [J [J|9= 9= 9= 9= 9=? 9= 9= 9=x6 6 6 6 6O 6 6 6&6 6 6 6 6_ 6 6 6&6 6 6 6 6o 6 6 60* * * *$: : : : : :r%   