
    'j5E                        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j!        dej"        dej#        dej$        diZ%ddZ&dS )    )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dUdZe	 dVdWd            ZdXdZ	dYdZ
dZdZd[dZd\dZd]dZd^dZd_dZeZed`d            Zej        dad!            Zedbd#            Zej        dcd%            Zedbd&            Zddd'Zded)Zedfd+            Zedfd,            Zedfd-            Zedfd.            Zdfd/Zdgd1Zdcd2Zdcd3Z dhd5Z!did8Z"djd9Z#djd:Z$dkd<Z%d^d=Z&d^d>Z'd^d?Z(dldmdCZ)dndodGZ*dpdKZ+dqdOZ,drdQZ-dsdSZ.dsdTZ/dS )tr   startr   c                h    t          |          g| _        g | _        g | _        d| _        d | _        d S )NF)r
   r   r   r   r   r    )selfr"   s     I/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/path/path.py__init__zPath.__init__,   s3    &*5kk]')(*##    Nvertices
list[Vec3]command_codeslist[Command]	user_datar   returnr	   c                     |             }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  6   K   | ]}|t           j        k    V  d S Nr   MOVE_TO.0cmds     r%   	<genexpr>z2Path.from_vertices_and_commands.<locals>.<genexpr>C   s)      %V%VcW_&<%V%V%V%V%V%Vr'   )lenr   r   make_vertex_indexr   anyr   r    )clsr(   r*   r,   new_paths        r%   from_vertices_and_commandszPath.from_vertices_and_commands5   sq     355x==AO%* 1- @ @"%%V%V%V%V%V"V"V'r'   mr   c                    |                                  }t          |                    | j                            |_        |S )zReturns a new transformed path.

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

        )clonelisttransform_verticesr   )r$   r=   r;   s      r%   	transformzPath.transformG   s6     ::<<!!"6"6t~"F"FGGr'   r   c                D    t          |                                           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2333r'   intc                *    t          | j                  S )zReturns count of path elements.)r7   r   rE   s    r%   __len__zPath.__len__X   s    4>"""r'   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   r2   r   LINE_TOr   	CURVE3_TOr   	CURVE4_TOr   
ValueError)r$   itemr5   indexr(   s        r%   __getitem__zPath.__getitem__\   s   dE"" 	53444nT"!$'>'/!!(5/***'/!!(5/***'###HUQY/%AAA'#####  
 2S22333r'   Iterator[PathElement]c                ^      fdt          t           j                            D             S )Nc              3  (   K   | ]}|         V  d S r0    )r4   ir$   s     r%   r6   z Path.__iter__.<locals>.<genexpr>r   s'      <<AQ<<<<<<r'   )ranger7   r   rE   s   `r%   __iter__zPath.__iter__q   s/    <<<<s4>':':!;!;<<<<r'   list[PathElement]c                D    t          |                                           S )z"Returns all path elements as list.)r@   r]   rE   s    r%   commandszPath.commandst   s    DMMOO$$$r'   c                    |                                  }| j                                        |_        |                     |           |S )z?Returns a new copy of :class:`Path` with shared immutable data.)	__class__r   copy_copy_properties)r$   rc   s     r%   __copy__zPath.__copy__x   s?    ~~,,..d###r'   r?   Nonec                   t          | j                  t          |j                  k    sJ | j                                        |_        | j                                        |_        | j        |_        | j        |_        d S r0   )r7   r   r   rc   r   r   r    )r$   r?   s     r%   rd   zPath._copy_properties   sn    4>""c%/&:&:::::.--//!.3355#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    rE   s    r%   r,   zPath.user_data   s     r'   datac                    || _         d S r0   ri   )r$   rj   s     r%   r,   zPath.user_data   s    r'   r
   c                    | j         d         S )zc:class:`Path` start point, resetting the start point of an empty
        path is possible.
        r   r   rE   s    r%   r"   z
Path.start   s    
 ~a  r'   locationc                `    | j         rt          d          t          |          | j        d<   d S )NzRequires an empty path.r   )r   rS   r
   r   r$   rn   s     r%   r"   z
Path.start   s3    > 	/6777 $XDN1r'   c                    | j         d         S )z:class:`Path` end point.rm   rE   s    r%   endzPath.end   s     ~b!!r'   c                <    | j         rt          | j                  S g S )z6Yields all path control vertices in consecutive order.)r   r@   r   rE   s    r%   rD   zPath.control_vertices   s!    > 	('''	r'   	list[int]c                *    t          | j                  S )zInternal API.)r@   r   rE   s    r%   r*   zPath.command_codes   s    DN###r'   boolc                |    | j         }t          |          dk    r!|d                             |d                   S dS )z>Returns ``True`` if the start point is close to the end point.r   r   rr   F)r   r7   isclose)r$   r(   s     r%   	is_closedzPath.is_closed   s=     >x==1A;&&x|444ur'   c                (    t           j        | j        v S )z3Returns ``True`` if the path has any line segments.)r   rP   r   rE   s    r%   	has_lineszPath.has_lines   s     $.00r'   c                N    t           j        | j        v pt           j        | j        v S )z4Returns ``True`` if the path has any curve segments.)r   rR   r   rQ   rE   s    r%   
has_curveszPath.has_curves   s%     /V73D3V	
r'   c                    | j         S )zoReturns ``True`` if the path is a :term:`Multi-Path` object that
        contains multiple sub-paths.

        )r   rE   s    r%   has_sub_pathszPath.has_sub_paths   s     ""r'   c                V    | 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)r   rO   r   r   rE   s    r%   r   zPath.has_clockwise_orientation   s/      	OMNNN(888r'   r5   c                   |j         }|t          j        k    r|                     |j                   dS |t          j        k    r|                     |j                   dS |t          j        k    r"|                     |j        |j	                   dS |t          j
        k    r(|                     |j        |j        |j                   dS t          d|           )zAppend a single path element.rL   N)typer   rP   line_tors   r2   move_torQ   	curve3_toctrlrR   	curve4_toctrl1ctrl2rS   )r$   r5   ts      r%   append_path_elementzPath.append_path_element   s    HLL!!!!!'/!!LL!!!!!'###NN37CH-----'###NN37CIsy99999444555r'   c                    | j                             t          j                   | j                            t          | j                             | j                            t          |                     dS )z4Add a line from actual path end point to `location`.N)r   appendr   rP   r   r7   r   r
   rp   s     r%   r   zPath.line_to   s]    go...  T^!4!4555d8nn-----r'   c                   | j         }|st          |          | j        d<   dS d| _        |d         t          j        k    rF|                                 | j                                         | j                                         |                    t          j                   | j                            t          | j                             | j                            t          |                     dS )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   NTrr   )
r   r
   r   r   r   r2   popr   r   r7   )r$   rn   r`   s      r%   r   zPath.move_to   s     > 	 $XDN1F"B<7?**LLNNNN   !!###(((  T^!4!4555d8nn-----r'   r   c                   | j                             t          j                   | j                            t          | j                             | j                            t          |          t          |          f           dS )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   rQ   r   r7   r   extendr
   )r$   rn   r   s      r%   r   zPath.curve3_to  sk     	g/000  T^!4!4555tDzz4>>:;;;;;r'   r   r   c                .   | j                             t          j                   | j                            t          | j                             | j                            t          |          t          |          t          |          f           dS )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   rR   r   r7   r   r   r
   )r$   rn   r   r   s       r%   r   zPath.curve4_to  ss     	g/000  T^!4!4555tE{{DKKhHIIIIIr'   c                L    | j         s|                     | j                   dS dS )z[Close path by adding a line segment from the end point to the start
        point.
        N)rz   r   r"   rE   s    r%   closez
Path.close  s2     ~ 	%LL$$$$$	% 	%r'   c                    | j         rS|                                 }|
J d            | j                            |          s|                     |           dS dS |                                  dS )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)r   _start_of_last_sub_pathrs   ry   r   r   )r$   start_points     r%   close_sub_pathzPath.close_sub_path  s    
  	6688K''C (''8##K00 *[)))))* * JJLLLLLr'   Optional[Vec3]c                    t           j        }| j        }t          |          dz
  }|dk    r/||         |k    r| j        | j        |                  S |dz  }|dk    /d S )Nr   r   )r   r2   r   r7   r   r   )r$   r   r`   rU   s       r%   r   zPath._start_of_last_sub_path,  sh    />H!aii'))~d&7&>??QJE aii tr'   c                   |                                  }|j        s|S |j        d         t          j        k    rn|j                                         |j                                         |j                                         t          d |j        D                       |_        |j        	                                 |j        	                                 t          |j                  |_        |S )zZReturns a new :class:`Path` with reversed commands and control
        vertices.

        rr   c              3  6   K   | ]}|t           j        k    V  d S r0   r1   r3   s     r%   r6   z Path.reversed.<locals>.<genexpr>G  s:       & &+.w&& & & & & &r'   )r?   r   r   r2   r   r   r   r9   r   reverser8   )r$   paths     r%   reversedzPath.reversed7  s    
 zz||~ 	K>"00
 N   N   !!###"% & &26.& & & # #D 	      -dn==r'   c                z    |                                  r|                                 S |                                 S )zReturns new :class:`Path` in clockwise orientation.

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

        )r   r?   r   rE   s    r%   	clockwisezPath.clockwiseO  s4     ))++ 	#::<<==??"r'   c                z    |                                  r|                                 S |                                 S )zReturns new :class:`Path` in counter-clockwise orientation.

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

        )r   r   r?   rE   s    r%   counter_clockwisezPath.counter_clockwise[  s4     ))++ 	 ==??"::<<r'      segmentsIterator[Vec3]c                H    d
fd}dfd	}|                      ||          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.

        p0r
   p1p2r-   r   c                h    t          t          | ||f                                                  S r0   )iterr   approximate)r   r   r   r   s      r%   curve3z Path.approximate.<locals>.curve3t  s-    "b"..::8DDEEEr'   p3c                j    t          t          | |||f                                                  S r0   )r   r   r   )r   r   r   r   r   s       r%   curve4z Path.approximate.<locals>.curve4w  s0    "b"b!122>>xHHIIIr'   r   r
   r   r
   r   r
   r-   r   
r   r
   r   r
   r   r
   r   r
   r-   r   _approximate)r$   r   r   r   s    `  r%   r   zPath.approximateh  sc    	F 	F 	F 	F 	F 	F	J 	J 	J 	J 	J 	J   000r'   r   distancefloatc                N    d
fd}dfd	}|                      ||          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

        r   r
   r   r   r-   r   c                    dk    rt          d          t          t          | ||f                                                  S Ng        zinvalid max distance: 0.0)rS   r   r   
flattening)r   r   r   r   r   s      r%   r   zPath.flattening.<locals>.curve3  sG    3 !=>>>"b"..99(HMMNNNr'   r   c                    dk    rt          d          t          t          | |||f                                                  S r   )rS   r   r   r   )r   r   r   r   r   r   s       r%   r   zPath.flattening.<locals>.curve4  sJ    3 !=>>>"b"b!122==hQQRRRr'   r   r   r   )r$   r   r   r   r   s    ``  r%   r   zPath.flattening|  sp    *	O 	O 	O 	O 	O 	O 	O
	S 	S 	S 	S 	S 	S 	S
   000r'   r   r   r   c              #  &  K   | j         sd S | j        d         }|V  | j        }t          | j        | j                   D ]\  }}|t          j        k    s|t          j        k    r||         }|V  n|t          j        k    r5|||dz            \  }} ||||          }	t          |	           |	E d {V  nY|t          j	        k    r7|||dz            \  }
}} |||
||          }	t          |	           |	E d {V  nt          d|           |}d S )Nr   rK      rL   )r   r   zipr   r   rP   r2   rQ   nextrR   rS   )r$   r   r   r"   r(   sir5   end_locationr   ptsr   r   s               r%   r   zPath._approximate  s\     ~ 	Fq!>4,dn== 	! 	!GBgo%%)?)?'|""""")))%-b26k%:"lfUD,77S			)))-5b26k-B*ulfUE5,??S			 !:S!:!:;;; EE!	! 	!r'   ocsr   	elevationc                V    t          fd| j        D                       | _        dS )z;Transform path from given `ocs` to WCS coordinates inplace.c              3     K   | ]:}                     |                    t                                         V  ;dS ))zN)to_wcsreplacer   )r4   vr   r   s     r%   r6   zPath.to_wcs.<locals>.<genexpr>  sV       
 
:;CJJqyy5#3#3y4455
 
 
 
 
 
r'   N)r@   r   )r$   r   r   s    ``r%   r   zPath.to_wcs  sF     
 
 
 
 
?C~
 
 
 
 
r'   Iterator[Self]c              #  >  K   |                      | j                  }| j        |_        t          j        }|                                 D ]N}|j        |k    r,|V  |                      |j                  }| j        |_        9|                    |           O|V  d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`.

        )r"   N)	rb   r"   r    r   r2   r`   r   rs   r   )r$   r   r   r5   s       r%   	sub_pathszPath.sub_paths  s       ~~DJ~////==?? 	. 	.Cx7""


~~CG~44"&/((----




r'   r   c                    t          |          rF|                     |j                   |                                D ]}|                     |           dS dS )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)r7   r   r"   r`   r   r$   r   r5   s      r%   extend_multi_pathzPath.extend_multi_path  sh     t99 	.LL$$$}} . .((----	. 	.. .r'   c                "   t          |          dk    rdS | j        r:| j                            |j                  s|                     |j                   n|j        | _        |                                D ]}|                     |           dS )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)r7   r   rs   ry   r"   r   r`   r   r   s      r%   append_pathzPath.append_path  s    
 t99>>F> 	$8##DJ// )TZ(((DJ==?? 	* 	*C$$S))))	* 	*r'   )r"   r   r0   )r(   r)   r*   r+   r,   r   r-   r	   )r=   r   r-   r	   )r-   r   )r-   rG   )r-   r   )r-   rW   )r-   r^   )r-   r	   )r?   r   r-   rf   )r-   r   )rj   r   )r-   r
   )rn   r   r-   rf   )r-   r)   )r-   ru   )r-   rw   )r5   r   r-   rf   )rn   r   r   r   r-   rf   )rn   r   r   r   r   r   r-   rf   )r-   rf   )r-   r   )r   )r   rG   r-   r   )r   )r   r   r   rG   r-   r   )r   r   r   r   r-   r   )r   r   r   r   r-   rf   )r-   r   )r   r   r-   rf   )0__name__
__module____qualname___slots	__slots__r   r&   classmethodr<   rB   rF   rI   rV   r]   r`   re   rd   r?   propertyr,   setterr"   rs   rD   r*   rz   r|   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rZ   r'   r%   r   r   )   s       I%, $ $ $ $ $ RV    ["	 	 	 	4 4 4 4# # # #4 4 4 4*= = = =% % % %   + + + + E   X     ! ! ! X! \/ / / \/ " " " X"   $ $ $ $    X 1 1 1 X1 
 
 
 X
 # # # X#
9 
9 
9 
96 6 6 6. . . .. . . ..< < < <J J J J% % % %   	 	 	 	   0
# 
# 
# 
#       1 1 1 1 1(1 1 1 1 1B! ! ! !4
 
 
 
   &
. 
. 
. 
.* * * * * *r'   rK   r   r*   Iterable[Command]r-   ru   c                f    t           }d}g }| D ]"}|                    |           |||         z  }#|S )Nr   )CMD_SIZEr   )r*   cmd_sizer"   start_indexcodes        r%   r8   r8     sJ    HEK    5!!!$r'   N)r*   r   r-   ru   )'
__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   r2   rP   rQ   rR   r   r8   rZ   r'   r%   <module>r      s   # " " " " "              # " " " " "
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                (		S@* @* @* @* @* @* @* @*H OQOQqq	     r'   