
    hu<                       S SK Jr  S SKJrJrJr  S SKJr  S SKrS SK	J
r
  S SKJr  S SKJrJrJrJrJr  S SKJr  S S	KJrJr  S S
KJr  / SQr " S S\R4                  5      r " S S\5      r " S S\5      r " S S\5      rSS.       SS jjrSS.       SS jjr SS.       SS jjr! S       S S jjr"SS.       S!S jjr#SS.       S"S jjr$SS.       S#S jjr% " S S5      r&g)$    )annotations)IterableCallableSequence)overrideN)bbox)	DXFEntity)UVecVec2Vec3BoundingBox2dis_point_in_polygon_2d)CohenSutherlandLineClipping2d)rtreeBoundingBox)EntityQuery)
bbox_chainedbbox_crosses_fencebbox_insidebbox_outsidebbox_overlapCirclePlanarSearchIndexpoint_in_bboxPolygonWindowc                      \ rS rSrSr\R                  SS j5       r\R                  SS j5       r\R                  SS j5       r	Sr
g)	SelectionShape   znAbstractBaseClass for selection shapes.

It is guaranteed that all methods get an entity_bbox which has data!
c                    g N selfentity_bboxs     >/var/www/html/env/lib/python3.13/site-packages/ezdxf/select.pyis_inside_bboxSelectionShape.is_inside_bbox$   s    BE    c                    g r!   r"   r#   s     r&   is_outside_bboxSelectionShape.is_outside_bbox'   s    CFr)   c                    g r!   r"   r#   s     r&   is_overlapping_bbox"SelectionShape.is_overlapping_bbox*   s    GJr)   r"   Nr%   r   returnbool)__name__
__module____qualname____firstlineno____doc__abcabstractmethodr'   r+   r.   __static_attributes__r"   r)   r&   r   r      sE    
 	E EF FJ Jr)   r   c                  ^    \ rS rSrSrS	S jr\S
S j5       r\S
S j5       r\S
S j5       r	Sr
g)r   .   zThis selection shape tests entities against a rectangular and axis-aligned 2D
window.  All entities are projected on the xy-plane.

Args:
    p1: first corner of the window
    p2: second corner of the window
c                &    [        X45      U l        g r!   )r   _bbox)r$   p1p2s      r&   __init__Window.__init__7   s    "B8,
r)   c                8    U R                   R                  U5      $ r!   )r>   containsr#   s     r&   r'   Window.is_inside_bbox:   s    zz"";//r)   c                B    U R                   R                  U5      (       + $ r!   r>   has_overlapr#   s     r&   r+   Window.is_outside_bbox>   s    ::))+666r)   c                8    U R                   R                  U5      $ r!   rG   r#   s     r&   r.   Window.is_overlapping_bboxB   s    zz%%k22r)   )r>   N)r?   r
   r@   r
   r0   )r3   r4   r5   r6   r7   rA   r   r'   r+   r.   r:   r"   r)   r&   r   r   .   sH    - 0 0 7 7 3 3r)   r   c                  h    \ rS rSrSrS
S jrSS jr\SS j5       r\SS j5       r	\SS j5       r
Srg	)r   G   zThis selection shape tests entities against a circle.  All entities are
projected on the xy-plane.

Args:
    center: center of the circle
    radius: radius of the circle
c                    [        U5      U l        [        U5      U l        [        U R                  U R                  5      n[	        U R                  U-
  U R                  U-   45      U l        g r!   )r   _centerfloat_radiusr   r>   )r$   centerradiusr_vecs       r&   rA   Circle.__init__P   sO    F|V}T\\4<<0"DLL5$8$,,:N#OP
r)   c                R    U R                   R                  U5      U R                  :*  $ r!   )rO   distancerQ   )r$   vs     r&   _is_vertex_insideCircle._is_vertex_insideV   s     ||$$Q'4<<77r)   c                J   ^  [        U 4S jUR                  5        5       5      $ )Nc              3  F   >#    U  H  nTR                  U5      v   M     g 7fr!   rY   .0rX   r$   s     r&   	<genexpr>(Circle.is_inside_bbox.<locals>.<genexpr>[   s!     R6Q4))!,,6Q   !)allrect_verticesr#   s   ` r&   r'   Circle.is_inside_bboxY   s    Rk6O6O6QRRRr)   c                .    U R                  U5      (       + $ r!   r.   r#   s     r&   r+   Circle.is_outside_bbox]       ++K888r)   c                   ^  T R                   R                  U5      (       d  g[        U 4S jUR                  5        5       5      (       a  gT R	                  UR
                  5      $ )NFc              3  F   >#    U  H  nTR                  U5      v   M     g 7fr!   r]   r^   s     r&   r`   -Circle.is_overlapping_bbox.<locals>.<genexpr>e   s!     N2MQt%%a((2Mrb   T)r>   rH   anyrd   rY   rR   r#   s   ` r&   r.   Circle.is_overlapping_bboxa   sO    zz%%k22N+2K2K2MNNN%%k&8&899r)   )r>   rO   rQ   N)rR   r
   rS   rP   )rX   r   r1   r2   r0   )r3   r4   r5   r6   r7   rA   rY   r   r'   r+   r.   r:   r"   r)   r&   r   r   G   sP    Q8 S S 9 9 : :r)   r   c                  h    \ rS rSrSrS
S jrSS jr\SS j5       r\SS j5       r	\SS j5       r
Srg	)r   j   zThis selection shape tests entities against an arbitrary closed polygon.
All entities are projected on the xy-plane. Complex **concave** polygons may not
work as expected.
c                0   [         R                  " U5      n[        U5      S:  a  [        S5      eUS   R	                  US   5      (       a  UR                  5         [        U5      S:  a  [        S5      eX l        [        U R                  5      U l        g )N   z3 or more vertices requiredr   )	r   listlen
ValueErrorisclosepop	_verticesr   r>   )r$   verticesrX   s      r&   rA   Polygon.__init__p   ss    IIhq6A::;;Q4<<"EEGq6A::;;%&"4>>2
r)   c                    [        X5      nU R                  n[        U5       H#  u  pVUR                  XES-
     U5      (       d  M#    g   g)N   TF)r   ry   	enumerate	clip_line)r$   extminextmaxcsrz   indexends          r&   _has_intersectionPolygon._has_intersection{   sF    *6:>>#H-JE||HQY/55 . r)   c                *  ^ ^^^^ T R                   R                  U5      (       d  g[        U 4S jUR                  5        5       5      (       a  gUR                  u  mmUR
                  u  mm[        UUUU4S jT R                   5       5      (       + $ )NFc              3  V   >#    U  H  n[        UTR                  5      S :  v   M      g7fr   Nr   ry   r^   s     r&   r`   )Polygon.is_inside_bbox.<locals>.<genexpr>   s(      
0 #1dnn590   &)c              3     >#    U  HJ  nTUR                   s=:  =(       a    T:  Os  =(       a    TUR                  s=:  =(       a    T:  Os  v   ML     g 7fr!   )xy)r_   rX   max_xmax_ymin_xmin_ys     r&   r`   r      s>      
ESUQSS  5 ;uqss':':U':;^s   AA)r>   rH   rm   rd   r   r   ry   )r$   r%   r   r   r   r   s   ` @@@@r&   r'   Polygon.is_inside_bbox   s    zz%%k22 
 ..0
 
 
  #))u"))u 
EI^^
 
 
 	
r)   c                .    U R                  U5      (       + $ r!   rg   r#   s     r&   r+   Polygon.is_outside_bbox   ri   r)   c                   ^  T R                   R                  U5      (       d  g[        U 4S jUR                  5        5       5      (       a  gT R	                  UR
                  UR                  5      $ )NFc              3  V   >#    U  H  n[        UTR                  5      S :  v   M      g7fr   r   r^   s     r&   r`   .Polygon.is_overlapping_bbox.<locals>.<genexpr>   s(      
0 #1dnn5:0r   T)r>   rH   rm   rd   r   r   r   r#   s   ` r&   r.   Polygon.is_overlapping_bbox   sd    zz%%k22 
 ..0
 
 
  %%k&8&8+:L:LMMr)   )r>   ry   N)rz   Iterable[UVec])r   r   r   r   r1   r2   r0   )r3   r4   r5   r6   r7   rA   r   r   r'   r+   r.   r:   r"   r)   r&   r   r   j   sO    
	3 
 
$ 9 9 
N 
Nr)   r   )cachec               .    [        XR                  U5      $ )zSelects entities whose bounding box lies withing the selection shape.

Args:
    shape: seclection shape
    entities: iterable of DXFEntities
    cache: optional :class:`ezdxf.bbox.Cache` instance

)select_by_bboxr'   shapeentitiesr   s      r&   r   r      s     ($8$8%@@r)   c               .    [        XR                  U5      $ )zSelects entities whose bounding box is completely outside the selection shape.

Args:
    shape: seclection shape
    entities: iterable of DXFEntities
    cache: optional :class:`ezdxf.bbox.Cache` instance

)r   r+   r   s      r&   r   r      s     ($9$95AAr)   c               .    [        XR                  U5      $ )zSelects entities whose bounding box overlaps the selection shape.

Args:
    shape: seclection shape
    entities: iterable of DXFEntities
    cache: optional :class:`ezdxf.bbox.Cache` instance

)r   r.   r   s      r&   r   r      s     ($=$=uEEr)   c                    / nU  HV  n[         R                  " U4SUS9nUR                  (       d  M-  U" [        U5      5      (       d  ME  UR	                  U5        MX     [        U5      $ )ah  Calculates the bounding box for each entity and returns all entities for that the
test function returns ``True``.

Args:
    entities: iterable of DXFEntities
    func: test function which takes the bounding box of the entity as input and
        returns ``True`` if the entity is part of the selection.
    cache: optional :class:`ezdxf.bbox.Cache` instance

Tfastr   )r   extentshas_datar   appendr   )r   	test_funcr   	selectionentityr   s         r&   r   r      s^     "$I,,yt5A]7+,,V$  y!!r)   c                  ^^ SUU4S jjn[         R                  " U 5      m[        T5      S:  a  [        S5      e[	        T5      m[        XU5      $ )aK  Selects entities whose bounding box intersects an open polyline.

All entities are projected on the xy-plane.

A single point can not be selected by a fence polyline by definition.

Args:
    vertices: vertices of the selection polyline
    entities: iterable of DXFEntities
    cache: optional :class:`ezdxf.bbox.Cache` instance

c           	     $  >^ ^ TR                  T 5      (       d  g[        U 4S jT 5       5      (       a  gT R                  nT R                  nUR	                  U5      (       a  g[        X5      m[        U4S j[        TTSS  5       5       5      $ )NFc              3  F   >#    U  H  nTR                  U5      v   M     g 7fr!   inside)r_   rX   r%   s     r&   r`   :bbox_crosses_fence.<locals>.is_crossing.<locals>.<genexpr>  s     8i{!!!$$irb   Tc              3  J   >#    U  H  u  pTR                  X5      v   M     g 7fr!   )r   )r_   startr   r   s      r&   r`   r     s#      
7TBLL$$7Ts    #r}   )rH   rm   r   r   rw   r   zip)r%   r   r   r   r>   ry   s   `  @r&   is_crossing'bbox_crosses_fence.<locals>.is_crossing  s      --8i888 ####>>&!!*6: 
7:9iPQPRm7T
 
 	
r)      z2 or more vertices requiredr0   )r   rt   ru   rv   r   r   )rz   r   r   r   r>   ry   s       @@r&   r   r      sL    &
 
  		(#I
9~677)$E(77r)   c               B   ^ SU4S jjn[        U 5      m[        XU5      $ )zSelects entities where the selection point lies within the bounding box.
All entities are projected on the xy-plane.

Args:
    point: selection point
    entities: iterable of DXFEntities
    cache: optional :class:`ezdxf.bbox.Cache` instance

c                &   > U R                  T5      $ r!   r   )r%   points    r&   r   "point_in_bbox.<locals>.is_crossing-  s    !!%((r)   r0   )r   r   )locationr   r   r   r   s       @r&   r   r      s     ) NE(77r)   c               b  ^ SU4S jjnTc  [         R                  " 5       mX" U 5      0n[        U5      nSnU(       aY  SnU HH  nXd;   a  M
  U" U5      nUR                  5        H"  nUR	                  U5      (       d  M  XtU'   Sn  MF     MJ     U(       a  MY  [        UR                  5       5      $ )uk  Selects elements that are directly or indirectly connected to each other by
overlapping bounding boxes. The selection begins at the specified starting element.

Warning: the current implementation has a complexity of O(n²).

Args:
    start: first entity of selection
    entities: iterable of DXFEntities
    cache: optional :class:`ezdxf.bbox.Cache` instance

c                D   > [        [        R                  " U 4STS95      $ )NTr   )r   r   r   )r   r   s    r&   get_bbox_2d!bbox_chained.<locals>.get_bbox_2dC  s    T\\6)$eLMMr)   TF)r   r	   r1   r   )r   Cachert   valuesrH   r   keys)	r   r   r   r   selectedrestartr   r%   selected_bboxs	     `      r&   r   r   4  s    N }

05{57I/JHH~HG
F!%f-K!)!2**=99'2V$"G	 "3	  ' x}}''r)   c                  Z    \ rS rSrSr  S	   S
S jjrSS jr      SS jrSS jrSr	g)r   i[  a  **Spatial Search Index for DXF Entities**

This class implements a spatial search index for DXF entities based on their
bounding boxes except for POINT and LINE.
It operates strictly within the two-dimensional (2D) space of the xy-plane.
The index is built once and cannot be extended afterward.

The index can be used to pre-select DXF entities from a certain area to reduce the
search space for other selection tools of this module.

**Functionality**

- The index relies on the bounding boxes of DXF entities, and only the corner
  vertices of these bounding boxes are indexed except for POINT and LINE.
- It can only find DXF entities that have at least one bounding box vertex located
  within the search area. Entities whose bounding boxes overlap the search area but
  have no vertices inside it will not be found (e.g., a circle whose center point
  is inside the search area but none of its bounding box vertices will not be
  included).
- The detection behavior can be customized by overriding the :meth:`detection_points`
  method.

**Recommendations**

Since this index is intended to be used in conjunction with other selection tools
within this module, it's recommended to maintain a bounding box cache to avoid
the computational cost of recalculating them frequently. This class creates a new
bounding box cache if none is specified. This cache can be accessed through the
public attribute :attr:`cache`.

Nc           	       ^^^	  " S S[         5      mSU4S jjmU=(       d    [        R                  " 5       U l        0 U l        / nU HR  nU R                  U5      nU(       d  M  [        U5      m	XPR                  T	'   UR                  UU	4S jU 5       5        MT     [        R                  " U[        S[        U5      5      S9U l        g )Nc                      \ rS rSrSrSrg),PlanarSearchIndex.__init__.<locals>.RTreeVtxi  uidr"   N)r3   r4   r5   r6   	__slots__r:   r"   r)   r&   RTreeVtxr     s     Ir)   r   c                $   > T" U 5      nXl         U$ r!   r   )r   r   vertexr   s      r&   detection_vertex4PlanarSearchIndex.__init__.<locals>.detection_vertex  s    h'FJMr)   c              3  6   >#    U  H  nT" UT5      v   M     g 7fr!   r"   )r_   pntr   r   s     r&   r`   -PlanarSearchIndex.__init__.<locals>.<genexpr>  s       &6Fs c**6Fs      )max_node_size)r   r   r   intr1   r   )r   r   r   r   	_entitiesdetection_pointsidextendr   RTreemaxr   _search_tree)
r$   r   r   r   detection_verticesr   r   r   r   r   s
          @@@r&   rA   PlanarSearchIndex.__init__|  s    	!t 	!	
 *djjl
/1-/F#44V<#V*C"(NN3%% &6F&   "KKc!S5G.H
r)   c                   UR                  5       nUS:X  a   [        UR                  R                  5      4$ US:X  a>  [        UR                  R                  5      [        UR                  R
                  5      4$ [        [        R                  " U4SU R                  S95      nUR                  (       a  UR                  5       $ [        5       $ )a  Returns the detection points for a given DXF entity.

The detection points must be 2D points projected onto the xy-plane (ignore z-axis).
This implementation returns the corner vertices of the entity bounding box.

Override this method to return more sophisticated detection points
(e.g., the vertices of LWPOLYLINE and POLYLINE or equally spaced raster points
for block references).
POINTLINETr   )dxftyper   dxfr   r   r   r   r   r   r   r   rd   tuple)r$   r   r   box2ds       r&   r   "PlanarSearchIndex.detection_points  s     .."g,,-//f))*D,@AAdllF94tzzRS>>&&((wr)   c                    U R                   R                  [        U5      U5      nU R                  n[	        S U 5       5       Vs/ s H  oTU   PM	     sn$ s  snf )zzReturns all DXF entities that have at least one detection point located
around `center` with a max. distance of `radius`.
c              3  8   #    U  H  oR                   v   M     g 7fr!   r   r_   rX   s     r&   r`   >PlanarSearchIndex.detection_point_in_circle.<locals>.<genexpr>       ,O<NqUU<N   )r   points_in_spherer   r   set)r$   rR   rS   r   r   r   s         r&   detection_point_in_circle+PlanarSearchIndex.detection_point_in_circle  sR     "..??VfU>>),,O<N,O)OP)O#)OPPPs   Ac                    U R                   R                  [        [        U5      [        U5      /5      5      nU R                  n[        S U 5       5       Vs/ s H  oTU   PM	     sn$ s  snf )zReturns all DXF entities that have at least one detection point located
inside or at the border of the rectangle defined by the two given corner points.
c              3  8   #    U  H  oR                   v   M     g 7fr!   r   r   s     r&   r`   <PlanarSearchIndex.detection_point_in_rect.<locals>.<genexpr>  r   r   )r   points_in_bboxr   r   r   r   )r$   r?   r@   r   r   r   s         r&   detection_point_in_rect)PlanarSearchIndex.detection_point_in_rect  sc     "..==b48,-
 >>),,O<N,O)OP)O#)OPPPs   A*)r   r   r   )Nr   )r   Iterable[DXFEntity]r   bbox.Cache | None)r   r	   r1   zSequence[Vec2])rR   r
   rS   rP   r1   Sequence[DXFEntity])r?   r
   r@   r
   r1   r   )
r3   r4   r5   r6   r7   rA   r   r   r   r:   r"   r)   r&   r   r   [  sS    F $(	
%
 !
>*QQ$)Q	QQr)   r   )r   r   r   r   r   r   r1   r   r!   )r   r   r   zCallable[[BoundingBox2d], bool]r   r   r1   r   )rz   r   r   r   r   r   r1   r   )r   r
   r   r   r   r   r1   r   )r   r	   r   r   r   r   r1   r   )'
__future__r   typingr   r   r   typing_extensionsr   r8   ezdxfr   ezdxf.entitiesr	   
ezdxf.mathr
   r   r   r   r   ezdxf.math.clippingr   r   r   ezdxf.queryr   __all__ABCr   r   r   r   r   r   r   r   r   r   r   r   r"   r)   r&   <module>r     s   # / / & 
  $ N N = ) #KSWW K 3^ 32 :^  :F;Nn ;ND  $	AA!A 	A
 A*  $	BB!B 	B
 B*  $	FF!F 	F
 F(  $"!"." " 	"<  $	(8(8!(8 	(8
 (8X RV8818=N88* TX$($( 3$(?P$($(NgQ gQr)   