
    Og5E                       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
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 dgZdZd	Zd
ZdZ G d d      Z ejB                  dejD                  dejF                  dejH                  diZ%ddZ&y)    )annotations)OptionalIteratorIterableAnyCallable)Self)	Vec3NULLVECOCSBezier3PBezier4PMatrix44has_clockwise_orientationUVecBoundingBox   )CommandLineToMoveToCurve3ToCurve4ToPathElementPathg{Gz?   g-C6?)	_vertices_start_index	_commands_has_sub_paths
_user_datac                     e Zd ZeZefd*dZe	 d+	 	 	 	 	 	 	 d,d       Zd-dZ	d.dZ
d/dZd0dZd1dZd2d	Zd3d
Zd4dZeZed5d       Zej(                  d6d       Zed7d       Zej(                  d8d       Zed7d       Zd9dZ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d8dZd8dZ d=dZ!d>dZ"d?dZ#d?dZ$d@dZ%d3d Z&d3d!Z'd3d"Z(dAdBd#Z)dCdDd$Z*dEd%Z+dFd&Z,dGd'Z-dHd(Z.dHd)Z/y)Ir   c                ^    t        |      g| _        g | _        g | _        d| _        d | _        y )NF)r
   r   r   r   r   r    )selfstarts     T/var/www/html/public_html/myphp/venv/lib/python3.12/site-packages/ezdxf/path/path.py__init__zPath.__init__,   s-    &*5k]')(*##    Nc                     |        }t        |      dk(  r|S ||_        ||_        t        |      |_        t        d |D              |_        ||_        |S )zECreate path instances from a list of vertices and a list of commands.r   c              3  B   K   | ]  }|t         j                  k(    y wNr   MOVE_TO.0cmds     r%   	<genexpr>z2Path.from_vertices_and_commands.<locals>.<genexpr>C   s     %VcW__&<%V   )lenr   r   make_vertex_indexr   anyr   r    )clsverticescommand_codes	user_datanew_paths        r%   from_vertices_and_commandszPath.from_vertices_and_commands5   sY     5x=AO%* 1- @"%%V%V"V'r'   c                x    | j                         }t        |j                  | j                              |_        |S )zReturns a new transformed path.

        Args:
             m: transformation matrix of type :class:`~ezdxf.math.Matrix44`

        )clonelisttransform_verticesr   )r#   mr9   s      r%   	transformzPath.transformG   s0     ::<!!"6"6t~~"FGr'   c                4    t        | j                               S )zoReturns the bounding box of all control vertices as
        :class:`~ezdxf.math.BoundingBox` instance.
        )r   control_verticesr#   s    r%   bboxz	Path.bboxR   s     400233r'   c                ,    t        | j                        S )zReturns count of path elements.)r2   r   rC   s    r%   __len__zPath.__len__X   s    4>>""r'   c                   t        |t              rt        d      | j                  |   }| j                  |   }| j
                  }|t        j                  k(  rt        ||         S |t        j                  k(  rt        ||         S |t        j                  k(  rt        ||dz      ||         S |t        j                  k(  rt        ||dz      ||   ||dz            S t        d|       )zBReturns the path element at given index, slicing is not supported.zslicing not supportedr      Invalid command: )
isinstanceslice	TypeErrorr   r   r   r   r,   r   LINE_TOr   	CURVE3_TOr   	CURVE4_TOr   
ValueError)r#   itemr/   indexr6   s        r%   __getitem__zPath.__getitem__\   s    dE"344nnT"!!$'>>'//!(5/**'//!(5/**'###HUQY/%AA'##### 
 ,SE233r'   c                R      fdt        t         j                              D        S )Nc              3  (   K   | ]	  }|     y wr*    )r.   ir#   s     r%   r0   z Path.__iter__.<locals>.<genexpr>r   s     <AQ<s   )ranger2   r   rC   s   `r%   __iter__zPath.__iter__q   s    <s4>>':!;<<r'   c                4    t        | j                               S )z"Returns all path elements as list.)r=   rY   rC   s    r%   commandszPath.commandst   s    DMMO$$r'   c                    | j                         }| j                  j                         |_        | j                  |       |S )z?Returns a new copy of :class:`Path` with shared immutable data.)	__class__r   copy_copy_properties)r#   r^   s     r%   __copy__zPath.__copy__x   s5    ~~,,.d#r'   c                   t        | j                        t        |j                        k(  sJ | j                  j                         |_        | j                  j                         |_        | j
                  |_        | j                  |_        y r*   )r2   r   r   r^   r   r   r    )r#   r<   s     r%   r_   zPath._copy_properties   sg    4>>"c%//&::::..--/!..335#22??r'   c                    | j                   S )zAttach arbitrary user data to a :class:`Path` object.
        The user data is copied by reference, no deep copy is applied
        therefore a mutable state is shared between copies.
        r    rC   s    r%   r8   zPath.user_data   s     r'   c                    || _         y r*   rc   )r#   datas     r%   r8   zPath.user_data   s	    r'   c                     | j                   d   S )zc:class:`Path` start point, resetting the start point of an empty
        path is possible.
        r   r   rC   s    r%   r$   z
Path.start   s    
 ~~a  r'   c                b    | j                   rt        d      t        |      | j                  d<   y )NzRequires an empty path.r   )r   rP   r
   r   r#   locations     r%   r$   z
Path.start   s'    >>677 $XDNN1r'   c                     | j                   d   S )z:class:`Path` end point.rg   rC   s    r%   endzPath.end   s     ~~b!!r'   c                H    | j                   rt        | j                        S g S )z6Yields all path control vertices in consecutive order.)r   r=   r   rC   s    r%   rB   zPath.control_vertices   s    >>''	r'   c                ,    t        | j                        S )zInternal API.)r=   r   rC   s    r%   r7   zPath.command_codes   s    DNN##r'   c                f    | j                   }t        |      dkD  r|d   j                  |d         S y)z>Returns ``True`` if the start point is close to the end point.r   r   rl   F)r   r2   isclose)r#   r6   s     r%   	is_closedzPath.is_closed   s5     >>x=1A;&&x|44r'   c                :    t         j                  | j                  v S )z3Returns ``True`` if the path has any line segments.)r   rM   r   rC   s    r%   	has_lineszPath.has_lines   s     $..00r'   c                v    t         j                  | j                  v xs t         j                  | j                  v S )z4Returns ``True`` if the path has any curve segments.)r   rO   r   rN   rC   s    r%   
has_curveszPath.has_curves   s/     /V73D3D3V	
r'   c                    | j                   S )zoReturns ``True`` if the path is a :term:`Multi-Path` object that
        contains multiple sub-paths.

        )r   rC   s    r%   has_sub_pathszPath.has_sub_paths   s     """r'   c                Z    | j                   rt        d      t        | j                        S )zReturns ``True`` if 2D path has clockwise orientation, ignores
        z-axis of all control vertices.

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

        z/can't detect orientation of a multi-path object)rx   rL   r   r   rC   s    r%   r   zPath.has_clockwise_orientation   s(     MNN(88r'   c                   |j                   }|t        j                  k(  r| j                  |j                         y|t        j
                  k(  r| j                  |j                         y|t        j                  k(  r'| j                  |j                  |j                         y|t        j                  k(  r2| j                  |j                  |j                  |j                         yt        d|       )zAppend a single path element.rI   N)typer   rM   line_torm   r,   move_torN   	curve3_toctrlrO   	curve4_toctrl1ctrl2rP   )r#   r/   ts      r%   append_path_elementzPath.append_path_element   s    HHLL!'//!LL!'###NN377CHH-'###NN377CIIsyy90455r'   c                    | j                   j                  t        j                         | j                  j                  t        | j                               | j                  j                  t        |             y)z4Add a line from actual path end point to `location`.N)r   appendr   rM   r   r2   r   r
   ri   s     r%   r|   zPath.line_to   sK    goo.  T^^!45d8n-r'   c                   | j                   }|st        |      | j                  d<   yd| _        |d   t        j
                  k(  rD|j                          | j                  j                          | j                  j                          |j                  t        j
                         | j                  j                  t        | j                               | j                  j                  t        |             y)aS  Start a new sub-path at `location`. This creates a gap between the
        current end-point and the start-point of the new sub-path. This converts
        the instance into a :term:`Multi-Path` object.

        If the :meth:`move_to` command is the first command, the start point of
        the path will be reset to `location`.

        r   NTrl   )
r   r
   r   r   r   r,   popr   r   r2   )r#   rj   r[   s      r%   r}   zPath.move_to   s     >> $XDNN1"B<7??*LLNNN !!#(  T^^!45d8n-r'   c                   | j                   j                  t        j                         | j                  j                  t        | j                               | j                  j                  t        |      t        |      f       y)u   Add a quadratic Bèzier-curve from actual path end point to
        `location`, `ctrl` is the control point for the quadratic Bèzier-curve.
        N)	r   r   r   rN   r   r2   r   extendr
   )r#   rj   r   s      r%   r~   zPath.curve3_to  sX     	g//0  T^^!45tDz4>:;r'   c                $   | j                   j                  t        j                         | j                  j                  t        | j                               | j                  j                  t        |      t        |      t        |      f       y)u   Add a cubic Bèzier-curve from actual path end point to `location`,
        `ctrl1` and `ctrl2` are the control points for the cubic Bèzier-curve.
        N)	r   r   r   rO   r   r2   r   r   r
   )r#   rj   r   r   s       r%   r   zPath.curve4_to  s^     	g//0  T^^!45tE{DKhHIr'   c                T    | j                   s| j                  | j                         yy)z[Close path by adding a line segment from the end point to the start
        point.
        N)rr   r|   r$   rC   s    r%   closez
Path.close  s      ~~LL$ r'   c                    | j                   rG| j                         }|J d       | j                  j                  |      s| j	                  |       yy| j                          y)zClose last sub-path by adding a line segment from the end point to
        the start point of the last sub-path. Behaves like :meth:`close` for
        :term:`Single-Path` instances.
        Nz2internal error: required MOVE_TO command not found)rx   _start_of_last_sub_pathrm   rq   r|   r   )r#   start_points     r%   close_sub_pathzPath.close_sub_path  sa    
 668K'DCD'88##K0[) 1 JJLr'   c                    t         j                  }| j                  }t        |      dz
  }|dkD  r/||   |k(  r| j                  | j
                  |      S |dz  }|dkD  r/y )Nr   r   )r   r,   r   r2   r   r   )r#   r}   r[   rR   s       r%   r   zPath._start_of_last_sub_path,  sf    //>>H!ai')~~d&7&7&>??QJE ai r'   c                   | j                         }|j                  s|S |j                  d   t        j                  k(  ro|j                  j	                          |j
                  j	                          |j                  j	                          t        d |j                  D              |_        |j                  j                          |j
                  j                          t        |j                        |_        |S )zZReturns a new :class:`Path` with reversed commands and control
        vertices.

        rl   c              3  B   K   | ]  }|t         j                  k(    y wr*   r+   r-   s     r%   r0   z Path.reversed.<locals>.<genexpr>G  s      &+.w&&r1   )r<   r   r   r,   r   r   r   r4   r   reverser3   )r#   paths     r%   reversedzPath.reversed7  s    
 zz|~~K>>"0
 NN NN !!#"% &26..& #D 	  -dnn=r'   c                b    | j                         r| j                         S | j                         S )zReturns new :class:`Path` in clockwise orientation.

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

        )r   r<   r   rC   s    r%   	clockwisezPath.clockwiseO  s(     ))+::<==?"r'   c                b    | j                         r| j                         S | j                         S )zReturns new :class:`Path` in counter-clockwise orientation.

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

        )r   r   r<   rC   s    r%   counter_clockwisezPath.counter_clockwise[  s(     ))+==?"::<r'   c                @    dfd}dfd}| j                  ||      S )uY  Approximate path by vertices, `segments` is the count of
        approximation segments for each Bézier curve.

        Does not yield any vertices for empty paths, where only a start point
        is present!

        Approximation of :term:`Multi-Path` objects is possible, but gaps are
        indistinguishable from line segments.

        c                P    t        t        | ||f      j                              S r*   )iterr   approximate)p0p1p2segmentss      r%   curve3z Path.approximate.<locals>.curve3t  s$    "b".::8DEEr'   c                R    t        t        | |||f      j                              S r*   )r   r   r   )r   r   r   p3r   s       r%   curve4z Path.approximate.<locals>.curve4w  s'    "b"b!12>>xHIIr'   r   r
   r   r
   r   r
   returnIterator[Vec3]
r   r
   r   r
   r   r
   r   r
   r   r   _approximate)r#   r   r   r   s    `  r%   r   zPath.approximateh  s$    	F	J   00r'   c                F    dfd}dfd}| j                  ||      S )ug  Approximate path by vertices and use adaptive recursive flattening
        to approximate Bèzier curves. The argument `segments` is the
        minimum count of approximation segments for each curve, if the distance
        from the center of the approximation segment to the curve is bigger than
        `distance` the segment will be subdivided.

        Does not yield any vertices for empty paths, where only a start point
        is present!

        Flattening of :term:`Multi-Path` objects is possible, but gaps are
        indistinguishable from line segments.

        Args:
            distance: maximum distance from the center of the curve to the
                center of the line segment between two approximation points to
                determine if a segment should be subdivided.
            segments: minimum segment count per Bézier curve

        c                r    dk(  rt        d      t        t        | ||f      j                              S Ng        zinvalid max distance: 0.0)rP   r   r   
flattening)r   r   r   distancer   s      r%   r   zPath.flattening.<locals>.curve3  s9    3 #<>>"b".99(HMNNr'   c                t    dk(  rt        d      t        t        | |||f      j                              S r   )rP   r   r   r   )r   r   r   r   r   r   s       r%   r   zPath.flattening.<locals>.curve4  s<    3 #<>>"b"b!12==hQRRr'   r   r   r   )r#   r   r   r   r   s    ``  r%   r   zPath.flattening|  s$    *	O
	S
   00r'   c              #  8  K   | j                   sy | j                  d   }| | j                  }t        | j                  | j                         D ]  \  }}|t        j
                  k(  s|t        j                  k(  r
||   }| n|t        j                  k(  r+|||dz    \  }} ||||      }	t        |	       |	E d {    nN|t        j                  k(  r-|||dz    \  }
}} |||
||      }	t        |	       |	E d {    nt        d|       |} y 7 X7 w)Nr   rH      rI   )r   r   zipr   r   rM   r,   rN   nextrO   rP   )r#   r   r   r$   r6   sir/   end_locationr   ptsr   r   s               r%   r   zPath._approximate  s    ~~q!>>4,,dnn= 	!GBgoo%)?'|"")))%-b26%:"lUD,7S	)))-5b26-B*ulUE5,?S	 #4SE!:;; E!	! 
 s$   B;D=D>?D=D>DDc                P    t        fd| j                  D              | _        y)z;Transform path from given `ocs` to WCS coordinates inplace.c              3  r   K   | ].  }j                  |j                  t                            0 yw))zN)to_wcsreplacefloat)r.   v	elevationocss     r%   r0   zPath.to_wcs.<locals>.<genexpr>  s/      
:;CJJqyy5#3y45
s   47N)r=   r   )r#   r   r   s    ``r%   r   zPath.to_wcs  s      
?C~~
 
r'   c              #  \  K   | j                  | j                        }| j                  |_        t        j                  }| j                         D ]T  }|j                  |k(  r2| | j                  |j                        }| j                  |_        D|j                  |       V | yw)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`.

        )r$   N)	r]   r$   r    r   r,   r[   r{   rm   r   )r#   r   r}   r/   s       r%   	sub_pathszPath.sub_paths  s      ~~DJJ~/////==? 	.Cxx7"
~~CGG~4"&//((-	. 
s   B*B,c                    t        |      rB| j                  |j                         |j                         D ]  }| j	                  |        yy)zExtend the path by another path. The source path is automatically a
        :term:`Multi-Path` object, even if the previous end point matches the
        start point of the appended path. Ignores paths without any commands
        (empty paths).

        N)r2   r}   r$   r[   r   r#   r   r/   s      r%   extend_multi_pathzPath.extend_multi_path  sC     t9LL$}} .((-. r'   c                *   t        |      dk(  ry| j                  rA| j                  j                  |j                        s-| j                  |j                         n|j                  | _        |j                         D ]  }| j                  |        y)zAppend another path to this path. Adds a :code:`self.line_to(path.start)`
        if the end of this path != the start of appended path.

        r   N)r2   r   rm   rq   r$   r|   r[   r   r   s      r%   append_pathzPath.append_path  sm    
 t9>>>88##DJJ/TZZ(DJ==? 	*C$$S)	*r'   )r$   r   r*   )r6   
list[Vec3]r7   zlist[Command]r8   r   r   r	   )r?   r   r   r	   )r   r   )r   int)r   r   )r   zIterator[PathElement])r   zlist[PathElement])r   r	   )r<   r   r   None)r   r   )re   r   )r   r
   )rj   r   r   r   )r   r   )r   	list[int])r   bool)r/   r   r   r   )rj   r   r   r   r   r   )rj   r   r   r   r   r   r   r   )r   r   )r   zOptional[Vec3])   )r   r   r   r   )r   )r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   )r   zIterator[Self])r   r   r   r   )0__name__
__module____qualname___slots	__slots__r   r&   classmethodr:   r@   rD   rF   rS   rY   r[   r`   r_   r<   propertyr8   setterr$   rm   rB   r7   rr   rt   rv   rx   r   r   r|   r}   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rV   r'   r%   r   r   )   s   I%, $ RV!2?LO	 "	4#4*=%+ E    ! ! \\/ / " "$   1 1 
 
 # #
96...<J%	0
# 1(1B!4
&
.*r'   rH   r   c                Z    t         }d}g }| D ]  }|j                  |       |||   z  } |S )Nr   )CMD_SIZEr   )r7   cmd_sizer$   start_indexcodes        r%   r3   r3     sD    HEK  5!$  r'   N)r7   zIterable[Command]r   r   )'
__future__r   typingr   r   r   r   r   typing_extensionsr	   
ezdxf.mathr
   r   r   r   r   r   r   r   r   r[   r   r   r   r   r   r   __all__MAX_DISTANCEMIN_SEGMENTSG1_TOLr   r   r,   rM   rN   rO   r   r3   rV   r'   r%   <module>r      s    #  #
 
 
  (		S@* @*H OOQOOQqq	r'   