
    Og                       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;	 	 	 	 	 	 	 dd<Z?dd:dd=dej:                  fdd.	 	 	 	 	 	 	 	 	 dd>Z@	 	 	 	 	 	 	 	 dd?ZA	 	 	 	 	 	 dd@ZB	 	 	 	 	 	 ddAZCefddBZDefddCZE	 	 	 	 	 	 ddDZF	 	 	 	 	 	 ddEZGddFZH	 	 	 	 	 	 	 	 ddGZI	 	 	 	 	 	 ddHZJ	 di	 	 	 	 	 ddIZKdddd1	 	 	 	 	 ddJ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	            W/var/www/html/public_html/myphp/venv/lib/python3.12/site-packages/ezdxf/render/forms.pyr   r   >   s     $ 6]FHHuEEu HHUOf$HHUOf$1a##	 61i(( 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JE$3E
((C
((Cu @eem+3u:?CJOY??@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      sC     " 9-F$$VUQY7 *nnyn))*s   <>      ?c                    |r7| dz  }t        | |       t        ||       t        ||      t        | |      fS t        dd      t        | d      t        | |       t        d|       fS )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      sg    
 3JQB|T!aR[$q!*dA2qkAAAqz4a=$tT*:DDMII    c                    |r<| dz  }|dz  }t        | |       t        ||       t        ||      t        | |      fS t        dd      t        | d      t        | |      t        d|      fS )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syra   rb   bs        rL   r   r      so     HHQB|T!aR[$q!*dA2qkAAAqz4A;Rd1bk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     	eck*+d2Aq>41:tTEA2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 	eck*+d2Ad+,q0IdUAQ
dUQBdUY"	 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 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   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 qyEFF	SyBCC	SyBCCb8y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    < qy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99\C/+=>Ly  HHu|++u4DJEOOEE
((C
((C1u9 $EOO#u'=#F F#e*$fs5z&99EEOO#YEemm#%%Ee(((TMEe&&&%%E=E
5###OOE-$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" iikq6S=3x1}s12w'Vs]3x1}s12w'Vs]qr7==%DAqd58U1X..FLd))%s<<FL%s   C5C7c              #  >   K   t        |      }| D ]	  }||z     yw)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 Qh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      <aQ""5)<   $'c              3  R   K   | ]  }t        |      j                           y wr   )r   r$   r   s     rL   r   zrotate.<locals>.<genexpr>  s     8!Qu%8r   r   )r   rj   degs    ` rL   r$   r$     s     <8<<8x88rc   c              #     K   |\  }}}t        j                  |       D ]8  }t        |j                  |z  |j                  |z  |j                  |z         : yw)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   scalingre   rf   szry   s         rL   r%   r%     sR      JBB]]8$ 11338QSS2XqssRx001s   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:gbk7GLwqz"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53t9,-'!+, )5LDHHHHUOf$HHUOf$1a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"(nHMM8: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yy)()9:YYt_Nh/456 #K&qr* #)K7>NOs# 22OO*+;^L 	 DMM$	 )"# &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     s{    58tABx5HI62rr{{2IOI'LeGK 3r{\123 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     G9HdDH% 	B2g&&M!		&="89:E#+.D519% $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    us{c11 3;"[0#dhh/?&@@#dhh/?&@@c3L+sCmSMM;==+--	
  	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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$	 %	&
 l3B'(''--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@@ufD9:Lyz!F
STK	{#	 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
 	
 E6q!W5F5F.GdSD8FLL$9gF 	NN3::K	  8Fw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M!$77hx{+,/4+:ONh-  B"2r* 	 DMM$	   hrl#''-- 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&QF""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     (!s1v(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|$ O+34a544)-9MNO aMM}- 6/45ttM"556	 5
 6s   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4Xy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     sv    $ DveV489Kk;qr?3 &Br2tn%&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4j6!GK
 	
 vQ7+<+<$=DID8FLL$9gF 	NN3::K	  8Fw78r$  )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    & qy&&%L5 ET$Z/A '(1tAw(G(yH3u: !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+DHH\*Q.0F0JA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    HHUY&'&0+.T!Q'DAw4G
U#Fm 	4FA&B
B*Br2z23z2r23	4rc   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ZF6{aH((U6]*K%-'ID4O
4 
4 8)a-U+ xi!mX\: 0!A%
\*Z(XXi,./&8XXi*,-6v 	0A2r"BAr2&BAr2&B2r"Br2r2./G#L3$67HHY,*<=>G
 r2v./r2v./r2v./r2v./!	002 (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  s8   2 Q?,,Q?,,99U<01L99U<01Ld,--d,--|#788$txx/KDHH)$txx/	#K;J<<
DHH5Lk)J ;D9q!$
 	QSS!QSSN  T9GHA!((;/HHD"M1?@A188J'@K@Dh}-.; B*=+F 	 DMM$	 #5@Aqxx
+AA	B 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T3TT1)-EEE(DDD 	FDs!   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     s[      AG!nGmAB'QR9 Br2w&&s   24c              #  x   K   | d   }|d   }t        | dd  |dd        D ]  \  }}|||f |||f |}|} y wrL  rn  ro  s         rL   r	  r	    se      AG!nGmAB'QR9 B'7##r2o	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'GFCCrc   c                    	 t        t        j                  | j                        t        |      S # t        $ r2 t        | j
                  j                  t              t        |      cY S w xY w)zReference 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fll588,GG HehhnnV,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~    s|      )Y/ )
d$T40BA:Q%KaZQ%**RU##r(--Q(()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     '5Q&7%8H .,7 B !$B,fb""b,D  !$D$qr( 3 E	9_Y	BCDEOOL$%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
 ==UXX&*Fz}}*--PJ 2"5&112s   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    
 IIm$E		'*NLIeU12Y/ B6/"9gv>	Y445FGHm,-@QQ[@AB <'' 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  s_    
 (%'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 Wm4H	 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 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 ! 	, 
	!!!! !rc   