
    Ti,X                     <   d Z ddlmZ ddlmZ ddlZddlmZ ddlm	Z	 dd	l
mZmZ dd
lmZmZ  ee          Z G d de	          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          ZdS )z
entities.py
--------------

Basic geometric primitives which only store references to
vertex indices rather than vertices themselves.
    )deepcopy)	getLoggerN   )util)ABC   )
arc_centerdiscretize_arc)discretize_bezierdiscretize_bsplinec                       e Zd Z	 ddZed             Zed             Zej        d             ZdefdZ	ed             Z
ed	             Zed
             Zed             ZddZd Zd Zd Zd Zd Zd Zd ZdS )EntityNc                     t          j        |t           j                  | _        ||| _        ||| _        || j                            |           i | _        || _	        || _
        d S Ndtype)np
asanyarrayint64pointsclosedlayermetadataupdate_cachecolorkwargs)selfr   r   r   r   r   r   s          O/DATA/AppData/hermes/venv/lib/python3.11/site-packages/trimesh/path/entities.py__init__zEntity.__init__   sm     mF"(;;; DKDJM  *** 
    c                 >    t          | d          si | _        | j        S )z
        Get any metadata about the entity.

        Returns
        ---------
        metadata : dict
          Bag of properties.
        	_metadata)hasattrr#   r   s    r   r   zEntity.metadata,   s%     t[)) 	 DN~r!   c                 6    | j                             d          S )z
        Set the layer the entity resides on as a shortcut
        to putting it in the entity metadata.

        Returns
        ----------
        layer : any
          Hashable layer identifier.
        r   )r   getr%   s    r   r   zEntity.layer;   s     }  )))r!   c                     || j         d<   dS )z
        Set the current layer of the entity.

        Returns
        ----------
        layer : any
          Hashable layer indicator
        r   N)r   r   values     r   r   zEntity.layerH   s     "'gr!   returnc                 Z    | j         j        | j                                        | j        dS )z
        Returns a dictionary with all of the information
        about the entity.

        Returns
        -----------
        as_dict : dict
          Has keys 'type', 'points', 'closed'
        )typer   r   )	__class____name__r   tolistr   r%   s    r   to_dictzEntity.to_dictT   s1     N+k((**k
 
 	
r!   c                 j    t          | j                  dk    o| j        d         | j        d         k    S )z
        If the first point is the same as the end point
        the entity is closed

        Returns
        -----------
        closed : bool
          Is the entity closed or not?
        r   r   lenr   r%   s    r   r   zEntity.closedd   s/     4;!#IA$+b/(IIr!   c                     t          j        | j        | j        f                              d          dd                             d          S )aS  
        Returns an (n,2) list of nodes, or vertices on the path.
        Note that this generic class function assumes that all of the
        reference points are on the path which is true for lines and
        three point arcs.

        If you were to define another class where that wasn't the case
        (for example, the control points of a bezier curve),
        you would need to implement an entity- specific version of this
        function.

        The purpose of having a list of nodes is so that they can then be
        added as edges to a graph so we can use functions to check
        connectivity, extract paths, etc.

        The slicing on this function is essentially just tiling points
        so the first and last vertices aren't repeated. Example:

        self.points = [0,1,2]
        returns:      [[0,1], [1,2]]
        r3   r   r3   r   )r   column_stackr   reshaper%   s    r   nodeszEntity.nodesq   sE    0 OT[$+677??CCAbDIQQRYZZ	
r!   c                      | j         ddg         S )ax  
        Returns the first and last points. Also note that if you
        define a new entity class where the first and last vertices
        in self.points aren't the endpoints of the curve you need to
        implement this function for your class.

        Returns
        -------------
        ends : (2,) int
          Indices of the two end points of the entity
        r   r3   r   r%   s    r   
end_pointszEntity.end_points   s     {Ar7##r!   c                     dS )
        Is the current entity valid.

        Returns
        -----------
        valid : bool
          Is the current entity well formed
        T r%   s    r   is_validzEntity.is_valid   s	     tr!   r3   c                 2    |dk     r	d| _         dS d| _         dS )z
        Reverse the current entity in place.

        Parameters
        ----------------
        direction : int
          If positive will not touch direction
          If negative will reverse self.points
        r   r3   r   N)
_direction)r   	directions     r   reversezEntity.reverse   s#     q== DOOODOOOr!   c                 R    t          | d          r| j        dk     r|ddd         S |S )a1  
        Reverse a curve if a flag is set.

        Parameters
        --------------
        curve : (n, dimension) float
          Curve made up of line segments in space

        Returns
        ------------
        orient : (n, dimension) float
          Original curve, but possibly reversed
        rC   r   Nr3   )r$   rC   )r   curves     r   _orientzEntity._orient   s7     4&& 	4?Q+>+>2;r!   c                     t          j        || j                                     d          || j                                     d          g          }|S )a!  
        Return the AABB of the current entity.

        Parameters
        -----------
        vertices : (n, dimension) float
          Vertices in space

        Returns
        -----------
        bounds : (2, dimension) float
          Coordinates of AABB, in (min, max) form
        r   axis)r   arrayr   minmax)r   verticesboundss      r   rP   zEntity.bounds   sT     dk"&&A&..0E0I0Iq0I0Q0QR
 
 r!   c                     t          j        |                     |          d          dz  }t          j        |dg|j        d         z            dz                                  }|S )a  
        Return the total length of the entity.

        Parameters
        --------------
        vertices : (n, dimension) float
          Vertices in space

        Returns
        ---------
        length : float
          Total length of entity
        r   rJ   r   r   g      ?)r   diffdiscretedotshapesum)r   rO   rR   lengths       r   rW   zEntity.length   s^     wt}}X..Q7771<&sX^A%66773>CCEEr!   c                 ,    |                                  gS )z
        Split the entity into multiple entities.

        Returns
        ------------
        explode : list of Entity
          Current entity split into multiple entities.
        )copyr%   s    r   explodezEntity.explode   s     		}r!   c                 &   t          |           }t          | d          rEt          | j                  |_        t          |j                  t          | j                  k    sJ t          |j                  t          | j                  k    sJ |S )z
        Return a copy of the current entity.

        Returns
        ------------
        copied : Entity
          Copy of current entity
        r#   )r   r$   r#   idr   )r   copieds     r   rY   zEntity.copy   s     $4%% 	>'77Ff&''2dn+=+=====&-  Bt{OO3333r!   c                 D    t          |                                           S )z
        Return a hash that represents the current entity.

        Returns
        ----------
        hashed : int
            Hash of current class name, points, and closed
        )hash_bytesr%   s    r   __hash__zEntity.__hash__
  s     DKKMM"""r!   c                 0   | j         d         | j         d         k    r9| j        j                            d          | j                                         z   S | j        j                            d          | j         ddd                                         z   S )z
        Get hashable bytes that define the current entity.

        Returns
        ------------
        data : bytes
          Hashable data defining the current entity
        r   r3   utf-8N)r   r.   r/   encodetobytesr%   s    r   r`   zEntity._bytes  s~     ;q>DKO++>*11'::T[=P=P=R=RRR>*11'::T[2=N=V=V=X=XXXr!   )NNNN)r3   )r/   
__module____qualname__r    propertyr   r   setterdictr1   r   r:   r=   rA   rE   rH   rP   rW   rZ   rY   ra   r`   r@   r!   r   r   r      s       DH   *   X 
* 
* X
* \	' 	' \	'
 
 
 
 
  
J 
J X
J 
 
 X
4 $ $ X$ 	 	 X	         $  &  $	 	 	  $	# 	# 	#Y Y Y Y Yr!   r   c                   B   e Zd ZdZ	 	 	 	 	 	 	 ddZed             Zej        d             Zed             Zej        d             Zed             Z	e	j        d	             Z	ddZ
d Zd Zd Zed             Zed             Zed             Zed             Zd ZdS )Textz+
    Text to annotate a 2D or 3D path.
    Nc
                    || _         || _        || _        || _        ||| _        |	| j                            |	           || _        |ddg}n<t          |t                    r||g}n"t          |          dk    rt          d          || _        t          |d          r|                    d          | _        dS t          |          | _        dS )a  
        An entity for text labels.

        Parameters
        --------------
        origin : int
          Index of a single vertex for text origin
        text : str
          The text to label
        height : float or None
          The height of text
        vector : int or None
          An vertex index for which direction text
          is written along unitized: vector - origin
        normal : int or None
          A vertex index for the plane normal:
          vector is along unitized: normal - origin
        align : (2,) str or None
          Where to draw from for [horizontal, vertical]:
              'center', 'left', 'right'
        Ncenterr   zalign must be (2,) strdecoderc   )originvectornormalheightr   r   r   r   
isinstancestrr5   
ValueErroralignr$   ro   text)
r   rp   rx   rs   rq   rr   rw   r   r   r   s
             r   r    zText.__init__*  s    D DJM  *** 
 =x(EEs## 	7 ENEEZZ1__5666
 4"" 	"G,,DIIID		DIIIr!   c                     | j         d         S )z
        The origin point of the text.

        Returns
        -----------
        origin : int
          Index of vertices
        r   r<   r%   s    r   rp   zText.originq  s     {1~r!   c                     t          |          }t          | d          rt          j        | j                  dk    r*t          j        dt          j                  |z  | _        d S || j        d<   d S )Nr   r      r   )intr$   r   ptpr   onesr   r)   s     r   rp   zText.origin}  se    E

tX&& 	#"&*=*=*B*B'!28444u<DKKK"DKNNNr!   c                     | j         d         S )z
        A point representing the text direction
        along the vector: vertices[vector] - vertices[origin]

        Returns
        ----------
        vector : int
          Index of vertex
        r   r<   r%   s    r   rq   zText.vector       {1~r!   c                 <    |d S t          |          | j        d<   d S )Nr   r|   r   r)   s     r   rq   zText.vector  !    =FUAr!   c                     | j         d         S )z
        A point representing the plane normal along the
        vector: vertices[normal] - vertices[origin]

        Returns
        ------------
        normal : int
          Index of vertex
        r   r<   r%   s    r   rr   zText.normal  r   r!   c                 <    |d S t          |          | j        d<   d S )Nr   r   r)   s     r   rr   zText.normal  r   r!   Fc           	      >   |j         d         dk    rt          d          ddlm} t	          j        |                     |                    } |j        || j                 | j        || j	        d         | j	        d         dd |r|
                                 dS dS )z
        Plot the text using matplotlib.

        Parameters
        --------------
        vertices : (n, 2) float
          Vertices in space
        show : bool
          If True, call plt.show()
        r   r   zonly for 2D points!r   N   )srotationhavasize)rU   rv   matplotlib.pyplotpyplotr   degreesanglerx   rp   rw   show)r   rO   r   pltr   s        r   plotz	Text.plot  s     >!!!2333'''''' 
4::h//00 	dk"iz!}z!}	
 	
 	
 	
  	HHJJJJJ	 	r!   c                     |j         d         dk    rt          d          || j                 || j                 z
  }t	          j        |ddd          }|S )a  
        If Text is 2D, get the rotation angle in radians.

        Parameters
        -----------
        vertices : (n, 2) float
          Vertices in space referenced by self.points

        Returns
        ---------
        angle : float
          Rotation angle in radians
        r   r   zangle only valid for 2D points!Nr3   )rU   rv   rq   rp   r   arctan2)r   rO   rD   r   s       r   r   z
Text.angle  sZ     >!!!>??? T[)HT[,AA	
IdddO,r!   c                     dS )Ng        r@   )r   rO   s     r   rW   zText.length  s    sr!   c                 *    t          j        g           S Nr   rL   )r   argsr   s      r   rS   zText.discrete  s    x||r!   c                     dS )NFr@   r%   s    r   r   zText.closed  s    ur!   c                     dS )NTr@   r%   s    r   rA   zText.is_valid  s    tr!   c                 *    t          j        g           S r   r   r%   s    r   r:   z
Text.nodes      x||r!   c                 *    t          j        g           S r   r   r%   s    r   r=   zText.end_points  r   r!   c                     d                     d| j                                        | j                            d          g          }|S )Nr!   s   Textrc   )joinr   re   rx   rd   )r   datas     r   r`   zText._bytes  s=    xx$+"5"5"7"79I9I'9R9RSTTr!   )NNNNNNN)F)r/   rf   rg   __doc__r    rh   rp   ri   rq   rr   r   r   rW   rS   r   rA   r:   r=   r`   r@   r!   r   rl   rl   %  s         E" E" E" E"N 	 	 X	 ]# # ]# 
 
 X
 ]$ $ ]$
 
 
 X
 ]$ $ ]$
   @  2       X   X   X   X    r!   rl   c                       e Zd ZdZddZed             Zej        defd            Zed             Z	d Z
d	 Zd
efdZdS )Linez$
    A line or poly-line entity
          ?c                 B    |                      || j                           S )ap  
        Discretize into a world- space path.

        Parameters
        ------------
        vertices: (n, dimension) float
          Points in space
        scale : float
          Size of overall scene for numerical comparisons

        Returns
        -------------
        discrete: (m, dimension) float
          Path in space composed of line segments
        )rH   r   r   rO   scales      r   rS   zLine.discrete  s      ||HT[1222r!   c                 j    t          | j                  dk    o| j        d         | j        d         k    S Nr   r   r3   r4   r%   s    r   r   zLine.closed  s-    4;!#IA$+b/(IIr!   r*   c                     | j         d         | j         d         k    }|r0|s.t          j        | j         | j         d         gf          | _         d S |s|rt                              d           d S d S d S )Nr   r3   zignoring `Line.closed = False`)r   r   concatenatelogdebug)r   r*   currents      r   r   zLine.closed  s    +a.DKO3 	8 	8 .$+A7G)HIIDKKK 	87 	8II677777	8 	8 	8 	8r!   c                 \    t          j        | j        | j        d         z
  dk              }|S )r?   r   )r   anyr   )r   valids     r   rA   zLine.is_valid%  s*     dk!n4:;;r!   c                     | j         t          j        | j        | j        f                                          dd                             d          }fd|D             }|S )z
        If the current Line entity consists of multiple line
        break it up into n Line entities.

        Returns
        ----------
        exploded: (n,) Line entities
        r   r3   r7   c                 2    g | ]}t          |           S ))r   )r   ).0ir   s     r   
<listcomp>z Line.explode.<locals>.<listcomp>@  s&    999QD%(((999r!   )r   r   r8   r   ravelr9   )r   r   explodedr   s      @r   rZ   zLine.explode2  sj     
OT[$+677==??"EMMgVV 	 :999&999r!   c                     | j         d         | j         d         k    rd| j                                         z   S d| j         d d d                                         z   S )Nr   r3   s   Line)r   re   r%   s    r   r`   zLine._bytesC  sV    ;q>DKO++T[002222T[2.668888r!   r+   c                 N    | j         j        | j                                        dS )a  
        Returns a dictionary with all of the information
        about the Line. `closed` is not additional information
        for a Line like it is for Arc where the value determines
        if it is a partial or complete circle. Rather it is a check
        which indicates the first and last points are identical,
        and thus should not be included in the export

        Returns
        -----------
        as_dict
          Has keys 'type', 'points'
        )r-   r   )r.   r/   r   r0   r%   s    r   r1   zLine.to_dictJ  s,     N+k((**
 
 	
r!   Nr   )r/   rf   rg   r   rS   rh   r   ri   boolrA   rZ   r`   rj   r1   r@   r!   r   r   r     s         3 3 3 3$ J J XJ ]8D 8 8 8 ]8 
 
 X
  "9 9 9
 
 
 
 
 
 
r!   r   c                   z    e Zd Zed             Zej        d             Zed             Zd Zd ZddZ	d Z
d	 Zd
S )Arcc                 $    t          | dd          S )z
        A boolean flag for whether the arc is closed (a circle) or not.

        Returns
        ----------
        closed : bool
          If set True, Arc will be a closed circle
        _closedF)getattrr%   s    r   r   z
Arc.closed_  s     tY...r!   c                 .    t          |          | _        dS )z
        Set the Arc to be closed or not, without
        changing the control points

        Parameters
        ------------
        value : bool
          Should this Arc be a closed circle or not
        N)r   r   r)   s     r   r   z
Arc.closedk  s     E{{r!   c                 V    t          t          j        | j                            dk    S )z
        Is the current Arc entity valid.

        Returns
        -----------
        valid : bool
          Does the current Arc have exactly 3 control points
        r{   )r5   r   uniquer   r%   s    r   rA   zArc.is_validx  s#     29T[))**a//r!   c                     t          | j        d         | j        d         k              dz  dz
  }dt          | j                  z   | j        d d |                                         z   S )Nr   r3   r   r   s   Arc)r|   r   bytesr   re   )r   orders     r   r`   z
Arc._bytes  s]    DKNT[_4559A=dk***T[5-A-I-I-K-KKKr!   c                     | j         r/|                     |dd          }t          j        |j        z  dz  S |                     |dd          }|j        |j        z  dz  S )z
        Return the arc length of the 3-point arc.

        Parameter
        ----------
        vertices : (n, d) float
          Vertices for overall drawing.

        Returns
        -----------
        length : float
          Length of arc.
        Freturn_normalreturn_angle   Tr   )r   rn   r   piradiusspan)r   rO   fits      r   rW   z
Arc.length  sf     ; 	* ++he%+PPC53:%))kk(%dkKKx#*$q((r!   r   c                 l    |                      t          || j                 | j        |                    S )a~  
        Discretize the arc entity into line sections.

        Parameters
        ------------
        vertices : (n, dimension) float
            Points in space
        scale : float
            Size of overall scene for numerical comparisons

        Returns
        -------------
        discrete : (m, dimension) float
          Path in space made up of line segments
        )closer   )rH   r
   r   r   r   s      r   rS   zArc.discrete  s5    " ||8DK05QQQ
 
 	
r!   c                 2    t          || j                 fi |S )a  
        Return the center information about the arc entity.

        Parameters
        -------------
        vertices : (n, dimension) float
          Vertices in space

        Returns
        -------------
        info : dict
          With keys: 'radius', 'center'
        )r	   r   )r   rO   r   s      r   rn   z
Arc.center  s!     (4;/::6:::r!   c                    t          j        |d          r\| j        rU|                     |dd          }t	          j        |j        |j        z
  |j        |j        z   gt          j                  }n_|                     |          }t	          j        |	                    d          |
                    d          gt          j                  }|S )a  
        Return the AABB of the arc entity.

        Parameters
        -----------
        vertices: (n, dimension) float
          Vertices in space

        Returns
        -----------
        bounds : (2, dimension) float
          Coordinates of AABB in (min, max) form
        r7   Fr   r   r   rJ   )r   is_shaper   rn   r   rL   r   float64rS   rM   rN   )r   rO   inforP   rS   s        r   rP   z
Arc.bounds  s     =7++ 	 	 ;;xu5;QQDXt{*DK$+,EFbj  FF }}X..HX1%%x|||';';<BJ  F r!   Nr   )r/   rf   rg   rh   r   ri   rA   r`   rW   rS   rn   rP   r@   r!   r   r   r   ^  s        	/ 	/ X	/ ]
# 
# ]
# 	0 	0 X	0L L L
) ) )0
 
 
 
*; ; ;     r!   r   c                   (    e Zd ZdZed             ZdS )Curvez8
    The parent class for all wild curves in space.
    c                     | j         t          | j                   dz           }| j         d         |g|| j         d         ggS r   )r   r5   )r   mids     r   r:   zCurve.nodes  s@     k#dk**a/0Q%T[_'=>>r!   N)r/   rf   rg   r   rh   r:   r@   r!   r   r   r     s9          ? ? X? ? ?r!   r   c                       e Zd ZdZddZdS )Bezierz(
    An open or closed Bezier curve
    r   Nc                 b    |                      t          || j                 ||                    S )a  
        Discretize the Bezier curve.

        Parameters
        -------------
        vertices : (n, 2) or (n, 3) float
          Points in space
        scale : float
          Scale of overall drawings (for precision)
        count : int
          Number of segments to return

        Returns
        -------------
        discrete : (m, 2) or (m, 3) float
          Curve as line segments
        )countr   )rH   r   r   )r   rO   r   r   s       r   rS   zBezier.discrete  s3    $ ||ht{35NNN
 
 	
r!   )r   N)r/   rf   rg   r   rS   r@   r!   r   r   r     s2         
 
 
 
 
 
r!   r   c                   4    e Zd ZdZd	dZd
dZd ZdefdZdS )BSplinez&
    An open or closed B- Spline.
    Nc                    t          j        |t           j                  | _        t          j        |t           j                  | _        ||| _        || j                            |           i | _	        || _
        || _        d S r   )r   r   r   r   r   knotsr   r   r   r   r   r   )r   r   r   r   r   r   r   s          r   r    zBSpline.__init__  st    mF"(;;;]5
;;;
DJM  ***


r!   r   c                 r    t          || j                 | j        ||          }|                     |          S )a  
        Discretize the B-Spline curve.

        Parameters
        -------------
        vertices : (n, 2) or (n, 3) float
          Points in space
        scale : float
          Scale of overall drawings (for precision)
        count : int
          Number of segments to return

        Returns
        -------------
        discrete : (m, 2) or (m, 3) float
          Curve as line segments
        )controlr   r   r   )r   r   r   rH   )r   rO   r   r   rS   s        r   rS   zBSpline.discrete  s?    $ &T[)5PU
 
 
 ||H%%%r!   c                 6   | j         d         | j         d         k    r6d| j                                        z   | j                                         z   S d| j        d d d                                         z   | j         d d d                                         z   S )Nr   r3   s   BSpline)r   r   re   r%   s    r   r`   zBSpline._bytes5  s    ;q>DKO++
 2 2 4 44t{7J7J7L7LLL
44R4 0 8 8 : ::T[2=N=V=V=X=XXXr!   r+   c                     | j         j        | j                                        | j                                        | j        dS )z\
        Returns a dictionary with all of the information
        about the entity.
        )r-   r   r   r   )r.   r/   r   r0   r   r   r%   s    r   r1   zBSpline.to_dict<  sB     N+k((**Z&&((k	
 
 	
r!   )NNN)Nr   )	r/   rf   rg   r   r    rS   r`   rj   r1   r@   r!   r   r   r     ss         	 	 	 	& & & &.Y Y Y

 

 

 

 

 

 

r!   r   )r   rY   r   loggingr   numpyr    r   r   arcr	   r
   rG   r   r   r/   r   r   rl   r   r   r   r   r   r@   r!   r   <module>r      s                                 + + + + + + + + 8 8 8 8 8 8 8 8iLY LY LY LY LYS LY LY LY^W W W W W6 W W Wt\
 \
 \
 \
 \
6 \
 \
 \
~E E E E E& E E EP	? 	? 	? 	? 	?F 	? 	? 	?
 
 
 
 
U 
 
 
88
 8
 8
 8
 8
e 8
 8
 8
 8
 8
r!   