
    OgM                       U d dl mZ d dlmZmZmZmZ d dlmZm	Z	 d dl
Z
d dl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 d dlmZmZmZmZmZmZm Z m!Z! 	 d dl"m#Z# g dZ% e&ejN                        Z( e&ejR                        Z* e&ejV                        Z, e&ejZ                        Z. G d	 d
e/      Z0 G d de0      Z1ejd                  Z3de4d<   ejj                  Z6de4d<    ejn                  g e6      Z8 ejn                  g e3      Z9 G d de
jt                        Z; G d de;      Z< G d de;      Z=d&dZ>dZ?dZ@dZAdZBde@feAeAfeBeBeBfe?fgZCddd&dZDd'd ZEd(d!ZF G d" d#e
jt                        ZG G d$ d%eG      ZHy# e$$ r dZ#Y +w xY w))    )annotations)IterableOptionalIteratorSequence)Self	TypeAliasN)	Matrix44UVecVec2Vec3has_clockwise_orientationBezier3PBezier4PBoundingBox2dBoundingBox)PathCommandPathElementLineToMoveToCurve3ToCurve4Tonesting)
np_support)	NumpyPath2dNumpyPoints2dNumpyPoints3dNumpyShapesExceptionEmptyShapeErrorto_qpainter_pathto_matplotlib_pathsingle_pathsorient_pathsc                      e Zd Zy)r   N__name__
__module____qualname__     S/var/www/html/public_html/myphp/venv/lib/python3.12/site-packages/ezdxf/npshapes.pyr   r   9       r+   r   c                      e Zd Zy)r    Nr&   r*   r+   r,   r    r    =   r-   r+   r    r	   CommandNumpyTypeVertexNumpyTypedtypec                  ~    e Zd ZU dZeZded<   ddZej                  dd       Z
ddZddZddZdd	Zdd
ZddZy)NumpyShape2dzThis is an optimization to store many 2D paths and polylines in a compact way
    without sacrificing basic functions like transformation and bounding box calculation.
    npt.NDArray[VertexNumpyType]	_verticesc                    | j                   }t        |      dkD  r4t        |j                  d            t        |j	                  d            fS t        d      zBReturns the extents of the bounding box as tuple (extmin, extmax).r   zempty shape has no extends)r6   lenr   minmaxr    selfvs     r,   extentszNumpyShape2d.extentsN   E    NNq6A:a>4a>11!">??r+   c                     y Nr*   r=   s    r,   clonezNumpyShape2d.cloneV       r+   c                    | j                   S rB   r6   rC   s    r,   np_verticeszNumpyShape2d.np_verticesZ       ~~r+   c                ^    | j                   }t        |      dk(  ry|j                  |d       y)-Transforms the vertices of the shape inplace.r   N   r6   r9   transform_array_inplacer=   mr>   s      r,   transform_inplacezNumpyShape2d.transform_inplace]   )    NNq6Q;	!!!Q'r+   c                R    | j                   D cg c]  }t        |       c}S c c}w )ziReturns the shape vertices as list of :class:`Vec2` 
        e.g. [Vec2(1, 2), Vec2(3, 4), ...] 
        r6   r   r<   s     r,   verticeszNumpyShape2d.verticesd   s      "&0AQ000   $c                R    | j                   D cg c]  }t        |       c}S c c}w )z[Returns the shape vertices as list of 2-tuples 
        e.g. [(1, 2), (3, 4), ...]
        )r6   tupler<   s     r,   	to_tupleszNumpyShape2d.to_tuplesj   s      #'..1Qa111rV   c                6    | j                   j                         S )zXReturns the shape vertices as list of lists 
        e.g. [[1, 2], [3, 4], ...]
        )r6   tolistrC   s    r,   to_listzNumpyShape2d.to_listp   s     ~~$$&&r+   c                4    t        | j                               S z)Returns the bounding box of all vertices.)r   r?   rC   s    r,   bboxzNumpyShape2d.bboxv   s    T\\^,,r+   N)returnztuple[Vec2, Vec2]r`   r   r`   r5   rP   r
   r`   Noner`   z
list[Vec2])r`   zlist[tuple[float, float]])r`   zlist[list[float]])r`   r   )r'   r(   r)   __doc__EMPTY_SHAPEr6   __annotations__r?   abcabstractmethodrD   rH   rQ   rU   rY   r\   r_   r*   r+   r,   r4   r4   G   sR     /:I+9@ 	 (12'-r+   r4   c                  ,    e Zd ZdZddZddZeZddZy)	r   z5Represents an array of 2D points stored as a ndarray.c                    |rEt        j                  |D cg c]  }|j                  |j                  f c}t              | _        y y c c}w Nr1   )nparrayxyr0   r6   r=   pointsr>   s      r,   __init__zNumpyPoints2d.__init__~   s9    XX%+,!##qss,ODN ,s   A	c                f    | j                  d       }| j                  j                         |_        |S rB   	__class__r6   copyr=   rD   s     r,   rD   zNumpyPoints2d.clone   )    t$..--/r+   c                ,    t        | j                        S rB   r9   r6   rC   s    r,   __len__zNumpyPoints2d.__len__       4>>""r+   N)rs   zOptional[Iterable[Vec2 | Vec3]]r`   rd   ra   r`   intr'   r(   r)   rf   rt   rD   __copy__r}   r*   r+   r,   r   r   {       ?
 H#r+   r   c                  0   e Zd ZU dZded<   ddZddZedd       Zedd       Z	ddZ
dd	ZeZd d
Zd!dZd"dZe	 d#	 	 	 	 	 d$d       Zed%d       Zed%d       Zed%d       Zed%d       Zd&dZd%dZddZddZddZd'd(dZd)dZed*d       Zy)+r   ab  Represents a 2D path, the path control vertices and commands are stored as ndarray.

    This class cannot build paths from scratch and is therefore not a drop-in replacement
    for the :class:`ezdxf.path.Path` class. Operations like transform and reverse are
    done inplace to utilize the `numpy` capabilities. This behavior is different from the
    :class:`ezdxf.path.Path` class!!!

    Construct new paths by the :class:`Path` class and convert them to
    :class:`NumpyPath2d` instances::

        path = Path((0, 0))
        path.line_to((50, 70))
        ...
        path2d = NumpyPath2d(path)

    znpt.NDArray[CommandNumpyType]	_commandsc                   |t         | _        t        | _        y |j	                         D cg c]  }|j
                  |j                  f }}t        |      dk(  r	 t        |j                        g}t        j                  |t              | _        t        j                  |j                         t              | _        y c c}w # t        $ r g }Y aw xY w)Nr   r1   )rg   r6   NO_COMMANDSr   control_verticesrp   rq   r9   r   start
IndexErrorrn   ro   r0   command_codesr/   )r=   pathr>   rU   s       r,   rt   zNumpyPath2d.__init__   s    <(DN(DN(,(=(=(?@1QSS!##J@@x=A ,- (/B$"4"4"6>NO A  s   CC CCc                ,    t        | j                        S rB   )r9   r   rC   s    r,   r}   zNumpyPath2d.__len__   r~   r+   c                2    t        | j                  d         S )z>Returns the start point as :class:`~ezdxf.math.Vec2` instance.r   r   r6   rC   s    r,   r   zNumpyPath2d.start   s     DNN1%&&r+   c                2    t        | j                  d         S )z<Returns the end point as :class:`~ezdxf.math.Vec2` instance.r   rC   s    r,   endzNumpyPath2d.end   s     DNN2&''r+   c                R    | j                   D cg c]  }t        |       c}S c c}w rB   rT   r<   s     r,   r   zNumpyPath2d.control_vertices   s    !%0AQ000rV   c                    | j                  d       }| j                  j                         |_        | j                  j                         |_        |S rB   )rw   r   rx   r6   ry   s     r,   rD   zNumpyPath2d.clone   s=    t$..--/..--/r+   c                ,    t        | j                        S )zInternal API.)listr   rC   s    r,   r   zNumpyPath2d.command_codes   s    DNN##r+   c              #  t  K   | j                         }d}| j                  D ]  }|t        k(  rt        ||          |dz  }"|t        k(  rt        ||dz      ||          |dz  }H|t        k(  r$t        ||dz      ||   ||dz             |dz  }u|t        k(  st        ||          |dz  } y w)N   rL      )
rU   r   CMD_LINE_TOr   CMD_CURVE3_TOr   CMD_CURVE4_TOr   CMD_MOVE_TOr   )r=   rU   indexcmds       r,   commandszNumpyPath2d.commands   s     ==?>> 	Ck!Xe_--
%x	2HUODD
%UQY'%(519:M  
#Xe_--
	s   BB8 B8c                    | j                   D cg c]  }t        |       }}| j                  D cg c]  }t        |       }}t	        j
                  ||      S c c}w c c}w )z0Returns a new :class:`ezdxf.path.Path` instance.)r6   r   r   r   r   from_vertices_and_commands)r=   r>   rU   cr   s        r,   to_pathzNumpyPath2d.to_path   sS    %)^^4DG44(,71GAJ77..xBB 57s
   AA c                    | d       }t        |      }t        |      dk(  r|S |r+|d   j                  |d         s|j                  |d          |D cg c]  }|j                  |j
                  f }}t        j                  |t              |_	        t        j                  t        |      dz
  t        t              |_        |S c c}w )Nr   r   r1   r   )
fill_valuer2   )r   r9   iscloseappendrp   rq   rn   ro   r0   r6   fullr   r/   r   )clsrU   closenew_pathr>   rs   s         r,   from_verticeszNumpyPath2d.from_vertices   s     t9>x=AO!,,Xb\:OOHQK(&./133*//XXfODWWK!O;K
  0s   C	c                &    t         | j                  v S )zoReturns ``True`` if the path is a :term:`Multi-Path` object that
        contains multiple sub-paths.

        )r   r   rC   s    r,   has_sub_pathszNumpyPath2d.has_sub_paths   s     dnn,,r+   c                ~    t        | j                        dkD  r%| j                  j                  | j                        S y)z>Returns ``True`` if the start point is close to the end point.r   F)r9   r6   r   r   r   rC   s    r,   	is_closedzNumpyPath2d.is_closed  s1     t~~"::%%dhh//r+   c                &    t         | j                  v S )z3Returns ``True`` if the path has any line segments.)r   r   rC   s    r,   	has_lineszNumpyPath2d.has_lines  s     dnn,,r+   c                N    t         | j                  v xs t        | j                  v S )z4Returns ``True`` if the path has any curve segments.)r   r   r   rC   s    r,   
has_curveszNumpyPath2d.has_curves  s!     .Q-4>>2QQr+   c           	     z   	 d 	fd} j                   t              dk(  rg S t        vr gS g  j                  d	dddD ]P  }|t        k(  rdz  n:|t
        k(  rdz  n+|t        k(  rdz  n|t        k(  r |        dz  	dz   dz  R d   t        k7  r |        S )zYield all sub-paths as :term:`Single-Path` objects.

        It's safe to call :meth:`sub_paths` on any path-type:
        :term:`Single-Path`, :term:`Multi-Path` and :term:`Empty-Path`.

        c                 x    j                  d       } dz    | _         | _        j                  |        y )Nr   )rw   r6   r   r   )	s	cmd_indexcmd_start_indexr   r=   	sub_pathsrU   	vtx_indexvtx_start_indexs	    r,   append_sub_pathz.NumpyPath2d.sub_paths.<locals>.append_sub_path  s?    nnT*A"?Y]CAK"?9=AKQr+   r   r   rL   r   r   )r`   rd   )r   r9   r   r6   r   r   r   )
r=   r   r   r   r   r   r   rU   r   r   s
   `  @@@@@@@r,   r   zNumpyPath2d.sub_paths  s    	  	  >>x=AIh&6M "	>>		 	Ck!Q	%Q	%Q	#!Q	"+"+a-NI	 B<;&r+   c                    | j                   rt        d      t        t        | j	                               S t        j                  | j
                        S )zReturns ``True`` if 2D path has clockwise orientation.

        Raises:
            TypeError: can't detect orientation of a :term:`Multi-Path` object

        z/can't detect orientation of a multi-path object)r   	TypeErrorr   r   rU   r6   rC   s    r,   r   z%NumpyPath2d.has_clockwise_orientation?  sE     MNN,T]]_==77GGr+   c                   | j                   }t        | j                         s| S |d   t        k(  rht        j                  |dd       j                         | _         t        j                  | j                  dddf   d      j                         | _        | S t        j                  |      j                         | _         t        j                  | j                  d      j                         | _        | S )z!Reverse path orientation inplace.r   N.r   axis)r   r9   r   rn   fliprx   r6   )r=   r   s     r,   reversezNumpyPath2d.reverseM  s    >>4>>"KB<;&
  WWXcr]388:DNWWT^^CRCH%=AFKKMDN   WWX.335DNWWT^^!<AACDNr+   c                F    | j                         s| j                          | S )zApply clockwise orientation inplace.

        Raises:
            TypeError: can't detect orientation of a :term:`Multi-Path` object

        r   r   rC   s    r,   	clockwisezNumpyPath2d.clockwise^  s     --/LLNr+   c                F    | j                         r| j                          | S )zApply counter-clockwise orientation inplace.

        Raises:
            TypeError: can't detect orientation of a :term:`Multi-Path` object

        r   rC   s    r,   counter_clockwisezNumpyPath2d.counter_clockwisei  s     ))+LLNr+   c           	   #  ~  K   t        | j                        sy| j                         }|d   }| d}| j                  D ]  }|t        k(  s	|t        k(  r||   }|dz  }| n|t
        k(  rW|||dz    \  }}|dz  }t        j                  t        |||f      j                  ||            }	t        |	       |	E d{    np|t        k(  rY|||dz    \  }
}}|dz  }t        j                  t        ||
||f      j                  ||            }	t        |	       |	E d{    nt        d|       |} y7 z7 w)z4Flatten path to vertices as :class:`Vec2` instances.Nr   r   rL   r   zInvalid command: )r9   r   rU   r   r   r   r   generater   
flatteningnextr   r   
ValueError)r=   distancesegmentsrU   r   r   r   end_locationctrlptsctrl1ctrl2s               r,   r   zNumpyPath2d.flatteningu  sW    4>>"==?>> 	!Ck!SK%7'
""%%-eeai%@"l
mmeT<89DDXxX S	%-5eeai-H*ul
mmeUE<@ALL (
 S	 #4SE!:;; E3	!  s%   B<D=>D9?A!D= D;!D=;D=c                   t        |      syt        | j                        s|d   }|dd }n| }|j                  g}|j                  g}|j                  }|D ]  }t        |j                        dk(  r|j	                  |j
                        sK|j                  t        j                  t        ft                     |j                  |j                         n|j                  |j                  dd        |j                  }|j                  |j                          t        j                  |d      | _        t        j                  |      | _        y)zExtend an existing path by appending additional paths. The paths are
        connected by MOVE_TO commands if the end- and start point of sequential paths
        are not coincident (multi-path).
        Nr   r   r1   r   )r9   r   r6   r   r   r   r   rn   ro   r   r/   concatenate)r=   pathsfirstrU   r   r   	next_paths          r,   extendzNumpyPath2d.extend  s   
 5z4>>"!HE!"IEE&+oo%6&+oo%6II 		1I9&&'1,;;y/+?O PQ	 3 34	 3 3AB 78--COOI//0		1 q91r+   c                n    | st        d      S | d   j                         }|j                  | dd        |S )zReturns a new path of concatenated paths. The paths are connected by
        MOVE_TO commands if the end- and start point of sequential paths are not
        coincident (multi-path).
        Nr   r   )r   rD   r   )r   r   s     r,   r   zNumpyPath2d.concatenate  s9     t$$a U12Yr+   N)r   zOptional[Path]r`   rd   r   )r`   r   re   ra   )r`   z	list[int])r`   zIterator[PathElement])r`   r   )F)rU   zIterable[Vec2 | Vec3]r   boolr`   r   )r`   r   )r`   z
list[Self])   )r   floatr   r   r`   zIterator[Vec2])r   Sequence[NumpyPath2d]r`   rd   )r   r   r`   r   )r'   r(   r)   rf   rh   rt   r}   propertyr   r   r   rD   r   r   r   r   classmethodr   r   r   r   r   r   r   r   r   r   r   r   staticmethodr   r*   r+   r,   r   r      s   " -,P# ' ' ( (1 H$&C <A,59	 " - -   - - R R+ZH"	
"!T2< 
 
r+   r   c           	        ddl m}m} t        |       } t	        |       dk(  rt        d       |       }| D ]  }|j                         D cg c]  } ||j                  |j                        ! }}|j                  |d          d}|j                         D ]  }|t        k(  r|j                  ||          |dz  }&|t        k(  r!|j                  ||   ||dz             |dz  }P|t        k(  r(|j!                  ||   ||dz      ||dz             |dz  }|t"        k(  s|j                  ||          |dz  } 
 |S c c}w )z>Convert the given `paths` into a single :class:`QPainterPath`.r   )QPainterPathQPointFone or more paths requiredr   rL   r   )ezdxf.addons.xqtr   r   r   r9   r   rU   rp   rq   moveTor   r   lineTor   quadTor   cubicTor   )	r   r   r   qpathr   r>   rs   r   r   s	            r,   r!   r!     sA   6KE
5zQ566NE -1]]_='!##qss#==VAY%%' 	Ck!VE]+
%VE]F519,=>
%fUmVEAI->uqy@QR
#VE]+
		$ L# >s   $Er   rL   r   r   )r   F)detect_holesc                  ddl m} t        |       } t        |       dk(  rt	        d      |rt        |       } g }g }| D ]c  }|j                  |j                                |j                  t               |j                         D ]  }|j                  t        |           e t        j                  |      }	  |||      S # t        $ r4}t	        dt        |       dt        |       dt        |             d}~ww xY w)a  Convert the given `paths` into a single :class:`matplotlib.path.Path`.

    Matplotlib requires counter-clockwise oriented outside paths and clockwise oriented
    holes. Set the `detect_holes` argument to ``True`` if this path orientation is not
    yet satisfied.
    r   )r   r   zmatplotlib.path.Path(z, z): N)matplotlib.pathr   r   r9   r   r$   r   rH   
MPL_MOVETOr   r   	MPL_CODESrn   r   	Exceptionstr)	r   r   r   rU   codesr   r   rs   es	            r,   r"   r"     s     %KE
5zQ566U#!#HE )((*+Z %%' 	)CLL3(	))
 ^^H%FYFE"" Y0VRE
|3sSTvhWXXYs   :C 	D /C;;D c                `    g }| D ]&  }|j                         }|s|j                  |       ( |S rB   )r   r   )r   single_paths_pr   s       r,   r#   r#     s:    ')M ,KKM	  +, r+   c                    t        |       }t        |      dk  r| S t        j                  |      }t        j                  |      \  }}|D ]  }|j                           |D ]  }|j                           ||z   S )zoReturns a new list of paths, with outer paths oriented counter-clockwise and
    holes oriented clockwise.
    rL   )r#   r9   r   make_polygon_structurewinding_deconstructionr   r   )r   r   polygonsouter_pathsholesr   s         r,   r$   r$     s     $0#6I
9~--i8H !77AK  ! ! r+   c                  n    e Zd ZU dZeZded<   ddZej                  dd       Z
ddZddZddZdd	Zy
)NumpyShape3dzThis is an optimization to store many 3D paths and polylines in a compact way
    without sacrificing basic functions like transformation and bounding box calculation.
    r5   r6   c                    | j                   }t        |      dkD  r4t        |j                  d            t        |j	                  d            fS t        d      r8   )r6   r9   r   r:   r;   r    r<   s     r,   r?   zNumpyShape3d.extents;  r@   r+   c                     y rB   r*   rC   s    r,   rD   zNumpyShape3d.cloneC  rE   r+   c                    | j                   S rB   rG   rC   s    r,   rH   zNumpyShape3d.np_verticesG  rI   r+   c                ^    | j                   }t        |      dk(  ry|j                  |d       y)rK   r   Nr   rM   rO   s      r,   rQ   zNumpyShape3d.transform_inplaceJ  rR   r+   c                R    | j                   D cg c]  }t        |       c}S c c}w )z4Returns the shape vertices as list of :class:`Vec3`.)r6   r   r<   s     r,   rU   zNumpyShape3d.verticesQ  s    !%0AQ000rV   c                4    t        | j                               S r^   )r   r?   rC   s    r,   r_   zNumpyShape3d.bboxU  s    4<<>**r+   N)r`   ztuple[Vec3, Vec3]ra   rb   rc   )r`   z
list[Vec3])r`   r   )r'   r(   r)   rf   rg   r6   rh   r?   ri   rj   rD   rH   rQ   rU   r_   r*   r+   r,   r  r  4  sH     /:I+9@ 	 (1+r+   r  c                  ,    e Zd ZdZddZddZeZddZy)	r   z5Represents an array of 3D points stored as a ndarray.c                    |rBt        j                  |D cg c]  }t        |      j                   c}t              | _        y y c c}w rm   )rn   ro   r   xyzr0   r6   rr   s      r,   rt   zNumpyPoints3d.__init__]  s5    XX&,-a-_DN -s   Ac                f    | j                  d       }| j                  j                         |_        |S rB   rv   ry   s     r,   rD   zNumpyPoints3d.clonec  rz   r+   c                ,    t        | j                        S rB   r|   rC   s    r,   r}   zNumpyPoints3d.__len__j  r~   r+   N)rs   zOptional[Iterable[UVec]]r`   rd   ra   r   r   r*   r+   r,   r   r   Z  r   r+   r   )r   Iterable[NumpyPath2d])r   r  r`   list[NumpyPath2d])r   r  r`   r  )I
__future__r   typingr   r   r   r   typing_extensionsr   r	   ri   numpyrn   numpy.typingnpt
ezdxf.mathr
   r   r   r   r   r   r   r   r   
ezdxf.pathr   r   r   r   r   r   r   r   	ezdxf.accr   ImportError__all__r   MOVE_TOr   LINE_TOr   	CURVE3_TOr   	CURVE4_TOr   r   r   r    int8r/   rh   float64r0   ro   rg   r   ABCr4   r   r   r!   r   
MPL_LINETO
MPL_CURVE3
MPL_CURVE4r   r"   r#   r$   r  r   r*   r+   r,   <module>r%     s   # 9 9 - 
  
 
 
	 	 	$
 '//"'//"G%%&G%%&	9 		* 	 !gg ) %ZZ 'bhhr1bhhr!121-377 1-h#L #(y, yx	< 



 	MZ(M	 FK Y>*#+377 #+L#L #o  Js   E< <FF