
    'j                    ~   d dl mZ d dlmZmZmZmZmZ d dlZd dl	Z	d dl
Z
d dlmZ d dlmZmZ d dlmZmZmZmZmZmZmZmZmZmZmZmZmZmZ d dlm Z  erd dl!m"Z" g d	Z#e	j$         G d
 de	j%                              Z&e	j$         G d de	j%                              Z' G d dej(                  Z) G d dej(                  Z* G d d          Z+	 d1d2dZ,d3d Z-d4d%Z. G d& de)          Z/ G d' d(e)          Z0 G d) d*e*          Z1 G d+ d,e*          Z2 G d- d.e*          Z3 G d/ d0e*          Z4de1e2e3e4gZ5dS )5    )annotations)UnionIterableSequenceOptionalTYPE_CHECKINGN)const)Tags
group_tags)Vec2Vec3UVecOCSbulge_to_arcConstructionEllipseConstructionArcBSplineNonUniformScalingErroropen_uniform_knot_vectorglobal_bspline_interpolationarc_angle_span_degangle_to_paramparam_to_angle)OCSTransform)AbstractTagWriter)BoundaryPathsPolylinePathEdgePathLineEdgeArcEdgeEllipseEdge
SplineEdgeEdgeTypeBoundaryPathTypeAbstractEdgeAbstractBoundaryPathc                      e Zd ZdZdZdS )r$         N)__name__
__module____qualname__POLYLINEEDGE     W/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/entities/boundary_paths.pyr$   r$   /   s        HDDDr0   r$   c                      e Zd ZdZdZdZdZdS )r#   r(   r)         N)r*   r+   r,   LINEARCELLIPSESPLINEr/   r0   r1   r#   r#   5   s"        D
CGFFFr0   r#   c                      e Zd ZU ded<   ded<   ded<   ej        dd	            Zeej        dd                        Zej        dd            Z	ej        dd            Z
ej        dd            ZdS )r&   r$   typeintpath_type_flags	list[str]source_boundary_objectsreturnNonec                    d S Nr/   selfs    r1   clearzAbstractBoundaryPath.clearB   s     Sr0   tagsr
   c                    d S rB   r/   )clsrF   s     r1   	load_tagszAbstractBoundaryPath.load_tagsE   s    <?Cr0   	tagwriterr   dxftypestrc                    d S rB   r/   )rD   rJ   rK   s      r1   
export_dxfzAbstractBoundaryPath.export_dxfI   s    NQcr0   ocsr   	elevationfloatc                    d S rB   r/   rD   rO   rP   s      r1   	transformzAbstractBoundaryPath.transformL       FIcr0   boolc                    d S rB   r/   rC   s    r1   is_validzAbstractBoundaryPath.is_validO        #r0   Nr?   r@   )rF   r
   r?   r&   rJ   r   rK   rL   r?   r@   rO   r   rP   rQ   r?   r@   r?   rV   )r*   r+   r,   __annotations__abcabstractmethodrE   classmethodrI   rN   rT   rX   r/   r0   r1   r&   r&   =   s         &&&&     ???  [?QQQ QIII I### ###r0   r&   c                     e Zd ZU ded<   eej        dd                        Zeej        dd                        Zej        dd
            Z	ej        dd            Z
ej        dd            Zedd            Zedd            ZdS )r%   r#   r:   r?   r   c                    d S rB   r/   rC   s    r1   start_pointzAbstractEdge.start_pointV   s    #&3r0   c                    d S rB   r/   rC   s    r1   	end_pointzAbstractEdge.end_pointZ   s    !$r0   rJ   r   r@   c                    d S rB   r/   )rD   rJ   s     r1   rN   zAbstractEdge.export_dxf^   s    @Cr0   rO   r   rP   rQ   c                    d S rB   r/   rS   s      r1   rT   zAbstractEdge.transforma   rU   r0   rV   c                    d S rB   r/   rC   s    r1   rX   zAbstractEdge.is_validd   rY   r0   c                    | j         S rB   )rd   rC   s    r1   real_start_pointzAbstractEdge.real_start_pointg   s    r0   c                    | j         S rB   )rf   rC   s    r1   real_end_pointzAbstractEdge.real_end_pointk   s
    ~r0   Nr?   r   rJ   r   r?   r@   r\   r]   )r*   r+   r,   r^   propertyr_   r`   rd   rf   rN   rT   rX   rk   rm   r/   r0   r1   r%   r%   S   s         NNN&&&  X&$$$  X$CCC CIII I### #      X     X  r0   r%   c                      e Zd ZdBdCdZd Zd Zd ZdDd
ZedEd            Z	e
dDd            ZdFdZdGdZdGdZdGdZej        fdHdZdIdZ	 	 dJdKd"ZdLdMd$ZdNd)ZdOdPd/ZdQdFd0ZdRdSd4ZdFd5ZdTdUd8ZdVdWd;ZdXdUd=ZdXdUd>ZdYdZd@ZdDdAZ dS )[r   Npaths$Optional[list[AbstractBoundaryPath]]c                    |pg | _         d S rB   rr   )rD   rr   s     r1   __init__zBoundaryPaths.__init__q   s    16"


r0   c                *    t          | j                  S rB   )lenrr   rC   s    r1   __len__zBoundaryPaths.__len__t   s    4:r0   c                    | j         |         S rB   ru   )rD   items     r1   __getitem__zBoundaryPaths.__getitem__w   s    z$r0   c                *    t          | j                  S rB   )iterrr   rC   s    r1   __iter__zBoundaryPaths.__iter__z       DJr0   r?   rV   c                >    t          d | j        D                       S )Nc              3  >   K   | ]}|                                 V  d S rB   rX   .0ps     r1   	<genexpr>z)BoundaryPaths.is_valid.<locals>.<genexpr>~   *      44A1::<<444444r0   )allrr   rC   s    r1   rX   zBoundaryPaths.is_valid}   !    44444444r0   rF   r
   c                P   g }|d         j         dk    sJ t          |d          }|D ]s}|d         j        }t          |dz            }|rt                              |          nt                              |          }||_        |                    |           t | |          S )Nr   \   	splitcoder)   )	coder   valuerV   r   rI   r   r<   append)rH   rF   rr   grouped_path_tags	path_tagsr<   is_polyline_pathpaths           r1   rI   zBoundaryPaths.load_tags   s    Aw|r!!!!&tr:::* 		 		I'l0O#Oa$788 $3&&y111''	22 
 $3D LLs5zzr0   c                >    t          d | j        D                       S )Nc              3  @   K   | ]}|j         t          j        k    V  d S rB   )r:   r$   r.   r   s     r1   r   z/BoundaryPaths.has_edge_paths.<locals>.<genexpr>   s-      GGq16-22GGGGGGr0   )anyrr   rC   s    r1   has_edge_pathszBoundaryPaths.has_edge_paths   s!    GGDJGGGGGGr0   r@   c                    g | _         dS )zRemove all boundary paths.Nru   rC   s    r1   rE   zBoundaryPaths.clear       


r0   Iterable[AbstractBoundaryPath]c              #  N   K   | j         D ]}|j        t          j        z  r|V  dS )z+Iterable of external paths, could be empty.N)rr   r<   r	   BOUNDARY_PATH_EXTERNALrD   bs     r1   external_pathszBoundaryPaths.external_paths   s>       	 	A 5#?? 	 	r0   c              #  N   K   | j         D ]}|j        t          j        z  r|V  dS )z,Iterable of outermost paths, could be empty.N)rr   r<   r	   BOUNDARY_PATH_OUTERMOSTr   s     r1   outermost_pathszBoundaryPaths.outermost_paths   s>       	 	A 5#@@ 	 	r0   c              #     K   t           j        t           j        z   }| j        D ]}t	          |j        |z            du r|V   dS )z*Iterable of default paths, could be empty.FN)r	   r   r   rr   rV   r<   )rD   not_defaultr   s      r1   default_pathszBoundaryPaths.default_paths   sV      3e6RR 	 	AA%344==	 	r0   hatch_styler;   c                    d	dt          fdt          | j                  D                       }d|t          j        k    rdn|t          j        k    rdfd|D             S )
am  Iterable of paths to process for rendering, filters unused
        boundary paths according to the given hatch style:

        - NESTED: use all boundary paths
        - OUTERMOST: use EXTERNAL and OUTERMOST boundary paths
        - IGNORE: ignore all paths except EXTERNAL boundary paths

        Yields paths in order of EXTERNAL, OUTERMOST and DEFAULT.

        r?   r;   c                J    | t           j        z  rdS | t           j        z  rdS dS )Nr   r(   r)   )r	   r   r   flagss    r1   path_type_enumz5BoundaryPaths.rendering_paths.<locals>.path_type_enum   s1    u33 q66 q1r0   c              3  D   K   | ]\  }} |j                   ||fV  d S rB   )r<   )r   ir   r   s      r1   r   z0BoundaryPaths.rendering_paths.<locals>.<genexpr>   sL       
 
:>!Q^^A-..15
 
 
 
 
 
r0   r(   r3   r)   c              3  0   K   | ]\  }}}|k     |V  d S rB   r/   )r   	path_type_r   ignores       r1   r   z0BoundaryPaths.rendering_paths.<locals>.<genexpr>   s3      EEoiA)f2D2D2D2D2D2DEEr0   )r?   r;   )sorted	enumeraterr   r	   HATCH_STYLE_NESTEDHATCH_STYLE_OUTERMOST)rD   r   rr   r   r   s      @@r1   rendering_pathszBoundaryPaths.rendering_paths   s    	 	 	 	  
 
 
 
BKDJBWBW
 
 
 
 
 %222FFE777FEEEEEEEEr0   r   r&   c                    t          |t                    st          dt          |                     | j                            |           dS )zCAppend a new boundary path.

        .. versionadded:: 1.4
        zinvalid path type: N)
isinstancer&   	TypeErrorr:   rr   r   )rD   r   s     r1   r   zBoundaryPaths.append   sQ    
 $ 455 	@>$t**>>???
$r0   Tr(   path_verticesIterable[tuple[float, ...]]	is_closedr   r   c                h    t                               |||          }|                     |           |S )aA  Create and add a new :class:`PolylinePath` object.

        Args:
            path_vertices: iterable of polyline vertices as (x, y) or
                (x, y, bulge)-tuples.
            is_closed: 1 for a closed polyline else 0
            flags: default(0), external(1), derived(4), textbox(8) or outermost(16)

        )r   from_verticesr   )rD   r   r   r   new_paths        r1   add_polyline_pathzBoundaryPaths.add_polyline_path   s2      --mYNNHr0   r   c                Z    t                      }||_        |                     |           |S )zCreate and add a new :class:`EdgePath` object.

        Args:
            flags: default(0), external(1), derived(4), textbox(8) or outermost(16)

        )r   r<   r   )rD   r   r   s      r1   add_edge_pathzBoundaryPaths.add_edge_path   s,     ::#( Hr0   rJ   r   rK   rL   c                    |                     dt          | j                             | j        D ]}|                    ||           d S )N[   )
write_tag2rx   rr   rN   )rD   rJ   rK   r   s       r1   rN   zBoundaryPaths.export_dxf   sR    RTZ111J 	0 	0DOOIw////	0 	0r0   r   rO   r   rP   rQ   c                    |j         s*|                     d           |                                  | j        D ]}|                    ||           dS )zoTransform HATCH boundary paths.

        These paths are 2d elements, placed in the OCS of the HATCH.

        Tjust_with_bulgerP   N)scale_uniformpolyline_to_edge_pathsarc_edges_to_ellipse_edgesrr   rT   )rD   rO   rP   r   s       r1   rT   zBoundaryPaths.transform   sl       	.'''===++---J 	5 	5DNN3)N4444	5 	5r0   c                    dddfd}t          | j                  D ]D\  }}t          |t                    r*|r|                                s1 ||          | j        |<   EdS )	zConvert polyline paths including bulge values to line- and arc edges.

        Args:
            just_with_bulge: convert only polyline paths including bulge
                values if ``True``

        r?   "Iterable[Union[LineEdge, ArcEdge]]c              3    K   d }d}| D ]I\  }}}t          ||          }||}|}|dk    rt                      }t          |||          \  |_        }}	|_        |j        t          j        ||j                  z   }
|
                    |d          |_        t          j
        |          dz  |_        t          j
        |	          dz  |_        t          j        |j        |j                  r!t          j        |j        d          rd|_        |V  n8t                      }|j        |j        f|_        |j        |j        f|_        |V  |}|}Kd S )N        g&.>)abs_tol     v@r   )r   r    r   centerradiusr   
from_angleiscloseccwmathdegreesstart_angle	end_angler   xystartend)points
prev_point
prev_bulger   r   bulgepointarcr   r   	chk_pointlines               r1   _edgesz4BoundaryPaths.polyline_to_edge_paths.<locals>._edges  sp     &*J #J% !# !#1eQ

%!&J!&J$$!))C %Z
CC
#!
 #
T_[#*-U-U UI'//
D/IICG&*l;&?&?%&GCO$(L$;$;e$CCM|COS]CC .I I . ).IIII#::D",,
!=DJ %1DHJJJ"
"

C!# !#r0   r   c                    t                      }t          | j                  }| j        r|                    |d                    t           |                    |_        |S Nr   )r   listverticesr   r   edges)polyline_path	edge_pathr   r   s      r1   to_edge_pathz:BoundaryPaths.polyline_to_edge_paths.<locals>.to_edge_path4  s\     

I!-"899H& -,,,"66(#3#344IOr0   N)r?   r   )r?   r   )r   rr   r   r   	has_bulge)rD   r   r   
path_indexr   r   s        @r1   r   z$BoundaryPaths.polyline_to_edge_paths  s    $	# $	# $	# $	#L	 	 	 	 	 	 !*$* 5 5 	< 	<J$-- <" 4>>+;+; )5d););
:&		< 	<r0      distancesegmentsc                    g }| j         D ]=}|j        t          j        k    rt	          |||          }|                    |           >|| _         dS )ae  Convert all edge paths to simple polyline paths without bulges.

        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 curve

        N)rr   r:   r$   r.   flatten_to_polyline_pathr   )rD   r   r   	convertedr   s        r1   edge_to_polyline_pathsz$BoundaryPaths.edge_to_polyline_pathsB  s^     	J 	# 	#Dy,111/hIIT""""


r0   c                    dd}| j         D ]V}t          |t                    r?|j        }t	          |          D ](\  }}t          |t
                    r ||          ||<   )WdS )z'Convert all arc edges to ellipse edges.r   r    r?   r!   c                    t                      }| j        |_        d|_        | j        df|_        | j        |_        | j        |_        | j        |_        |S )N      ?r   )r!   r   ratior   
major_axisr   r   r   )r   ellipses     r1   
to_ellipsez<BoundaryPaths.arc_edges_to_ellipse_edges.<locals>.to_ellipseV  sL    !mmG ZGNGM"%*c!2G"%/G #G'GKNr0   N)r   r    r?   r!   )rr   r   r   r   r   r    )rD   r  r   r   
edge_indexedges         r1   r   z(BoundaryPaths.arc_edges_to_ellipse_edgesS  s    	 	 	 	 J 	= 	=D$)) =
(1%(8(8 = =$J!$00 =,6Jt,<,<j)	= 	=r0       numc                    dfd}t          | j                  D ]Y\  }}t          |t                    r?|j        }t          |          D ](\  }}t          |t
                    r ||          ||<   )ZdS )z
        Convert all ellipse edges to spline edges (approximation).

        Args:
            num: count of control points for a **full** ellipse, partial
                ellipses have proportional fewer control points but at least 3.

        er!   r?   r"   c                   t          | j        | j        | j        | j        | j                  }t          t          t                    |j	        z  t          j        z            d          }t          j        ||          }t                      }|j        |_        | j        s|                                }t%          j        |j                  |_        |                                |_        |                                |_        |S )Nr   r   r   start_param	end_paramr3   )r   r   r   r   r  r  maxr;   rQ   
param_spanr   taur   ellipse_approximationr"   degreer   reverser   r   control_pointsknotsknot_valuesweights)r  r  counttoolspliner  s        r1   to_spline_edgezCBoundaryPaths.ellipse_edges_to_spline_edges.<locals>.to_spline_edgeq  s     *x<gM+  G E#JJ);;dhFGGKKE0%@@D\\F KFM5 &||~~$(Id.A$B$BF!!%F!\\^^FNMr0   N)r  r!   r?   r"   )r   rr   r   r   r   r!   )rD   r  r  r   r   r   r  r  s    `      r1   ellipse_edges_to_spline_edgesz+BoundaryPaths.ellipse_edges_to_spline_edgesg  s    	 	 	 	 	 	, !*$* 5 5 	A 	AJ$)) A
(1%(8(8 A A$J!$44 A,:N4,@,@j)	A 	Ar0      factorc                
   dfd}| j         D ]s}t          |t                    r\g }|j        D ]K}t          |t                    r|                     ||                     6|                    |           L||_        tdS )zConvert all spline edges to line edges (approximation).

        Args:
            factor: count of approximation segments = count of control
                points x factor

        spline_edger"   c              3  t  K   | j         }t          | j                  r7t          | j        | j        dz   | j        t          |          r|nd           }nHt          | j                  r t          j        | j        | j                  }nt          j	        d          t          t          |j                  d          dz
  z  }t          |                    |                    }t          |d d         |dd                    D ]/\  }}t                      }|j        |_        |j        |_        |V  0d S )Nr(   )r  orderr  r  z2SplineEdge() without control points or fit points.r3   )r  rx   r  r   r  r  
fit_pointsfrom_fit_pointsr	   DXFStructureErrorr  r   approximatezipr   vec2r   r   )	r  r  bsplinesegment_countr   v1v2r  r  s	           r1   to_line_edgesz?BoundaryPaths.spline_edges_to_line_edges.<locals>.to_line_edges  sM     !)G;-.. !#.#=%,q0%1'*7||=GG	   [+,, !1*K,>  -H   !W%;!<!<a@@1DNMG//>>??HhssmXabb\::  BzzW
7



	 r0   N)r  r"   )rr   r   r   r   r"   extendr   )rD   r  r-  r   	new_edgesr  s    `    r1   spline_edges_to_line_edgesz(BoundaryPaths.spline_edges_to_line_edges  s    	 	 	 	 	 	2 J 	' 	'D$)) '	 J / /D!$
33 /!((t)<)<====!((....&
	' 	'r0   @   c                   fd}| j         D ]s}t          |t                    r\g }|j        D ]K}t          |t                    r|                     ||                     6|                    |           L||_        tdS )zConvert all ellipse edges to line edges (approximation).

        Args:
            num: count of control points for a **full** ellipse, partial
                ellipses have proportional fewer control points but at least 3.

        c              3  >  K   t          | j        | j        | j        | j        | j                  }t          t          t                    |j	        z  t          j        z            d          }|                    |dz             }| j        st          t          |                    }t          |                    |                    }t#          |d d         |dd                    D ]/\  }}t%                      }|j        |_        |j        |_        |V  0d S )Nr
  r3   r(   r"  )r   r   r   r   r  r  r  r;   rQ   r  r   r  paramsr   reversedr   r   r'  r   r(  r   r   )	r  r  r*  r4  r   r+  r,  r   r  s	           r1   r-  z@BoundaryPaths.ellipse_edges_to_line_edges.<locals>.to_line_edges  s     ){?j ,.  G  E#JJ1C$Cdh$N O OQRSSM^^MA$566F 8 0!$v,,//G,,V4455HhssmXabb\::  BzzW
7



	 r0   N)rr   r   r   r   r!   r.  r   )rD   r  r-  r   r/  r  s    `    r1   ellipse_edges_to_line_edgesz)BoundaryPaths.ellipse_edges_to_line_edges  s    	 	 	 	 	, J 	' 	'D$)) '	 J / /D!$44 /!((t)<)<====!((....&
	' 	'r0   c                    |                      d           |                                  |                     |           dS )a"  Convert all bulge, arc and ellipse edges to spline edges
        (approximation).

        Args:
            num: count of control points for a **full** circle/ellipse, partial
                circles/ellipses have proportional fewer control points but at
                least 3.

        Tr   N)r   r   r  )rD   r  s     r1   all_to_spline_edgesz!BoundaryPaths.all_to_spline_edges  sG     	##D#999'')))**3/////r0   spline_factorc                    |                      d           |                                  |                     |           |                     |           dS )a  Convert all bulge, arc and ellipse edges to spline edges and
        approximate this splines by line edges.

        Args:
            num: count of control points for a **full** circle/ellipse, partial
                circles/ellipses have proportional fewer control points but at
                least 3.
            spline_factor: count of spline approximation segments = count of
                control points x spline_factor

        Tr   N)r   r   r6  r0  )rD   r  r9  s      r1   all_to_line_edgeszBoundaryPaths.all_to_line_edges  s[     	##D#999'')))((---''66666r0   c                ,   | j         D ]}t          |t                    r|                                c S t          |t                    r.|j        D ]%}|j        t          j        t          j	        hv r  dS &pt          t          |                    dS )zgReturns ``True`` if any boundary path has bulge values or arc edges
        or ellipse edges.

        TF)rr   r   r   r   r   r   r:   r#   r6   r7   r   )rD   r   r  s      r1   has_critical_elementsz#BoundaryPaths.has_critical_elements  s    
 J 	, 	,D$-- ,~~'''''D(++ , J $ $DyX\83C$DDD#ttt E$  T

+++ur0   rB   )rr   rs   r]   )rF   r
   r?   r   rZ   )r?   r   )r   r;   r?   r   )r   r&   r?   r@   Tr(   r   r   r   rV   r   r;   r?   r   )r(   )r   r;   r?   r   r[   )r   r\   Tr   )r   rQ   r   r;   )r  )r  r;   r?   r@   )r  )r  r;   r?   r@   )r1  )r1  r  )r  r;   r9  r;   r?   r@   )!r*   r+   r,   rv   ry   r|   r   rX   ra   rI   rp   r   rE   r   r   r   r	   r   r   r   r   r   rN   rT   r   r   r   r  r0  r6  r8  r;  r=  r/   r0   r1   r   r   p   s       = = = = =            5 5 5 5    [  H H H XH             "'!9F F F F F>        	    &
 
 
 
 
0 0 0 0
5 5 5 5 5;< ;< ;< ;< ;<z    "= = = =(%A %A %A %A %AN*' *' *' *' *'X'' '' '' '' ''R0 0 0 0 07 7 7 7 7"     r0   r   r   r   r   rQ   r   r;   r?   r   c                    dd l }|j                            | t                      d          }d |                    ||          D             }t
                              || j                  S )Nr   )rO   rP   c              3  2   K   | ]}|j         |j        fV  d S rB   )r   r   )r   vs     r1   r   z+flatten_to_polyline_path.<locals>.<genexpr>  s*      KKqac
KKKKKKr0   r   )
ezdxf.pathr   from_hatch_boundary_pathr   
flatteningr   r   r<   )r   r   r   ezdxfez_pathr   s         r1   r   r     s{      j11$CEEQ1OOGKKG$6$6x$J$JKKKH%%" &   r0   r   r
   r=   c                   g }t          |           ro| d         j        dv rP|                                 }|j        dk    r|                    |j                   n|                                 |S nt          |           og S )Nr"  )a   J  rL  )rx   r   popr   r   r  )r   source_boundary_object_tagslast_tags      r1    pop_source_boundary_objects_tagsrP  !  s    "$
i.. 
R=** }}H}##+228>BBBB ,3355522 i.. 
 Ir0   rJ   r   handlesSequence[str]c                    |                      dt          |                     |D ]}|                      d|           d S )NrK  rL  )r   rx   )rJ   rQ  handles      r1   export_source_boundary_objectsrU  2  sR     S\\*** * *S&))))* *r0   c                      e Zd Zej        Zd!dZd"dZe	 	 d#d$d            Z	ed%d            Z
	 d&d'dZd!dZd"dZd(dZd)dZd S )*r   r?   r@   c                R    t           j        | _        d| _        g | _        g | _        d S )NF)r	   BOUNDARY_PATH_POLYLINEr<   r   r   r>   rC   s    r1   rv   zPolylinePath.__init__=  s-    $)$@ ;= 35$$$r0   rV   c                    dS NTr/   rC   s    r1   rX   zPolylinePath.is_validG      tr0   Tr(   r   r   r   r   r;   c                v    t                      }|                    ||           |t          j        z  |_        |S )aG  Create a new :class:`PolylinePath` object from vertices.

        Args:
            path_vertices: iterable of polyline vertices as (x, y) or
                (x, y, bulge)-tuples.
            is_closed: 1 for a closed polyline else 0
            flags: default(0), external(1), derived(4), textbox(8) or outermost(16)

        )r   set_verticesr	   rX  r<   )rH   r   r   r   r   s        r1   r   zPolylinePath.from_verticesJ  s8       >>mY777#(5+G#G r0   rF   r
   c                   t                      }t          |          |_        |D ]}|\  }}|dk    r*|j                            |d         |d         df           7|dk    r;|j                                        \  }}}|j                            |||f           x|dk    r|dk    r||_        |dk    r||_        |d	k    r	 |S )
N
   r   r(   r   *   H   I   r   ]   )r   rP  r>   r   r   rM  r   r<   )	rH   rF   r   tagr   r   r   r   r   s	            r1   rI   zPolylinePath.load_tags_  s    ~~'G'M'M$ 	 	CKD%rzz$$eAha#%>????"m//111e$$aE]3333!&',$$r0   r   Iterable[Sequence[float]]c                    g }|D ]c}t          |          dk    r|\  }}d}n.t          |          dk    r|\  }}}nt          j        d          |                    |||f           d|| _        || _        dS )zpSet new `vertices` as new polyline path, a vertex has to be a
        (x, y) or a (x, y, bulge)-tuple.

        r)   r   r3   z7Invalid vertex format, expected (x, y) or (x, y, bulge)N)rx   r	   DXFValueErrorr   r   r   )rD   r   r   new_verticesvertexr   r   r   s           r1   r]  zPolylinePath.set_verticesv  s      
	/ 
	/F6{{a1V!!$1ee)M   Au....$"r0   c                0    g | _         d| _        g | _        dS )zrRemoves all vertices and all handles to associated DXF objects
        (:attr:`source_boundary_objects`).
        FN)r   r   r>   rC   s    r1   rE   zPolylinePath.clear  s      ')$$$r0   c                >    t          d | j        D                       S )Nc              3  "   K   | ]
\  }}}|V  d S rB   r/   )r   r   r   r   s       r1   r   z)PolylinePath.has_bulge.<locals>.<genexpr>  s(      ::[Q55::::::r0   )r   r   rC   s    r1   r   zPolylinePath.has_bulge  s!    ::DM::::::r0   rJ   r   rK   rL   c                   |                                  }|j        } |dt          | j                             |dk    r8 |dt          |                      |dt          | j                             nP|dk    r8 |dt          | j                              |dt          |                     nt          d|            |dt          | j                             | j        D ]S\  }}}|                    dt          |          t          |          f           |r |d	t          |                     T|dk    rt          || j                   d S d S )
Nr   HATCHra  rb  MPOLYGONzunsupported DXF type rc  r_  r`  )r   r   r;   r<   r   
ValueErrorrx   r   write_vertexrQ   rU  r>   )rD   rJ   rK   r   	write_tagr   r   r   s           r1   rN   zPolylinePath.export_dxf  sx   NN$$	(		"c$.//000gIb#i..)))Ib#dn--....
""Ib#dn--...Ib#i..))))>W>>???	"c$-(()))= 	, 	,KAq%""2a%((';<<< ,	"eEll+++g*9d6RSSSSS r0   rO   r   rP   rQ   c                x     j           fd} j        rt           |                       _        dS dS )zTransform polyline path.c               3     K   j         D ]N\  } }}|rrt          d                              t          | |                    }|j        |j        |fV  Od S )Nz<Polyline path with arcs does not support non-uniform scaling)r   r   transform_vertexr   r   r   )r   r   r   rD  rP   has_non_uniform_scalingrO   rD   s       r1   
_transformz*PolylinePath.transform.<locals>._transform  s      #} 	& 	&1e  4 0"   ((aI)>)>??c13o%%%%	& 	&r0   N)r   r   r   )rD   rO   rP   rw  rv  s   ``` @r1   rT   zPolylinePath.transform  si    &)&7"7
	& 
	& 
	& 
	& 
	& 
	& 
	& 
	& = 	/ ..DMMM	/ 	/r0   NrZ   r]   r>  r?  )rF   r
   r?   r   r@  )r   re  r   rV   r?   r@   r[   r\   )r*   r+   r,   r$   r-   r:   rv   rX   ra   r   rI   r]  rE   r   rN   rT   r/   r0   r1   r   r   :  s       $D5 5 5 5     	    [(    [. FJ# # # # #,* * * *; ; ; ;T T T T,/ / / / / /r0   c                      e Zd Zej        ZdAdZd ZdBdZe	dCd	            Z
dDdZdEdZ	 	 	 	 dFdGdZ	 	 	 	 	 dHdId#Z	 	 	 	 	 	 	 	 dJdKd4Z	 	 dLdMd9ZdAd:ZdNd>ZdOd@Zd$S )Pr   r?   r@   c                D    t           j        | _        g | _        g | _        d S rB   )r	   BOUNDARY_PATH_DEFAULTr<   r   r>   rC   s    r1   rv   zEdgePath.__init__  s"    $:)+
')$$$r0   c                *    t          | j                  S rB   )r~   r   rC   s    r1   r   zEdgePath.__iter__  r   r0   rV   c                >    t          d | j        D                       S )Nc              3  >   K   | ]}|                                 V  d S rB   r   )r   r  s     r1   r   z$EdgePath.is_valid.<locals>.<genexpr>  r   r0   )r   r   rC   s    r1   rX   zEdgePath.is_valid  r   r0   rF   r
   c                L    |             }t          |          |_        t          |d          D ]s}t          |          dk    r|d         j        }d|cxk     rdk     rCn 3|j                            t          |                             |dd                               t|S )Nra  r   r      r(   )	rP  r>   r   rx   r   r   r   EDGE_CLASSESrI   )rH   rF   r   	edge_tags	edge_types        r1   rI   zEdgePath.load_tags  s    CEE	,LT,R,R	)#DB777 	Y 	YI9~~""!!*I9    q     &&|I'>'H'HSTSUSU'W'WXXXr0   rO   r   rP   rQ   c                H    | j         D ]}|                    ||           dS )zTransform edge boundary paths.r   N)r   rT   )rD   rO   rP   r  s       r1   rT   zEdgePath.transform  s6    J 	5 	5DNN3)N4444	5 	5r0   r   r   r   r   c                    t                      }t          |          |_        t          |          |_        | j                            |           |S )zAdd a :class:`LineEdge` from `start` to `end`.

        Args:
            start: start point of line, (x, y)-tuple
            end: end point of line, (x, y)-tuple

        )r   r   r   r   r   r   )rD   r   r   r   s       r1   add_linezEdgePath.add_line  sB     zz%[[
99
$r0   r   r   r   Tr   r   r   r   r   r    c                    t                      }t          |          |_        ||_        ||_        ||_        t          |          |_        | j        	                    |           |S )ac  Add an :class:`ArcEdge`.

        **Adding Clockwise Oriented Arcs:**

        Clockwise oriented :class:`ArcEdge` objects are sometimes necessary to
        build closed loops, but the :class:`ArcEdge` objects are always
        represented in counter-clockwise orientation.
        To add a clockwise oriented :class:`ArcEdge` you have to swap the
        start- and end angle and set the `ccw` flag to ``False``,
        e.g. to add a clockwise oriented :class:`ArcEdge` from 180 to 90 degree,
        add the :class:`ArcEdge` in counter-clockwise orientation with swapped
        angles::

            edge_path.add_arc(center, radius, start_angle=90, end_angle=180, ccw=False)

        Args:
            center: center point of arc, (x, y)-tuple
            radius: radius of circle
            start_angle: start angle of arc in degrees (`end_angle` for a
                clockwise oriented arc)
            end_angle: end angle of arc in degrees (`start_angle` for a
                clockwise oriented arc)
            ccw: ``True`` for counter-clockwise ``False`` for
                clockwise orientation

        )
r    r   r   r   r   r   rV   r   r   r   )rD   r   r   r   r   r   r   s          r1   add_arczEdgePath.add_arc  sZ    D ii&\\

%! s))
#
r0   r   r   r   r   r!   c                ,   |dk    rt          j        d          t                      }t          |          |_        t          |          |_        ||_        ||_        ||_        t          |          |_
        | j                            |           |S )a  Add an :class:`EllipseEdge`.

        **Adding Clockwise Oriented Ellipses:**

        Clockwise oriented :class:`EllipseEdge` objects are sometimes necessary
        to build closed loops, but the :class:`EllipseEdge` objects are always
        represented in counter-clockwise orientation.
        To add a clockwise oriented :class:`EllipseEdge` you have to swap the
        start- and end angle and set the `ccw` flag to ``False``,
        e.g. to add a clockwise oriented :class:`EllipseEdge` from 180 to 90
        degree, add the :class:`EllipseEdge` in counter-clockwise orientation
        with swapped angles::

            edge_path.add_ellipse(center, major_axis, ratio, start_angle=90, end_angle=180, ccw=False)

        Args:
            center: center point of ellipse, (x, y)-tuple
            major_axis: vector of major axis as (x, y)-tuple
            ratio: ratio of minor axis to major axis as float
            start_angle: start angle of ellipse in degrees (`end_angle` for a
                clockwise oriented ellipse)
            end_angle: end angle of ellipse in degrees (`start_angle` for a
                clockwise oriented ellipse)
            ccw: ``True`` for counter-clockwise ``False`` for
                clockwise orientation

        r   z!argument 'ratio' has to be <= 1.0)r	   rg  r!   r   r   r   r   r   r   rV   r   r   r   )rD   r   r   r   r   r   r   r  s           r1   add_ellipsezEdgePath.add_ellipse  s    J 3;;%&IJJJ--f!*-- *% 3ii
'"""r0   Nr3   r   r#  Optional[Iterable[UVec]]r  r  Optional[Iterable[float]]r  r  r;   periodicstart_tangentOptional[UVec]end_tangentr"   c	                ~   t                      }	|t          j        |          |	_        |t          j        |          |	_        |t          |          |	_        n7t          t          t          |	j                  |dz                       |	_        |t          |          |	_        ||	_	        t          t          t          |	j                                      |	_        t          |          |	_        |t          |          |	_        |t          |          |	_        | j                            |	           |	S )a  Add a :class:`SplineEdge`.

        Args:
            fit_points: points through which the spline must go, at least 3 fit
                points are required. list of (x, y)-tuples
            control_points: affects the shape of the spline, mandatory and
                AutoCAD crashes on invalid data. list of (x, y)-tuples
            knot_values: (knot vector) mandatory and AutoCAD crashes on invalid
                data. list of floats; `ezdxf` provides two tool functions to
                calculate valid knot values: :func:`ezdxf.math.uniform_knot_vector`,
                :func:`ezdxf.math.open_uniform_knot_vector` (default if ``None``)
            weights: weight of control point, not mandatory, list of floats.
            degree: degree of spline (int)
            periodic: 1 for periodic spline, 0 for none periodic spline
            start_tangent: start_tangent as 2d vector, optional
            end_tangent: end_tangent as 2d vector, optional

        .. warning::

            Unlike for the spline entity AutoCAD does not calculate the
            necessary `knot_values` for the spline edge itself. On the contrary,
            if the `knot_values` in the spline edge are missing or invalid
            AutoCAD **crashes**.

        Nr(   )r"   r   r   r#  r  r  r   rx   r  r  r;   rV   rationalr  r  r  r   r   )
rD   r#  r  r  r  r  r  r  r  r  s
             r1   
add_splinezEdgePath.add_splineQ  s   H ! $	* 5 5F%$(In$=$=F!"!%k!2!2F!%(V-B)C)CVaZPP" "F !']]FNd3v~#6#67788h--$#'#6#6F "!%k!2!2F
&!!!r0   r   Iterable[tuple[float, float]]methodrL   c                    t          |||          }|                     ||j        |                                          S )N)r#  r  r  )r#  r  r  )r   r  r  r  )rD   r#  r  r  r)  s        r1   add_spline_control_framez!EdgePath.add_spline_control_frame  sP     /!&
 
 
 !"1  
 
 	
r0   c                    g | _         dS )zDelete all edges.N)r   rC   s    r1   rE   zEdgePath.clear  r   r0   rJ   r   rK   c                   |                     dt          | j                             |                     dt          | j                             | j        D ]}|                    |           t          || j                   d S )Nr   rc  )r   r;   r<   rx   r   rN   rU  r>   )rD   rJ   rK   r  s       r1   rN   zEdgePath.export_dxf  s    RT%9!:!:;;;RTZ111J 	' 	'DOOI&&&&&y$2NOOOOOr0   len_tolc                   t          | j                  dk     rdS t          | j                  }|                    d          }|                    |           |g}|j        }|D ]s}|j        }|                    |          |k    r1t                      }||_	        ||_
        |                    |           ||ur|                    |           |j        }t|| _        dS )zInsert line-edges between the existing edges if the gap between these edges
        are bigger than `len_tol`.

        .. versionadded:: 1.4

        r)   Nr   )rx   r   r   rM  r   rm   rk   r   r   r   r   )	rD   r  current_edges
first_edger/  rf   r  rd   	line_edges	            r1   
close_gapszEdgePath.close_gaps  s     tz??QFTZ(("&&q))
Z((()3	-	! 		, 		,D/K!!+..88$JJ	"+	 +	  +++:%%  &&&+II


r0   rZ   r]   )rF   r
   r?   r   r\   )r   r   r   r   r?   r   )r   r   r   T)r   r   r   rQ   r   rQ   r   rQ   r   rV   r?   r    )r  r   r   r   T)r   r   r   r   r   rQ   r   rQ   r   rQ   r   rV   r?   r!   )NNNNr3   r   NN)r#  r  r  r  r  r  r  r  r  r;   r  r;   r  r  r  r  r?   r"   )r3   r   )r#  r  r  r;   r  rL   r?   r"   r[   )r  rQ   r?   r@   )r*   r+   r,   r$   r.   r:   rv   r   rX   ra   rI   rT   r  r  r  r  r  rE   rN   r  r/   r0   r1   r   r     s        D* * * *
     5 5 5 5 	 	 	 [	5 5 5 5
   "   , , , , ,b &  3 3 3 3 3n 043715-1(,&*9 9 9 9 9|  	
 
 
 
 
   P P P P     r0   r   c                      e Zd Zd Zej        Zd ZddZe	dd            Z
e	dd            Zedd
            ZddZddZdS )r   c                Z    t          dd          | _        t          dd          | _        d S r   r   r   r   rC   s    r1   rv   zLineEdge.__init__  s$    !QZZ
1::r0   r?   rV   c                    dS rZ  r/   rC   s    r1   rX   zLineEdge.is_valid  r[  r0   r   c                    | j         S rB   )r   rC   s    r1   rd   zLineEdge.start_point  s
    zr0   c                    | j         S rB   )r   rC   s    r1   rf   zLineEdge.end_point  s	    xr0   rF   r
   c                     |             }|D ]<}|\  }}|dk    rt          |          |_        "|dk    rt          |          |_        =|S )Nr_     r  rH   rF   r  rd  r   r   s         r1   rI   zLineEdge.load_tags  sY    suu 	' 	'CKD%rzz!%[[

;;r0   rJ   r   r@   c                r   |                     dd           | j        ^}}}|                     dt          |                     |                     dt          |                     | j        ^}}}|                     dt          |                     |                     dt          |                     d S )Nra  r(   r_     r     )r   r   rQ   r   )rD   rJ   r   r   r   s        r1   rN   zLineEdge.export_dxf  s    R###:1qRq***Rq***81qRq***Rq*****r0   rO   r   rP   rQ   c                    |                     | j        |          | _        |                     | j        |          | _        d S rB   )transform_2d_vertexr   r   rS   s      r1   rT   zLineEdge.transform  s8    ,,TZCC
**48Y??r0   Nr]   rn   )rF   r
   r?   r   ro   r\   )r*   r+   r,   	EDGE_TYPEr#   r5   r:   rv   rX   rp   rd   rf   ra   rI   rN   rT   r/   r0   r1   r   r     s        I=D         X    X    [	+ 	+ 	+ 	+@ @ @ @ @ @r0   r   c                      e Zd Zej        Zd ZddZddZe	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S ) r    r?   r@   c                h    t          dd          | _        d| _        d| _        d| _        d| _        d S )Nr   r   r   T)r   r   r   r   r   r   rC   s    r1   rv   zArcEdge.__init__  s2    3nn "% %r0   rV   c                    dS rZ  r/   rC   s    r1   rX   zArcEdge.is_valid  r[  r0   r   c                4    |                                  j        S rB   )construction_toolrd   rC   s    r1   rd   zArcEdge.start_point   s    %%''33r0   c                ,    | j         r| j        S | j        S rB   r   rd   rf   rC   s    r1   rk   zArcEdge.real_start_point      8 	$##~r0   c                4    |                                  j        S rB   )r  rf   rC   s    r1   rf   zArcEdge.end_point
  s    %%''11r0   c                ,    | j         r| j        S | j        S rB   r   rf   rd   rC   s    r1   rm   zArcEdge.real_end_point      8 	">!r0   rF   r
   c                4    |             }d}d}|D ]\}|\  }}|dk    rt          |          |_        "|dk    r||_        0|dk    r|}9|dk    r|}B|dk    rt          |          |_        ]|j        r||_        ||_        nd|z
  |_        d|z
  |_        |S )Nr   r_  (   2   3   rb  r   )r   r   r   rV   r   r   r   rH   rF   r  r   r   rd  r   r   s           r1   rI   zArcEdge.load_tags  s    suu 	' 	'CKD%rzz"5kk#;; 8 	+$D DNN$s{D"U]DNr0   rJ   r   c                   |                     dd           | j        ^}}}| j        r| j        }| j        }nd| j        z
  }d| j        z
  }|                     dt          |                     |                     dt          |                     |                     d| j                   |                     d|           |                     d|           |                     d	t          | j                             d S )
Nra  r)   r   r_  r  r  r  r  rb  )r   r   r   r   r   rQ   r   r;   rD   rJ   r   r   r   r   r   s          r1   rN   zArcEdge.export_dxf5  s    R###;1q8 	+$E.CC DN*E$**CRq***Rq***R---R'''R%%%RTX/////r0   rO   r   rP   rQ   c                   |                     | j        |          | _        |                    t          | j        dd                    | _        t          j        t          | j        | j	                  d          s@|
                    | j                  | _        |
                    | j	                  | _	        d S |
                    | j                  | _        | j        dz   | _	        d S )Nr   r   )r  r   transform_lengthr   r   r   r   r   r   r   transform_deg_anglerS   s      r1   rT   zArcEdge.transformG  s    --dk9EE**4Q+B+BCC|t/@@%
 
 	6  #66t7GHHD 44T^DDDNNN  #66t7GHHD!-5DNNNr0   r   c                P    t          | j        | j        | j        | j                  S )z5Returns ConstructionArc() for the OCS representation.)r   r   r   r   )r   r   r   r   r   rC   s    r1   r  zArcEdge.construction_tool\  s.    ;;(n	
 
 
 	
r0   NrZ   r]   rn   )rF   r
   r?   r    ro   r\   )r?   r   )r*   r+   r,   r#   r6   r:   r  rv   rX   rp   rd   rk   rf   rm   ra   rI   rN   rT   r  r/   r0   r1   r    r      s%       <DI       4 4 4 X4    X
 2 2 2 X2       X 
    [@0 0 0 0$6 6 6 6*
 
 
 
 
 
r0   r    c                  4   e Zd Zd Zej        ZddZddZe	d d            Z
e	d d            Ze	d d	            Ze	d d
            Ze	d!d            Zej        d"d            Ze	d!d            Zej        d"d            Zed#d            Zd$dZd%dZd&dZdS )'r!   r?   r@   c                    t          d          | _        t          d          | _        d| _        d| _        d| _        d| _        d S )N)r   r   r  r   r   r   T)r   r   r   r   r   r   r   rC   s    r1   rv   zEllipseEdge.__init__j  sA    :&&z**
"% %r0   rV   c                    dS rZ  r/   rC   s    r1   rX   zEllipseEdge.is_validu  r[  r0   r   c                >    |                                  j        j        S rB   )r  rd   r(  rC   s    r1   rd   zEllipseEdge.start_pointx  s    %%''388r0   c                >    |                                  j        j        S rB   )r  rf   r(  rC   s    r1   rf   zEllipseEdge.end_point|  s    %%''166r0   c                ,    | j         r| j        S | j        S rB   r  rC   s    r1   rk   zEllipseEdge.real_start_point  r  r0   c                ,    | j         r| j        S | j        S rB   r  rC   s    r1   rm   zEllipseEdge.real_end_point  r  r0   rQ   c                Z    t          | j        t          j        | j                            S rB   )r   r   r   radiansr   rC   s    r1   r  zEllipseEdge.start_param  s!    dj$,t7G*H*HIIIr0   paramc                ^    t          j        t          | j        |                    | _        d S rB   )r   r   r   r   r   rD   r  s     r1   r  zEllipseEdge.start_param  s&    <tz5(I(IJJr0   c                Z    t          | j        t          j        | j                            S rB   )r   r   r   r  r   rC   s    r1   r  zEllipseEdge.end_param  s     dj$,t~*F*FGGGr0   c                ^    t          j        t          | j        |                    | _        d S rB   )r   r   r   r   r   r  s     r1   r  zEllipseEdge.end_param  s#    nTZ&G&GHHr0   rF   r
   c                j    |             }d}d}|D ]w}|\  }}|dk    rt          |          |_        "|dk    rt          |          |_        =|dk    r||_        K|dk    r|}T|dk    r|}]|dk    rt	          |          |_        x|j        r||_        ||_        nd|z
  |_        d|z
  |_        |S )	Nr   r_  r  r  r  r  rb  r   )r   r   r   r   rV   r   r   r   r  s           r1   rI   zEllipseEdge.load_tags  s    suu 	' 	'CKD%rzz"5kk"&u++"

;;8 	+$D DNN  %s{D"U]DNr0   rJ   r   c                   |                     dd           | j        ^}}}|                     dt          |                     |                     dt          |                     | j        ^}}}|                     dt          |                     |                     dt          |                     |                     d| j                   | j        r| j        }| j        }nd| j        z
  }d| j        z
  }|                     d	|           |                     d
|           |                     dt          | j                             d S )Nra  r3   r_  r  r  r  r  r   r  r  rb  )	r   r   rQ   r   r   r   r   r   r;   r  s          r1   rN   zEllipseEdge.export_dxf  s@   R###;1qRq***Rq***?1qRq***Rq***R,,,8 	+$E.CC DN*E$**CR'''R%%%RTX/////r0   r   c           	         t          t          | j                  t          | j                  t          ddd          | j        | j        | j                  S )z9Returns ConstructionEllipse() for the OCS representation.r   r(   )r   r   	extrusionr   r  r  )r   r   r   r   r   r  r  rC   s    r1   r  zEllipseEdge.construction_tool  sR    "$$DO,,1amm* (n	
 	
 	
 		
r0   rO   r   rP   c                X   |                                  }|j        j        } ||j                            |                    |_         ||j                  |_        |j        |_        |                    |j	                   |j
        j        } ||j                  j        | _         ||j                  j        | _        |j        | _        |j        | _        |j        | _        | j        dz  | _        | j        dz  | _        t%          j        | j        d          r	d| _        d S d S )Nzr   r   )r  old_ocsto_wcsr   replacer   old_extrusionr  rT   mnew_ocsfrom_wcsr(  r   r  r  r   r   r   r   )rD   rO   rP   r  
ocs_to_wcs
wcs_to_ocss         r1   rT   zEllipseEdge.transform  s   ""$$ ['
:ah...;;<<!z!,//' 	
CE [)
 j**/$*Q\227W
 =  +e3%/<** 	#"DNNN	# 	#r0   NrZ   r]   rn   )r?   rQ   )r  rQ   r?   r@   )rF   r
   r?   r!   ro   )r?   r   r\   )r*   r+   r,   r  r#   r7   r:   rv   rX   rp   rd   rf   rk   rm   r  setterr  ra   rI   rN   r  rT   r/   r0   r1   r!   r!   f  s       ID	 	 	 	    9 9 9 X9 7 7 7 X7    X
       X 
 J J J XJ K K K K H H H XH I I I I ! ! ! [!F0 0 0 0,
 
 
 
## ## ## ## ## ##r0   r!   c                      e Zd Zd Zej        ZddZ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S )r"   r?   r@   c                    d| _         d| _        d| _        g | _        g | _        g | _        g | _        d | _        d | _        d S )Nr3   r   )	r  r  r  r  r  r#  r  r  r  rC   s    r1   rv   zSplineEdge.__init__  sK    (**,&($&-1+/r0   rV   c                    t          | j                  rF| j        dz   }t          | j                  }||k    rdS ||z   }t          | j                  |k    rdS nt          | j                  dk     rdS dS )Nr(   Fr)   T)rx   r  r  r  r#  )rD   r!  r  required_knot_counts       r1   rX   zSplineEdge.is_valid  s    t"## 		K!OE+,,Eu}}u"'%-4#$$(;;;u <!!A%%5tr0   r   c                    | j         d         S r   r  rC   s    r1   rd   zSplineEdge.start_point&  s    "1%%r0   c                    | j         d         S )Nr"  r  rC   s    r1   rf   zSplineEdge.end_point*  s    "2&&r0   rF   r
   c                ,    |             }|D ]}|\  }}|dk    r||_         |dk    r||_        $|dk    r||_        2|dk    r|j                            |           S|dk    r|j                            |           t|dk    r(|j                            t          |                     |dk    r(|j                            t          |                     |dk    rt          |          |_	        |d	k    rt          |          |_
        |S )
N^   rb  J   r  r`  r_  r        )r  r  r  r  r   r  r  r   r#  r  r  r  s         r1   rI   zSplineEdge.load_tags.  s(   suu 	/ 	/CKD%rzz# % % ''....##E****#**4;;7777&&tE{{3333%)%[[""#';; r0   rJ   r   c                    d fd}t           j                  rFt           j                  t           j                  k    rd _        nt	          j        d          d _        |j        } |dd            |d	t           j                              |d
t           j                              |dt           j	                              |dt           j
                              |dt           j                             t           j
                  r$ j
        D ]} |dt          |                     nt	          j        d          t          j         j                  } j        rqt          | j                  D ]Z\  }} |dt          |j                              |dt          |j                              |dt          |                     [n:|D ]7\  }}	 |dt          |                      |dt          |	                     8t           j                  dk    ri ||            |dt           j                              j        D ]7^}}	}
 |dt          |                      |dt          |	                     8n!|j        t          j        k    r |dd            j        < j        ^}}	}
 |dt          |                      |dt          |	                      j        > j        ^}}	}
 |dt          |                      |dt          |	                     d S d S )Nr   
list[Vec2]c                    t          |           dk    r<j        | d         | d         z
  _        j        | d         | d         z
  _        d S d S d S )Nr(   r   r"  )rx   r  r  )r   rD   s    r1   set_required_tangentsz4SplineEdge.export_dxf.<locals>.set_required_tangentsH  sc    6{{Q%-)/VAY)>D&#+'-bzF2J'>D$$$	  ,+r0   r(   zASplineEdge: count of control points and count of weights mismatchr   ra  r4   r  rb  r  _   `   r  z(SplineEdge: missing required knot valuesr_  r  r`  rK  r  r  r     r     )r   r  )rx   r  r  r  r	   rg  r   r;   r  r  r  rQ   r   r   r'  r   r   r#  
dxfversionDXF2010r  r  )rD   rJ   r  rr  r   cpr   weightr   r   r   s   `          r1   rN   zSplineEdge.export_dxfG  s   	? 	? 	? 	? 	? 	? t| 		4<  C(;$<$<<< !)  
 DM(		"a	"c$+&&'''	"c$-(()))	"c$-(()))	"c$*++,,,	"c$-../// t   	R) , ,	"eEll++++, %&PQQQ Yt*++= 	(!$R!6!6 - -v	"eEGnn---	"eEGnn---	"eFmm,,,,-
  ( (1	"eAhh'''	"eAhh'''' t!##!!"%%%Ib#do../// O ( (1q	"eAhh'''	"eAhh''''( !U]22Ib!))HAq1Ib%((###Ib%((###''HAq1Ib%((###Ib%((##### ('r0   rO   r   rP   rQ   c                   t          fd| j        D                       | _        t          fd| j        D                       | _        | j        Gt	          | j                                                }                    |          j        | _        | j        It	          | j                                                }                    |          j        | _        d S d S )Nc              3  D   K   | ]}                     |          V  d S rB   r  r   rD  rP   rO   s     r1   r   z'SplineEdge.transform.<locals>.<genexpr>  sD       #
 #
67C##Ay11#
 #
 #
 #
 #
 #
r0   c              3  D   K   | ]}                     |          V  d S rB   r   r  s     r1   r   z'SplineEdge.transform.<locals>.<genexpr>  sD       
 
67C##Ay11
 
 
 
 
 
r0   r  )	r   r  r#  r  r   r  transform_directionr(  r  )rD   rO   rP   ts    `` r1   rT   zSplineEdge.transform  s   " #
 #
 #
 #
 #
;?;N#
 #
 #
 
 
  
 
 
 
 
;??
 
 
 
 
 )T'((0090==A!$!8!8!;!;!@D'T%&&...;;A"66q99>D ('r0   r   c                V    t          | j        | j        | j        dz   | j                  S )z-Returns BSpline() for the OCS representation.r(   )r  r  r!  r  )r   r  r  r  r  rC   s    r1   r  zSplineEdge.construction_tool  s3    ."+/L	
 
 
 	
r0   NrZ   r]   rn   )rF   r
   r?   r"   ro   r\   )r?   r   )r*   r+   r,   r  r#   r8   r:   rv   rX   rp   rd   rf   ra   rI   rN   rT   r  r/   r0   r1   r"   r"   	  s        I?D
0 
0 
0 
0    & & & X& ' ' ' X'    [0B$ B$ B$ B$H? ? ? ?
 
 
 
 
 
r0   r"   rA  )r   r&   r   rQ   r   r;   r?   r   )r   r
   r?   r=   )rJ   r   rQ  rR  )6
__future__r   typingr   r   r   r   r   r_   enumr   ezdxf.lldxfr	   ezdxf.lldxf.tagsr
   r   
ezdxf.mathr   r   r   r   r   r   r   r   r   r   r   r   r   r   ezdxf.math.transformtoolsr   ezdxf.lldxf.tagwriterr   __all__uniqueIntEnumr$   r#   ABCr&   r%   r   r   rP  rU  r   r   r   r    r!   r"   r  r/   r0   r1   <module>r     s   # " " " " " E E E E E E E E E E E E E E 



         - - - - - - - -                                 3 2 2 2 2 2 8777777       t|   
     t|   $ $ $ $ $37 $ $ $,    37   :` ` ` ` ` ` ` `H BD       "* * * *D/ D/ D/ D/ D/' D/ D/ D/N~ ~ ~ ~ ~# ~ ~ ~B+@ +@ +@ +@ +@| +@ +@ +@\s
 s
 s
 s
 s
l s
 s
 s
l`# `# `# `# `#, `# `# `#FW
 W
 W
 W
 W
 W
 W
 W
t hjAr0   