Skip to content

ray_mesh_intersect

ray_mesh_intersect(cam_pos, cam_dir, V, F, use_embree=True, C=None, W=None, CH=None, tri_ind=None)

Shoot a ray from a position and see where it crashes into a given mesh

Uses a bounding volume hierarchy to efficiently compute intersections of many different rays with a given mesh.

Parameters:

Name Type Description Default
cam_pos numpy double array

Matrix of camera positions

required
cam_dir numpy double array

Matrix of camera directions

required
V (n,d) numpy array

vertex list of a triangle mesh

required
F (m,3) numpy int array

face index list of a triangle mesh

required
use_embree bool, optional (default True)

Whether to use the much more optimzed C++ AABB embree implementation of ray mesh intersections. If False, uses gpytoolbox's native AABB tree and gpytoolbox's intersection queries.

True
C numpy double array, optional (default None)

Matrix of AABB box centers (if None and use_embree=False, will be computed)

None
W numpy double array, optional (default None)

Matrix of AABB box widths (if None and use_embree=False, will be computed)

None
CH numpy int array, optional (default None)

Matrix of child indeces (-1 if leaf node). If None and use_embree=False, will be computed

None
tri_indices numpy int array, optional (default None)

Vector of AABB element indices (-1 if not leaf node). If None and use_embree=False, will be computed

required

Returns:

Name Type Description
ts list of doubles

The i-th entry of this list is the time it takes a ray starting at the i-th camera position with the i-th camera direction to hit the surface (inf if no hit is detected)

ids list of ints

The i-th entry is the index into F of the mesh element that the i-th ray hits (-1 if no hit is detected)

lambdas numpy double array

The i-th row contains the barycentric coordinates of where in the triangle the ray hit (all zeros is no hit is detected)

Examples:

from gpytoolbox import ray_mesh_intersect
v,f = gpytoolbox.read_mesh("test/unit_tests_data/cube.obj")
cam_pos = np.array([[1,0.1,0.1],[1,0.2,0.0]])
cam_dir = np.array([[-1,0,0],[-1,0,0]])
t, ids, l = ray_mesh_intersect(cam_pos,cam_dir,v,f)
Source code in src/gpytoolbox/ray_mesh_intersect.py
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
def ray_mesh_intersect(cam_pos,cam_dir,V,F,use_embree=True,C=None,W=None,CH=None,tri_ind=None):
    """Shoot a ray from a position and see where it crashes into a given mesh

    Uses a bounding volume hierarchy to efficiently compute intersections of many different rays with a given mesh.

    Parameters
    ----------
    cam_pos : numpy double array
        Matrix of camera positions
    cam_dir : numpy double array
        Matrix of camera directions
    V : (n,d) numpy array
        vertex list of a triangle mesh
    F : (m,3) numpy int array
        face index list of a triangle mesh
    use_embree : bool, optional (default True)
        Whether to use the much more optimzed C++ AABB embree implementation of ray mesh intersections. If False, uses gpytoolbox's native AABB tree and gpytoolbox's intersection queries.
    C : numpy double array, optional (default None)
        Matrix of AABB box centers (if None and use_embree=False, will be computed)
    W : numpy double array, optional (default None)
        Matrix of AABB box widths (if None and use_embree=False, will be computed)
    CH : numpy int array, optional (default None)
        Matrix of child indeces (-1 if leaf node). If None and use_embree=False, will be computed
    tri_indices : numpy int array, optional (default None)
        Vector of AABB element indices (-1 if *not* leaf node). If None and use_embree=False, will be computed

    Returns
    -------
    ts : list of doubles
        The i-th entry of this list is the time it takes a ray starting at the i-th camera position with the i-th camera direction to hit the surface (inf if no hit is detected)
    ids : list of ints
        The i-th entry is the index into F of the mesh element that the i-th ray hits (-1 if no hit is detected)
    lambdas : numpy double array
        The i-th row contains the barycentric coordinates of where in the triangle the ray hit (all zeros is no hit is detected)

    Examples
    --------
    ```python
    from gpytoolbox import ray_mesh_intersect
    v,f = gpytoolbox.read_mesh("test/unit_tests_data/cube.obj")
    cam_pos = np.array([[1,0.1,0.1],[1,0.2,0.0]])
    cam_dir = np.array([[-1,0,0],[-1,0,0]])
    t, ids, l = ray_mesh_intersect(cam_pos,cam_dir,v,f)
    ```
    """
    if use_embree:
        try:
            from gpytoolbox_bindings import _ray_mesh_intersect_cpp_impl
        except:
            raise ImportError("Gpytoolbox cannot import its C++ ray_mesh_intersect binding.")

        ts, ids, lambdas = _ray_mesh_intersect_cpp_impl(cam_pos.astype(np.float64),cam_dir.astype(np.float64),V.astype(np.float64),F.astype(np.int32))
    else:
        ts = np.Inf*np.ones(cam_pos.shape[0])
        ids = -np.ones(cam_pos.shape[0],dtype=int)
        lambdas = np.zeros((cam_pos.shape[0],3))
        # print("building tree")
        if ((C is None) or (W is None) or (tri_ind is None) or (CH is None)):
            C,W,CH,_,_,tri_ind,_ = initialize_aabbtree(V,F=F)
        # print("built tree")
        # print("computing distances")
        for i in range(cam_pos.shape[0]):
            trav = ray_mesh_intersect_traversal(cam_pos[i,:],cam_dir[i,:],V,F)
            traverse_fun = trav.traversal_function
            add_to_queue_fun = trav.add_to_queue
            _ = traverse_aabbtree(C,W,CH,tri_ind,None,traverse_fun,add_to_queue=add_to_queue_fun)
            ts[i] = trav.t
            ids[i] = trav.id
            lambdas[i,:] = trav.lmbd
        # print("computed distances")
    return ts, ids, lambdas