
    l0jJ                        d Z ddlZddlmZ ddlmZmZ ddlm	Z	 ddl
mZ ddl
mZ 	 dd	lmZ n## e$ rZdd
lmZ  ee          ZY dZ[ndZ[ww xY wd Zd Zd Zd Z G d d          Z G d d          Zd Z	 ddZddZdS )z<
proximity.py
---------------

Query mesh- point proximity.
    N   )util)log_timetol)	group_min)closest_point)points_to_barycentric)cKDTree)ExceptionWrapperc                    t          j        |t           j                  }t          j        |d          st          d          | j        t          | j        | j	                           }|
                    |          d                             d          }|t          j        z  }t          j        ||z
  ||z   f          }fd|D             }|S )an  
    For each point find nearby faces relatively quickly.

    The closest point on the mesh to the queried point is guaranteed to be
    on one of the faces listed.

    Does this by finding the nearest vertex on the mesh to each point, and
    then returns all the faces that intersect the axis aligned bounding box
    centered at the queried point and extending to the nearest vertex.

    Parameters
    ----------
    mesh : trimesh.Trimesh
      Mesh to query.
    points : (n, 3) float
       Points in space

    Returns
    -----------
    candidates : (points,) int
      Sequence of indexes for mesh.faces
    dtype   points must be (n,3)!r   )r   r   c                 T    g | ]$}t                              |                    %S  )listintersection).0brtrees     T/home/wildlama/miniconda3/envs/lam/lib/python3.11/site-packages/trimesh/proximity.py
<listcomp>z nearby_faces.<locals>.<listcomp>@   s/    >>>!$u))!,,-->>>    )np
asanyarrayfloat64r   is_shape
ValueErrortriangles_treer
   verticesreferenced_verticesqueryreshaper   mergecolumn_stack)meshpointskdtreedistance_vertexbounds
candidatesr   s         @r   nearby_facesr/      s    . ]6444F=)) 20111 ET]4#;<==F ll6**1-55g>>Osy O _f68PQRRF ?>>>v>>>Jr   c                    | j                             t          j                  t          j        |t          j                  }t          j        d          st          d          t          j        |d          st          d          t          j	        |dt                    f          }t          j        fd|D                       }d t          ||          D             }t          j        d	 |D                       }t          j        d
 t          ||          D                       }t          j        d t          ||          D                       dz  }|||fS )a]  
    Given a mesh and a list of points find the closest point
    on any triangle.

    Does this by constructing a very large intermediate array and
    comparing every point to every triangle.

    Parameters
    ----------
    mesh : Trimesh
      Takes mesh to have same interfaces as `closest_point`
    points : (m, 3) float
      Points in space

    Returns
    ----------
    closest : (m, 3) float
      Closest point on triangles for each point
    distance : (m,) float
      Distances between point and triangle
    triangle_id : (m,) int
      Index of triangle containing closest point
    r   )r   r   r   ztriangles shape incorrectr   zpoints must be (n,3)r   c                 V    g | ]%}t          |                    d                     &S )r   )_correspondingr&   )r   i	triangless     r   r   z'closest_point_naive.<locals>.<listcomp>i   s/    MMM1	199W#5#5	6	6MMMr   c                 L    g | ]!\  }}||z
  d z                       d          "S )   r   axis)sum)r   r3   qs      r   r   z'closest_point_naive.<locals>.<listcomp>m   s5    RRRAAEa<$$!$,,RRRr   c                 6    g | ]}|                                 S r   )argmin)r   r3   s     r   r   z'closest_point_naive.<locals>.<listcomp>o   s     ;;;1AHHJJ;;;r   c                 $    g | ]\  }}||         S r   r   r   r3   gs      r   r   z'closest_point_naive.<locals>.<listcomp>r   s     GGGA!GGGr   c                 $    g | ]\  }}||         S r   r   r>   s      r   r   z'closest_point_naive.<locals>.<listcomp>s   s     GGG$!Q1GGGr         ?)r4   viewr   ndarrayr   r   r   r    r!   tilelenarrayzip)	r)   r*   points_tiledon_triangle
distance_2triangle_idclosestdistancer4   s	           @r   closest_point_naiverN   E   s`   2 ##BJ//I]6444F=J// 64555=)) 1/000 76As9~~#677L(MMMMMMM K
 SR[&9Q9QRRRJ(;;
;;;<<K hGG[+)F)FGGGHHGxGG#k:*F*FGGGHHCOHHk))r   c                    t          j        |t           j                  }t          j        |d          st          d          t          | |          }| j                            t           j	                  }t          j
        |          }t          t          t          |                    }t          j        t          j        t          |                    |          }||ddf         }||         }t!          ||          }	t          j        |          dd         }
||	z
  }t          j        ||          }t          j        ||
          }t          j        d |D                       }|ddxx         |
                    dd          z  cc<   |	|         }||         }||         }|	|dddf                  }|dddf         }|dddf         }t          j        |d	          t.          j        k     }t          j        t          j        |          t.          j        k    d	          }t          j        ||          }| j        ||                  }|||                  ||                             dd
d          dz  z  }||z                      d
	          }|                    d	          }|||f         ||<   |||f         ||<   |||f         ||<   |dz  }|||fS )a  
    Given a mesh and a list of points find the closest point
    on any triangle.

    Parameters
    ----------
    mesh : trimesh.Trimesh
      Mesh to query
    points : (m, 3) float
      Points in space

    Returns
    ----------
    closest : (m, 3) float
      Closest point on triangles for each point
    distance : (m,)  float
      Distance to mesh.
    triangle_id : (m,) int
      Index of triangle containing closest point
    r   r   r   Nr   c                 t    g | ]5}t          |          d k    r|                                dd         nddg6S )r   Nr6   r   )rE   argsort)r   qds     r   r   z!closest_point.<locals>.<listcomp>   s@    OOORR1RZZ\\"1"%%1a&OOOr   r   r   r7   r6   rA   )r   r   r   r   r    r!   r/   r4   rB   rC   concatenater   maprE   repeataranger2   cumsumdiagonal_dotarray_splitint32r&   ptpr   r'   allabsbitwise_andface_normalsr9   argmax)r)   r*   r.   r4   all_candidatesnum_candidates	tile_idxsquery_point	query_triquery_closequery_groupquery_vectorquery_distanceqdsidxs
two_points	two_diststwo_candidatesresult_close
result_tidresult_distancecheck_distancecheck_magnitudec_masknormalsvectorsdotsc_idxss                               r   r   r   x   s   * ]6444F=)) 20111 dF++J ##BJ//I ^J//N#c:..//N	")CKK00.AAIAAA&K.)I !K88K)N++CRC0K ,L&|\BBN .
5
5C8OO3OOOPPDHHH##B***HHH T"Jt$I#D)N tAAAqDz*L1%J1oO VIA...:NfRVI..:CCCO ^NO<<F v 67G4<(9V+<+D+DRA+N+NRU+UUGg"""**D [[a[  F (7Jv'7OF%ffn5L O*44r   c           	         t          j        |t           j                  }t          | |          \  }}}|t          j        k    }|                                s|S t          j        |          d         }| j        |         }||         ||         j	        t          j
        d||         ||         z
  ||                   z  j	        z
  }t          | j        ||                  |          }|t          j         k     |dt          j        z   k    z                      d           }	t          j        t          j
        d|||	                  |||	                  ||	         z
                      }
|||	         xx         d|
z  z  cc<   | j                            |||	                             }|                    t"                    dz  dz
  }
|||	          xx         |
z  cc<   |S )	a  
    Find the signed distance from a mesh to a list of points.

    * Points OUTSIDE the mesh will have NEGATIVE distance
    * Points within tol.merge of the surface will have POSITIVE distance
    * Points INSIDE the mesh will have POSITIVE distance

    Parameters
    -----------
    mesh : trimesh.Trimesh
      Mesh to query.
    points : (n, 3) float
      Points in space

    Returns
    ----------
    signed_distance : (n,) float
      Signed distance from point to mesh
    r   r   zij,ij->ir   r7   g      r6   g      ?)r   r   r   r   r   r'   anywherer_   Teinsumr	   r4   signraycontains_pointsastypeint)r)   r*   rL   rM   rK   nonzeroru   
projectionbarycentric
ontriangler~   insides               r   signed_distancer      s   * ]6444F &34%@%@"GX{ "G;;==  hw"G,GwGi
F7Ogg6F$FPWHXYYZ
		  ({77K(LjYYK


"{Q]'B	CHHaHPPJ 7
	GJ'(7:&'*Z*@@	
 	
 D WZ !!!TD[0!!! X%%fWj[-A&BCCFMM#"c)D Wj[!"""d*"""Or   c                       e Zd ZdZd Zd ZdS )NearestQueryResultzN
    Stores the nearest points and attributes for nearest points queries.
    c                 h    d | _         d | _        d | _        d | _        d | _        d | _        d | _        d S N)nearest	distancesru   triangle_indicesbarycentric_coordinatesinterpolated_normalsvertex_indicesselfs    r   __init__zNearestQueryResult.__init__%  s=     $'+$$(!"r   c                 &    | j         d up| j        d uS r   )ru   r   r   s    r   has_normalszNearestQueryResult.has_normals.  s    |4'P4+DD+PPr   N)__name__
__module____qualname____doc__r   r   r   r   r   r   r      sA         # # #Q Q Q Q Qr   r   c                   :    e Zd ZdZd Zed             Zd Zd ZdS )ProximityQueryz1
    Proximity queries for the current mesh.
    c                     || _         d S r   )_mesh)r   r)   s     r   r   zProximityQuery.__init__7  s    


r   c                 .    t          | j        |          S )a  
        Given list of points, for each point find the closest point
        on any triangle of the mesh.

        Parameters
        ----------
        points : (m,3) float, points in space

        Returns
        ----------
        closest : (m, 3) float
          Closest point on triangles for each point
        distance : (m,) float
          Distance to surface
        triangle_id : (m,) int
          Index of closest triangle for each point.
        )r)   r*   )r   r   r   r*   s     r   
on_surfacezProximityQuery.on_surface:  s    & $*V<<<<r   c                 D    | j         j        }|                    |          S )az  
        Given a set of points, return the closest vertex index to each point

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

        Returns
        ----------
        distance : (n,) float
           Distance from source point to vertex.
        vertex_id : (n,) int
          Index of mesh.vertices for closest vertex.
        )r   r+   r%   )r   r*   trees      r   vertexzProximityQuery.vertexO  s       z zz&!!!r   c                 ,    t          | j        |          S )a  
        Find the signed distance from a mesh to a list of points.

        * Points OUTSIDE the mesh will have NEGATIVE distance
        * Points within tol.merge of the surface will have POSITIVE distance
        * Points INSIDE the mesh will have POSITIVE distance

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

        Returns
        ----------
        signed_distance : (n,) float
          Signed distance from point to mesh.
        )r   r   r   s     r   r   zProximityQuery.signed_distanceb  s    $ tz6222r   N)	r   r   r   r   r   r   r   r   r   r   r   r   r   r   2  sf            = = X=(" " "&3 3 3 3 3r   r   c           	         t          j        |t           j                  }t          j        |d          st          d          t          j        |t           j                  }t          j        |d          st          d          t          |          t          |          k    rt          d          | j                            ||dd          \  }}}t          |          dk    r+t           j	        
                    |||         z
  d	
          }nt          j        g           }||t          j        k             }||t          j        k             }t          j        t          j        t          |                    |          }t          j        ||f          }t          j        |t          j        t           j        t          |                    f          }t'          ||          S )ae  
    Find the lengths of the longest rays which do not intersect the mesh
    cast from a list of points in the provided directions.

    Parameters
    -----------
    points : (n, 3) float
      Points in space.
    directions : (n, 3) float
      Directions of rays.

    Returns
    ----------
    signed_distance : (n,) float
      Length of rays.
    r   r   r   zdirections must be (n,3)!z1number of points must equal number of directions!T)return_locationsmultiple_hitsr   r   r7   )r   r   r   r   r    r!   rE   r   intersects_idlinalgnormrF   r   planar	setdiff1drV   rS   rU   infr   )r)   r*   
directions_facesrays	locationsr   no_intersectionss           r   longest_rayr   w  s   " ]6444F=)) 20111z<<<J=W-- 64555
6{{c*oo%%LMMM"h44
T 5  FD) 4yy1}}INN9vd|#;!NDD		HRLL	 	CJ&'D)cj01I |BIc&kk$:$:DAA>4!1233D	29RVSAQ=R=R+S+STUUIT9%%%r   Tư>d   c                    t          j        |t           j                  }t          j        |d          st          d          |tt          j        |t           j                  }t          j        |d          st          d          t          |          t          |          k    rt          d          n!| j        t          | |          d                  }|r| }t          | ||          }|dz  }t          j
        t          |          t                    }t          j        t          j        |                    d	         D ]}	t          j        | j        ||	         z
  ||	                   }
|
                                t"          j        k     rt           j        ||	<   d
||	<   b| j        |
                                         }t          j        |||	         z
  |||	         z
            dt          j        |||	         z
  ||	                   z  z  ||	<   ||t          j        |                    dd                    z  z   }t           j        t           j        t           j        g|t          j        |          <   t           j                            | j        d         | j        d	         z
            }||z  }d	}|                                d	k    r||k     r|dz  }| j                            ||                   \  }}}t          j        |t           j                            ||         ||         z
  d          z
            t"          j        k     }d
|t          j        |          d	         |         <   ||          ||         z
  }||                                         }t          j         d||          dt          j         d|||                   z  z  ||<   ||         ||         ||                             dd          z  z   ||<   |||         z
  |k     }d
|t          j        |          d	         |         <   |                                d	k    r||k     ||fS )aH  
    Find the center and radius of the sphere which is tangent to
    the mesh at the given point and at least one more point with no
    non-tangential intersections with the mesh.

    Masatomo Inui, Nobuyuki Umezu & Ryohei Shimane (2016)
    Shrinking sphere:
    A parallel algorithm for computing the thickness of 3D objects,
    Computer-Aided Design and Applications, 13:2, 199-207,
    DOI: 10.1080/16864360.2015.1084186

    Parameters
    ----------
    points : (n, 3) float
      Points in space.
    inwards : bool
      Whether to have the sphere inside or outside the mesh.
    normals : (n, 3) float or None
      Normals of the mesh at the given points
      if is None computed automatically.

    Returns
    ----------
    centers : (n,3) float
      Centers of spheres
    radii : (n,) float
      Radii of spheres
    r   r   r   Nnormals must be (n,3)!.number of points must equal number of normals!r6   rA   r   Fr   r   r7   z	ij, ij->i)!r   r   r   r   r    r!   rE   r_   r   r   onesboolr{   isinfdotr#   maxr   r   r   r`   
nan_to_numr&   nanr   r   r-   r9   r   r   r]   copyr}   )r)   r*   inwardsru   	thresholdmax_iterr   radiinot_convergedr3   projectionsr   centersDconvergence_thresholdn_itern_pointsn_dists_n_facesdonediff	old_radiicvgeds                          r   max_tangent_spherer     s)   > ]6444F=)) 20111-rz:::}Wg.. 	75666v;;#g,,&&MNNN ' #M$$?$?$BC ( D&'22IOEGCKKt444M Xbhy))**1-  fT]VAY6
CC
 ??sz))vE!H$M!];#5#5#7#78Fvfvay0&6!92DEEBF6F1I-wqz:::E!HH
 wu}}R/C/C!D!DDDG "7GBHUOO 		t{1~A677A%MF





!
!fx&7&7!&*l&=&=gm>T&U&U#'8
 F)..!7&:O!OVW.XXY  j	 	 ;@bh}--a067 !66-(--//	!ydDAA	+tW]-CDDD 
m "(!69ORWS

'"a..: "
 E-003HH;@bh}--a078; 




!
!fx&7&7> E>r   F
max_spherec                 t   t          j        |t           j                  }t          j        |d          st          d          |tt          j        |t           j                  }t          j        |d          st          d          t          |          t          |          k    rt          d          n!| j        t          | |          d                  }|dk    rt          | || |	          \  }}|dz  }|S |d
k    r%|rt          | ||          S t          | ||           S t          d          )a  
    Find the thickness of the mesh at the given points.

    Parameters
    ----------
    points : (n, 3) float
      Points in space
    exterior : bool
      Whether to compute the exterior thickness
      (a.k.a. reach)
    normals : (n, 3) float
      Normals of the mesh at the given points
      If is None computed automatically.
    method : string
      One of 'max_sphere' or 'ray'

    Returns
    ----------
    thickness : (n,) float
      Thickness at given points.
    r   r   r   Nr   r   r6   r   )r)   r*   r   ru   r   z)Invalid method, use "max_sphere" or "ray")r   r   r   r   r    r!   rE   r_   r   r   r   )r)   r*   exteriorru   method_centersradius	thicknesss           r   r   r     sK   , ]6444F=)) 20111-rz:::}Wg.. 	75666v;;#g,,&&MNNN ' #M$$?$?$BC-f(lG
 
 
& QJ		5 	7tVW555tVgX666DEEEr   )TNr   r   )FNr   )r   numpyr    r   	constantsr   r   groupingr   r4   r   r2   r	   scipy.spatialr
   BaseExceptionE
exceptionsr   r/   rN   r   r   r   r   r   r   r   r   r   <module>r      s              $ $ $ $ $ $ $ $       6 6 6 6 6 6 , , , , , ,"%%%%%%% " " ",,,,,,q!!GGGGGG"* * *Z0* 0* 0*f^5 ^5 ^5BD D DNQ Q Q Q Q Q Q Q$B3 B3 B3 B3 B3 B3 B3 B3J,& ,& ,&` HKq q q qh1F 1F 1F 1F 1F 1Fs   / AA

A