
    Og                    &   d dl mZ d dlmZmZmZmZmZmZm	Z	 d dl
mZ d dlmZ d dlmZmZmZmZmZmZmZ d dlmZmZmZ d dlmZ d dlmZmZmZmZm Z  d d	l!m"Z"m#Z# d d
l$m%Z% d dl&m'Z' d dl(m)Z) d dl*m+Z+ d dl,m-Z- ddl.m/Z/m0Z0 ddl1m2Z2m3Z3m4Z4 ddl5m6Z6 ddl7m8Z8 er$d dl,m9Z9 d dl*m:Z:m;Z;m<Z<m=Z= d dl>m?Z? d dl@mAZA d dlBmCZC g dZD ed edej                  e       edd        edd d !       ed"d d !       ed#d d ej                  e$       ed%d d ej                  e$       ed&d d !       ed'd d !       ed(d d  ej                  h d)      e$       ed*d d !       ed+ej                  ed ej                  e,      d-      ZI eeId./      ZJ ee4eJ      ZKe+j                   G d0 d1e8             ZM G d2 d3eM      ZN G d4 d5      ZO G d6 d7      ZP G d8 d9eM      ZQ G d: d;      ZR ed< edej                  =       edd d !       ed"d d !       ed>d d !       edd        ed?d @       ed#d @       ed%d @       ed&d @       ed'd @       edAd @      dB      ZS eeS      ZT ee4eT      ZUe+j                   G dC dDe2             ZVdGdHdEZWyF)I    )annotations)TYPE_CHECKINGIterableIteratorUnioncastSequenceOptional)chain)	validator)DXFAttrDXFAttributesDefSubclassXTypeRETURN_DEFAULTgroup_code_mappingmerge_group_code_mappings)DXF12SUBCLASS_MARKERVERTEXNAMES)const)Vec3Matrix44NULLVECZ_AXISUVec)OCSTransformNonUniformScalingError)virtual_polyline_entitiesexplode_entity)EntityQuery)factory)
AuditError   )
base_classSubclassProcessor)
DXFGraphicacdb_entityacdb_entity_group_codes)FORMAT_CODES)LinkedEntities)Auditor)DXFNamespaceLineArcFace3d)
BaseLayout)AbstractTagWriter)FaceType)PolylinePolyfacePolymeshAcDbPolylineDummy
   )xtypedefaultF   )r;   (   T)r;   optional)   G   )r;   r>   r   fixerH   I   J   K   >   r            '      )r:   r;   r>   r   rA   	elevationflagsdefault_start_widthdefault_end_widthm_countn_countm_smooth_densityn_smooth_densitysmooth_type	thickness	extrusion)B   )ignorec                  <    e Zd ZdZdZ eeee      Z	dZ
e
ZdZdZdZdZdZd	Zd
ZdZdZdZdZeez  ez  Zed1d       Z	 d2	 	 	 d3 fdZd4 fdZd5 fdZd6dZd7dZd8dZd9dZ ed:d       Z!ed:d       Z"ed:d       Z#e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<dZ*d;d<d Z+d=d<d!Z,d8d"Z-d>d#Z.d?d$Z/d?d%Z0d@d&Z1d2dAd'Z2	 	 dB	 	 	 	 	 dCd(Z3d2dDd)Z4	 d2	 	 	 	 	 dEd*Z5	 	 	 	 	 	 dFd+Z6dGd,Z7dHd-Z8d2dId.Z9dJd/Z:dKd0Z; xZ<S )Lr5   zDXF POLYLINE entity

    The POLYLINE entity is hard owner of its VERTEX entities and the SEQEND entity:

       VERTEX.dxf.owner == POLYLINE.dxf.handle
       SEQEND.dxf.owner == POLYLINE.dxf.handle

    POLYLINEr%         rH          @      r   rF   rG   c                    | j                   S N)_sub_entitiesselfs    \/var/www/html/public_html/myphp/venv/lib/python3.12/site-packages/ezdxf/entities/polyline.pyverticeszPolyline.vertices   s    !!!    c                ^    t         t        |   |      }|r|j                  |t               |S z!Loading interface. (internal API))superr(   load_dxf_attribssimple_dxfattribs_loadermerged_polyline_group_codesre   	processordxf	__class__s      rf   rl   zPolyline.load_dxf_attribs   s/    
 J6yA..s4OP
rh   c                N    t         |          | j                  fd       y)z?Export POLYLINE entity and all linked entities: VERTEX, SEQEND.c                &    | j                        S rb   )
export_dxf)e	tagwriters    rf   <lambda>z%Polyline.export_dxf.<locals>.<lambda>   s    ALL,C rh   N)rk   ru   process_sub_entitiesre   rw   rr   s    `rf   ru   zPolyline.export_dxf   s    9%!!"CDrh   c                    t         |   |       |j                  t        kD  r$|j	                  t
        | j                                |j	                  dd       | j                  j                  |g d       y)z*Export POLYLINE specific data as DXF tags.rW   r%   rK   N)	rk   export_entity
dxfversionr   
write_tag2r   get_moderq   export_dxf_attribsrz   s     rf   r|   zPolyline.export_entity   s^    i(%'  $--/BR###	
rh   c                H    | j                   D ]  }||j                  _         y)zEvent handler for layer change. Changes also the layer of all vertices.

        Args:
            layer: new layer as string

        N)rg   rq   layer)re   r   vs      rf   on_layer_changezPolyline.on_layer_change   s"      	 AAEEK	 rh   c                H    | j                   D ]  }||j                  _         y)zEvent handler for linetype change. Changes also the linetype of all
        vertices.

        Args:
            linetype: new linetype as string

        N)rg   rq   linetype)re   r   r   s      rf   on_linetype_changezPolyline.on_linetype_change   s"      	&A%AEEN	&rh   c                D    t         j                  | j                            S rb   )r   VERTEX_FLAGSr   rd   s    rf   get_vertex_flagszPolyline.get_vertex_flags   s    !!$--/22rh   c                R    | j                   ry| j                  ry| j                  ryy)zReturns POLYLINE type as string:

        - "AcDb2dPolyline"
        - "AcDb3dPolyline"
        - "AcDbPolygonMesh"
        - "AcDbPolyFaceMesh"

        AcDb3dPolylineAcDbPolygonMeshAcDbPolyFaceMeshAcDb2dPolyline)is_3d_polylineis_polygon_meshis_poly_face_meshrd   s    rf   r   zPolyline.get_mode   s+     #!!$##%#rh   c                N    | j                   j                  | j                  z  dk(  S )z&``True`` if POLYLINE is a 2D polyline.r   )rq   rM   ANY3Drd   s    rf   is_2d_polylinezPolyline.is_2d_polyline   s      xx~~

*a//rh   c                Z    t        | j                  j                  | j                  z        S )z&``True`` if POLYLINE is a 3D polyline.)boolrq   rM   POLYLINE_3Drd   s    rf   r   zPolyline.is_3d_polyline   s"     DHHNNT%5%5566rh   c                Z    t        | j                  j                  | j                  z        S )z=``True`` if POLYLINE is a polygon mesh, see :class:`Polymesh`)r   rq   rM   POLYMESHrd   s    rf   r   zPolyline.is_polygon_mesh         DHHNNT]]233rh   c                Z    t        | j                  j                  | j                  z        S )z?``True`` if POLYLINE is a poly face mesh, see :class:`Polyface`)r   rq   rM   POLYFACErd   s    rf   r   zPolyline.is_poly_face_mesh   r   rh   c                Z    t        | j                  j                  | j                  z        S )z``True`` if POLYLINE is closed.)r   rq   rM   CLOSEDrd   s    rf   	is_closedzPolyline.is_closed  s      DHHNNT[[011rh   c                Z    t        | j                  j                  | j                  z        S )zV``True`` if POLYLINE (as :class:`Polymesh`) is closed in m
        direction.
        )r   rq   rM   MESH_CLOSED_M_DIRECTIONrd   s    rf   is_m_closedzPolyline.is_m_closed
  "    
 DHHNNT%A%AABBrh   c                Z    t        | j                  j                  | j                  z        S )zV``True`` if POLYLINE (as :class:`Polymesh`) is closed in n
        direction.
        )r   rq   rM   MESH_CLOSED_N_DIRECTIONrd   s    rf   is_n_closedzPolyline.is_n_closed  r   rh   c                T    | j                   rt        d | j                  D              S y)z3Returns ``True`` if 2D POLYLINE has an arc segment.c              3     K   | ]@  }|j                   j                  d       xr t        |j                   j                         B yw)bulgeN)rq   hasattrr   r   ).0r   s     rf   	<genexpr>z#Polyline.has_arc.<locals>.<genexpr>  s7      ABg&<4+<<   AAF)r   anyrg   rd   s    rf   has_arczPolyline.has_arc  s0      FJmm   rh   c                   | j                   r | j                  j                  d      r t        | j                  j                        ry| j                  j                  d      r t        | j                  j
                        ry| j                  D ]{  }|j                  j                  d      r!t        |j                  j                        r y|j                  j                  d      s[t        |j                  j                        s{ y y)zoReturns ``True`` if 2D POLYLINE has default width values or any
        segment with width attributes.
        rN   TrO   start_width	end_widthF)	r   rq   r   r   rN   rO   rg   r   r   )re   r   s     rf   	has_widthzPolyline.has_width"  s    
 xx 564,,< xx 34**: ]]  55==/D9J9J4K55==-$quu2G	 
 rh   c                @    | j                  | j                  |d       y)zClose POLYMESH in m direction if `status` is ``True`` (also closes
        POLYLINE), clears closed state if `status` is ``False``.
        rM   nameN)set_flag_stater   re   statuss     rf   m_closezPolyline.m_close7       	D88&wOrh   c                @    | j                  | j                  |d       y)zuClose POLYMESH in n direction if `status` is ``True``, clears closed
        state if `status` is ``False``.
        rM   r   N)r   r   r   s     rf   n_closezPolyline.n_close=  r   rh   c                H    | j                  |       | j                  |       y)zSet closed state of POLYMESH and POLYLINE in m direction and n
        direction. ``True`` set closed flag, ``False`` clears closed flag.
        N)r   r   )re   r   r   s      rf   closezPolyline.closeC  s     	WWrh   c                ,    t        | j                        S )z*Returns count of :class:`Vertex` entities.lenrg   rd   s    rf   __len__zPolyline.__len__J      4==!!rh   c                     | j                   |   S )zIGet :class:`Vertex` entity at position `pos`, supports list-like slicing.rg   re   poss     rf   __getitem__zPolyline.__getitem__N  s    }}S!!rh   c                (    d | j                   D        S )a  Returns all polyline points in :ref:`OCS` or :ref:`WCS` coordinates as
        :class:`~ezdxf.math.Vec3`.

        These are the raw location coordinates stored in the :class:`Vertex` entities.
        A separately stored elevation value will not be applied. The points of
        2D polylines are :ref:`OCS` coordinates other polyline types return :ref:`WCS`
        coordinates.
        c              3  H   K   | ]  }|j                   j                    y wrb   rq   locationr   vertexs     rf   r   z"Polyline.points.<locals>.<genexpr>[  s     @

##@    "r   rd   s    rf   pointszPolyline.pointsR  s     A$--@@rh   c                2   | j                         }| j                  s|S | j                  j                  j                  rfd|D        }t        j                  | j                  j                        r|S | j                         }|j                  |      S )zReturns all polyline points in :ref:`WCS` coordinates as
        :class:`~ezdxf.math.Vec3`.

        .. versionadded:: 1.4

        c              3  B   K   | ]  }|j                           yw)zN)replace)r   prL   s     rf   r   z)Polyline.points_in_wcs.<locals>.<genexpr>j  s     =aii)i,=s   )
r   r   rq   rL   r   r   iscloserV   ocspoints_to_wcs)re   r   r   rL   s      @rf   points_in_wcszPolyline.points_in_wcs]  sw     ""M88--//	=f=F>>$((,,-Mhhj  ((rh   c                :    | j                   j                  |       y rb   )rg   append)re   r   s     rf   _append_vertexzPolyline._append_vertexr  s    V$rh   c                r    t        |xs i       }| j                  ||      D ]  }| j                  |        y)zAppend multiple :class:`Vertex` entities at location `points`.

        Args:
            points: iterable of (x, y[, z]) tuples
            dxfattribs: dict of DXF attributes for the VERTEX objects

        Ndict_build_dxf_verticesr   )re   r   
dxfattribsr   s       rf   append_verticeszPolyline.append_verticesu  s=     **+
..vzB 	(F'	(rh   c                   t        |xs i       }|j                  dd      | j                         z  |d<   | j                  j                  |d<   | j                  j
                  |d<   | j                  j                  d      r| j                  j                  |d<   |D ]P  }t        ||      }|j                  |       t        t        | j                  d|            }| j                  |       R y)aP  Append multiple :class:`Vertex` entities at location `points`.

        Args:
            points: iterable of (x, y, [start_width, [end_width, [bulge]]])
                    tuple
            format: format string, default is "xy", see: :ref:`format codes`
            dxfattribs: dict of DXF attributes for the VERTEX objects

        rM   r   ownerr   r   VERTEXN)r   getr   rq   r   r   r   r   vertex_attribsupdater   	DXFVertex_new_compound_entityr   )re   r   formatr   pointattribsr   s          rf   append_formatted_verticesz"Polyline.append_formatted_vertices  s     **+
(nnWa84;P;P;RR
7 #hhnn
7"hhnn
788J'%)XX%6%6Jz" 	(E$UF3GNN:&)T%>%>x%QRF'		(rh   c                t    t        |xs i       }| j                  |g|      D ]  }| j                  |        y)zAppend a single :class:`Vertex` entity at location `point`.

        Args:
            point: as (x, y[, z]) tuple
            dxfattribs: dict of DXF attributes for :class:`Vertex` class

        Nr   )re   r   r   r   s       rf   append_vertexzPolyline.append_vertex  s?     **+
..w
C 	(F'	(rh   c                r    t        |xs i       }t        | j                  ||            | j                  || y)a9  Insert vertices `points` into :attr:`Polyline.vertices` list
        at insertion location `pos` .

        Args:
            pos: insertion position of list :attr:`Polyline.vertices`
            points: list of (x, y[, z]) tuples
            dxfattribs: dict of DXF attributes for :class:`Vertex` class

        N)r   listr   rg   )re   r   r   r   s       rf   insert_verticeszPolyline.insert_vertices  s5     **+
!%d&>&>vz&R!Sc#rh   c              #    K   |j                  dd      | j                         z  |d<   | j                  j                  |d<   | j                  j                  |d<   | j                  j                  d      r| j                  j                  |d<   |D ]2  }t        |      |d<   t        t        | j                  d|             4 yw)	zConverts point (x, y, z) tuples into DXFVertex objects.

        Args:
            points: list of (x, y, z)-tuples
            dxfattribs: dict of DXF attributes
        rM   r   r   r   r   r   r   N)r   r   rq   handler   r   r   r   r   r   r   )re   r   r   r   s       rf   r   zPolyline._build_dxf_vertices  s      )nnWa84;P;P;RR
7 #hhoo
7"hhnn
788J'%)XX%6%6Jz" 	SE%)%[Jz"y$";";Hj"QRR	Ss   CCc                    | j                         }|dk(  rt        j                  |       S |dk(  rt        j                  |       S | S )Nr   r   )r   r6   from_polyliner7   )re   modes     rf   r   zPolyline.cast  sF    }}%%))$//&&))$//Krh   c                     fd} j                   r j                  }t         j                  j                  |      }|j                  s j
                  rt        d      |j                  d      r|j                  j                  }nd} ||      D cg c]  }|j                  |       }}|r|d   j                  dd      |_        t         j                  |      D ]{  \  }}|j                  }	||	_        |	j                  d      r |j                  |	j                         |	_        |	j                  d	      s\|j                  |	j"                        |	_        } |j                  d
      r |j                  |j$                        |_        |j                  d      r |j                  |j&                        |_        |j                  d      r |j)                  |j*                        |_        |j,                  |_        n" j                  D ]  }|j/                  |         j1                  |        S c c}w )a  Transform the POLYLINE entity by transformation matrix `m` inplace.

        A non-uniform scaling is not supported if a 2D POLYLINE contains
        circular arc segments (bulges).

        Args:
            m: transformation :class:`~ezdxf.math.Matrix44`

        Raises:
            NonUniformScalingError: for non-uniform scaling of 2D POLYLINE
                containing circular arc segments (bulges)

        c              3     K   j                   D ]0  }|j                  j                  }| |j                  |       }| 2 y w)Nr   )rg   rq   r   r   )rL   r   r   re   s      rf   _ocs_locationsz*Polyline.transform.<locals>._ocs_locations  sI     -- !::..(  (//)/<Hs   AAzI2D POLYLINE containing arcs (bulges) does not support non uniform scalingrL   Nr   g        )xyr   r   rN   rO   rU   )r   rq   r   rV   scale_uniformr   r   r   rL   r   transform_vertexr   ziprg   r   transform_widthr   r   rN   rO   transform_thicknessrU   new_extrusion	transformpost_transform)
re   mr   rq   r   z_axisr   rg   r   vdxfs
   `         rf   r  zPolyline.transform  s   	 ((Ctxx1115C$$,_ 
 {{;';I&;Q17$$V,H   ( 3 3cS 3 A$'x$@ I zz (<<.'*':':4;K;K'LD$<<,%(%8%8%HDNI {{01*-*=*=c>U>U*V'{{./(+(;(;C<Q<Q(R%{{;' # 7 7 F--CM-- $  #$A;s   H<c                    t        | |      S )a  Explode the POLYLINE entity as DXF primitives (LINE, ARC or 3DFACE)
        into the target layout, if the target layout is ``None``, the target
        layout is the layout of the POLYLINE entity.

        Returns an :class:`~ezdxf.query.EntityQuery` container referencing all
        DXF primitives.

        Args:
            target_layout: target layout for DXF primitives, ``None`` for same
                layout as source entity.

        r    )re   target_layouts     rf   explodezPolyline.explode  s     dM22rh   c              #  V   K   t        |       D ]  }|j                  |        |  yw)a&  Yields the graphical representation of POLYLINE as virtual DXF
        primitives (LINE, ARC or 3DFACE).

        These virtual entities are located at the original location, but are not
        stored in the entity database, have no handle and are not assigned to
        any layout.

        N)r   set_source_of_copy)re   rv   s     rf   virtual_entitieszPolyline.virtual_entities*  s/      +40 	A  &G	s   ')c                l   fd}| j                   | j                  j                  | j                  j                  | j                  D ]
  } ||        | j
                  }|r	 ||       yr@| j                          |j                  t        j                  dt        |        d|        yy)z%Audit and repair the POLYLINE entity.c                    | _         | j                  }|j                  k7  r|_        |j                  k7  r|_        y y rb   )docrq   r   r   )entityrq   r  r   r   s     rf   audit_sub_entityz(Polyline.audit.<locals>.audit_sub_entity:  s>    FJ**CyyE!!	yyE!!	 "rh   z#Created required SEQEND entity for .)codemessage
dxf_entityN)r  rq   r   r   rg   seqend
new_seqendfixed_errorr$   MISSING_REQUIRED_SEQENDstr)re   auditorr  r   r  r  r   r   s        @@@rf   auditzPolyline.audit7  s    	" hhmm 	%FV$	% V$OO77=c$i[J    rh   returnlist[DXFVertex]rb   rp   zOptional[SubclassProcessor]r#  r.   )rw   r3   rw   r3   r#  None)r   r  )r   r  r#  int)r#  r  r#  r   )T)r#  r'  )TF)r#  r   )r#  zIterator[Vec3])r   r   r#  r'  )r   Iterable[UVec]r#  r'  )xyN)r   zIterable[Sequence]r   r  r#  r'  )r   r   r#  r'  )r   r)  r   r+  r#  r'  )r   r+  r   r   r#  zIterator[DXFVertex])r#  z#Union[Polyline, Polymesh, Polyface])r	  r   r#  r5   )r  zOptional[BaseLayout]r#  r"   )r#  z"Iterator[Union[Line, Arc, Face3d]])r   r-   r#  r'  )=__name__
__module____qualname____doc__DXFTYPEr   r&   r)   acdb_polyline
DXFATTRIBSr   r   CURVE_FIT_VERTICES_ADDEDSPLINE_FIT_VERTICES_ADDEDr   r   r   r   GENERATE_LINETYPE_PATTERN	NO_SMOOTHQUADRATIC_BSPLINECUBIC_BSPLINEBEZIER_SURFACEr   propertyrg   rl   ru   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r!  __classcell__rr   s   @rf   r5   r5   }   s7    Gz;FJF$  !KH H #IMN("X-E" " 8<4	E
0 	&3$$ 0 0 7 7 4 4 4 4 2 2 C C C C    (PP""	A)*%
( 	("( (
 
(<
( <@TT .T	TS$S26S	S(BH3rh   r5   c                  r    e Zd ZdZedd       ZdddZ	 	 	 	 ddZdddZdddZ	ddZ
ddd	Zdd
ZddZy)r6   a  
    PolyFace structure:

    POLYLINE
      AcDbEntity
      AcDbPolyFaceMesh
    VERTEX - Vertex
      AcDbEntity
      AcDbVertex
      AcDbPolyFaceMeshVertex
    VERTEX - Face
      AcDbEntity
      AcDbFaceRecord
    SEQEND

    Order of mesh_vertices and face_records is important (DXF R2010):

        1. mesh_vertices: the polyface mesh vertex locations
        2. face_records: indices of the face forming vertices

    c                l    | j                  |      }|j                  |_        |j                  |_        |S rb   shallow_copyrc   r  )clspolylinepolyfaces      rf   r   zPolyface.from_polylinek  s0    ##H-!)!7!7"//rh   Nc                *    | j                  |g|       y)zAppend a single face. A `face` is a sequence of (x, y, z) tuples.

        Args:
            face: sequence of (x, y, z) tuples
            dxfattribs: dict of DXF attributes for the VERTEX objects

        N)append_faces)re   facer   s      rf   append_facezPolyface.append_faces  s     	4&*-rh   c           
         |j                  dd      | j                         z  |d<   | j                  dd      |d<   g }|D ]2  }||d<   |j                  t	        d| j                  d|                   4 |S )zConvert (x, y, z) tuples into DXFVertex objects.

        Args:
            points: sequence of (x, y, z) tuples
            dxfattribs: dict of DXF attributes for the VERTEX entity

        rM   r   r   0r   r   r   )r   r   get_dxf_attribr   r   r   )re   r   r   rg   r   s        rf   _points_to_dxf_verticesz Polyface._points_to_dxf_vertices}  s     )nnWa84;P;P;RR
7 #11'3?
7$& 	E%*Jz"OO[$";";Hj"QR	
 rh   c           
          fd}t        xs i        j                         \  }}g }|D ]x  } j                  |i       }t        |      }	|j	                  |       t         |       |      }
t        t        |	|	t        |      z               |
_        |j                  |
       z  j                  t        ||             y)a  Append multiple `faces`. `faces` is a list of single faces and a
        single face is a sequence of (x, y, z) tuples.

        Args:
            faces: iterable of sequences of (x, y, z) tuples
            dxfattribs: dict of DXF attributes for the VERTEX entity

        c                     t         j                   d<   t                d<   t        t        j                  d             S )NrM   r   r   )r   VTX_3D_POLYFACE_MESH_VERTEXr   r   r   r   )r   re   s   rf   new_face_recordz.Polyface.append_faces.<locals>.new_face_record  s9    "'"C"CJw%)VJz"	4#<#<Xz#RSSrh   N)r   indexed_facesrL  r   extend	FaceProxytuplerangeindicesr   _rebuildr   )re   facesr   rP  existing_verticesexisting_faces	new_facesrG  face_mesh_verticesindexface_records   ` `        rf   rF  zPolyface.append_faces  s    	T **+
,0,>,>,@)>%'	 		*D!%!=!=dB!G)*E$$%78#O$57HIK #(eUSAS=T5T(U"VK[)		* 	eNI67rh   c                    t        ||      }|j                         | _        | j                  |j                  |j
                         y)zyBuild a valid POLYFACE structure from `faces`.

        Args:
            faces: iterable of FaceProxy objects.

        )	precisionN)PolyfaceBuilderget_verticesrc   update_count	nverticesnfaces)re   rX  r`  polyface_builders       rf   rW  zPolyface._rebuild  sB     +5IF .::<*446F6M6MNrh   c                H    || j                   _        || j                   _        y rb   )rq   rP   rQ   )re   rd  re  s      rf   rc  zPolyface.update_count  s    $!rh   c                N    | j                         \  }}| j                  ||       y)zRebuilds the :class:`Polyface` by merging vertices with nearly same vertex
        locations.

        Args:
            precision: floating point precision for determining identical
                vertex locations

        N)rQ  rW  )re   r`  rg   rX  s       rf   optimizezPolyface.optimize  s$     ,,.%eY'rh   c              #     K   | j                         \  }}|D ],  }t        |      }|j                  |j                         | . yw)zIterable of all faces, a face is a tuple of vertices.

        Returns:
             list of [vertex, vertex, vertex, [vertex,] face_record]

        N)rQ  r   r   r^  )re   _rX  rG  face_verticess        rf   rX  zPolyface.faces  sL      %%'5 	 D JM  !1!12	 r   c                    g g }| j                   D ]!  }|j                  rn|j                  |       # fd|D        }|fS )zoReturns a list of all vertices and a generator of FaceProxy()
        objects.

        (internal API)
        c              3  6   K   | ]  }t        |        y wrb   )rS  )r   r^  rg   s     rf   r   z)Polyface.indexed_faces.<locals>.<genexpr>  s     Rk;1Rs   )rg   is_poly_face_mesh_vertexr   )re   face_recordsr   rX  rg   s       @rf   rQ  zPolyface.indexed_faces  sT     %'(*mm 	F88XlRR	
 S\Rrh   )rC  r5   r#  r6   rb   )rG  r4   r#  r'  )r   r+  r#  r$  )rX  zIterable[FaceType]r#  r'  rG   )rX  Iterable[FaceProxy]r`  r)  r#  r'  )rd  r)  re  r)  r#  r'  )r`  r)  r#  r'  )r#  zIterator[list[DXFVertex]])r#  z+tuple[list[DXFVertex], Iterator[FaceProxy]])r-  r.  r/  r0  classmethodr   rH  rL  rF  rW  rc  ri  rX  rQ   rh   rf   r6   r6   T  sU    ,  .$	,8@O"
( rh   r6   c                  T    e Zd ZdZdZddZddZddZddZddZ	ddZ
dd	Zdd
Zy)rS  af  Represents a single face of a polyface structure. (internal class)

    vertices:

        List of all polyface vertices.

    face_record:

        The face forming vertex of type ``AcDbFaceRecord``, contains the indices
        to the face building vertices. Indices of the DXF structure are 1-based
        and a negative index indicates the beginning of an invisible edge.
        Face.face_record.dxf.color determines the color of the face.

    indices:

        Indices to the face building vertices as tuple. This indices are 0-base
        and are used to get vertices from the list `Face.vertices`.

    )rg   r^  rV  c                J    || _         || _        | j                         | _        y)zBReturns iterable of all face vertices as :class:`Vertex` entities.N)rg   r^  _indicesrV  )re   r^  rg   s      rf   __init__zFaceProxy.__init__  s    -5&1&*mmorh   c                ,    t        | j                        S )z5Returns count of face vertices (without face_record).)r   rV  rd   s    rf   r   zFaceProxy.__len__  s    4<<  rh   c                :    | j                   | j                  |      S )zlReturns :class:`Vertex` at position `pos`.

        Args:
            pos: vertex position 0-based

        )rg   rV  r   s     rf   r   zFaceProxy.__getitem__  s     }}T\\#.//rh   c                .      fd j                   D        S )Nc              3  <   K   | ]  }j                   |     y wrb   r   )r   r]  re   s     rf   r   z%FaceProxy.__iter__.<locals>.<genexpr>  s     ?e$?s   )rV  rd   s   `rf   __iter__zFaceProxy.__iter__  s    ?$,,??rh   c                    d | D        S )zBReturns iterable of all face vertex locations as (x, y, z)-tuples.c              3  H   K   | ]  }|j                   j                    y wrb   r   r   s     rf   r   z#FaceProxy.points.<locals>.<genexpr>  s     7

##7r   rt  rd   s    rf   r   zFaceProxy.points  s    7$77rh   c                6      fdt         j                  D        S )Nc              3  V   K   | ]   }j                   j                  |d        " yw)r   N)r^  rK  )r   r   re   s     rf   r   z)FaceProxy._raw_indices.<locals>.<genexpr>   s$     WT  //a8Ws   &))r   r   rd   s   `rf   _raw_indiceszFaceProxy._raw_indices  s    WUEVEVWWrh   c                B    t        d | j                         D              S )Nc              3  D   K   | ]  }|d k7  s	t        |      dz
    yw)r   r%   N)abs)r   r]  s     rf   r   z%FaceProxy._indices.<locals>.<genexpr>#  s     SQR
SZ!^Ss   
  )rT  r  rd   s    rf   rw  zFaceProxy._indices"  s    S1B1B1DSSSrh   c                d    t         j                  |   }| j                  j                  |      dkD  S )zReturns ``True`` if edge starting at vertex `pos` is visible.

        Args:
            pos: vertex position 0-based

        r   )r   r   r^  rK  )re   r   r   s      rf   is_edge_visiblezFaceProxy.is_edge_visible%  s0       %..t4q88rh   N)r^  r   rg   zSequence[DXFVertex]r(  )r   r)  r#  r   )r#  zIterator['DXFVertex'])r#  zIterator[UVec])r#  zIterable[int])r#  zSequence[int])r   r)  r#  r   )r-  r.  r/  r0  	__slots__rx  r   r   r}  r   r  rw  r  rt  rh   rf   rS  rS    s9    ( 7I6!0@8XT9rh   rS  c                  V    e Zd ZdZd	d
dZedd       Zedd       ZddZddZ	ddZ
y)ra  z,Optimized POLYFACE builder. (internal class)c                ^    || _         g | _        g | _        i | _        | j	                  |       y rb   )r`  rX  rg   index_mappingbuild)re   rX  r`  s      rf   rx  zPolyfaceBuilder.__init__3  s+    '&(
)+;=

5rh   c                ,    t        | j                        S rb   r   rd   s    rf   rd  zPolyfaceBuilder.nvertices:  r   rh   c                ,    t        | j                        S rb   )r   rX  rd   s    rf   re  zPolyfaceBuilder.nfaces>  s    4::rh   c                Z    | j                   d d  }|j                  | j                         |S rb   )rg   rR  rX  )re   rg   s     rf   rb  zPolyfaceBuilder.get_verticesB  s%    ==#

#rh   c                <   |D ]  }|j                   }t        |t              D ][  \  }}| j                  |      }|j                  j                  |d      dk  rdnd}|j                  j                  ||dz   |z         ] | j                  j                  |        y )Nr   r%   )	r^  r  r   addrq   r   setrX  r   )re   rX  rG  r^  r   r   r]  signs           rf   r  zPolyfaceBuilder.buildG  s     	+D**K #D+ 6 >((__00q9A=r2##D519*<=	>
 JJk*	+rh   c                     fd} ||j                   j                        }	  j                  |   S # t        $ rD t	         j
                        }| j                  |<    j
                  j                  |       |cY S w xY w)Nc                ,    t        fd| D              S )Nc              3  J   K   | ]  }t        |j                          y wrb   )roundr`  )r   coordre   s     rf   r   z3PolyfaceBuilder.add.<locals>.key.<locals>.<genexpr>S  s     J5%t~~6Js    #)rT  )r   re   s    rf   keyz PolyfaceBuilder.add.<locals>.keyR  s    JEJKKrh   )rq   r   r  KeyErrorr   rg   r   )re   r   r  r   r]  s   `    rf   r  zPolyfaceBuilder.addQ  sy    	L vzz**+	%%h// 	&E+0Dx(MM  (L		s   3 A
B ?B Nrq  )rX  rr  r`  r)  r(  r"  )rX  rr  r#  r'  )r   r   r#  r)  )r-  r.  r/  r0  rx  r;  rd  re  rb  r  r  rt  rh   rf   ra  ra  0  sA    6 " "  
+rh   ra  c                  <    e Zd ZdZedd       Zdd	dZd
dZddZy)r7   z
    PolyMesh structure:

    POLYLINE
      AcDbEntity
      AcDbPolygonMesh
    VERTEX
      AcDbEntity
      AcDbVertex
      AcDbPolygonMeshVertex
    c                l    | j                  |      }|j                  |_        |j                  |_        |S rb   r@  )rB  rC  polymeshs      rf   r   zPolymesh.from_polylinel  s0    ##H-!)!7!7"//rh   Nc                p    t        |xs i       }||d<   | j                  |      }|j                  |       y)a  Set location and DXF attributes of a single mesh vertex.

        Args:
            pos: 0-based (row, col) tuple, position of mesh vertex
            point: (x, y, z) tuple, new 3D coordinates of the mesh vertex
            dxfattribs: dict of DXF attributes

        r   N)r   get_mesh_vertexupdate_dxf_attribs)re   r   r   r   r   s        rf   set_mesh_vertexzPolymesh.set_mesh_vertexs  s;     **+
!&
:%%c*!!*-rh   c                   | j                   j                  }| j                   j                  }|\  }}d|cxk  r|k  r&n n#d|cxk  r|k  rn n| j                  ||z  |z      S t	        j
                  t        |            )zGet location of a single mesh vertex.

        Args:
            pos: 0-based (row, col) tuple, position of mesh vertex

        r   )rq   rP   rQ   rg   r   DXFIndexErrorrepr)re   r   rP   rQ   r	  ns         rf   r  zPolymesh.get_mesh_vertex  sp     ((""((""1GQ 0 0==Wq11%%d3i00rh   c                    t        |       S )zGet a :class:`MeshVertexCache` object for this POLYMESH.
        The caching object provides fast access to the :attr:`location`
        attribute of mesh vertices.

        )MeshVertexCacherd   s    rf   get_mesh_vertex_cachezPolymesh.get_mesh_vertex_cache  s     t$$rh   )rC  r5   r#  r7   rb   )r   tuple[int, int]r   r   )r   r  r#  r   )r#  r  )	r-  r.  r/  r0  rs  r   r  r  r  rt  rh   rf   r7   r7   _  s*    
  .1%rh   r7   c                  4    e Zd ZdZdZddZd	dZd
dZddZy)r  zCache mesh vertices in a dict, keys are 0-based (row, col)-tuples.

    vertices:
        Dict of mesh vertices, keys are 0-based (row, col)-tuples. Writing to
        this dict doesn't change the DXF entity.

    r   c                    | j                  ||j                  j                  |j                  j                        | _        y rb   )_setuprq   rP   rQ   rg   )re   meshs     rf   rx  zMeshVertexCache.__init__  s-    :>++$((""DHH$4$4;
rh   c                    i }t        |j                        }t        |      D ]"  }t        |      D ]  }t        |      |||f<    $ |S rb   )iterrg   rU  next)re   r  rP   rQ   cacherg   r	  r  s           rf   r  zMeshVertexCache._setup  sS    24&w 	/A7^ / $Xq!f/	/ rh   c                    	 | j                   |   j                  j                  S # t        $ r t	        j
                  t        |            w xY w)zpGet mesh vertex location as (x, y, z)-tuple.

        Args:
            pos: 0-based (row, col)-tuple.

        rg   rq   r   r  r   r  r  r   s     rf   r   zMeshVertexCache.__getitem__  sF    	1==%))222 	1%%d3i00	1s	   "% (Ac                    	 || j                   |   j                  _        y# t        $ r t	        j
                  t        |            w xY w)zGet mesh vertex location as (x, y, z)-tuple.

        Args:
            pos: 0-based (row, col)-tuple.
            location: (x, y, z)-tuple

        Nr  )re   r   r   s      rf   __setitem__zMeshVertexCache.__setitem__  sB    	1.6DMM#""+ 	1%%d3i00	1s	   ! (A	N)r  r5   )r  r5   rP   r)  rQ   r)  r#  r   )r   r  r#  r   )r   r  r   r   r#  r'  )	r-  r.  r/  r0  r  rx  r  r   r  rt  rh   rf   r  r    s"     I


11rh   r  
AcDbVertex)r:   *   2   )r>   [   r   r   r   r   rM   tangentvtx0vtx1vtx2vtx3vertex_identifierc                       e Zd ZdZdZ eeee      Z	dZ
dZdZdZdZdZd	Zeez   Zeez   ez   Z	 d	 	 	 d fd
Zd f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dZ xZS )r   zDXF VERTEX entityr   r%   r[   rH   r]   r^   r_   r`   c                ^    t         t        |   |      }|r|j                  |t               |S rj   )rk   r(   rl   rm   merged_vertex_group_codesro   s      rf   rl   zDXFVertex.load_dxf_attribs   s/    
 J6yA..s4MN
rh   c                   t         |   |       |j                  t        kD  r| j                  r|j                  t        d       n|j                  t        d       | j                  r|j                  t        d       n\| j                  r|j                  t        d       n9| j                  r|j                  t        d       n|j                  t        d       | j                  j                  |g d       y)	z(Export entity specific data as DXF tags.AcDbFaceRecordr  AcDb3dPolylineVertexAcDbPolyFaceMeshVertexAcDbPolygonMeshVertexAcDb2dVertexr  N)rk   r|   r}   r   is_face_recordr~   r   is_3d_polyline_vertexro  is_polygon_mesh_vertexrq   r   rz   s     rf   r|   zDXFVertex.export_entity
  s    
 	i(%'""$$_6FG$$_lC--((:PQ22((:RS00((:QR((.I##	
rh   c                N    | j                   j                  | j                  z  dk(  S )Nr   )rq   rM   VTX3Drd   s    rf   is_2d_polyline_vertexzDXFVertex.is_2d_polyline_vertex/  s    xx~~

*a//rh   c                H    | j                   j                  | j                  z  S rb   )rq   rM   POLYLINE_3D_VERTEXrd   s    rf   r  zDXFVertex.is_3d_polyline_vertex3  s    xx~~ 7 777rh   c                H    | j                   j                  | j                  z  S rb   )rq   rM   POLYGON_MESH_VERTEXrd   s    rf   r  z DXFVertex.is_polygon_mesh_vertex7  s    xx~~ 8 888rh   c                b    | j                   j                  | j                  z  | j                  k(  S rb   )rq   rM   
FACE_FLAGSrd   s    rf   ro  z"DXFVertex.is_poly_face_mesh_vertex;  s"    xx~~/4??BBrh   c                b    | j                   j                  | j                  z  | j                  k(  S rb   )rq   rM   r  POLYFACE_MESH_VERTEXrd   s    rf   r  zDXFVertex.is_face_record?  s$    0T5N5NNNrh   c                    | j                   r| S |j                  | j                  j                        | j                  _        | S )zATransform the VERTEX entity by transformation matrix `m` inplace.)r  r  rq   r   )re   r	  s     rf   r  zDXFVertex.transformC  s4    KKK(9(9:rh   c                  
 | j                   }t        |j                        }|j                  \  }}}|j                  }|j
                  }|j                  }	t               
t        
fd|j                         D              S )a  Return formatted vertex components as tuple.

        Format codes:

            - ``x`` = x-coordinate
            - ``y`` = y-coordinate
            - ``z`` = z-coordinate
            - ``s`` = start width
            - ``e`` = end width
            - ``b`` = bulge value
            - ``v`` = (x, y, z) as tuple

        Args:
            format: format string, default is "xyz"

        c              3  (   K   | ]	  }|     y wrb   rt  )r   r  varss     rf   r   z#DXFVertex.format.<locals>.<genexpr>b  s     ;DT$Z;s   )
rq   r   r   xyzr   r   r   localsrT  lower)re   r   rq   r   r   r   r   bsrv   r  s             @rf   r   zDXFVertex.formatJ  sd    " hh%%1aIIOOMMx;FLLN;;;rh   rb   r%  r&  r*  )r	  r   r#  r   )r  )r#  r	   )r-  r.  r/  r0  r1  r   r&   r)   acdb_vertexr3  EXTRA_VERTEX_CREATEDCURVE_FIT_TANGENTSPLINE_VERTEX_CREATEDSPLINE_FRAME_CONTROL_POINTr  r  r  r  r  rl   r|   r;  r  r  r  ro  r  r  r   r<  r=  s   @rf   r   r     s    Gz;DJ
  !#$';;J!447KKE 8<4	#
J 0 0 8 8 9 9 C C O O< <rh   r   c                   t               }|j                         D cg c]  }|t        v s| }}t               }t	        ||       D ]  \  }}|t        vr|dk(  rt        |      } |dk(  rt        |      |d<   4|dk(  rt        |      |d<   H|dk(  rt        |      |d<   \|dk(  r|j                  t        |      	      }}|d
k(  s|j                  t        |            } ||d<   |S c c}w )a  Create VERTEX attributes from input data.

    Format codes:

        - ``x`` = x-coordinate
        - ``y`` = y-coordinate
        - ``s`` = start width
        - ``e`` = end width
        - ``b`` = bulge value
        - ``v`` = (x, y [,z]) tuple (z-axis is ignored)

    Args:
        data: list or tuple of point components
        format: format string, default is 'xyseb'

    Returns:
       dict with keys: 'location', 'bulge', 'start_width', 'end_width'

    r   r  r   r  r   rv   r   r   )r   r   )r   r   )r   r  r+   r   r  floatr   )datar   r   r  r   values         rf   r   r   e  s    ( fG%||~Ft1EdFFFvH64( 8e|#3;E{HS[$U|GGS[%*5\GM"S[#(<GK S[''%,'7HS[''%,'7H8 #GJN% Gs
   C.C.N)xyseb)r  r	   r#  r   )X
__future__r   typingr   r   r   r   r   r	   r
   	itertoolsr   ezdxf.lldxfr   ezdxf.lldxf.attributesr   r   r   r   r   r   r   ezdxf.lldxf.constr   r   r   r   
ezdxf.mathr   r   r   r   r   ezdxf.math.transformtoolsr   r   ezdxf.render.polyliner   ezdxf.exploder!   ezdxf.queryr"   ezdxf.entitiesr#   ezdxf.auditr$   	dxfentityr&   r'   dxfgfxr(   r)   r*   
lwpolyliner+   	subentityr,   r-   r.   r/   r0   r1   ezdxf.layoutsr2   ezdxf.lldxf.tagwriterr3   ezdxf.eztypesr4   __all__point3dis_greater_or_equal_zero	is_one_ofis_not_null_vectorr2  acdb_polyline_group_codesrn   register_entityr5   r6   rS  ra  r7   r  r  acdb_vertex_group_codesr  r   r   rt  rh   rf   <module>r     s   #    !   B A  < < J ; ( # " " 4 D D $ %#>>(7&
. Ru}}gF Q'&r1tD$RTB88 
 88 
 $BDA#BDA )i)),7 
 RT:--22 
_7:v /}UK 76 $ 	S~ S SlWx Wt?9 ?9D, ,^7%x 7%t/1 /1d  Bemm4r1t<RT:
 Q6Q'2-T*T*T*T*$R$7#, -[9 54 
 	z<
 z< z<z'rh   