Ë
    £èhB¸  ã                  ó²  — d dl mZ d dlmZmZmZmZmZ d dlZd dl	m
Z
 d dlmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZmZ g d¢Z	 dK	 	 	 	 	 	 	 	 	 dLd
„Zddd ej:                  d f	 	 	 	 	 	 	 	 	 	 	 	 	 dMd„Z	 dN	 	 	 	 	 	 	 	 	 dOd„ZdPdQd„Z 	 dR	 	 	 	 	 dSd„Z!dTdUd„Z"	 dV	 	 	 	 	 	 	 dWd„Z#	 	 	 	 	 dX	 	 	 	 	 	 	 	 	 	 	 	 	 dYd„Z$	 	 	 dZ	 	 	 	 	 	 	 	 	 	 	 	 	 d[d„Z% G d„ de
«      Z&	 	 d\	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d]d„Z' ed d «      d fd^d„Z(d_d`d„Z)	 da	 	 	 	 	 	 	 dbd„Z*dcddd„Z+	 de	 	 	 	 	 	 	 dfd„Z,	 	 dg	 	 	 	 	 	 	 	 	 dhd„Z- ed d d «       edd d «       eddd «       ed dd «       ed d d«       edd d«       eddd«       ed dd«      gZ. ed d d «       ed!d d «       ed!d!d «       ed d!d «       ed d d!«       ed!d d!«       ed!d!d!«       ed d!d!«      gZ/g d"¢g d#¢g d$¢g d%¢g d&¢g d'¢gZ0didjd(„Z1	 dk	 	 	 	 	 dld)„Z2dmd*„Z3dnd+„Z4ddddd	dd,œ	 	 	 	 	 	 	 	 	 	 	 dod-„Z5	 	 	 	 dpdd.œ	 	 	 	 	 	 	 	 	 dqd/„Z6	 	 	 	 drdd.œ	 	 	 	 	 	 	 	 	 dsd0„Z7ddd	d1œ	 	 	 dtd2„Z8	 	 	 du	 	 	 	 	 	 	 	 	 dvd3„Z9	 dw	 	 	 	 	 dxd4„Z:	 dwddd	d1œ	 	 	 	 	 dyd5„Z;	 	 	 dzdd.œ	 	 	 	 	 	 	 d{d6„Z<	 	 	 	 d|dd.œ	 	 	 	 	 	 	 	 	 d}d7„Z=ej:                  d8fd	d.œ	 	 	 	 	 	 	 	 	 d~d9„Z>	 ddd;œ	 	 	 	 	 	 	 d€d<„Z?dd:dd=dej:                  fdd.œ	 	 	 	 	 	 	 	 	 d�d>„Z@	 	 	 	 	 	 	 	 d‚d?„ZA	 	 	 	 	 	 dƒd@„ZB	 	 	 	 	 	 dƒdA„ZCefd„dB„ZDefd…dC„ZE	 	 	 	 	 	 d†dD„ZF	 	 	 	 	 	 d‡dE„ZGdˆdF„ZH	 	 	 	 	 	 	 	 d‰dG„ZI	 	 	 	 	 	 dŠdH„ZJ	 di	 	 	 	 	 dŠdI„ZKdddd1œ	 	 	 	 	 d‹dJ„ZLy)Œé    )Ú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              #  ó  K  — t        |«      }t        j                  | z  }d}t        | «      D ]F  }t        j                  |«      |z  }t        j
                  |«      |z  }t        |||«      –— ||z  }ŒH |rt        |d|«      –— yy­w)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	            ú2lib/python3.12/site-packages/ezdxf/render/forms.pyr   r   >   s‡   è ø€ ô$ �6‹]€FÜ�H‰H�uÑ€EØ€EÜ�u–ˆÜ�H‰H�U‹O˜fÑ$ˆÜ�H‰H�U‹O˜fÑ$ˆÜ�1�a˜Ó#Ò#Ø�‰‰ð	 ñ Ü�6˜1˜iÓ(Ó(ð ùs   ‚BB
c              #  óB  K  — t        |«      }t        |«      }t        |«      }t        |«      }t        | «      } ||z
  | dz
  z  }t        j                  }t        j                  }t        | «      D ]+  }	||	|z  z   }
t         ||
«      |z   ||
«      |z  |«      –— Œ- y­w)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Ü�‹J€EØ˜Ñ$¨°©Ñ3€EÜ
�(‰(€CÜ
�(‰(€CÜ�u–ˆØ˜e e™mÑ+ˆÜ‘3�u“: ‘?¡C¨£J°¡O°YÓ?Ó?ñ ùs   ‚BBc              #  ó€   K  — t        |¬«      }|j                  || dz
  «      D ]  }|j                  |¬«      –— Œ y­w)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Ø×$Ñ$ V¨U°Q©YÖ7ˆØ�n‰n˜yˆnÓ)Ó)ñ 8ùs   ‚<>ç      ð?c                óÐ   — |r7| dz  }t        | | «      t        || «      t        ||«      t        | |«      fS t        dd«      t        | d«      t        | | «      t        d| «      fS )zâReturns 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   ›   sg   € ñ
 Ø�3‰JˆÜ�Q�B˜˜‹|œT ! a R›[¬$¨q°!«*´d¸A¸2¸q³kÐAÐAä�A�q‹zœ4  a›=¬$¨t°TÓ*:¼DÀÀD»MÐIÐIó    c                óÚ   — |r<| dz  }|dz  }t        | | «      t        || «      t        ||«      t        | |«      fS t        dd«      t        | d«      t        | |«      t        d|«      fS )zÞReturns 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Úsyra   rb   Úbs        rL   r   r   §   so   € ñ Ø�‰HˆØ�‰HˆÜ�Q�B˜˜‹|œT ! a R›[¬$¨q°!«*´d¸A¸2¸q³kÐAÐAä�A�q‹zœ4  A›;¬¨R°«´d¸1¸b³kÐAÐArc   c                óª   — t        j                  t        j                  |dz  «      «      | z  }t        |  |«      t        dd«      t        |  | «      fS )aF  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   )r`   ÚangleÚhs      rL   r   r   ¶   sI   € ô 	�‰”—‘˜e c™kÓ*Ó+¨dÑ2€AÜ���q‹>œ4  1›:¤t¨T¨E°A°2£Ð6Ð6rc   c                ó  — t        j                  t        j                  |dz  «      «      | z  }t        j                  t        j                  |«      «      |z  }t	        |  |«      t	        dd«      t	        |  | «      t	        |  |z   d«      fS )av  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   ri   Útanr   )r`   rj   Úbetark   Ú	back_steps        rL   r   r   Å   s}   € ôD 	�‰”—‘˜e c™kÓ*Ó+¨dÑ2€AÜ—‘œŸ™ dÓ+Ó,¨qÑ0€IäˆdˆU�A‹ÜˆQ�‹
ÜˆdˆU�Q�B‹ÜˆdˆU�YÑ Ó"ð	ð rc   r<   c              #  óØ  K  — | dk  rt        d«      ‚|�=|dk  rt        d«      ‚|dz  t        j                  t        j                  | z  «      z  }n|�|dk  rt        d«      ‚t        d«      ‚t        j                  | z  }|}d}t        j
                  }	t        j                  }
t        | «      D ].  }t        | |	|«      z  | |
|«      z  |«      }|€|}|–— ||z  }Œ0 |r|–— yy­w)	aW  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   rj   ÚfirstrA   rB   Ú_Úvs                rL   r   r   ñ   s÷   è ø€ ð0 ˆq‚yÜÐEÓFÐFØÐØ�SŠ=ÜÐJÓKÐKØ˜#‘¤§¡¬¯©°5©Ó 9Ñ9‰Ø	Ð	Ø�SŠ=ÜÐJÓKÐKäÐBÓCÐCä�H‰H�uÑ€EØ€EØ€EÜ
�(‰(€CÜ
�(‰(€CÜ�5Ž\ˆÜ�™#˜e›*Ñ$ f©s°5«zÑ&9¸9ÓEˆØˆ=ØˆEØŠØ�‰‰ð ñ Ø‹ð ùs   ‚C(C*c              #  ó&  K  — | dk  rt        d«      ‚|dk  rt        d«      ‚|dk  rt        d«      ‚t        | |||d¬«      }t        | |t        j                  | z  |z   |d¬«      }d}t	        ||«      D ]  \  }	}
|€|	}|	–— |
–— Œ |r|–— yy­w)	ae  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

    rq   rr   r<   z'Argument `r1` has to be greater than 0.z'Argument `r2` has to be greater than 0.F)rD   rv   rE   rF   N)rt   r   r>   ru   Úzip)rC   Úr1Úr2rv   rE   rF   Úcorners1Úcorners2rw   Ús1Ús2s              rL   r    r    %  s½   è ø€ ð4 ˆq‚yÜÐEÓFÐFØ	ˆS‚yÜÐBÓCÐCØ	ˆS‚yÜÐBÓCÐCäØ�b 8°yÈô€Hô ØØÜ—‘˜5‘ 8Ñ+ØØô€Hð €EÜ�h Ö)‰ˆˆBØˆ=ØˆEØŠØ‹ð	 *ñ Ø‹ð ùs   ‚BBc                  ó   — e Zd ZdZdZdZdZy)Ú_Gearr   r:   é   rq   N)Ú__name__Ú
__module__Ú__qualname__Ú	TOP_STARTÚTOP_ENDÚBOTTOM_STARTÚ
BOTTOM_END© rc   rL   rƒ   rƒ   [  s   „ Ø€IØ€GØ€LØ�Jrc   rƒ   c              #  óä  K  — | dk  rt        d«      ‚|dk  rt        d«      ‚|dk  rt        d«      ‚|dk  rt        d«      ‚|dk  rt        d«      ‚||k\  rt        d«      ‚||z
  }t        j                  |dz  |z  «      }t        j                  |dz  |z  «      }	|	|z
  dz  }
t        j                  | |	z  z
  | z  }| dz  }t        j
                  }d	}t        j                  }t        j                  }t        d
| z  «      D ]à  }|t        j
                  k(  s|t        j                  k(  r|}n|}t        | ||«      z  | ||«      z  |«      }|t        j
                  k(  r||z  }nJ|t        j                  k(  r||
z  }n1|t        j                  k(  r||z  }n|t        j                  k(  r||
z  }|€|}|–— |dz  }|t        j                  kD  sŒÑt        j
                  }Œâ |r|–— y	y	­w)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

    rq   rr   r<   rs   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:   )rt   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_differencern   rj   Ústaterw   rA   rB   rx   rD   ry   s                       rL   r!   r!   b  sÿ  è ø€ ð< ˆq‚yÜÐEÓFÐFØ˜ÒÜÐFÓGÐGØ�CÒÜÐEÓFÐFØ�sÒÜÐEÓFÐFØ�‚}ÜÐFÓGÐGØ�ÒÜÐLÓMÐMà  6Ñ)€KÜ—	‘	˜) c™/¨NÑ:Ó;€IÜ—9‘9˜\¨CÑ/°+Ñ=Ó>€Là�yÑ ØñÐô �H‰H�u˜|Ñ+Ñ+¨uÑ4€DØˆJ˜Ñ€EÜ�O‰O€EØ€EÜ
�(‰(€CÜ
�(‰(€CÜ�1�u‘9ÖˆØ”E—O‘OÒ# u´·±Ò'=Ø#‰Fà ˆFÜ�™#˜e›*Ñ$ f©s°5«zÑ&9¸9ÓEˆà”E—O‘OÒ#Ø�YÑ‰EØ”e—m‘mÒ#ØÐ%Ñ%‰EØ”e×(Ñ(Ò(Ø�T‰M‰EØ”e×&Ñ&Ò&ØÐ%Ñ%ˆEàˆ=ØˆEØŠà�‰
ˆØ”5×#Ñ#Ó#Ü—O‘O‰Eð- ñ0 Ø‹ð ùs   ‚GG0ÇG0c              #  óò  K  — |}|–— | j                  d«      D ]Ù  }|j                  «       }|d   dk(  r&t        |«      dk(  r|dz  }Œ/|t        |dd «      z  }ŒA|d   dk(  r&t        |«      dk(  r|dz  }Œ]|t        |dd «      z  }Œo|d   dk(  r=|dd j                  d	«      \  }}|t	        t        |«      t        |«      «      z  }|–— Œ´|t	        j
                  |t        |«      «      z  }|–— ŒÛ y­w)
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Ústartrj   ÚcursorÚcmdrJ   rK   s          rL   r"   r"   µ  s÷   è ø€ ð& €FØ
‚LØ�~‰~˜cÖ"ˆØ�i‰i‹kˆØˆq‰6�SŠ=Ü�3‹x˜1Š}Ø˜‘‘àœ˜s 1 2˜w›Ñ'‘Ø�‰V�sŠ]Ü�3‹x˜1Š}Ø˜‘‘àœ˜s 1 2˜w›Ñ'‘Ø�‰V�sŠ]Ø�q�r�7—=‘= Ó%‰DˆAˆqØ”dœ5 ›8¤U¨1£XÓ.Ñ.ˆFØ‹Là”d×)Ñ)¨%´°s³Ó<Ñ<ˆFØ‹Lñ% #ùs   ‚C5C7c              #  ó>   K  — t        |«      }| D ]	  }||z   –— Œ y­w)zÊTranslate `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$   è ø€ ô �‹9€DÛˆØ�Q‰h‹ñ ùs   ‚Tc                ó4   ‡— |rˆfd„| D «       S ˆfd„| D «       S )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  óR   •K  — | ]  }t        |«      j                  ‰«      –— Œ  y ­w©N)r   Ú
rotate_deg©Ú.0ry   rj   s     €rL   Ú	<genexpr>zrotate.<locals>.<genexpr>ý  s!   øè ø€ Ð<±8¨a”�Q“×"Ñ" 5×)±8ùó   ƒ$'c              3  óR   •K  — | ]  }t        |«      j                  ‰«      –— Œ  y ­wr¯   )r   r$   r±   s     €rL   r³   zrotate.<locals>.<genexpr>ÿ  s   øè ø€ Ð8©x¨!”�Q“—‘˜u×%©xùr´   rŒ   )r©   rj   Údegs    ` rL   r$   r$   î  s   ø€ ñ Û<±8Ó<Ð<ã8©xÓ8Ð8rc   c              #  ó¸   K  — |\  }}}t        j                  | «      D ]8  }t        |j                  |z  |j                  |z  |j                  |z  «      –— Œ: y­w)zúScale `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©   Úscalingre   rf   Úszry   s         rL   r%   r%     sM   è ø€ ð �J€BˆˆBÜ�]‰]˜8Ö$ˆÜ�1—3‘3˜‘8˜QŸS™S 2™X q§s¡s¨R¡xÓ0Ó0ñ %ùs   ‚AAc                óx   — t        | «      }|d   j                  |d   ||¬«      s|j                  |d   «       |S )zgReturns 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‰:×Ñ˜g b™k°7ÀGÐÔLØ�‰�w˜q‘zÔ"Ø€Nrc   é   c              #  óN  K  — dt        |d«      z  }|s| }t        |t        |«      z  «      }t        |dz   «      D ]e  }||z  }|t        j
                  z  }	t	        j                  |	«      | z  }
t	        j                  |	«      | z  }t        |
|t        |«      |z  «      –— Œg y­w)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   Útrj   rJ   rK   s               rL   r'   r'     s�   è ø€ ð& œ˜J¨Ó*Ñ*€DÙØˆuˆÜ˜5¤3 t£9Ñ,Ó-ÐÜÐ'¨!Ñ+Ö,ˆØ�5‰LˆØ”D—H‘H‘ˆÜ�H‰H�U‹O˜fÑ$ˆÜ�H‰H�U‹O˜fÑ$ˆÜ�1�aœ˜Q› %™Ó(Ó(ñ -ùs   ‚B#B%g      à¿ç      à?)r   rq   r„   r:   )r:   r„   é   é   )rq   é   rÏ   r„   )r   rŽ   rÑ   rq   )r   r:   rÐ   rŽ   )rŽ   rÐ   rÏ   rÑ   c                ód   — t        «       }| rt        nt        }|j                  |t        ¬«       |S )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)ra   Úmeshr©   s      rL   r(   r(   `  s*   € ô Ó€DÙ"(�¬n€HØ‡M�M˜8¬:€MÔ6Ø€Krc   c                óº  — t        «       }t        j                  | «      }|rt        |«      }t        j                  |«      }|r|j	                  t        |dd «      «       |d   }|dd D ]?  }||z
  }	|D �
cg c]  }
|
|	z   ‘Œ	 }}
t        ||«      D ]  }|j	                  |«       Œ |}|}ŒA |r|j	                  |dd «       t        j                  |«      S c c}
w )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Ü—y‘y Ó)ÐÙÜ(Ð)9Ó:Ðä—Y‘Y˜t“_€NÙØ�‰”hÐ/°°Ð4Ó5Ô6Ø  Ñ#€KØ& q rÓ*ˆØ)¨KÑ7ÐÙ>NÓOÑ>N°s˜#Ð 2Ó2Ð>NˆÐOÜ*Ð+;¸^ÖLˆDØ�M‰M˜$Õð Mà)ÐØ"‰ð +ñ Ø�‰Ð& s¨Ð+Ô,Ü×'Ñ'¨Ó-Ð-ùò Ps   Á7Cc                óÒ   — t        | | dd  «      D ��cg c]  \  }}|j                  |«      ‘Œ }}}t        |«      }dg}d}|D ]  }||z  }|j                  ||z  «       Œ |S c c}}w )Nr:   r<   )r{   ÚdistanceÚsumrÁ   )rß   Úv1Úv2Úpartial_lengthsÚtotal_lengthÚfactorsÚpartial_sumÚpls           rL   Ú_partial_path_factorsrò   —  sy   € Ü58¸¸tÀAÀB¸xÔ5HÔIÑ5H©6¨2¨r�r—{‘{ 2•Ð5H€OÑIÜ�Ó'€LØˆe€GØ€KÛˆØ�rÑˆØ�‰�{ \Ñ1Õ2ð ð €Nùó Js   “A#c                ó2  — | d   g}t        | | dd  «      D ]~  \  }}||z
  }|j                  }||kD  rRt        t        j                  ||z  «      «      }|d|z  z  }t        |dz
  «      D ]  }	||z  }|j                  |«       Œ |j                  |«       Œ€ |S )Nr   r:   r\   )r{   Ú	magnituderN   r>   Úceilr@   rÁ   )
rß   Úmax_step_sizeÚnew_pathÚv0rë   Úsegment_vecrY   ÚpartsrË   rx   s
             rL   Ú_divide_path_into_stepsrû   ¢  s§   € Ø  ™G˜9€HÜ�d˜D  ˜HÖ%‰ˆˆBØ˜2‘gˆØ×&Ñ&ˆØ�MÒ!ÜœŸ	™	 &¨=Ñ"8Ó9Ó:ˆEØ #¨¡+Ñ.ˆDÜ˜5 1™9Ö%�Ø�d‘
�Ø—‘ Õ#ð &ð 	�‰˜Õð &ð €Orc   )Útwistr%   Ú	step_sizerF   rà   Úquadsc               óJ  ‡‡‡‡— dˆˆˆˆfd„}t        «       }	t        j                  | «      }
|rt        |
«      }
|r|	j	                  t        |
dd «      «       t        j                  |«      }|dk7  rt        ||«      }t        |«      }|d   Š|
}|rt        nt        }t        |dd |dd «      D ]F  \  Š}t         ||«      j                  |
«      «      } |||«      D ]  }|	j	                  |«       Œ |}ŒH |r|	j	                  |dd «       t        j                  |	«      S )a6  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                ó  •— d‰dz
  | z  z   }‰	| z  }‰‰z
  }|t        j                  |«      z  }|t        j                  |«      z  }t        ||dd| |dddd|d|j                  |j
                  |j                  dg«      S )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   Úmatrixz#extrude_twist_scale.<locals>.matrixÜ  s–   ø€ Ø˜u s™{¨cÑ1Ñ1ˆØ  3™;ÐØ" [Ñ0ˆØ#¤d§h¡hÐ/?Ó&@Ñ@ˆØ#¤d§h¡hÐ/?Ó&@Ñ@ˆäØ˜ c¨3ØˆL˜+ s¨CØ��m SØ�M‰M˜;Ÿ=™=¨+¯-©-¸ð	
ó ð 	rc   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Ü—y‘y Ó)ÐÙÜ(Ð)9Ó:ÐÙØ�‰”hÐ/°°Ð4Ó5Ô6ä—Y‘Y˜t“_€NØ�CÒÜ0°ÀÓKˆä# NÓ3€GØ  Ñ#€KØ#€LÙ/4Õ+Ô:O€NÜ # N°1°2Ð$6¸ÀÀ¸Ö DÑˆ�fÜ™f V›n×?Ñ?Ð@PÓQÓRˆÙ" <°Ö@ˆDØ�M‰M˜$Õð Aà%‰ð	 !Eñ
 Ø�‰�l 3 BÐ'Ô(Ü×'Ñ'¨Ó-Ð-rc   )rà   c          	     óä   — |€|}t        j                  |d«      rt        | ||¬«      S t        t	        | |d¬«      «      }t        t        t	        | |d¬«      |«      «      }t        ||gdd|¬«      S )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,     sw   € ð( ÐØˆ
ä‡|�|�J Ô$Ü˜%¨°ZÔ@Ð@äœ˜u f°DÔ9Ó:€LÜ”y¤¨¨zÀÔ!FÈ
ÓSÓT€KÜØ	�{Ð#ØØØô	ð rc   c               óZ  — t        |«      }t        |«      |z
  }|j                  rt        d«      ‚t        | |dd|j                  f|¬«      }	 t        |t        j                  |«      |¬«      }|j                  |j                  «       |S # t        $ r t        |t        |¬«      }Y Œ:w xY w)aK  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_nullrt   r,   rô   r   r   ÚcrossÚZeroDivisionErrorr   Ú	transformr  )	rC   rD   Úbase_centerr  rà   r  ÚheadingrØ   Úucss	            rL   r-   r-   (  s¥   € ô0 �+Ó€FÜ�:Ó Ñ'€GØ‡‚ÜØQó
ð 	
ô �E˜6¨q°!°W×5FÑ5FÐ.GÈdÔS€Dð8Ü˜¤F§L¡L°Ó$9¸gÔFˆð 	‡N�N�3—:‘:ÔØ€Køô	 ò 8ä˜¤F¨wÔ7Šð8úó   Á!B ÂB*Â)B*r  c               óp  — t        «       }|r| D �cg c]  }t        |«      ‘Œ } }|r|j                  t        | d   «      «       |rt        nt
        }t        | | dd «      D ]$  \  }} |||«      D ]  }	|j                  |	«       Œ Œ& |r|j                  | d   «       t        j                  |«      S c c}w )aQ  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Ó7©h¨”M !Õ$¨hˆÐ7ÙØ�‰”h˜x¨™{Ó+Ô,Ù/4Õ+Ô:O€NÜ�h ¨¨ Ö-‰ˆˆBÙ" 2 rÖ*ˆDØ�M‰M˜$Õñ +ð .ñ Ø�‰�h˜r‘lÔ#Ü×'Ñ'¨Ó-Ð-ùò 8s   ‘B3c                óˆ   — t        | «      } t        | ||¬«      }t        |j                  t        | «      dz
  |z  ¬«      «      S )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*  r+  Ú	subdivideÚsplines        rL   r0   r0   o  sB   € ô* �H‹~€HÜ)¨(¸6È&ÔQ€FÜ�×"Ñ"¬S°«]¸QÑ->À)Ñ,KÐ"ÓLÓMÐMrc   c              #  ót  K  — t        t        d„ | D «       «      «      dk7  rt        d«      ‚t        | d   «      }g }t        |«      D ]0  }| D �cg c]  }||   ‘Œ	 }}|j	                  t        ||¬«      «       Œ2 t        |d   «      }t        |«      D ]  }|D �	cg c]  }	|	|   ‘Œ	 c}	–— Œ yc c}w c c}	w ­w)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  ó2   K  — | ]  }t        |«      –— Œ y ­wr¯   )r¢   )r²   r¬   s     rL   r³   z/spline_interpolated_profiles.<locals>.<genexpr>—  s   è ø€ Ð(™x˜!Œs�1�v™xùs   ‚r:   z/All profiles have to have the same vertex countr   )r-  N)r¢   Úsetrt   r@   rÁ   r0   )
r&  r-  Ú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Ó4©8 a˜˜5›¨8ˆÐ4Ø�‰Ô)¨-À9ÔMÕNð %ô ˜˜a™“M€MÜ˜}Ö-ˆÙ/4Ó5©u tˆt�MÓ"¨uÑ5Ó5ñ .ùò	 5ùò
 6ùs   ‚AB8ÁB.ÁA B8ÂB3Â&B8c               ó~   — t        | «      dkD  rt        t        | |«      «      } nt        d«      ‚t	        | |||¬«      S )a6  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)

    rq   z1Spline interpolation requires at least 4 profilesr  )r¢   r¿   r1   rt   r.   )r&  r-  rF   rþ   rà   s        rL   r/   r/   ¥  sG   € ô, ˆ8ƒ}�qÒÜÔ4°X¸yÓIÓJ‰äÐLÓMÐMÜØØØØô	ð rc   c               óü   — t        «       }t        t        | |d¬«      «      }t        ||dd «      D ]  \  }}|j	                  |||g«       Œ |r|j	                  t        |«      «       t        j                  |«      S )aU  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   Ç  sq   € ô$ Ó€DÜ”v˜e V°4Ô8Ó9€KÜ�k ;¨q¨r ?Ö3‰ˆˆBØ�‰�r˜2˜t�nÕ%ð 4áà�‰”h˜{Ó+Ô,Ü×'Ñ'¨Ó-Ð-rc   c               óZ  — t        |«      }t        |«      |z
  }|j                  rt        d«      ‚t        | |dd|j                  f|¬«      }	 t        |t        j                  |«      |¬«      }|j                  |j                  «       |S # t        $ r t        |t        |¬«      }Y Œ:w xY w)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  rt   r2   rô   r   r   r  r  r   r   r  )	rC   rD   r!  r  rà   r  r"  rØ   r#  s	            rL   r3   r3   ã  s¤   € ô. �+Ó€FÜ�4‹j˜6Ñ!€GØ‡‚ÜØKó
ð 	
ô ��v Q¨¨7×+<Ñ+<Ð$=ÀDÔI€Dð8Ü˜¤F§L¡L°Ó$9¸gÔFˆð 	‡N�N�3—:‘:ÔØ€Køô	 ò 8ä˜¤F¨wÔ7Šð8úr$  )r:   r   r   c               óf  — | dk  rt        d«      ‚t        |«      | z  }t        j                  t	        |«      |«      }|D �cg c]  }t	        |«      ‘Œ }}|g}t        t        | «      «      D ]-  }	t        |j                  |«      «      }|j                  |«       Œ/ t        |dd|¬«      }
|
S c c}w )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)

    rq   z
count >= 2FTr  )rt   r=   r   Úaxis_rotater   r@   rN   r¿   r
  rÁ   r.   )rC   rÞ   rj   Úaxisrà   rG   Úmr¬   r&  rx   rØ   s              rL   r4   r4     s±   € ð& ˆq‚yÜ˜Ó&Ð&Ü�%‹L˜5Ñ €EÜ×ÑœT $›Z¨Ó/€AÙ 'Ó(¡˜1Œt�A�w €GÐ(Øˆy€HÜ”3�u“:ÖˆÜ�q×+Ñ+¨GÓ4Ó5ˆØ�‰˜Õ ð ô  ØØØØô	€Dð €Kùò )s   ÁB.é   )rþ   c               óæ  ‡‡‡‡‡‡‡— t        ‰«      Št        | «      Št        |«      dz  }t        j                  t        ‰«      z  Št        j                  t        |«      z  Št        «       Šd
ˆˆfd„Šdˆfd„Šdˆˆˆˆˆˆfd„	} || dz   d¬«       t        | dz   |dz
  «      D �]&  }|dz   } ‰|«      } ‰|«      }	t        j                  ‰|z  «      ‰z  }
t        j                  ‰|z  «      ‰z  }t        ‰«      D ]Ê  } ‰|||
«      } ‰|dz   ||
«      } ‰|dz   |	|«      } ‰||	|«      }|r‰j                  ||||g«       ŒI ‰|dz    ‰|dz   «      t        j                  ‰|dz   z  «      ‰z  «      }‰j                  |||g«       ‰j                  |||g«       ‰j                  |||g«       ‰j                  |||g«       ŒÌ �Œ)  ||dz
  d	¬«       t        j                  ‰«      S )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        j                  ‰| z  «      z  S r¯   )r>   rA   )ÚstackÚ	delta_phirD   s    €€rL   Úradius_of_stackzsphere.<locals>.radius_of_stackE  s   ø€ ØœŸ™ ¨UÑ!2Ó3Ñ3Ð3rc   c                ó€   •— ‰| z  }t        t        j                  |«      |z  t        j                  |«      |z  |«      S r¯   )r   r>   rA   rB   )Úslice_r�   rV   Úactual_thetaÚdelta_thetas       €rL   r[   zsphere.<locals>.vertexH  s8   ø€ Ø" VÑ+ˆÜ”D—H‘H˜\Ó*¨QÑ.´·±¸Ó0FÈÑ0JÈAÓNÐNrc   Fc                ó*  •— t        j                  | ‰z  «      ‰
z  }|rt        dd‰
«      nt        dd‰
 «      } ‰| «      }t        ‰«      D ]D  } ‰|||«      } ‰|dz   ||«      }|r‰	j	                  |||f«       Œ1‰	j	                  |||f«       ŒF y ©Nr   r:   )r>   rB   r   r@   rÚ   )rD  ÚtoprV   Ú
cap_vertexr|   rH  rë   rì   rE  rØ   rD   rF  Úslicesr[   s           €€€€€€rL   Úcap_triangleszsphere.<locals>.cap_trianglesL  s™   ø€ Ü�H‰H�U˜YÑ&Ó'¨&Ñ0ˆÙ+.”T˜!˜Q Ô'´D¸¸AÀ¸wÓ4Gˆ
Ù˜UÓ#ˆÜ˜F–mˆFÙ˜  AÓ&ˆBÙ˜ ™
 B¨Ó*ˆBÙØ—‘˜r 2 zÐ2Õ3à—‘˜z¨2¨rÐ2Õ3ñ $rc   r:   )rM  rÎ   T)rD  r=   r  r=   )rH  r=   r�   r=   rV   r=   r  r   )F)r=   rN   r>   r?   ru   r   r@   rB   rÚ   r   rÝ   )rC   ÚstacksrD   rþ   Ústacks_2rP  Úactual_stackÚ
next_stackr|   r}   Úz1Úz2Úirë   rì   Úv3Úv4ra   rE  rJ  rØ   rF  rO  r[   s     `               @@@@@@rL   r5   r5   0  sñ  þ€ ô �6‹]€FÜ�‹Z€FÜ�6‹{˜aÑ€HÜ—(‘(œU 6›]Ñ*€KÜ—‘œ% ›-Ñ'€IÜÓ€Dö4õO÷
4ò 
4ñ �8�)˜a‘- UÕ+ô ˜x˜i¨!™m¨X¸©\×:ˆØ! AÑ%ˆ
Ù˜\Ó*ˆÙ˜ZÓ(ˆÜ�X‰X�i ,Ñ.Ó/°&Ñ8ˆÜ�X‰X�i *Ñ,Ó-°Ñ6ˆÜ�v–ˆAÙ˜˜2˜rÓ"ˆBÙ˜˜A™˜r 2Ó&ˆBÙ˜˜A™˜r 2Ó&ˆBÙ˜˜2˜rÓ"ˆBÙØ—‘˜r 2 r¨2Ð.Õ/áØ˜‘GÙ# L°3Ñ$6Ó7Ü—H‘H˜Y¨,¸Ñ*<Ñ=Ó>ÀÑGó�ð
 —‘˜r 2 vÐ.Ô/Ø—‘˜r 2 vÐ.Ô/Ø—‘˜r 2 vÐ.Ô/Ø—‘˜r 2 vÐ.Õ/ò! ð ;ñ2 �(˜Q‘, DÕ)ä×'Ñ'¨Ó-Ð-rc   gš™™™™™¹?c               óÎ  — | dk  rt        d«      ‚|dk  rt        d«      ‚t        j                  t        |«      «      }t        j                  t        |«      «      }|dk  rt        d«      ‚|dk  rt        d«      ‚||k\  rt        d«      ‚t        |«      t        j                  z  }|t        j                  k7  rt        |«      t        j                  z  }t        ||«      }t        j                  |t        j                  «      }|| z  }	t        t        ||d	¬
«      t        |dd«      «      D �
cg c]#  }
t        |
j                  d|
j                  «      ‘Œ% }}
|j                  «        |dkD  r|D �
cg c]  }
|
j                  |«      ‘Œ }}
t        «       }|}|D �
cg c]  }
|
j                  |	«      ‘Œ }}
|s|r|j                  t!        |«      «       t#        | «      D ]D  }t%        ||«      D ]  }|j                  |«       Œ |}|D �
cg c]  }
|
j                  |	«      ‘Œ }}
ŒF |s|r|j                  |«       t'        j(                  |«      S c c}
w c c}
w c c}
w c c}
w )aV  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 < 1rq   zminor_count < 3ç•Ö&è.>zmajor_radius is 0zminor_radius is 0zminor_radius >= major_radiusTr  r   )rt   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_anglery   Úcircle_profilerØ   Ústart_profileÚend_profilerx   rç   s                    rL   r6   r6   z  s7  € ð2 �Q‚Ü˜?Ó,Ð,Ø�Q‚Ü˜?Ó,Ð,Ü—9‘9œU <Ó0Ó1€LÜ—9‘9œU <Ó0Ó1€LØ�dÒÜÐ,Ó-Ð-Ø�dÒÜÐ,Ó-Ð-Ø�|Ò#ÜÐ7Ó8Ð8Ü˜Ó$¤t§x¡xÑ/€KØ”D—H‘HÒÜ˜)Ó$¤t§x¡xÑ/ˆ	Ü# K°Ó;€JÜ—<‘< 
¬D¯H©HÓ5€LØ˜kÑ)€Jô Ü�; °DÔ9Ü�˜q !Ó$ô
óñ
ˆAô 	ˆQ�S‰S�!�Q—S‘SÕð
ð ð ð ×ÑÔØ�TÒÙ9GÓH¹°A˜!Ÿ(™( ;Õ/¸ˆÐHÜÓ€DØ"€MÙ1?Ó@±¨A�1—8‘8˜JÕ'°€KÐ@á™DØ�‰”h˜}Ó-Ô.ä�;ÖˆÜ*¨=¸+ÖFˆDØ�M‰M˜$Õð Gà#ˆÙ5@ÓA±[°�q—x‘x 
Õ+°[ˆÑAð	  ñ ™Dà�‰�mÔ$ä×'Ñ'¨Ó-Ð-ùò9ùò Iùò Aùò Bs   Ä2(IÅ5IÆIÈI"c              #  ó¦   K  — t        | «      t        |«      k(  sJ d«       ‚|rt        | |«      E d {  –—†  y t        | |«      E d {  –—†  y 7 Œ7 Œ­w)Nzprofiles differ in vertex count)r¢   rÜ   r	  )rh  ri  Úquads      rL   Úconnection_facesrl  Ä  sS   è ø€ ô ˆ}Ó¤ [Ó!1Ò1ÐTÐ3TÓTÐ1ÙÜ)¨-¸ÓE×EÑEä(¨¸ÓD×DÑDð 	FøàDús!   ‚0A²A³AÁAÁAÁAc              #  ól   K  — | d   }|d   }t        | dd  |dd  «      D ]  \  }}||||f–— |}|}Œ y ­wrL  ©r{   ©rh  ri  Úv0_prevÚv1_prevrø   rë   s         rL   rÜ   rÜ   Î  sV   è ø€ ð ˜AÑ€GØ˜!‰n€GÜ�m A BÐ'¨°Q°R¨Ö9‰ˆˆBØ�r˜2˜wÐ&Ò&ØˆØ‰ñ :ùs   ‚24c              #  óx   K  — | d   }|d   }t        | dd  |dd  «      D ]  \  }}|||f–— |||f–— |}|}Œ y ­wrL  rn  ro  s         rL   r	  r	  Ù  s`   è ø€ ð ˜AÑ€GØ˜!‰n€GÜ�m A BÐ'¨°Q°R¨Ö9‰ˆˆBØ�'˜7Ð#Ò#Ø�r˜2ˆoÒØˆØ‰ñ	 :ùs   ‚8:c                óD   — t        t        j                  | «      | |¬«      S )aŒ  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¸FÔCÐCrc   c                óÞ   — 	 t        t        j                  | j                  «      t        |¬«      S # t        $ r2 t        | j
                  j                  t        «      t        |¬«      cY S w xY w)z¨Reference frame calculation if heading vector is parallel to the WCS
    Z_AXIS.

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

    rt  )r  r  r  )r   r   r  r  r  r  )Úframer  s     rL   r8   r8   ü  sQ   € ðHÜ”f—l‘l 5§8¡8Ó,´ÀÔGÐGøÜò HÜ�e—h‘h—n‘n¤VÓ,´ÀÔGÒGðHús   ‚.1 ±8A,Á+A,c              #  óì   K  — t        | |«      D ]a  \  }}t        ||«      }t        |«      }|dk(  r|d   –— Œ*|dk(  r|d   j                  |d   «      –— ŒI|d   j                  |d   «      –— Œc y ­w)Nr:   r   r„   r¼   )r{   r   r¢   Úlerp)Ú	prev_raysÚ	next_raysÚray1Úray2ÚiprC   s         rL   Ú_intersect_raysr~    sw   è ø€ ô ˜) YÖ/‰
ˆˆdÜ$ T¨4Ó0ˆÜ�B“ˆØ�AŠ:Ø�Q‘%‹KØ�aŠZØ�Q‘%—*‘*˜R ™UÓ#Ó#à�r‘(—-‘-  Q¡Ó(Ó(ñ 0ùs   ‚A2A4c                óN  — | d   g}t        | |«      D ����cg c]&  \  }}t        ||«      D ��cg c]	  \  }}||f‘Œ c}}‘Œ( }}}}}t        ||dd  «      D ])  \  }}	|j                  t        t        ||	«      «      «       Œ+ |j                  |d   «       |S c c}}w c c}}}}w )Nr   r:   r¼   )r{   rÁ   r¿   r~  )
Ústart_profilesÚend_profilesr&  r'  r(  rø   rë   Úraysry  rz  s
             rL   Ú_intersection_profilesrƒ    s±   € ð '5°QÑ&7Ð%8€Hô ˜.¨,Ô7öá7‰FˆB�ô !$ B¨¤Ô,¡‘f�b˜"ˆ"ˆbŠ Ô,Ø7ð 	ó ô !$ D¨$¨q¨r¨(Ö 3Ñˆ	�9Ø�‰œœ_¨Y¸	ÓBÓCÕDð !4à‡O�O�L Ñ$Ô%Ø€Oùó 	-ùõs   ˜B
¯B½B
ÂB
c                óì   — 	 t        ||«      }|j                  j                  | j                  «      dk  r#t        ||j                  |j                   ¬«      }|S # t
        $ r t        | |«      cY S w xY w)a  Returns 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   )rv  r"  r  Ú
next_frames       rL   r9   r9   (  sj   € ð	2Ü& w°Ó7ˆ
ð �=‰=×Ñ˜UŸX™XÓ&¨Ò*Ü F¨z¯}©}À*Ç-Á-ÀÔPˆJØÐøÜò 2ä" 5¨&Ó1Ò1ð2ús   ‚AA ÁA3Á2A3c                ój  — t        j                  |«      }t        j                  | «      }g }g }t        «       }t        ||dd  «      D ]a  \  }}	|	|z
  }
 |||
|«      }t        |j	                  |«      «      }|j                  |«       |j                  |D �cg c]  }||
z   ‘Œ	 c}«       Œc ||fS c c}w )Nr:   )r   r¿   r   r{   Úpoints_to_wcsrÁ   )rÞ   Úsweeping_pathÚnext_ref_frameÚspathÚreference_profiler€  r�  Ú	ref_framer  Útargetr"  rh  ry   s                rL   Ú"_make_sweep_start_and_end_profilesr�  >  s¼   € ô
 �I‰I�mÓ$€EÜŸ	™	 'Ó*ÐØ€NØ€LÜ“€IÜ˜e U¨1¨2 YÖ/‰ˆ�Ø˜6‘/ˆÙ" 9¨g°vÓ>ˆ	Ü˜Y×4Ñ4Ð5FÓGÓHˆØ×Ñ˜mÔ,Ø×Ñ±-Ó@±-¨Q˜Q ›[°-Ñ@ÕAð 0ð ˜<Ð'Ð'ùò As   ÂB0
c                ó0   — t        t        | |t        «      Ž S )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!   € ô "Ü	+Ø�]Ô$=ó

ðð rc   c                ó¦   — |rt        | «      } g }t        t        | |t        «      Ž D ]'  \  }}|j	                  |«       |j	                  |«       Œ) |S r¯   )r&   r{   r�  r9   rÁ   )rÞ   r‰  rF   r&  ÚspÚeps         rL   Údebug_sweep_profilesr•  g  sZ   € ñ
 Ü Ó(ˆØ%'€HÜÜ	+Ø�]Ô$=ó

ó‰ˆˆBð
 	�‰˜ÔØ�‰˜Õðð €Orc   c               ó8   — t        | |«      }t        ||||¬«      S )ae  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 mÓ4€HÜØØØØô	ð rc   )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)r`   r=   r  útuple[Vec3, Vec3, Vec3, Vec3])r\   r\   F)re   r=   rf   r=   r  r™  )r\   ç      >@)r`   r=   rj   r=   r  ztuple[Vec3, Vec3, Vec3])r\   rš  g     €F@)r`   r=   rj   r=   rn   r=   r  r™  )NNr<   r<   F)rC   rN   rY   úOptional[float]rD   r›  rv   r=   rE   r=   rF   r—  r  r˜  )r<   r<   F)rC   rN   r|   r=   r}   r=   rv   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¤   Ústrrj   r=   r  zIterator[Vec2])©r   r   r   )r©   úIterable[UVec]rª   r   r  r˜  )r<   T)r©   rž  rj   r=   r¶   r—  r  r˜  ))r\   r\   r\   )r©   rž  r  r˜  )r[  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)ra   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   )rq   ÚchordrŽ   )
r©   rž  r*  rN   r+  rœ  r-  rN   r  rŸ  )rŽ   )r&  r£  r-  rN   r  zIterable[list[Vec3]])r&  r£  r-  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ž  rj   r=   r?  r   r  r   )rÃ   rA  r:   )rC   rN   rQ  rN   rD   r=   r  r   )
r^  rN   r_  rN   rb  r=   rc  r=   r  r   )rh  rŸ  ri  rŸ  rk  r—  r  úIterator[Sequence[Vec3]])rh  r¡  ri  r¡  r  r¥  )r"  r   r  r   r  r   )rv  r   r  r   r  r   )ry  r£  rz  r£  r  r   )r€  r£  r�  r£  r  úlist[Sequence[Vec3]])rv  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   rl  rÜ   r	  r7   r8   r~  rƒ  r9   r�  r‘  r•  r+   rŒ   rc   rL   Ú<module>r­     s°  ðõ #ß CÕ CÛ Ý ÷÷ ÷ ó ÷ @ò#€ðN HMð)Øð)Øð)Ø.3ð)Ø@Dð)àó)ðB ØØØ—x‘xØð%@Øð%@àð%@ð 	ð%@ð ð	%@ð
 ð%@ð ð%@ð ó%@ð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Ø%*ð9Ø7;ð9àó9ô(1ð" GLð	Øð	Ø',ð	Ø>Cð	àó	ð  Øð)Øð)àð)ð ð)ð ð	)ð ó)ñB 	ˆˆAˆqƒMÙˆˆAˆqƒMÙˆˆAˆqƒMÙˆˆAˆqƒMÙˆˆAˆqƒMÙˆˆAˆqƒMÙˆˆAˆqƒMÙˆˆAˆqƒMð	€ñ 	ˆˆt�TÓÙˆˆt�TÓÙˆˆt�TÓÙˆˆt�TÓÙˆˆt�TÓÙˆˆt�TÓÙˆˆt�TÓÙˆˆt�TÓð	€ò ÚÚÚÚÚð€
ôð$ EJð#.Øð#.Ø#1ð#.àó#.óLóð& ØØØ
Ø	Ø
ñP.ØðP.à
ðP.ð ð	P.ð
 ðP.ð ðP.ð óP.ðh ØØ"&Ø ð	!ð 
ñ!Øð!àð!ð  ð!ð ð	!ð ó!ðJ ØØ!Ø ð	%ð 
ñ%Øð%àð%ð ð%ð ð	%ð ó%ðV Ø
Ø	ñ.Ø&ð.ð ó.ðB ØØð	NØðNàðNð ðNð ð	Nð
 óNð6 :;ð6Ø&ð6Ø36ð6àó6ð< ðð Ø
Ø	ñØ&ðàðð óðF ØØð.ð
 
ñ.Øð.àð.ð ð.ð ó.ð: ØØ!Øð	%ð 
ñ%Øð%àð%ð ð%ð ð	%ð ó%ðV —8‘8Øð	"ð 
ñ"Øð"àð"ð ð"ð ð	"ð ó"ðL 78ðG.ØBFñG.ØðG.Ø ðG.Ø.3ðG.àóG.ðV ØØØØØ—x‘xð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 ðØðà!ðð ó	ð, Ø
Ø	ñ!Øð!à!ð!ð ô!rc   