
    Ti#-                         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dS )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dS )RayMeshIntersectorTscale_to_boxc                 j    || _         || _        t          j        | j         j                  | _        dS )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      R/DATA/AppData/hermes/venv/lib/python3.11/site-packages/trimesh/ray/ray_pyembree.py__init__zRayMeshIntersector.__init__   s0     	)m	0BCCC    c                 8    | j         rd| j        j        z  }nd}|S )z/
        Scaling factor for precision.
        g      Y@g      ?)r   r   scale)r   r    s     r   _scalezRayMeshIntersector._scale+   s+    
  	 DIO+EEEr   c                 X    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-    
 Y'tydk
 
 
 	
r   ray_originsray_directionsmultiple_hitsc                 F    |                      |||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   d   Fmax_hitsr+   c                    t          j        |t           j                  }t          j        |t           j                  }|j        |j        k    rt	          d          t          j        |          }t          j        dt           j                  g}t          j        dt           j                  g}t          j        dt           j                  g}|s|rQt          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                            ||         ||                   }|dk    }|                                s nL||         }||         }|s/|s-|                    |           |                    |            n||         |k    }|||<   ||          }||          }||         }t1          j        ||         ||         ||         ||                   \  }}||         ||         }}|                    |           |                    |           |                    |           |s nZ||
|         z   ||<   ||         |	z  |
|<   |
|xx         dz  cc<   ||xx         |
|         z  cc<   t          j        ||g          }t          j        |          }t          j        |          }|r||t          j        |          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)   r2   r+   result_triangleresult_ray_idxresult_locationsbase_offsetray_offsetsr9   r:   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 h{"*===.
CCC 444DEEEn55 8ARX6667(1BH5556HV2:>>>? 	3, 	3/CU1UVVK(;6K !I/1aaa8M I2M 73{++Rrx@@@ y[))**
 Hoo 7	8 7	8F KOOK$5~d7KLLE2+C7799  CyHSzH ! )9 &&x000%%h/// H%1D!)HXuoGuoG I
 "/!;+G4+G4(1 .w 7	" " "K  'u~wu~WG##K000""7+++!!'***   $/W1E#EK #1'#:[#HK 	"""c)"""	"""k)&<<""" >7I"677DDN?33	N>22	 	Ji8H)I)III)##r   c                 
   t          j        |t                    }t          j        |t                    }|j        |j        k    rt	          d          t          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
        r4   r6   )	r=   r>   _embree_dtyper@   rA   r   rB   r&   rN   )r   r'   r(   s      r   intersects_firstz#RayMeshIntersector.intersects_first   sq    & h{-@@@.FFF 444DEEEn55{{N;;;r   c                 @    |                      ||          }|dk    }|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(   r8   )rg   )r   r'   r(   firstr\   s        r   intersects_anyz!RayMeshIntersector.intersects_any  s3    $ %%#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                 d    | j                                         }|                    dd            |S )Nr   )__dict__copypopr   states     r   __getstate__zRayMeshIntersector.__getstate__+  s.    ""$$		(D!!!r   c                     | j                             |           t          j        | j        j                  | _        d S )Nr   )rn   updater   r   r   r   r   rq   s     r   __setstate__zRayMeshIntersector.__setstate__1  s5    U###m	0BCCCr   c                 *    |                                  S )N)__copy__r   argss     r   __deepcopy__zRayMeshIntersector.__deepcopy__6  s    }}r   c                 8    t          | j        | j                  S )N)r   r   )r   r   r   ry   s     r   rx   zRayMeshIntersector.__copy__9  s    !494CUVVVVr   N)T)Tr1   F)__name__
__module____qualname__boolr   propertyr!   r   cache_decoratorr&   r
   r0   r	   r   r,   rg   rj   r   rs   rv   r{   rx    r   r   r   r      s       D Dt D D D D" 
 
 X
 
 
 
 #	 /  / / " / 	 /  /  /  /D 
 #!&A$ A$A$ "A$ 	A$
 A$ A$ A$ A$ XA$F < < X<4  0- - -"  D D D
  W W W W Wr   r   c                       e Zd ZdZd Zd ZdS )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                  }|                    d          | _        t          |          | _        || j        z
  | j        z  }t          j                    | _	        t          | j	        |                    t                    |                    t           j                                      t           j                             d S )Nr4   r   )axis)scener#   indices)r=   r>   r?   minoriginfloatr    r   EmbreeScener   r   astyperf   viewndarrayint32)r   r#   r$   r    scaleds        r   r   z_EmbreeWrap.__init__D  s    ("*555jjaj((5\\
4;&$*4!-//
*]]=11JJrz**11"(;;	
 	
 	
 	
 	
 	
r   c                     t          j        |t           j                  | j        z
  | j        z  } | j        j        |                    t                    |                    t                    fi |S )Nr4   )	r=   r>   r?   r   r    r   rN   r   rf   )r   originsnormalskwargsr   s        r   rN   z_EmbreeWrap.runR  sh    (7"*555CtzQtz~MM-(('..*G*G
 
KQ
 
 	
r   N)r}   r~   r   __doc__r   rN   r   r   r   r%   r%   =  s<         
 
 

 
 
 
 
r   r%   )r   numpyr=   embreexr   embreex.mesh_constructionr    r   r   r   	constantsr	   typedr
   r   ray_utilr   float32rf   rG   rF   r   r%   r   r   r   <module>r      s   
     !           2 2 2 2 2 2 + + + + + + + + + +             & & & & & & & & % % % % % % 
   aW aW aW aW aW aW aW aWH	
 
 
 
 
 
 
 
 
 
r   