
    j#-                         d Z ddl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 ddlmZmZ d	d
lmZ ej$                  ZdZdZ G d d      Z G d d      Zy)z[
Ray queries using the embreex package with the
API wrapped to match our native raytracer.
    N)rtcore_scene)TriangleMesh   )cachingintersectionsutil)log_time)	ArrayLikeInteger   contains_pointsgư>g:0yE>c                       e Zd ZddefdZed        Zej                  d        Z		 dde
de
defdZe	 	 	 dde
de
ded	ed
ef
d       Zed        Zd Zd Zd Zd Zd Zd Zy)RayMeshIntersectorscale_to_boxc                 ~    || _         || _        t        j                  | j                   j                        | _        y)a7  
        Do ray- mesh queries.

        Parameters
        -------------
        geometry : Trimesh object
          Mesh to do ray tests on
        scale_to_box : bool
          If true, will scale mesh to approximate
          unit cube to avoid problems with extreme
          large or small meshes.
        id_functionN)mesh_scale_to_boxr   Cache__hash___cache)selfgeometryr   s      E/DATA/.local/lib/python3.12/site-packages/trimesh/ray/ray_pyembree.py__init__zRayMeshIntersector.__init__   s-     	)mm		0B0BC    c                 X    | j                   rd| j                  j                  z  }|S d}|S )z/
        Scaling factor for precision.
        g      Y@g      ?)r   r   scale)r   r    s     r   _scalezRayMeshIntersector._scale+   s4    
  DIIOO+E  Er   c                     t        | j                  j                  | j                  j                  | j                        S )z8
        A cached version of the embreex scene.
        )verticesfacesr    )_EmbreeWrapr   r#   r$   r!   )r   s    r   _scenezRayMeshIntersector._scene8   s.    
 YY''tyydkk
 	
r   ray_originsray_directionsmultiple_hitsc                 >    | j                  |||d      \  }}}|||fS )a  
        Return the location of where a ray hits a surface.

        Parameters
        ----------
        ray_origins : (n, 3) float
          Origins of rays
        ray_directions : (n, 3) float
          Direction (vector) of rays

        Returns
        ---------
        locations : (m) sequence of (p, 3) float
          Intersection points
        index_ray : (m,) int
          Indexes of ray
        index_tri : (m,) int
          Indexes of mesh.faces
        T)r'   r(   r)   return_locations)intersects_id)r   r'   r(   r)   	index_tri	index_ray	locationss          r   intersects_locationz&RayMeshIntersector.intersects_locationA   s;    2 -1,>,>#)'!	 -? -
)Iy )Y..r   max_hitsr+   c                    t        j                  |t         j                        }t        j                  |t         j                        }|j                  |j                  k7  rt	        d      t        j                  |      }t        j                  dt         j                        g}t        j                  dt         j                        g}t        j                  dt         j                        g}|s|rft        t        | j                  j                  t        z        }	||	z  }
| j                  j                  dddddf   }| j                  j                  }t        j                   t#        |      dt         j                        }t        j$                  t#        |            }t'        |      D ]@  }| j(                  j+                  ||   ||         }|dk7  }|j-                         s n||   }||   }|s&|s$|j/                  |       |j/                  |        n||   |k(  }|||<   ||    }||    }||   }t1        j2                  |   |   ||   ||         \  }}||   ||   }}|j/                  |       |j/                  |       |j/                  |       |s nM|
|   z   ||<   ||   	z  |
|<   |
|xx   dz  cc<   ||xx   |
|   z  cc<   t        j4                  ||g      }C t        j4                  |      }t        j4                  |      }|r||t        j4                  |      fS ||fS )	aC  
        Find the triangles hit by a list of rays, including
        optionally multiple hits along a single ray.


        Parameters
        ----------
        ray_origins : (n, 3) float
          Origins of rays
        ray_directions : (n, 3) float
          Direction (vector) of rays
        multiple_hits : bool
          If True will return every hit along the ray
          If False will only return first hit
        max_hits : int
          Maximum number of hits per ray
        return_locations : bool
          Should we return hit locations or not

        Returns
        ---------
        index_tri : (m,) int
          Indexes of mesh.faces
        index_ray : (m,) int
          Indexes of ray
        locations : (m) sequence of (p, 3) float
          Intersection points, only returned if return_locations
        dtype%Ray origin and direction don't match!r   )r      N)plane_originsplane_normalsline_originsline_directionsg       @)nparrayfloat64shape
ValueErrorr   unitizezerosint64max_ray_offset_floorr   r    _ray_offset_factor	trianglesface_normalsfulllenarangeranger&   runanyappendr   planes_linesconcatenate)r   r'   r(   r)   r1   r+   result_triangleresult_ray_idxresult_locationsbase_offsetray_offsetsr8   r9   last_hitlive_depthqueryhithit_rayshit_trisdupeok_raysok_tris	dupe_raysnew_originsvalidr-   r.   s                               r   r,   z RayMeshIntersector.intersects_idc   s   N hh{"**=.

C 4 44DEEn5 88ARXX67((1BHH56HHV2::>?,/CU1UVK(;6K !II//1a8M II22M 773{+Rrxx@ yy[)*
 HoF KKOOK$5~d7KLE2+C779 CyHSzH !)9&&x0%%h/ H%1D!)HXuoGuoG I
 "/!;!;+G4+G4(1 .w 7	"K  'u~wu~WG##K0""7+!!'*  $/W1E#EK #1'#:[#HK 	"c)"	"k)&<<" >>7I"67Do &r NN?3	NN>2	i8H)III)##r   c                    t        j                  |t              }t        j                  |t              }|j                  |j                  k7  rt	        d      t        j                  |      }| j                  j                  ||      S )an  
        Find the index of the first triangle a ray hits.


        Parameters
        ----------
        ray_origins : (n, 3) float
          Origins of rays
        ray_directions : (n, 3) float
          Direction (vector) of rays

        Returns
        ----------
        triangle_index : (n,) int
          Index of triangle ray hit, or -1 if not hit
        r3   r5   )	r<   r=   _embree_dtyper?   r@   r   rA   r&   rM   )r   r'   r(   s      r   intersects_firstz#RayMeshIntersector.intersects_first   sg    & hh{-@.F 4 44DEEn5{{{N;;r   c                 6    | j                  ||      }|dk7  }|S )aO  
        Check if a list of rays hits the surface.


        Parameters
        -----------
        ray_origins : (n, 3) float
          Origins of rays
        ray_directions : (n, 3) float
          Direction (vector) of rays

        Returns
        ----------
        hit : (n,) bool
          Did each ray hit the surface
        )r'   r(   r7   )rf   )r   r'   r(   firstr[   s        r   intersects_anyz!RayMeshIntersector.intersects_any  s.    $ %%#N & 
 rk
r   c                     t        | |      S )ab  
        Check if a mesh contains a list of points, using ray tests.

        If the point is on the surface of the mesh, behavior is undefined.

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

        Returns
        ---------
        contains: (n,) bool
                         Whether point is inside mesh or not
        r   )r   pointss     r   r   z"RayMeshIntersector.contains_points  s     tV,,r   c                 ^    | j                   j                         }|j                  dd        |S )Nr   )__dict__copypopr   states     r   __getstate__zRayMeshIntersector.__getstate__+  s'    ""$		(D!r   c                     | j                   j                  |       t        j                  | j                  j
                        | _        y )Nr   )rm   updater   r   r   r   r   rp   s     r   __setstate__zRayMeshIntersector.__setstate__1  s.    U#mm		0B0BCr   c                 "    | j                         S )N)__copy__r   argss     r   __deepcopy__zRayMeshIntersector.__deepcopy__6  s    }}r   c                 D    t        | j                  | j                        S )N)r   r   )r   r   r   rx   s     r   rw   zRayMeshIntersector.__copy__9  s    !4994CUCUVVr   N)T)Td   F)__name__
__module____qualname__boolr   propertyr!   r   cache_decoratorr&   r
   r0   r	   r   r,   rf   ri   r   rr   ru   rz   rw    r   r   r   r      s    Dt D" 
 
 
 
 #	 / / " / 	 /D 
 #!&A$A$ "A$ 	A$
 A$ A$ A$F < <40-"D
Wr   r   c                       e Zd ZdZd Zd Zy)r%   z
    A light wrapper for Embreex scene objects which
    allows queries to be scaled to help with precision
    issues, as well as selecting the correct dtypes.
    c                    t        j                  |t         j                        }|j                  d      | _        t        |      | _        || j                  z
  | j                  z  }t        j                         | _	        t        | j                  |j                  t              |j                  t         j                        j                  t         j                               y )Nr3   r   )axis)scener#   indices)r<   r=   r>   minoriginfloatr    r   EmbreeScener   r   astypere   viewndarrayint32)r   r#   r$   r    scaleds        r   r   z_EmbreeWrap.__init__D  s    ("**5jjaj(5\
4;;&$**4!--/
**]]=1JJrzz*11"((;	
r   c                    t        j                  |t         j                        | j                  z
  | j                  z  } | j
                  j                  |j                  t              |j                  t              fi |S )Nr3   )	r<   r=   r>   r   r    r   rM   r   re   )r   originsnormalskwargsr   s        r   rM   z_EmbreeWrap.runR  s^    ((7"**5CtzzQtzz~~MM-('..*G
KQ
 	
r   N)r}   r~   r   __doc__r   rM   r   r   r   r%   r%   =  s    

r   r%   )r   numpyr<   embreexr   embreex.mesh_constructionr    r   r   r   	constantsr	   typedr
   r   ray_utilr   float32re   rF   rE   r   r%   r   r   r   <module>r      sX   
  ! 2 + +   & % 

   aW aWH	
 
r   