
    h                    ^   S SK Jr  S SKJrJrJrJrJr  S SKrS SK	J
r
  S SKJrJrJrJrJrJrJrJrJrJrJrJr  S SKJrJr  / SQr SK         SLS
 jjrSSS \R:                  S 4             SMS jjr SN         SOS jjrSPSQS jjr  SR     SSS jjr!STSUS jjr" SV       SWS jjr#     SX             SYS jjr$   SZ             S[S jjr% " S S\
5      r&  S\               S]S jjr'\" S S 5      S 4S^S jjr(S_S`S jjr) Sa       SbS jjr*ScSdS jjr+ Se       SfS jjr,  Sg         ShS jjr-\" S S S 5      \" SS S 5      \" SSS 5      \" S SS 5      \" S S S5      \" SS S5      \" SSS5      \" S SS5      /r.\" S S S 5      \" S!S S 5      \" S!S!S 5      \" S S!S 5      \" S S S!5      \" S!S S!5      \" S!S!S!5      \" S S!S!5      /r// S"Q/ S#Q/ S$Q/ S%Q/ S&Q/ S'Q/r0SiSjS( jjr1 Sk     SlS) jjr2SmS* jr3SnS+ jr4SSSSS	SS,.           SoS- jjr5    SpSS..         SqS/ jjjr6    SrSS..         SsS0 jjjr7SSS	S1.   StS2 jjr8   Su         SvS3 jjr9 Sw     SxS4 jjr: SwSSS	S1.     SyS5 jjjr;   SzSS..       S{S6 jjjr<    S|SS..         S}S7 jjjr=\R:                  S84S	S..         S~S9 jjjr> SSS;.       SS< jjjr?SS:SS=S\R:                  4SS..         SS> jjjr@        SS? jrA      SS@ jrB      SSA jrC\4SSB jjrD\4SSC jjrE      SSD jrF      SSE jrGSSF jrH        SSG jrI      SSH jrJ Si     SSI jjrKSSSS1.     SSJ jjrLg)    )annotations)IterableSequenceIteratorCallableOptionalN)IntEnum)Vec2Vec3UVecMatrix44global_bspline_interpolationEulerSpiralarc_angle_span_radNULLVECZ_AXISX_AXISUCSintersection_ray_ray_3d)MeshVertexMergerMeshTransformer)"circleellipseeuler_spiralsquarebox
open_arrowarrow2ngonstargearturtle	translaterotatescaleclose_polygonhelixcubeextrudeextrude_twist_scalesweepcylindercylinder_2pfrom_profiles_linearfrom_profiles_splinespline_interpolationspline_interpolated_profilesconecone_2protation_formspheretorusreference_frame_zreference_frame_extmake_next_reference_frame   Fc              #  &  #    [        U5      n[        R                  U -  nSn[        U 5       HG  n[        R                  " U5      U-  n[        R
                  " U5      U-  n[        XxU5      v   XT-  nMI     U(       a  [        USU5      v   gg7f)a  Create polygon vertices for a `circle <https://en.wikipedia.org/wiki/Circle>`_
with the given `radius` and approximated by `count` vertices, `elevation`
is the z-axis for all vertices.

Args:
    count: count of polygon vertices
    radius: circle radius
    elevation: z-axis for all vertices
    close: yields first vertex also as last vertex if ``True``.

Returns:
    vertices in counter-clockwise orientation as :class:`~ezdxf.math.Vec3`
    objects

        r   N)floatmathtaurangecossinr   )	countradius	elevationclosedeltaalphaindexxys	            D/var/www/html/env/lib/python3.13/site-packages/ezdxf/render/forms.pyr   r   >   s     $ 6]FHHuEEuHHUOf$HHUOf$1##	  61i(( s   BBc              #  B  #    [        U5      n[        U5      n[        U5      n[        U5      n[        U 5      n XC-
  U S-
  -  n[        R                  n[        R                  n[        U 5       H+  n	X9U-  -   n
[        U" U
5      U-  U" U
5      U-  U5      v   M-     g7f)u  Create polygon vertices for an `ellipse <https://en.wikipedia.org/wiki/Ellipse>`_
with given `rx` as x-axis radius and `ry` as y-axis radius approximated by
`count` vertices, `elevation` is the z-axis for all vertices.
The ellipse goes from `start_param` to `end_param` in counter clockwise
orientation.

Args:
    count: count of polygon vertices
    rx: ellipse x-axis radius
    ry: ellipse y-axis radius
    start_param: start of ellipse in range [0, 2π]
    end_param: end of ellipse in range [0, 2π]
    elevation: z-axis for all vertices

Returns:
    vertices in counter clockwise orientation as :class:`~ezdxf.math.Vec3`
    objects

r:   N)r=   intr>   rA   rB   r@   r   )rC   rxrystart_param	end_paramrE   rG   rA   rB   paramrH   s              rL   r   r   ]   s     6 
rB	rB$Ki IJE$3E
((C
((Cuem+3u:?CJOY?? s   BBc              #  v   #    [        US9nUR                  XS-
  5       H  nUR                  US9v   M     g7f)a  Create polygon vertices for an `euler spiral <https://en.wikipedia.org/wiki/Euler_spiral>`_
of a given `length` and radius of curvature. This is a parametric curve,
which always starts at the origin (0, 0).

Args:
    count: count of polygon vertices
    length: length of curve in drawing units
    curvature: radius of curvature
    elevation: z-axis for all vertices

Returns:
    vertices as :class:`~ezdxf.math.Vec3` objects

)	curvaturer:   )zN)r   approximatereplace)rC   lengthrU   rE   spiralvertexs         rL   r   r      s;     " 9-F$$VQY7nnyn)) 8   79      ?c                    U(       a5  U S-  n[        U* U* 5      [        X"* 5      [        X"5      [        U* U5      4$ [        SS5      [        U S5      [        X 5      [        SU 5      4$ )zReturns 4 vertices for a square with a side length of the given `size`.
The center of the square in (0, 0) if `center` is ``True`` otherwise
the lower left corner is (0, 0), upper right corner is (`size`, `size`).
       @r   r   )sizecenteras      rL   r   r      sa    
 3JQB|T!R[$q*dA2qkAAAqz4a=$t*:DDMII    c                    U(       a:  U S-  nUS-  n[        U* U* 5      [        X4* 5      [        X45      [        U* U5      4$ [        SS5      [        U S5      [        X5      [        SU5      4$ )zReturns 4 vertices for a box with a width of `sx` by and a height of
`sy`. The center of the box in (0, 0) if `center` is ``True`` otherwise
the lower left corner is (0, 0), upper right corner is (`sx`, `sy`).
r_   r   r`   )sxsyrb   rc   bs        rL   r   r      si     HHQB|T!R[$q*dA2qkAAAqz4A;Rd1bkAArd   c                    [         R                  " [         R                  " US-  5      5      U -  n[        U * U5      [        SS5      [        U * U* 5      4$ )a*  Returns 3 vertices for an open arrow `<` with a length of the given
`size`, argument `angle` defines the enclosing angle in degrees.
Vertex order: upward end vertex, tip (0, 0) , downward end vertex (counter-
clockwise order)

Args:
    size: length of arrow
    angle: enclosing angle in degrees

r_   r   )r>   rB   radiansr   )ra   anglehs      rL   r   r      sI     	eck*+d2Aq>41:tTEA266rd   c                &   [         R                  " [         R                  " US-  5      5      U -  n[         R                  " [         R                  " U5      5      U-  n[	        U * U5      [	        SS5      [	        U * U* 5      [	        U * U-   S5      4$ )a  Returns 4 vertices for an arrow with a length of the given `size`, and
an enclosing `angle` in degrees and a slanted back side defined by angle
`beta`::

                ****
            ****  *
        ****     *
    **** angle   X********************
        ****     * +beta
            ****  *
                ****

                ****
            ****    *
        ****         *
    **** angle        X***************
        ****         * -beta
            ****    *
                ****

Vertex order: upward end vertex, tip (0, 0), downward end vertex, bottom
vertex `X` (anti clockwise order).

Bottom vertex `X` is also the connection point to a continuation line.

Args:
    size: length of arrow
    angle: enclosing angle in degrees
    beta: angle if back side in degrees

r_   r   )r>   rB   rj   tanr   )ra   rk   betarl   	back_steps        rL   r   r      s}    D 	eck*+d2Ad+,q0IdUAQ
dUQBdUY"	 rd   r<   c              #    #    U S:  a  [        S5      eUb?  US::  a  [        S5      eUS-  [        R                  " [        R                  U -  5      -  nO Ub  US::  a  [        S5      eO[        S5      e[        R                  U -  nUnSn[        R
                  n	[        R                  n
[        U 5       H-  n[        X)" U5      -  X*" U5      -  U5      nUc  UnUv   Xv-  nM/     U(       a  Uv   gg7f)	a'  Returns the corner vertices of a `regular polygon <https://en.wikipedia.org/wiki/Regular_polygon>`_.
The polygon size is determined by the edge `length` or the circum `radius`
argument. If both are given `length` has the higher priority.

Args:
    count: count of polygon corners >= 3
    length: length of polygon side
    radius: circum radius
    rotation: rotation angle in radians
    elevation: z-axis for all vertices
    close: yields first vertex also as last vertex if ``True``.

Returns:
    vertices as :class:`~ezdxf.math.Vec3` objects

   *Argument `count` has to be greater than 2.Nr<   z+Argument `length` has to be greater than 0.r_   +Argument `radius` has to be greater than 0.z'Argument `length` or `radius` required.)
ValueErrorr>   rB   pir?   rA   r@   r   )rC   rY   rD   rotationrE   rF   rG   rk   firstrA   rB   _vs                rL   r   r      s     0 qyEFFS=JKK#5 99		S=JKK  BCCHHuEEE
((C
((C5\#e*$fs5z&99E=E   s   C4C6c              #  (  #    U S:  a  [        S5      eUS::  a  [        S5      eUS::  a  [        S5      e[        XX4SS9n[        U U[        R                  U -  U-   USS9nSn[	        Xg5       H  u  pUc  U	nU	v   U
v   M     U(       a  Uv   gg7f)	a1  Returns the corner vertices for a `star shape <https://en.wikipedia.org/wiki/Star_polygon>`_.

The shape has `count` spikes, `r1` defines the radius of the "outer"
vertices and `r2` defines the radius of the "inner" vertices,
but this does not mean that `r1` has to be greater than `r2`.

Args:
    count: spike count >= 3
    r1: radius 1
    r2: radius 2
    rotation: rotation angle in radians
    elevation: z-axis for all vertices
    close: yields first vertex also as last vertex if ``True``.

Returns:
    vertices as :class:`~ezdxf.math.Vec3` objects

rr   rs   r<   z'Argument `r1` has to be greater than 0.z'Argument `r2` has to be greater than 0.F)rD   rw   rE   rF   N)ru   r   r>   rv   zip)rC   r1r2rw   rE   rF   corners1corners2rx   s1s2s              rL   r    r    %  s     4 qyEFF	SyBCC	SyBCC8H 58+H Eh)=E	 *  s   BBc                  $    \ rS rSrSrSrSrSrSrg)_Geari[  r   r:      rr    N)	__name__
__module____qualname____firstlineno__	TOP_STARTTOP_ENDBOTTOM_START
BOTTOM_END__static_attributes__r   rd   rL   r   r   [  s    IGLJrd   r   c              #    #    U S:  a  [        S5      eUS::  a  [        S5      eUS::  a  [        S5      eUS::  a  [        S5      eUS::  a  [        S5      eX4:  a  [        S5      eXC-
  n[        R                  " US-  U-  5      n[        R                  " US-  U-  5      n	X-
  S-  n
[        R                  X	-  -
  U -  nU* S-  n[        R
                  nS	n[        R                  n[        R                  n[        S
U -  5       H  nU[        R
                  :X  d  U[        R                  :X  a  UnOUn[        UU" U5      -  UU" U5      -  U5      nU[        R
                  :X  a  X-  nOJU[        R                  :X  a  X-  nO1U[        R                  :X  a  X-  nOU[        R                  :X  a  X-  nUc  UnUv   US-  nU[        R                  :  d  M  [        R
                  nM     U(       a  Uv   g	g	7f)a`  Returns the corner vertices of a `gear shape <https://en.wikipedia.org/wiki/Gear>`_
(cogwheel).

.. warning::

    This function does not create correct gears for mechanical engineering!

Args:
    count: teeth count >= 3
    top_width: teeth width at outside radius
    bottom_width: teeth width at base radius
    height: teeth height; base radius = outside radius - height
    outside_radius: outside radius
    elevation: z-axis for all vertices
    close: yields first vertex also as last vertex if True.

Returns:
    vertices in counter clockwise orientation as :class:`~ezdxf.math.Vec3`
    objects

rr   rs   r<   rt   z*Argument `width` has to be greater than 0.z+Argument `height` has to be greater than 0.z1Argument `height` has to be smaller than `radius`r_   N   r:   )ru   r>   asinr?   r   r   rA   rB   r@   r   r   r   r   )rC   	top_widthbottom_widthheightoutside_radiusrE   rF   base_radius	alpha_topalpha_bottomalpha_differencero   rk   staterx   rA   rB   ry   rD   rz   s                       rL   r!   r!   b  s    < qyEFFFGGCEFFsEFF}FGGLMM )K		)c/N:;I99\C/+=>L  HHu++u4DJEOOEE
((C
((C1u9EOO#u'=#F F#e*$fs5z&99EEOO#Eemm#%Ee(((MEe&&&%E=E
5###OOE- 0  s   GH !H c              #  
  #    UnUv   U R                  S5       H  nUR                  5       nUS   S:X  a)  [        U5      S:X  a  US-  nM2  U[        USS 5      -  nME  US   S:X  a)  [        U5      S:X  a  US-  nMd  U[        USS 5      -  nMw  US   S:X  a=  USS R                  S	5      u  pVU[	        [        U5      [        U5      5      -  nUv   M  U[        R
                  " U[        U5      5      -  nUv   M     g7f)
a  Returns the 2D vertices of a polyline created by turtle-graphic like
commands:

- ``<length>`` - go <length> units forward in current direction and yield vertex
- ``r<angle>`` - turn right <angle> in degrees, a missing angle is 90 deg
- ``l<angle>`` - turn left <angle> in degrees, a missing angle is 90 deg
- ``@<x>,<y>`` - go relative <x>,<y> and yield vertex

The command string ``"10 l 10 l 10"`` returns the 4 corner vertices of a
square with a side length of 10 drawing units.

Args:
    commands: command string, commands are separated by spaces
    start: starting point, default is (0, 0)
    angle: starting direction, default is 0 deg

 r   lr:   Z   Nr@,)splitstriplenr=   r
   from_deg_angle)commandsstartrk   cursorcmdrJ   rK   s          rL   r"   r"     s     & F
L~~c"iikq6S=3x1}s12w'Vs]3x1}s12w'Vs]qr7==%DAd58U1X..FLd))%s<<FL% #s   DDc              #  @   #    [        U5      nU  H	  nX#-   v   M     g7f)zTranslate `vertices` along `vec`, faster than a Matrix44 transformation.

Args:
    vertices: iterable of vertices
    vec: translation vector

Returns: yields transformed vertices

Nr`   )verticesvec_vecps       rL   r#   r#     s!      9Dh s   Tc                B   ^ U(       a  U4S jU  5       $ U4S jU  5       $ )a  Rotate `vertices` about to z-axis at to origin (0, 0), faster than a
Matrix44 transformation.

Args:
    vertices: iterable of vertices
    angle: rotation angle
    deg: True if angle in degrees, False if angle in radians

Returns: yields transformed vertices

c              3  X   >#    U  H  n[        U5      R                  T5      v   M!     g 7fN)r   
rotate_deg.0rz   rk   s     rL   	<genexpr>rotate.<locals>.<genexpr>  s#     <8aQ""5))8   '*c              3  X   >#    U  H  n[        U5      R                  T5      v   M!     g 7fr   )r   r$   r   s     rL   r   r     s!     8x!Qu%%xr   r   )r   rk   degs    ` rL   r$   r$     s     <8<<8x88rd   c              #     #    Uu  p#n[         R                  " U 5       H9  n[        UR                  U-  UR                  U-  UR                  U-  5      v   M;     g7f)zScale `vertices` around the origin (0, 0), faster than a Matrix44
transformation.

Args:
    vertices: iterable of vertices
    scaling: scale factors as tuple of floats for x-, y- and z-axis

Returns: yields scaled vertices

N)r   generaterJ   rK   rV   )r   scalingrf   rg   szrz   s         rL   r%   r%     sJ      JBB]]8$1338QSS2XqssRx00 %s   AAc                z    [        U 5      nUS   R                  US   XS9(       d  UR                  US   5        U$ )z_Returns list of :class:`~ezdxf.math.Vec3`, where the first vertex is
equal to the last vertex.
r   )rel_tolabs_tol)listiscloseappend)r   r   r   polygons       rL   r&   r&     s=     x.G1:gbk7Lwqz"Nrd      c              #  \  #    S[        US5      -  nU(       d  U* n[        U[        U5      -  5      n[        US-   5       Hf  nXW-  nU[        R
                  -  n	[        R                  " U	5      U -  n
[        R                  " U	5      U -  n[        X[        U5      U-  5      v   Mh     g7f)a  Yields the vertices of a `helix <https://en.wikipedia.org/wiki/Helix>`_.
The center of the helix is always (0, 0), a positive `pitch` value
creates a helix along the +z-axis, a negative value along the -z-axis.

Args:
    radius: helix radius
    pitch: the height of one complete helix turn
    turns: count of turns
    resolution: vertices per turn
    ccw: creates a counter-clockwise turning (right-handed) helix if ``True``

r]   r:   N)	maxrN   absr@   r>   r?   rA   rB   r   )rD   pitchturns
resolutionccwsteptotal_step_countrI   trk   rJ   rK   s               rL   r'   r'     s     & J**Du53t9,-'!+,LDHHHHUOf$HHUOf$1Q%(( -s   B*B,g            ?)r   rr   r   r:   )r:   r         )rr      r   r   )r   r   r   rr   )r   r:   r   r   )r   r   r   r   c                h    [        5       nU (       a  [        O[        nUR                  U[        S9  U$ )a
  Create a `cube <https://en.wikipedia.org/wiki/Cube>`_ as
:class:`~ezdxf.render.MeshTransformer` object.

Args:
    center: 'mass' center of cube, ``(0, 0, 0)`` if ``True``, else first
        corner at ``(0, 0, 0)``

Returns: :class:`~ezdxf.render.MeshTransformer`

)r   faces)r   _cube0_vertices_cube_verticesadd_mesh
cube_faces)rb   meshr   s      rL   r(   r(   `  s*     D"(nHMM8:M6Krd   c                   [        5       n[        R                  " U 5      nU(       a  [        U5      n[        R                  " U5      nU(       a  UR	                  [        USS 5      5        US   nUSS  HB  nX-
  n	U V
s/ s H  oU	-   PM	     nn
[        X[5       H  nUR	                  U5        M     UnUnMD     U(       a  UR	                  USS 5        [        R                  " U5      $ s  sn
f )a  Extrude a `profile` polygon along a `path` polyline, the vertices of
`profile` should be in counter-clockwise order.
The sweeping profile will not be rotated at extrusion!

Args:
    profile: sweeping profile as list of (x, y, z) tuples in
        counter-clockwise order
    path:  extrusion path as list of (x, y, z) tuples
    close: close profile polygon if ``True``
    caps: close hull with top- and bottom faces (ngons)

Returns: :class:`~ezdxf.render.MeshTransformer`

Nr   r   r:   )	r   r   r   r&   add_facereversed_quad_connection_facesr   from_builder)profilepathrF   capsr   sweeping_profileextrusion_pathstart_pointtarget_pointtranslation_vectorr   target_profilefaces                rL   r)   r)   q  s    " Dyy)()9:YYt_Nh/456 #K&qr*)7>NO>Ns 22>NO*+;LDMM$ M)" + &s+,''-- Ps   C.c                    [        X SS  5       VVs/ s H  u  pUR                  U5      PM     nnn[        U5      nS/nSnU H  nXg-  nUR                  Xd-  5        M     U$ s  snnf )Nr:   r<   )r|   distancesumr   )r   v1v2partial_lengthstotal_lengthfactorspartial_sumpls           rL   _partial_path_factorsr     sq    58ABx5HI5H62r{{25HOI'LeGK{12  N Js   A$c                2   U S   /n[        X SS  5       H~  u  p4XC-
  nUR                  nXa:  aS  [        [        R                  " Xa-  5      5      nUSU-  -  n[        US-
  5       H  n	X8-  nUR                  U5        M     UR                  U5        M     U$ )Nr   r:   r]   )r|   	magnituderN   r>   ceilr@   r   )
r   max_step_sizenew_pathv0r   segment_vecrY   partsr   ry   s
             rL   _divide_path_into_stepsr     s     G9HdH%g&&!		&"89:E#+.D519%
# & 	 & Ord   )twistr%   	step_sizerF   r   quadsc                 ^^^^ SUUUU4S jjn[        5       n	[        R                  " U 5      n
U(       a  [        U
5      n
U(       a  U	R	                  [        U
SS 5      5        [        R                  " U5      nUS:w  a  [        X5      n[        U5      nUS   mU
nU(       a  [        O[        n[        USS USS 5       HI  u  mn[        U" U5      R                  U
5      5      nU" UU5       H  nU	R	                  U5        M     UnMK     U(       a  U	R	                  USS 5        [        R                  " U	5      $ )a  Extrude a `profile` polygon along a `path` polyline, the vertices of
`profile` should be in counter-clockwise order.
This implementation can scale and twist the sweeping profile along the
extrusion path. The `path` segment points are fix points, the
`max_step_size` is used to create intermediate profiles between this
fix points. The `max_step_size` is adapted for each
segment to create equally spaced distances.
The twist angle is the rotation angle in radians and the scale `argument`
defines the scale factor of the final profile.
The twist angle and scaling factor of the intermediate profiles will be
linear interpolated between the start and end values.

Args:
    profile: sweeping profile as list of (x, y, z) tuples in
        counter-clockwise order
    path:  extrusion path as list of (x, y, z) tuples
    twist: rotate sweeping profile up to the given end rotation angle in
        radians
    scale: scale sweeping profile gradually from 1.0 to given value
    step_size: rough distance between automatically created intermediate
        profiles, the step size is adapted to the distances between the
        path segment points, a value od 0.0 disables creating intermediate
        profiles
    close: close profile polygon if ``True``
    caps: close hull with top- and  bottom faces (ngons)
    quads: use quads for "sweeping" faces if ``True`` else triangles,
        the top and bottom faces are always ngons

Returns: :class:`~ezdxf.render.MeshTransformer`

c                  > STS-
  U -  -   nT	U -  nTT-
  nU[         R                  " U5      -  nU[         R                  " U5      -  n[        XESSU* USSSSUSUR                  UR
                  UR                  S/5      $ )Nr]   r<   )r>   rA   rB   r   rJ   rK   rV   )
faccurrent_scalecurrent_rotationtranslationscale_cos_ascale_sin_ar%   r   r   r   s
         rL   matrix#extrude_twist_scale.<locals>.matrix  s    us{c11 3;"[0#dhh/?&@@#dhh/?&@@c3L+sCmSMM;==+--	
  	rd   Nr   r<   r   r:   )r  r=   returnr   )r   r   r   r&   r   r   r   r   r   _tri_connection_facesr|   transform_verticesr   r   )r   r   r   r%   r  rF   r   r  r  r   r   r   r   prev_profileface_generatorfactorr   r   r   r   s     ``              @@rL   r*   r*     s   V  Dyy)()9:h/456YYt_NC0K#N3G #K#L/4+:ON #N12$6 DffVn??@PQR"<@DMM$ A%	 !E
 l3B'(''--rd   )r   c          
         Uc  Un[         R                  " US5      (       a
  [        XUS9$ [        [	        XSS95      n[        [        [	        XSS9U5      5      n[        XV/SSUS9$ )a  Create a `cylinder <https://en.wikipedia.org/wiki/Cylinder>`_ as
:class:`~ezdxf.render.MeshTransformer` object, the base center is fixed in
the origin (0, 0, 0).

Args:
    count: profiles edge count
    radius: radius for bottom profile
    top_radius: radius for top profile, if ``None`` top_radius == radius
    top_center: location vector for the center of the top profile
    caps: close hull with top- and  bottom faces (ngons)

r<   )rC   rD   apexTrF   FrF   r  r   )r>   r   r2   r   r   r#   r.   )rC   rD   
top_radius
top_centerr   base_profiletop_profiles          rL   r,   r,     sr    ( 
||J$$%Z@@uD9:Ly!F
STK	#	 rd   c               T   [        U5      n[        U5      U-
  nUR                  (       a  [        S5      e[        XSSUR                  4US9n [        U[        R                  " U5      US9nUR                  UR                  5        U$ ! [         a    [        U[        US9n N8f = f)a  Creates a `cylinder <https://en.wikipedia.org/wiki/Cylinder>`_ as
:class:`~ezdxf.render.MeshTransformer` object from two points,
`base_center` is the center of the base circle and, `top_center` the center
of the top circle.

Args:
    count: cylinder profile edge count
    radius: radius for bottom profile
    base_center: center of base circle
    top_center: center of top circle
    caps: close hull with top- and  bottom faces (ngons)

Raises:
    ValueError: the cylinder orientation cannot be detected (base center == top center)

zCcylinder orientation cannot be detected (base center == top center)r   )r  r   originuyuzr  uxr  )r   is_nullru   r,   r   r   r   crossZeroDivisionErrorr   	transformr  )	rC   rD   base_centerr  r   r  headingr   ucss	            rL   r-   r-   (  s    0 +F:'GQ
 	
 Eq!W5F5F.GdSD8FLL$9gF 	NN3::K	  8Fw78   B B'&B'r  c                  [        5       nU(       a  U  Vs/ s H  n[        U5      PM     n nU(       a  UR                  [        U S   5      5        U(       a  [        O[
        n[        X SS 5       H%  u  pxU" Xx5       H  n	UR                  U	5        M     M'     U(       a  UR                  U S   5        [        R                  " U5      $ s  snf )a5  Returns a :class:`~ezdxf.render.MeshTransformer` instance from linear
connected `profiles`.

Args:
    profiles: list of profiles
    close: close profile polygon if ``True``
    quads: use quadrilaterals as connection faces if ``True`` else triangles
    caps: close hull with top- and bottom faces (ngons)

r   r:   Nr   )	r   r&   r   r   r   r  r|   r   r   )
profilesrF   r  r   r   r   r  p0p1r   s
             rL   r.   r.   P  s    " D.67hM!$h7hx{+,/4+:ONh-"2*DMM$ + . hrl#''-- 8s   Cc                z    [        U 5      n [        XUS9n[        UR                  [        U 5      S-
  U-  S95      $ )a  B-spline interpolation, vertices are fit points for the spline
definition.

Only method 'uniform', yields vertices at fit points.

Args:
    vertices: fit points
    degree: degree of B-spline
    method: "uniform", "chord"/"distance", "centripetal"/"sqrt_chord" or
        "arc" calculation method for parameter t
    subdivide: count of sub vertices + 1, e.g. 4 creates 3 sub-vertices

Returns: list of vertices

)degreemethodr:   )segments)r   r   rW   r   )r   r/  r0  	subdividesplines        rL   r0   r0   o  s@    * H~H)(&QF""S]Q->),K"LMMrd   c              #  ~  #    [        [        S U  5       5      5      S:w  a  [        S5      e[        U S   5      n/ n[        U5       H/  nU  Vs/ s H  oUU   PM	     nnUR	                  [        XaS95        M1     [        US   5      n[        U5       H  nU V	s/ s H  oU   PM	     sn	v   M     gs  snf s  sn	f 7f)a  Profile interpolation by cubic B-spline interpolation.

Args:
    profiles: list of profiles
    subdivide: count of interpolated profiles + 1, e.g. 4 creates 3
        sub-profiles between two main profiles (4 face loops)

Returns: yields profiles as list of vertices

c              3  8   #    U  H  n[        U5      v   M     g 7fr   )r   )r   r   s     rL   r   /spline_interpolated_profiles.<locals>.<genexpr>  s     (x!s1vvxs   r:   z/All profiles have to have the same vertex countr   )r2  N)r   setru   r@   r   r0   )
r+  r2  vertex_countedgesrI   r   edge_verticesprofile_countprofile_indexedges
             rL   r1   r1     s      3(x(()Q.JKKx{#LE|$+348a584)-MN % aMM}-/45utM"u55 .	 5
 6s   AB=B3>B=B8)B=c               x    [        U 5      S:  a  [        [        X5      5      n O[        S5      e[	        U UUUS9$ )a
  Returns a :class:`~ezdxf.render.MeshTransformer` instance by spline
interpolation between given `profiles`.
Requires at least 4 profiles. A `subdivide` value of 4, means, create 4 face
loops between two profiles, without interpolation two profiles create one
face loop.

Args:
    profiles: list of profiles
    subdivide: count of face loops
    close: close profile polygon if ``True``
    quads: use quadrilaterals as connection faces if ``True`` else triangles
    caps: close hull with top- and bottom faces (ngons)

rr   z1Spline interpolation requires at least 4 profilesr  )r   r   r1   ru   r.   )r+  r2  rF   r  r   s        rL   r/   r/     sE    , 8}q4XIJLMM	 rd   c                   [        5       n[        [        XSS95      n[        XUSS 5       H  u  pgUR	                  XgU/5        M     U(       a  UR	                  [        U5      5        [        R                  " U5      $ )a5  Create a `cone <https://en.wikipedia.org/wiki/Cone>`_ as
:class:`~ezdxf.render.MeshTransformer` object, the base center is fixed in
the origin (0, 0, 0).

Args:
    count: edge count of basis_vector
    radius: radius of basis_vector
    apex: tip of the cone
    caps: add a bottom face as ngon if ``True``

Tr  r:   N)r   r   r   r|   r   r   r   r   )rC   rD   r  r   r   base_circler-  p2s           rL   r2   r2     si    $ Dve489Kkqr?3rtn% 4h{+,''--rd   c               T   [        U5      n[        U5      U-
  nUR                  (       a  [        S5      e[        XSSUR                  4US9n [        U[        R                  " U5      US9nUR                  UR                  5        U$ ! [         a    [        U[        US9n N8f = f)a  Create a `cone <https://en.wikipedia.org/wiki/Cone>`_ as
:class:`~ezdxf.render.MeshTransformer` object from two points, `base_center`
is the center of the base circle and `apex` as the tip of the cone.

Args:
    count: edge count of basis_vector
    radius: radius of basis_vector
    base_center: center point of base circle
    apex: tip of the cone
    caps: add a bottom face as ngon if ``True``

Raises:
    ValueError: the cone orientation cannot be detected (base center == apex)

z=the cone orientation cannot be detected (base center == apex)r   )r  r   r  r   )r   r"  ru   r2   r   r   r   r#  r$  r   r%  r  )	rC   rD   r&  r  r   r  r'  r   r(  s	            rL   r3   r3     s    . +F4j6!GK
 	
 Q7+<+<$=DID8FLL$9gF 	NN3::K	  8Fw78r)  )r:   r   r   c               n   U S:  a  [        S5      e[        U5      U -  n[        R                  " [	        U5      U5      nU Vs/ s H  n[	        U5      PM     nnU/n[        [        U 5      5       H.  n	[        UR                  U5      5      nUR                  U5        M0     [        USSUS9n
U
$ s  snf )a@  Returns a :class:`~ezdxf.render.MeshTransformer` instance created by
rotating a `profile` around an `axis`.

Args:
    count: count of rotated profiles
    profile: profile to rotate as list of vertices
    angle: rotation angle in radians
    axis: rotation axis
    caps: close hull with start- and end faces (ngons)

rr   z
count >= 2FTr  )ru   r=   r   axis_rotater   r@   rN   r   r  r   r.   )rC   r   rk   axisr   rG   mr   r+  ry   r   s              rL   r4   r4     s    & qy&&%L5 ET$Z/A '(1tAwG(yH3u:q++G45    	D K )s   B2   )r  c                 ^^^^^^^ [        T5      m[        U 5      m[        U5      S-  n[        R                  [        T5      -  m[        R                  [        U5      -  m[        5       mS
UU4S jjmSU4S jjmSUUUUUU4S jjnU" U* S-   SS9  [        U* S-   US-
  5       GH+  nUS-   nT" U5      nT" U5      n	[        R                  " TU-  5      T-  n
[        R                  " TU-  5      T-  n[        T5       H  nT" XU
5      nT" US-   X5      nT" US-   X5      nT" XU5      nU(       a  TR                  XUU/5        MJ  T" US-   T" US-   5      [        R                  " TUS-   -  5      T-  5      nTR                  XU/5        TR                  XU/5        TR                  UUU/5        TR                  UUU/5        M     GM.     U" US-
  S	S9  [        R                  " T5      $ )a?  Create a `sphere <https://en.wikipedia.org/wiki/Sphere>`_ as
:class:`~ezdxf.render.MeshTransformer` object, the center of the sphere is
always at (0, 0, 0).

Args:
    count: longitudinal slices
    stacks: latitude slices
    radius: radius of sphere
    quads: use quadrilaterals as faces if ``True`` else triangles

r   c                <   > T[         R                  " TU -  5      -  $ r   )r>   rA   )stack	delta_phirD   s    rL   radius_of_stacksphere.<locals>.radius_of_stackE  s    U!2333rd   c                   > TU -  n[        [        R                  " U5      U-  [        R                  " U5      U-  U5      $ r   )r   r>   rA   rB   )slice_r   rV   actual_thetadelta_thetas       rL   r[   sphere.<locals>.vertexH  s8    "V+DHH\*Q.0F0JANNrd   Fc                >  > [         R                  " U T-  5      T
-  nU(       a  [        SST
5      O[        SST
* 5      nT" U 5      n[        T5       HG  nT" XTU5      nT" US-   XB5      nU(       a  T	R	                  XgU45        M4  T	R	                  X7U45        MI     g Nr   r:   )r>   rB   r   r@   r   )rJ  toprV   
cap_vertexr}   rO  r   r   rK  r   rD   rL  slicesr[   s           rL   cap_trianglessphere.<locals>.cap_trianglesL  s    HHUY&'&0+.T!Q'DAw4G
U#FmFA&B
B*Brz23zr23 $rd   r:   )rU  r   T)rJ  r=   r  r=   )rO  r=   r   r=   rV   r=   r  r   )F)r=   rN   r>   r?   rv   r   r@   rB   r   r   r   )rC   stacksrD   r  stacks_2rX  actual_stack
next_stackr}   r~   z1z2ir   r   v3v4rb   rK  rQ  r   rL  rW  r[   s     `               @@@@@@rL   r5   r5   0  s    6]FZF6{aH((U6]*K%-'ID4 4O
4 
4 8)a-U+ xi!mX\:!A%
\*Z(XXi,./&8XXi*,-6vAr"BAr&BAr&Br"Brr2./G#L3$67HHY,*<=>G
 rv./rv./r2v./r2v./!  ;2 (Q,D)''--rd   g?c                  U S:  a  [        S5      eUS:  a  [        S5      e[        R                  " [        U5      5      n[        R                  " [        U5      5      nUS:  a  [        S5      eUS:  a  [        S5      eX2:  a  [        S5      e[        U5      [        R                  -  nU[        R                  :w  a  [        U5      [        R                  -  n[        XE5      n[        R                  " U[        R                  5      nXp-  n	[        [        XS	S
9[        USS5      5       V
s/ s H$  n
[        U
R                  SU
R                  5      PM&     nn
UR                  5         US:  a   U V
s/ s H  oR                  U5      PM     nn
[        5       nUnU V
s/ s H  oR                  U	5      PM     nn
U(       d!  U(       a  UR                  [!        U5      5        [#        U 5       HH  n[%        X5       H  nUR                  U5        M     UnU V
s/ s H  oR                  U	5      PM     nn
MJ     U(       d  U(       a  UR                  U5        [&        R(                  " U5      $ s  sn
f s  sn
f s  sn
f s  sn
f )a&  Create a `torus <https://en.wikipedia.org/wiki/Torus>`_ as
:class:`~ezdxf.render.MeshTransformer` object, the center of the torus is
always at (0, 0, 0). The `major_radius` has to be bigger than the
`minor_radius`.

Args:
    major_count: count of circles
    minor_count: count of circle vertices
    major_radius: radius of the circle center
    minor_radius: radius of circle
    start_angle: start angle of torus in radians
    end_angle: end angle of torus in radians
    caps: close hull with start- and end faces (ngons) if the torus is open

r:   zmajor_count < 1rr   zminor_count < 3&.>zmajor_radius is 0zminor_radius is 0zminor_radius >= major_radiusTr  r   )ru   r>   fabsr=   r?   r   r   r#   r   r   rJ   rK   reverser$   r   r   r   r@   r   r   r   )major_countminor_countmajor_radiusminor_radiusstart_angle	end_angler   
angle_spanclosed_torus
step_anglerz   circle_profiler   start_profileend_profilery   r   s                    rL   r6   r6   z  s)   2 Q?,,Q?,,99U<01L99U<01Ld,--d,--#788$txx/KDHH)$txx/	#K;J<<
DHH5L)J ;D9q!$

A 	QSS!QSS
   T9GHA((;/HD"M1?@A88J'K@Dh}-.;*=FDMM$ G#5@A[xx
+[A	   Dm$''--9 I A Bs   4+I7;I<'J"Jc              #     #    [        U 5      [        U5      :X  d   S5       eU(       a  [        X5       S h  vN   g [        X5       S h  vN   g  N N7f)Nzprofiles differ in vertex count)r   r   r  )rq  rr  quads      rL   connection_facesru    sM      }[!11T3TT1)-EEE(DDD 	FDs!   5AAAAAAc              #  j   #    U S   nUS   n[        U SS  USS  5       H  u  pEX$XS4v   UnUnM     g 7frT  r|   rq  rr  v0_prevv1_prevr   r   s         rL   r   r     sO      AG!nGmAB'QR92&& :s   13c              #  v   #    U S   nUS   n[        U SS  USS  5       H  u  pEXSU4v   X$U4v   UnUnM     g 7frT  rw  rx  s         rL   r  r    sY      AG!nGmAB'QR97##2o	 :r\   c                >    [        [        R                  " U 5      XS9$ )aX  Returns a reference frame as UCS from the given heading and the
WCS z-axis as reference "up" direction.
The z-axis of the reference frame is pointing in heading direction, the
x-axis is pointing right and the y-axis is pointing upwards.

The reference frame is used to project vertices in xy-plane
(construction plane) onto the normal plane of the given heading.

Use the :func:`reference_frame_ext` if heading is parallel to the WCS
Z_AXIS.

Args:
    heading: WCS direction of the reference frame z-axis
    origin: new UCS origin

Raises:
    ZeroDivisionError: heading is parallel to WCS Z_AXIS

r  r  r  )r   r   r#  )r'  r  s     rL   r7   r7     s    ( &,,w'GCCrd   c                     [        [        R                  " U R                  5      [        US9$ ! [         a/    [        U R
                  R                  [        5      [        US9s $ f = f)zReference frame calculation if heading vector is parallel to the WCS
Z_AXIS.

Args:
    frame: previous reference frame
    origin: new UCS origin

r}  )r!  r  r  )r   r   r#  r!  r$  r  )framer  s     rL   r8   r8     sQ    Hfll588,GG HehhnnV,GGHs   ,/ 6A('A(c              #     #    [        X5       Hd  u  p#[        X#5      n[        U5      nUS:X  a	  US   v   M*  US:X  a  US   R                  US   5      v   MK  US   R                  US   5      v   Mf     g 7f)Nr:   r   r   r   )r|   r   r   lerp)	prev_rays	next_raysray1ray2iprC   s         rL   _intersect_raysr    sp      )/
$T0BA:Q%KaZQ%**RU##r(--Q(( 0s   A5A7c                N   U S   /n[        X5       VVVVs/ s H&  u  p4[        X45       VVs/ s H  u  pVXV4PM
     snnPM(     nnnnn[        XwSS  5       H(  u  pUR                  [        [        X5      5      5        M*     UR                  US   5        U$ s  snnf s  snnnnf )Nr   r:   r   )r|   r   r   r  )
start_profilesend_profilesr+  r,  r-  r   r   raysr  r  s
             rL   _intersection_profilesr    s     '5Q&7%8H .77FB !$B,fb",7 	  !$Dqr( 3	_YBCD !4OOL$%O 	-s   B
BB
B
c                     [        X5      nUR                  R                  U R                  5      S:  a  [        X#R                  UR                  * S9nU$ ! [
         a    [        X5      s $ f = f)zReturns the following reference frame next to the current reference
`frame`.

Args:
    frame: the current reference frame
    heading: z-axis direction of the following frame in WCS
    origin: origin of the following reference frame

r   )r  r  r  )r7   r  dotr   r  r$  r8   )r  r'  r  
next_frames       rL   r9   r9   (  sd    	2&w7
 ==UXX&*F}}*--PJ 2"5112s   AA A/.A/c                l   [         R                  " U5      n[         R                  " U 5      n/ n/ n[        5       n[        X3SS  5       Ha  u  pX-
  n
U" XzU5      n[        UR	                  U5      5      nUR                  U5        UR                  U Vs/ s H  oU
-   PM	     sn5        Mc     XV4$ s  snf )Nr:   )r   r   r   r|   points_to_wcsr   )r   sweeping_pathnext_ref_framespathreference_profiler  r  	ref_framer  targetr'  rq  rz   s                rL   "_make_sweep_start_and_end_profilesr  >  s    
 IIm$E		'*NLIe12Y//"9v>	Y445FGHm,-@-Q[-@A 0 '' As   B1
c                .    [        [        X[        5      6 $ )a  Returns the intermediate profiles of sweeping a profile along a 3D path
where the sweeping path defines the final location in the `WCS`.

The profile is defined in a reference system. The origin of this reference
system will be moved along the sweeping path where the z-axis of the
reference system is pointing into the moving direction.

Returns the start-, end- and all intermediate profiles along the sweeping
path.

)r  r  r9   )r   r  s     rL   sweep_profiler  Q  s     "	+$=

 rd   c                    U(       a  [        U 5      n / n[        [        X[        5      6  H'  u  pEUR	                  U5        UR	                  U5        M)     U$ r   )r&   r|   r  r9   r   )r   r  rF   r+  speps         rL   debug_sweep_profilesr  g  sV    
 (%'H	+$=


 	 Ord   c               0    [        X5      n[        UUUUS9$ )a-  Returns the mesh from sweeping a profile along a 3D path, where the
sweeping path defines the final location in the `WCS`.

The profile is defined in a reference system. The origin of this reference
system will be moved along the sweeping path where the z-axis of the
reference system is pointing into the moving direction.

Returns the mesh as :class:`ezdxf.render.MeshTransformer` object.

Args:
    profile: sweeping profile defined in the reference system as
        iterable of (x, y, z) coordinates in counter-clockwise order
    sweeping_path: the sweeping path defined in the WCS as iterable of
        (x, y, z) coordinates
    close: close sweeping profile if ``True``
    quads: use quadrilaterals as connection faces if ``True`` else triangles
    caps: close hull with top- and bottom faces (ngons)

r  )r  r.   )r   r  rF   r  r   r+  s         rL   r+   r+   y  s'    6 W4H	 rd   )r:   r   F)
rC   rN   rD   r=   rE   r=   rF   boolr  Iterable[Vec3])rC   rN   rO   r=   rP   r=   rQ   r=   rR   r=   rE   r=   r  r  )r:   r:   r   )
rC   rN   rY   r=   rU   r=   rE   r=   r  r  )r]   F)ra   r=   r  tuple[Vec3, Vec3, Vec3, Vec3])r]   r]   F)rf   r=   rg   r=   r  r  )r]         >@)ra   r=   rk   r=   r  ztuple[Vec3, Vec3, Vec3])r]   r  g     F@)ra   r=   rk   r=   ro   r=   r  r  )NNr<   r<   F)rC   rN   rY   Optional[float]rD   r  rw   r=   rE   r=   rF   r  r  r  )r<   r<   F)rC   rN   r}   r=   r~   r=   rw   r=   rE   r=   rF   r  r  r  )r   F)rC   rN   r   r=   r   r=   r   r=   r   r=   rE   r=   rF   r  r  r  )r   strrk   r=   r  zIterator[Vec2])r   r   r   )r   Iterable[UVec]r   r   r  r  )r<   T)r   r  rk   r=   r   r  r  r  ))r]   r]   r]   )r   r  r  r  )rd  g-q=)r   r  r   r=   r   r=   r  
list[Vec3])r   T)
rD   r=   r   r=   r   r=   r   rN   r  Iterator[Vec3])T)rb   r  r  r   )TF)r   r  r   r  r  r   )r   r  r  zlist[float])r   Sequence[Vec3]r   r=   r  r  )r   r  r   r  r   r=   r%   r=   r  r=   r  r   )r   r]   Nr   r   r:   )
rC   rN   rD   r=   r  r  r  r   r  r   )r   r:   r  r  )
rC   rN   rD   r=   r&  r   r  r   r  r   )r+  Sequence[Sequence[Vec3]]r  r   )rr   chordr   )
r   r  r/  rN   r0  r  r2  rN   r  r  )r   )r+  r  r2  rN   r  zIterable[list[Vec3]])r+  r  r2  rN   r  r   )r   r]   r  )rC   rN   rD   r=   r  r   r  r   )r   r]   r  r  )
rC   rN   rD   r=   r&  r   r  r   r  r   )
rC   rN   r   r  rk   r=   rE  r   r  r   )r   rG  r:   )rC   rN   rZ  rN   rD   r=   r  r   )
rg  rN   rh  rN   rk  r=   rl  r=   r  r   )rq  r  rr  r  rt  r  r  Iterator[Sequence[Vec3]])rq  r  rr  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  list[Sequence[Vec3]])r  r   r'  r   r  r   r  r   )r   r  r  r  r  z Callable[[UCS, Vec3, Vec3], UCS]r  z)tuple[list[list[Vec3]], list[list[Vec3]]])r   r  r  r  r  r  )r   r  r  r  r  r   )M
__future__r   typingr   r   r   r   r   r>   enumr	   
ezdxf.mathr
   r   r   r   r   r   r   r   r   r   r   r   ezdxf.render.meshr   r   __all__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.   r0   r1   r/   r2   r3   r4   r5   r6   ru  r   r  r7   r8   r  r  r9   r  r  r  r+   r   rd   rL   <module>r     s   # C C      @#N HM))).3)@D))B xx%@%@%@ 	%@ 	%@
 %@ %@ %@R MN***.3*DI**,	J .3BBB"B7  ;?)
)#)27)")\ #"111 1 	1
 1 1 1p 333 	3 	3
 3 3 3lG  PPP P 	P
 P P P Pf !%Q
1 'T  ?C99%*97;99(1" GL		',	>C		  ))) ) 	) )B 	AqMAqMAqMAqMAqMAqMAqMAqM	 	tTtTtTtTtTtTtTtT	 
$ EJ#.#.#1#.#.L& 
	
P.P.
P. 	P.
 P. P. P.h "& 	! 
!!!  ! 	! !J ! 	% 
%%% % 	% %V 
	.&. .B 	NNN N 	N
 N6 :;6&63666<  
	& F .
 
... . .: !	% 
%%% % 	% %V 88	" 
""" " 	" "L 78G.BFG.G. G..3G.G.V xxG. 
G.G.G.
 G. G. G.TEE,6E>BEE!0>	!	0>		 5< D. 4; H)')4L)),* 2,((!( 5( /	(&! 2 ! 	, 
	!!!! !rd   