
    TiV                     *   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 dd	lmZmZmZ dd
lmZmZ  ee          ZdedefdZd dZd dZd Zd Zd Ze G d d                      Z	 d!defdZd Zd Zd dZd"dZ d Z!d#dZ"d Z#d Z$dS )$z`
triangles.py
-------------

Functions for dealing with triangle soups in (n, 3, 3) float form.
    )	dataclass)	getLoggerN   )util)tol)point_plane_distance)NDArrayOptionalfloat64)diagonal_dotunitize	trianglesreturnc                    | ddddddf         | ddddddf         z
  }| j         d         dk    r)t          j        |dddf         |dddf                   S | j         d         dk    rK|dddf         }|dddf         }|dddf         |dddf         z  |dddf         |dddf         z  z
  S t          | j                   )a  
    Returns the cross product of two edges from input triangles

    Parameters
    --------------
    triangles: (n, 3, 3) float
      Vertices of triangles

    Returns
    --------------
    crosses : (n, 3) float
      Cross product of two edge vectors
    Nr         r   )shapenpcross
ValueError)r   vectorsabs       K/DATA/AppData/hermes/venv/lib/python3.11/site-packages/trimesh/triangles.pyr   r      s    122qqq!Iaaa!QQQh$77GqQx1wqqq!t}555		q	 	 AAAqDMAAAqDMAw111a4 1QQQT7Qqqq!tW#444
Y_
%
%%    c                    |-t          t          j        | t          j                            }t	          |j                  dk    rt          j        |          dz  S t          j        |dz                      d                    dz  S )a  
    Calculates the sum area of input triangles

    Parameters
    ----------
    triangles : (n, 3, 3) float
      Vertices of triangles
    crosses : (n, 3) float or None
      As a speedup don't re- compute cross products
    sum : bool
      Return summed area or individual triangle area

    Returns
    ----------
    area : (n,) float or float
      Individual or summed area depending on `sum` argument
    Ndtyper   g       @r   axis)	r   r   
asanyarrayr   lenr   abssqrtsum)r   crossess     r   arear'   0   sy    $ irzBBBCC
7=Qvg$$7GQJ###++,,s22r   c                 Z   | t          j        | t           j                  } | j        d         dk    rPt          j        g d| j        d         df          }t          j        t          |           t                    }||fS |t          |           }t          |d	          \  }}||fS )
aV  
    Calculates the normals of input triangles

    Parameters
    ------------
    triangles : (n, 3, 3) float
      Vertex positions
    crosses : (n, 3) float
      Cross products of edge vectors

    Returns
    ------------
    normals : (m, 3) float
      Normal vectors
    valid : (n,) bool
      Was the face nonzero area or not
    Nr   r   )        r*         ?r   r   T)check_valid)
r   r!   r   r   tileonesr"   boolr   r   )r   r&   unitvalids       r   normalsr2   J   s    $ M)2:>>>	?2!##7???Y_Q-?,CDDDGC	NN$777E;	""'t444KD%;r   c                 .   t          j        | t           j                  } t          | dddf         | dddf         z
            }t          | dddf         | dddf         z
            }t          | dddf         | dddf         z
            }t          j        t          |           dft           j                  }t          j        t          j        t          ||          dd                    |dddf<   t          j        t          j        t          | |          dd                    |dddf<   t           j	        |dddf         z
  |dddf         z
  |dddf<   d||t          j        k                         d	          ddf<   |S )
a   
    Calculates the angles of input triangles.

    Parameters
    ------------
    triangles : (n, 3, 3) float
      Vertex positions

    Returns
    ------------
    angles : (n, 3) float
      Angles at vertex positions in radians
      Degenerate angles will be returned as zero
    r   Nr   r   r   r   r)   r*   r   )r   r!   r   r   zerosr"   arccosclipr   pir   mergeany)r   uvwresults        r   anglesr>   j   s     irz:::I 		!!!Q$)AAAqD/122A	!!!Q$)AAAqD/122A	!!!Q$)AAAqD/122A Xs9~~q)<<<F9RW\!Q%7%7Q??@@F111a4L9RW\1"a%8%8"a@@AAF111a4L56!!!Q$<'&A,6F111a4L 36FFSY###++QQQ./Mr   c                    t          j        | t           j                  } t          j        | d          st          d          t          |           d         }| d         d         }t          | dd                             d          ||          }t          j	        t          j
        |          t          j        k               }|S )	a   
    Check to see if a list of triangles are all coplanar

    Parameters
    ----------------
    triangles: (n, 3, 3) float
      Vertices of triangles

    Returns
    ---------------
    all_coplanar : bool
      True if all triangles are coplanar
    r   r)   r   r   Triangles must be (n, 3, 3)!r   r   Nr)   r   pointsplane_normalplane_origin)r   r!   r   r   is_shaper   r2   r   reshapeallr#   r   zero)r   test_normaltest_vertex	distancesall_coplanars        r   rN   rN      s     irz:::I=J// 97888)$$Q'KA,q/K$}$$W--    I
 6"&++ch677Lr   c           	         t          j        | t           j                  } t          j        | d          st          d          t          |           d         }| d         d         }t          | dd                             d          ||          }t          j	        t          j
        t          j        |                    d          t          j        k               d	                    }|S )
z
    For a list of triangles if the FIRST triangle is coplanar
    with ANY of the following triangles, return True.
    Otherwise, return False.
    r   r@   rA   r   r   NrB   rC   r   )r   r!   r   r   rG   r   r2   r   rH   r9   rI   r#   r   rJ   )r   rK   rL   rM   any_coplanars        r   rP   rP      s     irz:::I=J// 97888)$$Q'KA,q/K$}$$W--    I
 6"&	(9(9'(B(BSX(M!N!NUVWWWXXLr   c                   v    e Zd ZU eed<   eed<   eed<   ee         ed<   dZeee                  ed<   de	fdZ
dS )	MassPropertiesdensitymassvolumecenter_massNinertiaitemc                 "    t          | |          S N)getattr)selfrX   s     r   __getitem__zMassProperties.__getitem__   s    tT"""r   )__name__
__module____qualname__float__annotations__r	   r   rW   r
   strr]    r   r   rR   rR      s          NNN KKK MMM !!!! +/GXgg&'...# # # # # # #r   rR   Fc                 	   t          j        | t           j                  } t          j        | d          st          d          |t          |           }|d}| dddddf         | dddddf         z   | dddddf         z   }| dddddf         dz  | dddddf         dz  z   | dddddf         | dddddf         z  z   | dddddf         |z  z   }| dddddf         d	z  | dddddf         dz  | dddddf         z  z   | dddddf         | dddddf         dz  z  z   | dddddf         d	z  z   | dddddf         |z  z   }|| dddddf         |z   | dddddf         z  z   }|| dddddf         |z   | dddddf         z  z   }	|| dddddf         |z   | dddddf         z  z   }
t          j        d
t          |          f          }|dddf         |dddf         z  |d<   ||z  j	        |dd<   ||z  j	        |dd<   t          d	          D ]}}t          j        |dz   d	          }|dd|f         | ddd|f         |dd|f         z  | ddd|f         |	dd|f         z  z   | ddd|f         |
dd|f         z  z   z  ||dz   <   ~|                    d          t          j        g dt           j                  z  }|d         }|It          j        |          t          j        k     rt"                              d           |dd         |z  }t'          |||z  ||          }|r|S t          j        d          }|d         |d         z   ||ddg         dz                                  z  z
  |d<   |d         |d         z   ||ddg         dz                                  z  z
  |d<   |d         |d         z   ||ddg         dz                                  z  z
  |d<   |d         |t          j        |ddg                   z  z
   |d<   |d         |t          j        |ddg                   z  z
   |d<   |d         |t          j        |ddg                   z  z
   |d<   |d         |d<   |d         |d<   |d         |d<   ||z  |_        |S )aL  
    Calculate the mass properties of a group of triangles.

    Implemented from:
    http://www.geometrictools.com/Documentation/PolyhedralMassProperties.pdf

    Parameters
    ----------
    triangles : (n, 3, 3) float
      Triangle vertices in space
    crosses : (n,) float
      Optional cross products of triangles
    density : float
      Optional override for density
    center_mass :  (3,) float
      Optional override for center mass
    skip_inertia : bool
      if True will not return moments matrix

    Returns
    ---------
    info : dict
      Mass properties
    r   r@   rA   Nr+   r   r   r   r   
         r   )
      rj   rj   <   rk   rk   x   rl   rl   z@volume is negative center of mass is almost certain to be wrong!)rS   rT   rU   rV   )r   r      ri   )r   r   )r   r   )r   r   )r   r      )r   r   	   )r   r   )r   r   )r   r   )r   r   )r   r!   r   r   rG   r   r   r4   r"   Trangemodr%   arrayr#   r   rJ   logdebugrR   prodrW   )r   r&   rS   rV   skip_inertiaf1f2f3g0g1g2integrali
triangle_i
integratedrU   r=   rW   s                     r   mass_propertiesr      s-   6 irz:::I=J// 97888	"" 
111a7	i1aaa0	09QQQ111W3E	EB 	!!!Q'a
AAAq!!!G

!	"
AAAq!!!G
yAqqq1
1	2 AAAq!!!G
r
!	"  
111a7	q	 QQQ111W"yAqqq'9
:	;QQQ111W)AAAq!!!G"4"9
:	; QQQ111W"	$ QQQ111W"		$  
yAqqq!B&)AAAq!!!G*<<	<B	yAqqq!B&)AAAq!!!G*<<	<B	yAqqq!B&)AAAq!!!G*<<	<BxSWW&&H!!!Q$-"QQQT(*HQKr\$HQqSMr\$HQqSM1XX 
 
VAE1%%
!!!!Q$-qqq!Z'(2aaad83Az)*R1X57Az)*R1X57
Q 1%%222"*) ) ) J ]F 6&>>CH$$IIXYYY 1o.v	  F  hvG1
1%;1v3F!3K2P2P2R2R)RS DM 	1
1%;1v3F!3K2P2P2R2R)RS DM 	1
1%;1v3F!3K2P2P2R2R)RS DM !mvQF8K0L0L'LMNGDM mvQF8K0L0L'LMNGDM mvQF8K0L0L'LMNGDMDMGDMDMGDMDMGDMw&FNMr   c                    t          j        | t           j                  } t          j        | dd          st          d| j                  t          j        |t           j                  }t          |           \  }}|j        dk    rt          j        ||          }nt          |||                   }t          j
        t          |           t                    }|dk    ||<   |S )a^  
    Given a list of triangles and a list of normals determine if the
    two are aligned

    Parameters
    ----------
    triangles : (n, 3, 3) float
      Vertex locations in space
    normals_compare : (n, 3) float
      List of normals to compare

    Returns
    ----------
    aligned : (n,) bool
      Are normals aligned with triangles
    r   r@   T)allow_zerosz)triangles must have shape (n, 3, 3), got )r   r*   )r   r!   r   r   rG   r   r   r2   dotr   r4   r"   r/   )r   normals_compare
calculatedr1   
differencealigneds         r   windings_alignedr   O  s    " irz:::I=JDAAA ZXY_XXYYYmO2:FFFO	**J$$VJ88

 "*oe.DEE
hs9~~T222G#%GENNr   c                 2   t          j        | t           j                  } t          j        | d          st          d          t          j        |                     d          |                     d          f          }t          j	        |          }|S )a  
    Given a list of triangles, create an r-tree for broad- phase
    collision detection

    Parameters
    ---------
    triangles : (n, 3, 3) float
      Triangles in space

    Returns
    ---------
    tree : rtree.Rtree
      One node per triangle
    r   )r)   r   )r   r   rA   r   r   )
r   r!   r   r   rG   r   column_stackminmaxbounds_tree)r   triangle_boundstrees      r   r   r   s  s     irz:::I=O44 97888 oy}}!}'<'<immQRm>S>S&TUUOO,,DKr   c                     t          j        | t           j                  } t          j        | d          st          d          |t          j        }t          | |          |k    	                    d          }|S )a  
    Find all triangles which have an oriented bounding box
    where both of the two sides is larger than a specified height.

    Degenerate triangles can be when:
    1) Two of the three vertices are colocated
    2) All three vertices are unique but colinear


    Parameters
    ----------
    triangles : (n, 3, 3) float
      Triangles in space
    height : float
      Minimum edge length of a triangle to keep

    Returns
    ----------
    nondegenerate : (n,) bool
      True if a triangle meets required minimum height
    r   r@   rA   N)r   areasr   r   )
r   r!   r   r   rG   r   r   r8   extentsrI   )r   r   heightoks       r   nondegenerater     sx    , irz:::I=J// 97888~ IU
3
3
3f
<	A	Aq	A	I	IBIr   c                    t          j        | t           j                  } t          j        | d          st          d          |t          |           }| dddf         | dddf         z
  }| dddf         | dddf         z
  }|dz                      d	          d
z  }|dz                      d	          d
z  }|t          j	        k    }|t          j	        k    }t          j
        t          |           dft           j                  }||         dz  ||         z  |dddf         |<   ||         dz  ||         z  |dddf         |<   |S )a@  
    Return the 2D bounding box size of each triangle.

    Parameters
    ----------
    triangles : (n, 3, 3) float
      Triangles in space
    areas : (n,) float
      Optional area of input triangles

    Returns
    ----------
    box :  (n, 2) float
      The size of each triangle's 2D oriented bounding box
    r   r@   rA   N)r   r   r   r   r   g      ?)r   r!   r   r   rG   r   r'   r%   r   r8   r4   r"   )	r   r   r   r   length_alength_b	nonzero_a	nonzero_bboxs	            r   r   r     sh     irz:::I=J// 97888}y))) 	!!!Q$)AAAqD/)A!!!Q$)AAAqD/)A 1zzqz!!S(H1zzqz!!S(H 39$I39$I
 (C	NNA&bj
9
9
9C!),q0HY4GGC1Ii!),q0HY4GGC1IiJr   c                 6   t          j        |t           j                  }t          j        | t           j                  } ||                    d                              d          z  }| |                    d          z                      d          }|S )aG  
    Convert a list of barycentric coordinates on a list of triangles
    to cartesian points.

    Parameters
    ------------
    triangles : (n, 3, 3) float
      Triangles in space
    barycentric : (n, 2) float
      Barycentric coordinates

    Returns
    -----------
    points : (m, 3) float
      Points in space
    r   r   r   r)   r   )r)   r   r   )r   rs   r   r!   r%   rH   )r   barycentricrD   s      r   barycentric_to_pointsr     s    " (;bj999Kirz:::I ;???**227;;;K+--j999>>A>FFFMr   cramerc                 j     fd} fd}t          j         t           j                   t          j        |t           j                  }t           j                  dk    rt          d           j        d         }t          |j                  dk    s-|j        d         |k    s|j        d          j        d         k    rt          d	           d
d
dd
f          d
d
d
df         z
  | d
d
df                             d|f          z
  |dk    r
 |            S  |            S )a;  
    Find the barycentric coordinates of points relative to triangles.

    The Cramer's rule solution implements:
        http://blackpawn.com/texts/pointinpoly

    The cross product solution implements:
        https://www.cs.ubc.ca/~heidrich/Papers/JGT.05.pdf


    Parameters
    -----------
    triangles : (n, 3, 2 | 3) float
      Triangles vertices in space
    points : (n, 2 | 3) float
      Point in space associated with a triangle
    method :  str
      Which method to compute the barycentric coordinates with:
        - 'cross': uses a method using cross products, roughly 2x slower but
                  different numerical robustness properties
        - anything else: uses a cramer's rule solution

    Returns
    -----------
    barycentric : (n, 3) float
      Barycentric coordinates of each point
    c                     t          j        d d df         d d df                   } t          | |           }t          j        t	                    dft           j                  }t          t          j        d d df                   |           |z  |d d df<   t          t          j        d d df                   |           |z  |d d df<   d|d d df         z
  |d d df         z
  |d d df<   |S )Nr   r   r   r   r   )r   r   r   r4   r"   r   )ndenominatorr   edge_vectorsr   r<   s      r   method_crossz+points_to_barycentric.<locals>.method_cross  s   H\!!!Q$'aaad);<<"1a((hI2"*EEE(,qqq!t2Da)H)H!LL{ZAAAqD(!\!!!Q$5G)H)H!LL{ZAAAqDAAAqD 11K14EEAAAqDr   c                  \   t          d d df         d d df                   } t          d d df         d d df                   }t          d d df         	          }t          d d df         d d df                   }t          d d df         	          }d| |z  ||z  z
  z  }t          j        t                    dft          j                  }| |z  ||z  z
  |z  |d d df<   ||z  ||z  z
  |z  |d d df<   d|d d df         z
  |d d df         z
  |d d df<   |S )Nr   r   r+   r   r   r   )r   r   r4   r"   r   )
dot00dot01dot02dot11dot12inverse_denominatorr   r   r   r<   s
          r   method_cramerz,points_to_barycentric.<locals>.method_cramer  su   \!!!Q$/aaad1CDD\!!!Q$/aaad1CDD\!!!Q$/33\!!!Q$/aaad1CDD\!!!Q$/33!UU]UU]%BChI2"*EEE"U]UU]:>QQAAAqD"U]UU]:>QQAAAqDAAAqD 11K14EEAAAqDr   r   r   triangles shape incorrectr   r   r   z$triangles and points must correspondNr)   r   )r   r!   r   r"   r   r   rH   )r   rD   methodr   r   dimr   r<   s   `     @@r   points_to_barycentricr     sq   :              irz:::I]6444F 9?q  4555 /!
CFLQ<?c!!<?ioa000?@@@QQQU#i2A2&66L111a4(("c333A|~~=??r   c                 	   t          j        | t           j                  } t          j        |t           j                  }t          j        | d          st          d          t          j        |t          |           df          st          d          t          j        |          }t          j        t          |          t                    }g d}| dddddf         }| ddd	ddf         }| ddd
ddf         }||z
  }||z
  }	||z
  }
t          j
        ||
z  |          }t          j
        |	|
z  |          }t          j        |t          j        k     |t          j        k               }t          |          r||         ||<   d||<   ||z
  }t          j
        ||z  |          }t          j
        |	|z  |          }|t          j         k    ||k    z  |z  }t          |          r||         ||<   d||<   ||z  ||z  z
  }|t          j        k     |t          j         k    z  |t          j        k     z  |z  }t          |          rI||         ||         ||         z
  z                      d          }||         |||         z  z   ||<   d||<   ||z
  }t          j
        ||z  |          }t          j
        |	|z  |          }|t          j         k    ||k    z  |z  }t          |          r||         ||<   d||<   ||z  ||z  z
  }|t          j        k     |t          j         k    z  |t          j        k     z  |z  }t          |          rI||         ||         ||         z
  z                      d          }||         ||	|         z  z   ||<   d||<   ||z  ||z  z
  }|t          j        k     ||z
  t          j         k    z  ||z
  t          j         k    z  |z  }t          |          r`||         ||         z
  }||||         ||         z
  z   z                      d          }||         |||         ||         z
  z  z   ||<   d||<   t          |          r|d||         ||         z   ||         z   z  }||         |z                      d          }||         |z                      d          }||         ||         |z  z   |	|         |z  z   ||<   |S )a  
    Return the closest point on the surface of each triangle for a
    list of corresponding points.

    Implements the method from "Real Time Collision Detection" and
    use the same variable names as "ClosestPtPointTriangle" to avoid
    being any more confusing.


    Parameters
    ----------
    triangles : (n, 3, 3) float
      Triangle vertices in space
    points : (n, 3) float
      Points in space

    Returns
    ----------
    closest : (n, 3) float
      Point on each triangle closest to each point
    r   r@   r   r   z)need same number of triangles and points!)r+   r+   r+   Nr   r   r   Fr   r+   )r   r!   r   r   rG   r   r"   
zeros_liker.   r/   r   logical_andr   rJ   r9   rH   ) r   rD   r=   remainr.   r   r   cabacapd1d2is_abpd3d4is_bvcis_abr;   cpd5d6is_cvbis_acr<   vais_bcd43denoms                                    r   closest_pointr   G  s   0 irz:::I]6444F=J// 64555=#i..!!455 FDEEE ]6""FWS[[---F ??D 	!!!Q'A!!!Q'A!!!Q'A 
QB	
QB	!B 
R		B	R		B >"sx-ch77D
4yy wtt 
!B	R		B	R		B #(NrRx(61D
4yy wtt r'b2g	B#(]rSXI~."sx-@6IE
5zz Y"U)bi/099'BB%A5	M2uu 
!B	R		B	R		B#(NrRx(61D
4yy wtt r'b2g	B#(]rSXI~."sx-@6IE
5zz Y"U)bi/099'BB%1r%y=0uu r'b2g	B#(]RCH945"r'chY9NORXXE
5zz i"U)#C2e9r%y012;;GDD%1%1U8(;#<<uu 6{{ Ir&zBvJ.F;<Z%((11Z%((116bj1n5FaHvMr   c                 *   t          j        | t           j                  } t          j        | d          st          d          |                     d          }t          j        t          |                                        d          }||d}|S )a  
    Convert a list of triangles to the kwargs for the Trimesh
    constructor.

    Parameters
    ---------
    triangles : (n, 3, 3) float
      Triangles in space

    Returns
    ---------
    kwargs : dict
      Keyword arguments for the trimesh.Trimesh constructor
      Includes keys 'vertices' and 'faces'

    Examples
    ---------
    >>> mesh = trimesh.Trimesh(**trimesh.triangles.to_kwargs(triangles))
    r   r@   rA   rB   )verticesfaces)	r   r!   r   r   rG   r   rH   aranger"   )r   r   r   kwargss       r   	to_kwargsr     s    ( irz:::I=J// 97888  ))HIc(mm$$,,W55E"U33FMr   )NN)NNNFrZ   )r   )%__doc__dataclassesr   loggingr   numpyr    r   	constantsr   rD   r   typedr	   r
   r   r   r   r^   rt   r   r'   r2   r>   rN   rP   rR   r   r   r   r   r   r   r   r   r   rd   r   r   <module>r      s5    " ! ! ! ! !                       ( ( ( ( ( ( - - - - - - - - - - ' ' ' ' ' ' ' 'i&W & & & & &43 3 3 34   @# # #L  :  * # # # # # # # #. KPs ss s s sl! ! !H  2! ! ! !H* * * *Z  6L L L L^s s sl    r   