
    'jzZ                       U 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 d dlZd dl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 erd d	l m!Z! d d
l"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z( g dZ) edd          Z* edd          Z+eeeeef         Z,de-d<   ee         Z.de-d<   ed         Z/de-d<    G d d          Z0 G d de0          Z1d*d Z2 ed!          Z3 G d" d#e0          Z4d+d'Z5 G d( d)e          Z6dS ),    )annotations)TYPE_CHECKINGIterableTupleUnioncastSequenceOptional)	TypeAlias)abstractmethod)
namedtupleNVTX_EXTRA_VERTEX_CREATEDVTX_SPLINE_FRAME_CONTROL_POINT)	Vec2Vec3UVecBSplineConstructionRayOCSParallelRaysErrorbulge_to_arcConstructionArc)Drawing)
DXFGraphicSolidTraceFace3d
LWPolylinePolyline)TraceBuilderLinearTraceCurvedTraceLinearStation)vertexstart_width	end_widthCurveStation)vertex0vertex1r   FacePolygon)r   r   r   Quadrilateralc                  :    e Zd Zedd            ZddZ	 dddZdS )AbstractTracereturnIterable[Face]c                    d S N selfs    L/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/render/trace.pyfaceszAbstractTrace.faces2   s	     	    r,   c           	     J   dd}g }g }|                                  D ]5\  }}}}|                    ||f           |                    ||f           6t           ||                    }|                    t          t           ||                                         |S )Nverticesr,   r0   Iterable[UVec]c              3     K   t          |           sd S t          |           }t          |          }|V  |D ]}|                    |          s|V  |}d S r3   )leniternextisclose)r;   	_verticesprevr%   s       r7   mergez$AbstractTrace.polygon.<locals>.merge;   st      x== XI	??DJJJ# " "||F++ " LLL!D" "r9   )r;   r,   r0   r<   )r8   extendlistreversed)	r6   rD   forward_contourbackward_contourup1down1down2up2contours	            r7   polygonzAbstractTrace.polygon:   s    
	" 
	" 
	" 
	" ')')&*jjll 	0 	0"Cs""E5>222##S#J////uu_--..xUU+;%<%< = =>>???r9   TRACENdocOptional[Drawing]Iterable[Quadrilateral]c              #  f  K   ddl m} |dvrt          d| d          t          |pi           }|                                 D ]k}t          d          D ]}||         |d| <   |dk    r|d	         |d
<   |d         |d<    ||||          }|r|j                            |           |V  ldS )a  
        Yields faces as SOLID, TRACE or 3DFACE entities with DXF attributes
        given in `dxfattribs`.

        If a document is given, the doc attribute of the new entities will be
        set and the new entities will be automatically added to the entity
        database of that document.

        Args:
            dxftype: DXF type as string, "SOLID", "TRACE" or "3DFACE"
            dxfattribs: DXF attributes for SOLID, TRACE or 3DFACE entities
            doc: associated document

        r   )new>   SOLIDrP   3DFACEzInvalid dxftype .   vtxrW      vtx2   vtx3N)ezdxf.entities.factoryrU   	TypeErrordictr8   rangeentitydbadd)r6   dxftype
dxfattribsrQ   rU   faceientitys           r7   virtual_entitieszAbstractTrace.virtual_entitiesQ   s     " 	/.....6669w999:::**++
JJLL 	 	D1XX 0 0(,Q
999%%(""%)!W
6"%)!W
6"S*c22F )  (((LLLL	 	r9   r0   r1   )r0   r,   rP   NNrQ   rR   r0   rS   )__name__
__module____qualname__r   r8   rO   rj   r4   r9   r7   r/   r/   1   sf           ^   0 JN! ! ! ! ! ! !r9   r/   c                  R    e Zd ZdZddZd Zd Zedd            Z	 dddZ	ddZ
d	S )r"   ztLinear 2D banded lines like polylines with start- and end width.

    Accepts 3D input, but z-axis is ignored.

    r0   Nonec                "    g | _         d| _        d S Ng-q=)	_stationsabs_tolr5   s    r7   __init__zLinearTrace.__init__|   s    .0r9   c                *    t          | j                  S r3   r>   ru   r5   s    r7   __len__zLinearTrace.__len__       4>"""r9   c                    | j         |         S r3   ru   r6   items     r7   __getitem__zLinearTrace.__getitem__       ~d##r9   boolc                *    t          | j                  S )z%`True` if at least one station exist.)r   ru   r5   s    r7   
is_startedzLinearTrace.is_started   s     DN###r9   Npointr   r&   floatr'   Optional[float]c           	     J   ||}t          |          }| j        }t          |          r;|d         j                            || j                  r|                                 |                    t          |t          |          t          |                               dS )aa  Add a trace station (like a vertex) at location `point`,
        `start_width` is the width of the next segment starting at this station,
        `end_width` is the end width of the next segment.

        Adding the last location again, replaces the actual last location e.g.
        adding lines (a, b), (b, c), creates only 3 stations (a, b, c), this is
        very important to connect to/from splines.

        Args:
            point: 2D location (vertex), z-axis of 3D vertices is ignored.
            start_width: start width of next segment
            end_width:  end width of next segment

        N)rv   )
r   ru   r   r%   rA   rv   popappendr$   r   )r6   r   r&   r'   stationss        r7   add_stationzLinearTrace.add_station   s    " #IU>>> 	hrl199%9VV 	LLNNNeU;-?-?yAQAQRRSSSSSr9   r1   c           	   #  x   K   | j          t                     }|dk     rdS d fd}dd} d         j                             d         j                  }g t	          |dz
            D ]C} |         \  }}} |dz            j        }	                    t          ||	||                     D |d          \  }
}d}d}d         \  }}}}t	          t                              D ]}|         \  }}}}|dk    rH|r= |t                    dz
            \  }} |||
|          } ||||          }|}|}n|}|}|
}|}n |||
|          } ||||          }|t                    dz
  k     r4 ||dz             \  }} ||||          } |||
|          }|
}|}|}
|}n|}|}||||fV  dS )a2  Yields all faces as 4-tuples of :class:`~ezdxf.math.Vec2` objects.

        First and last miter is 90 degrees if the path is not closed, otherwise
        the intersection of first and last segment is taken into account,
        a closed path has to have explicit the same last and first vertex.

        r]   Nsegmentintr0   'tuple[ConstructionRay, ConstructionRay]c                \      fd}          \  }}}} |||           |||          fS )z0Create offset rays from segment offset vertices.c                    |                      |          r3         j        dz            j        z
  j        }t          | |          S t          | |          S )N   )rA   r%   angler   )v1v2r   r   r   s      r7   rayz3LinearTrace.faces.<locals>.offset_rays.<locals>.ray   s]    ::b>> 3 !)08GaK3H3OO  +2u555*2r222r9   r4   )r   r   left1left2right1right2segmentsr   s   `     r7   offset_raysz&LinearTrace.faces.<locals>.offset_rays   sZ    
3 3 3 3 3 3 ,4G+<(E5&&3ue$$cc&&&9&999r9   ray1r   ray2defaultr   c                    t          | j                            |j                            }|dk     s t          t          j        |z
            dk     r|S 	 |                     |          S # t          $ r |cY S w xY w)z7Intersect two rays but take parallel rays into account.g*5{?)abs	directionangle_betweenmathpi	intersectr   )r   r   r   r   s       r7   r   z$LinearTrace.faces.<locals>.intersect   s    
 44T^DDEEEx3tw#7#7(#B#B~~d+++$   s   A+ +A:9A:r   r   r   )r   r   r0   r   )r   r   r   r   r   r   r0   r   )ru   r>   r%   rA   rb   r   _normal_offset_points)!r6   countr   r   	is_closedstationstart_vertexr&   r'   
end_vertexoffset_ray1offset_ray2prev_offset_ray1prev_offset_ray2last_up1last_up2
last_down1
last_down2rh   rJ   rM   rK   rL   last_offset_ray1last_offset_ray2vtx0vtx1next_offset_ray1next_offset_ray2r\   r^   r   r   s!                                  @@r7   r8   zLinearTrace.faces   s      >H199F	: 	: 	: 	: 	: 	: 	:$	 	 	 	 QK&..x|/BCC	 UQY'' 	 	G3;G3D0L+y!'A+.5J OO%lJYWW    $/;q>> [ 6>b\2(J
s8}}%% &	) &	)A%-a["CeUAvv ! :ES]]UVEV9W9W6$&6$9%5{CHHD$9%5{EJJD  $H!%JJ D D#. #.   !y!1;DD y!1;FF3x==1$$$5@[Q5G5G2 "2 y!1;FF y!1;DD#. #. .. "dD(((((M&	) &	)r9   r0   rr   )r0   r   r3   )r   r   r&   r   r'   r   r0   rr   rk   )rn   ro   rp   __doc__rw   rz   r   propertyr   r   r8   r4   r9   r7   r"   r"   u   s            # # #$ $ $ $ $ $ X$
 MQT T T T T6o) o) o) o) o) o)r9   r"   startr   endr&   r   r'   r0   c                    || z
                                   }|                    d          }|                     |dz            }|                     |dz            }| |z   ||z   | |z
  ||z
  fS )NTr]   )	normalize
orthogonal)r   r   r&   r'   
dir_vectororthooffset_start
offset_ends           r7   r   r     s     +((**J!!$''E??;?33LQ//Jjj	 r9   )r   r   c                  j    e Zd ZdZddZd Zd Zedd            Ze	 ddd            Z	ddZ
d dZdS )!r#   z2D banded curves like arcs or splines with start- and end width.

    Represents always only one curved entity and all miter of curve segments
    are perpendicular to curve tangents.

    Accepts 3D input, but z-axis is ignored.

    r0   rr   c                    g | _         d S r3   r}   r5   s    r7   rw   zCurvedTrace.__init__4  s    -/r9   c                *    t          | j                  S r3   ry   r5   s    r7   rz   zCurvedTrace.__len__7  r{   r9   c                    | j         |         S r3   r}   r~   s     r7   r   zCurvedTrace.__getitem__:  r   r9   spliner   r&   r   r'   r   r   c                j    |             }|dz   }t          j        d|j        |          }t          |                    |d          t          j        |||                    D ]N\  \  }}	}
t          |	                              d          }|                    t          |          ||
           O|S )z
        Create curved trace from a B-spline.

        Args:
            spline: :class:`~ezdxf.math.BSpline` object
            start_width: start width
            end_width: end width
            segments: count of segments for approximation

        r   r   )nT)nplinspacemax_tzipderivativesr   r   _append)clsr   r&   r'   r   curve_tracer   tr   
derivativewidthnormals               r7   from_splinezCurvedTrace.from_spline=  s    $ cee1K6<//*-qA&&KE(R(R+
 +
 	< 	<&UJ *%%0066FUVU;;;;r9   @   arcr   c                   |j         dk    rt          d|j          d           |             }t          t          j        |j        dz  |z            d          dz   }t          |j                  }t          |	                    |
                    |                    t          j        |||                    D ]\  }}	|                    |||z
  |	            |S )a  
        Create curved trace from an arc.

        Args:
            arc: :class:`~ezdxf.math.ConstructionArc` object
            start_width: start width
            end_width: end width
            segments: count of segments for full circle (360 degree)
                approximation, partial arcs have proportional less segments,
                but at least 3

        Raises:
            ValueError: if arc.radius <= 0

        r   zInvalid radius: rX   g     v@r[   r   )radius
ValueErrormaxr   ceil
angle_spanr   centerr   r;   anglesr   r   r   )
r   r   r&   r'   r   r   r   r   r   r   s
             r7   from_arczCurvedTrace.from_arcY  s    . :??=
===>>>ceeDIcnu4x?@@!DDqHcj!!LLE**++KY66
 
 	> 	>LE5 uv~u====r9   r   r   r   r   c                    t                               |          rt           }n|                    |dz            }| j                            t          ||z   ||z
                       dS )z
        Add a curve trace station (like a vertex) at location `point`.

        Args:
            point: 2D curve location (vertex), z-axis of 3D vertices is ignored.
            normal: curve normal
            width:  width of station

        r]   N)	_NULLVEC2rA   r   ru   r   r(   )r6   r   r   r   s       r7   r   zCurvedTrace._append|  sf     V$$ 	1FF%%eai00Fl56>56>JJKKKKKr9   r1   c              #     K   t          | j                  }|dk     rdS d}d}| j        D ]\  }}||}|}||||fV  |}|}dS )zBYields all faces as 4-tuples of :class:`~ezdxf.math.Vec2` objects.r]   Nry   )r6   r   r   r   r\   r^   s         r7   r8   zCurvedTrace.faces  s      DN##199F. 	 	JD$|dD((((DDD	 	r9   Nr   )
r   r   r&   r   r'   r   r   r   r0   r#   r   )
r   r   r&   r   r'   r   r   r   r0   r#   )r   r   r   r   r   r   r0   rr   rk   )rn   ro   rp   r   rw   rz   r   classmethodr   r   r   r8   r4   r9   r7   r#   r#   *  s         0 0 0 0# # #$ $ $    [6          [ DL L L L      r9   r#   vertex_flagsr   r   c                6    | t           z  rdS | t          z  rdS dS )aa  Determine if a vertex should be included in rendering based on its flags.

    According to the DXF specification:
    - Flag 0: Straight-segment vertex (include)
    - Flag 1: Extra curve-fit vertex (exclude - auto-generated)
    - Flag 2: Curve-fit tangent vertex (include - carries tangent info)
    - Flag 8: Spline-vertex (fit-point) for 2D spline (include)
    - Flag 16: Spline-frame control point (exclude - internal calculation only)

    Args:
        vertex_flags: The vertex flags value (group code 70)

    Returns:
        True if the vertex should be included in rendering, False otherwise
    FTr   )r   s    r7   #should_include_vertex_for_renderingr     s3    " .. u 44 u 4r9   c                  z    e Zd ZdZd"dZd Zd Zd#d	Zd$dZd%dZ	d&dZ
d%dZ	 d'd(dZd Zed)d*d!            ZdS )+r!   a  Sequence of 2D banded lines like polylines with start- and end width or
    curves with start- and end width.


    .. note::

        Accepts 3D input, but z-axis is ignored. The :class:`TraceBuilder` is a
        2D only object and uses only the :ref:`OCS` coordinates!

    r0   rr   c                "    g | _         d| _        d S rt   )_tracesrv   r5   s    r7   rw   zTraceBuilder.__init__  s    ,.r9   c                *    t          | j                  S r3   )r>   r   r5   s    r7   rz   zTraceBuilder.__len__  s    4<   r9   c                    | j         |         S r3   )r   r~   s     r7   r   zTraceBuilder.__getitem__  s    |D!!r9   tracer/   c                :    | j                             |           dS )zAppend a new trace.N)r   r   r6   r   s     r7   r   zTraceBuilder.append  s    E"""""r9   r1   c              #  R   K   | j         D ]}|                                E d{V  dS )zaYields all faces as 4-tuples of :class:`~ezdxf.math.Vec2` objects
        in :ref:`OCS`.
        N)r   r8   r   s     r7   r8   zTraceBuilder.faces  sF       \ 	% 	%E{{}}$$$$$$$$	% 	%r9   ocsr   	elevationr   Iterable[Sequence[Vec3]]c              #     K   |                                  D ]2}t          |                    fd|D                                 V  3dS )zaYields all faces as 4-tuples of :class:`~ezdxf.math.Vec3` objects
        in :ref:`WCS`.
        c              3  N   K   | ]}t          |j        |j                  V   d S r3   r   xy.0vr   s     r7   	<genexpr>z)TraceBuilder.faces_wcs.<locals>.<genexpr>  s3      )R)R$qsAC*C*C)R)R)R)R)R)Rr9   N)r8   tuplepoints_to_wcs)r6   r   r   rg   s     ` r7   	faces_wcszTraceBuilder.faces_wcs  sh       JJLL 	T 	TD)))R)R)R)RT)R)R)RRRSSSSSS	T 	Tr9   Iterable[Polygon]c              #  J   K   | j         D ]}|                                V  dS )z{Yields for each sub-trace a single polygon as sequence of
        :class:`~ezdxf.math.Vec2` objects in :ref:`OCS`.
        N)r   rO   r   s     r7   polygonszTraceBuilder.polygons  s:       \ 	" 	"E--//!!!!	" 	"r9   c              #     K   | j         D ]D}t          |                    fd|                                D                                 V  EdS )z{Yields for each sub-trace a single polygon as sequence of
        :class:`~ezdxf.math.Vec3` objects in :ref:`WCS`.
        c              3  N   K   | ]}t          |j        |j                  V   d S r3   r   r  s     r7   r  z,TraceBuilder.polygons_wcs.<locals>.<genexpr>  s3      !U!U$qsAC";";!U!U!U!U!U!Ur9   N)r   r  r  rO   )r6   r   r   r   s     ` r7   polygons_wcszTraceBuilder.polygons_wcs  ss       \ 	 	E!!!U!U!U!UU]]__!U!U!UUU     	 	r9   rP   NrQ   rR   rS   c              #  X   K   | j         D ]}|                    |||          E d{V   dS )ar  Yields faces as SOLID, TRACE or 3DFACE entities with DXF attributes
        given in `dxfattribs`.

        If a document is given, the doc attribute of the new entities will be
        set and the new entities will be automatically added to the entity
        database of that document.

        .. note::

            The :class:`TraceBuilder` is a 2D only object and uses only the
            :ref:`OCS` coordinates!

        Args:
            dxftype: DXF type as string, "SOLID", "TRACE" or "3DFACE"
            dxfattribs: DXF attributes for SOLID, TRACE or 3DFACE entities
            doc: associated document

        N)r   rj   )r6   re   rf   rQ   r   s        r7   rj   zTraceBuilder.virtual_entities  sT      * \ 	H 	HE--gz3GGGGGGGGGG	H 	Hr9   c                x   | j         }t          |          dk     rdS t          |d         t                    r~t          |d         t                    ret	          t          |                    d                    }t	          t          |d                   }|D ]!\  }}}|                    |||           dS dS dS )zEClose multi traces by merging first and last trace, if linear traces.r]   Nr   r   )r   r>   
isinstancer"   r   r   r   )r6   tracesfirstlastr   r&   r'   s          r7   closezTraceBuilder.close  s    v;;??FfQi-- 	@*VBZ2U2U 	@fjjmm44EVBZ00D16 @ @-{I  Y????		@ 	@ 	@ 	@@ @r9   r   polyliner   r   r   c           	        |                                 }|dk    rft          d|          }|j        j        }g }|j        D ]7\  }}}}	}
t          ||          }|r|}|}	|                    |||	|
f           8|j        }n|dk    rt          d|          }|j        st          d          |j
        }|j        j        }|j        j        }d |j        D             }g }|D ]}t          |j        j                  }|j                            d          r|j        j        }n|}|j                            d          r|j        j        }	n|}	|j        j        }
|                    |||	|
f           nt          d	|           |rH|d
         d
                             |d         d
                   s|                    |d
                     |             }d}d}d}d}t)                      }|D ]\  }}}	}
|dk    rt+          |||          \  }}}}|d
k    rt-          ||t/          j        |          t/          j        |          d          }|j                            |          r|}|}n|}|}|                    t4                              ||||                     d}|
dk    rK|j        r:|                    |||	           |                    |           t)                      }|
}|}|	}|}|                    |||	           !|j        r|                    |           |r't=          |          dk    r|                                 |S )a  
        Create a complete trace from a LWPOLYLINE or a 2D POLYLINE entity, the
        trace consist of multiple sub-traces if :term:`bulge` values are
        present. Uses only the :ref:`OCS` coordinates!

        Args:
            polyline: :class:`~ezdxf.entities.LWPolyline` or 2D
                :class:`~ezdxf.entities.Polyline`
            segments: count of segments for bulge approximation, given count is
                for a full circle, partial arcs have proportional less segments,
                but at least 3

        
LWPOLYLINEr   POLYLINEr    z2D POLYLINE requiredc                b    g | ],}t          |j                            d d                    *|-S )flagsr   )r   dxfget)r  r%   s     r7   
<listcomp>z.TraceBuilder.from_polyline.<locals>.<listcomp>=  sF     ! ! !!6vz~~gq7Q7QRR!! ! !r9   r&   r'   zInvalid DXF type r   r   g        NT)is_counter_clockwiser   ) re   r   r  const_widthlwpointsr   r   closedis_2d_polyliner`   r   default_start_widthdefault_end_widthr;   locationhasattrr&   r'   bulgerA   r"   r   r   r   degreesstart_pointr#   r   r   r   r>   r  )r   r  r   re   r  pointsr   r   r&   r'   r'  r%  r!  r#  r$  filtered_verticesr%   r   store_bulgestore_start_widthstore_end_widthstore_pointlinear_tracer   r   start_angle	end_angler   r   swews                                  r7   from_polylinezTraceBuilder.from_polyline  s    ""$$l""L(33H",2KF7?7H I I31k9e1:: , #.K +IxiGHHHH_FF
""J11H* 8 6777'F"*,"B ( >! !%-%6! ! !
 F+ I I
 344:%%m44 6"(*"8KK"5K:%%k22 2 &
 4II 1I
(xiGHHHHI 999::: 	%&)A,..vbz!}== 	%MM&)$$$#'"}}4: !	D !	D0E;	5c!!9E: :6Y A::)[11Y//-1  C ..u55 /,.,.LL!5!5c2r8!L!LMMM!||* 1 ,,UKKKKLL...#.==L#$/!"+#$$UKCCCC" 	'LL&&& 	c%jj1nn KKMMMr9   r   )r   r/   r0   rr   rk   )r   r   r   r   r0   r   )r0   r  rl   rm   r   )r  r   r   r   r0   r!   )rn   ro   rp   r   rw   rz   r   r   r8   r  r
  r  rj   r  r   r5  r4   r9   r7   r!   r!     s       	 	   ! ! !" " "# # # #% % % %T T T T" " " "    JNH H H H H0	@ 	@ 	@ m m m m [m m mr9   r!   )
r   r   r   r   r&   r   r'   r   r0   r+   )r   r   r0   r   )7
__future__r   typingr   r   r   r   r   r	   r
   typing_extensionsr   abcr   collectionsr   r   numpyr   ezdxf.lldxf.constr   r   
ezdxf.mathr   r   r   r   r   r   r   r   r   ezdxf.documentr   ezdxf.entitiesr   r   r   r   r   r    __all__r$   r(   r+   __annotations__r,   r-   r/   r"   r   r   r#   r   r!   r4   r9   r7   <module>rB     s   # " " " " " "                  ( ' ' ' ' '       " " " " " "      V V V V V V V V
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  V&&&&&&UUUUUUUUUUUUUUUU
8
8
8
?,RSS z.*@AAdD$./ / / / /d^ # # # # !;< < < < <A A A A A A A AH`) `) `) `) `)- `) `) `)F    DLL	q q q q q- q q qh   >I I I I I8 I I I I Ir9   