
    l0jT                        d 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 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.
    )	dataclassN   )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       T/home/wildlama/miniconda3/envs/lam/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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   r   axisg       @)r   r   
asanyarrayr
   sqrtsum)r   crossess     r   arear$   -   sQ    $ irzBBBCC7GQJ###++,,s22r   c                     | 5| j         d         dk    r$t          j        g d| j         d         d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   T)check_valid)r   r   tiler   r   )r   r#   unitvalids       r   normalsr-   D   so    $ !4!9!9w);Q(?@@@	""'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   zeroslenarccosclipr   pir   mergeany)r   uvwresults        r   anglesr:   _   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   r-   r   reshapeallabsr   zero)r   test_normaltest_vertex	distancesall_coplanars        r   rK   rK      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<   r=   r   r   Nr>   r?   r   )r   r    r
   r   rC   r   r-   r   rD   r5   rE   rF   r   rG   )r   rH   rI   rJ   any_coplanars        r   rM   rM      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                   p    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 Z	dS )MassPropertiesdensitymassvolumecenter_massNinertiac                 "    t          | |          S N)getattr)selfitems     r   __getitem__zMassProperties.__getitem__   s    tT"""r   )
__name__
__module____qualname__float__annotations__r   r
   rT   r	   rZ    r   r   rO   rO      su          NNN KKK MMM !!!! +/GXgg&'...# # # # #r   rO   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         }|Pt          j        |          t          j        k     r!t          j        d	t           j                  }n|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<   r=   Nr(   r   r   r   r   
         r   )
      rf   rf   <   rg   rg   x   rh   rh   )rP   rQ   rR   rS   )r   r      re   )r   r   )r   r   )r   r   )r   r      )r   r   	   )r   r   )r   r   )r   r   )r   r   )r   r    r
   r   rC   r   r   r/   r0   Trangemodr"   arrayrF   r   rG   rO   prodrT   )r   r#   rP   rS   skip_inertiaf1f2f3g0g1g2integrali
triangle_i
integratedrR   r9   rT   s                     r   mass_propertiesr|      s2   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$$(1BJ777KK %QqS/F2K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   rC   r   r   r-   dotr   r/   r0   bool)r   normals_compare
calculatedr,   
differencealigneds         r   windings_alignedr   D  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   )
r   r    r
   r   rC   r   column_stackminmaxbounds_tree)r   triangle_boundstrees      r   r   r   h  s     irz:::I=J// 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<   r=   N)r   areasr   r   )
r   r    r
   r   rC   r   r   r4   extentsrE   )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<   r=   N)r   r   r   r   r   g      ?)r   r    r
   r   rC   r   r$   r"   r   r4   r/   r0   )	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   ro   r
   r    r"   rD   )r   barycentricr@   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   r/   r0   r
   )ndenominatorr   edge_vectorsr   r8   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   r/   r0   r
   )
dot00dot01dot02dot11dot12inverse_denominatorr   r   r   r8   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
   r0   r   r   rD   )r   r@   methodr   r   dimr   r8   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   rC   r   r0   
zeros_likeonesr   r   logical_andr   rG   r5   rD   ) r   r@   r9   remainr   r   r   cabacapd1d2is_abpd3d4is_bvcis_abr7   cpd5d6is_cvbis_acr8   vais_bcd43denoms                                    r   closest_pointr   <  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<   r=   r>   )verticesfaces)	r   r    r
   r   rC   r   rD   aranger0   )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)NNNFrV   )r   )!__doc__dataclassesr   numpyr    r   	constantsr   r@   r   typedr   r	   r
   r   r   r   r$   r-   r:   rK   rM   rO   r|   r   r   r   r   r   r   r   r   r`   r   r   <module>r      s    " ! ! ! ! !                 ( ( ( ( ( ( - - - - - - - - - - ' ' ' ' ' ' ' '&W & & & & &43 3 3 3.   6# # #L  :  * # # # # # # # #. KPs ss s s sl! ! !H  2! ! ! !H* * * *Z  6L L L L^s s sl    r   