Skip to content

Commit

Permalink
addressing suggestions + adding primitive_uvs to output
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitrishastin committed Oct 26, 2023
1 parent b80c5a9 commit 51b1e14
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 7 deletions.
19 changes: 13 additions & 6 deletions cpp/open3d/t/geometry/RaycastingScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ struct ListIntersectionsContext {
unsigned int* ray_ids;
unsigned int* geometry_ids;
unsigned int* primitive_ids;
float* primitive_uvs;
float* t_hit;
Eigen::VectorXi cumsum;
unsigned int* track_intersections;
Expand All @@ -138,6 +139,7 @@ void ListIntersectionsFunc(const RTCFilterFunctionNArguments* args) {
unsigned int* ray_ids = context->ray_ids;
unsigned int* geometry_ids = context->geometry_ids;
unsigned int* primitive_ids = context->primitive_ids;
float* primitive_uvs = context->primitive_uvs;
float* t_hit = context->t_hit;
Eigen::VectorXi cumsum = context->cumsum;
unsigned int* track_intersections = context->track_intersections;
Expand Down Expand Up @@ -166,6 +168,8 @@ void ListIntersectionsFunc(const RTCFilterFunctionNArguments* args) {
ray_ids[idx] = ray_id;
geometry_ids[idx] = hit.geomID;
primitive_ids[idx] = hit.primID;
primitive_uvs[idx * 2 + 0] = hit.u;
primitive_uvs[idx * 2 + 1] = hit.v;
t_hit[idx] = ray.tfar;
previous_geom_prim_ID_tfar->operator[](ray_id) = gpID;
++(track_intersections[ray_id]);
Expand Down Expand Up @@ -555,6 +559,7 @@ struct RaycastingScene::Impl {
unsigned int* ray_ids,
unsigned int* geometry_ids,
unsigned int* primitive_ids,
float* primitive_uvs,
float* t_hit,
const int nthreads) {
CommitScene();
Expand All @@ -563,6 +568,7 @@ struct RaycastingScene::Impl {
memset(ray_ids, 0, sizeof(uint32_t) * num_intersections);
memset(geometry_ids, 0, sizeof(uint32_t) * num_intersections);
memset(primitive_ids, 0, sizeof(uint32_t) * num_intersections);
memset(primitive_uvs, 0, sizeof(float) * num_intersections * 2);
memset(t_hit, 0, sizeof(float) * num_intersections);

std::vector<std::tuple<uint32_t, uint32_t, float>>
Expand All @@ -579,6 +585,7 @@ struct RaycastingScene::Impl {
context.ray_ids = ray_ids;
context.geometry_ids = geometry_ids;
context.primitive_ids = primitive_ids;
context.primitive_uvs = primitive_uvs;
context.t_hit = t_hit;
context.cumsum = cumsum;
context.track_intersections = track_intersections;
Expand Down Expand Up @@ -848,13 +855,9 @@ RaycastingScene::ListIntersections(const core::Tensor& rays,
intersections.GetDataPtr<int>(), nthreads);

// prepare shape with that number of elements
// not sure how to do proper conversion
const core::SizeVector dim = {0};
Eigen::Map<Eigen::VectorXi> intersections_vector(
intersections.GetDataPtr<int>(), num_rays);
Eigen::Map<Eigen::VectorXi> num_intersections(
intersections.Sum(dim).GetDataPtr<int>(), 1);
shape = {num_intersections[0], 1};
size_t num_intersections = intersections_vector.sum();

// prepare ray allocations (cumsum)
Eigen::VectorXi cumsum = Eigen::MatrixXi::Zero(num_rays, 1);
Expand All @@ -864,17 +867,21 @@ RaycastingScene::ListIntersections(const core::Tensor& rays,

// generate results structure
std::unordered_map<std::string, core::Tensor> result;
shape = {intersections_vector.sum(), 1};
result["ray_ids"] = core::Tensor(shape, core::UInt32);
result["geometry_ids"] = core::Tensor(shape, core::UInt32);
result["primitive_ids"] = core::Tensor(shape, core::UInt32);
result["t_hit"] = core::Tensor(shape, core::Float32);
shape.back() = 2;
result["primitive_uvs"] = core::Tensor(shape, core::Float32);

impl_->ListIntersections(data.GetDataPtr<float>(), num_rays,
num_intersections[0], cumsum,
num_intersections, cumsum,
track_intersections.GetDataPtr<uint32_t>(),
result["ray_ids"].GetDataPtr<uint32_t>(),
result["geometry_ids"].GetDataPtr<uint32_t>(),
result["primitive_ids"].GetDataPtr<uint32_t>(),
result["primitive_uvs"].GetDataPtr<float>(),
result["t_hit"].GetDataPtr<float>(), nthreads);
return result;
}
Expand Down
2 changes: 2 additions & 0 deletions cpp/open3d/t/geometry/RaycastingScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ class RaycastingScene {
/// {..}.
/// - \b primitive_ids A tensor with the primitive IDs, which
/// corresponds to the triangle index. The shape is {..}.
/// - \b primitive_uvs A tensor with the barycentric coordinates of
/// the closest points within the triangles. The shape is {.., 2}.
/// - \b t_hit A tensor with the distance to the hit. The shape is
/// {..}.
std::unordered_map<std::string, core::Tensor> ComputeClosestPoints(
Expand Down
50 changes: 49 additions & 1 deletion cpp/pybind/t/geometry/raycasting_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,51 @@ Computes the number of intersection of the rays with the scene.
raycasting_scene.def("list_intersections",
&RaycastingScene::ListIntersections, "rays"_a,
"nthreads"_a = 0, R"doc(
Lists the intersections of the rays with the scene.
Lists the intersections of the rays with the scene::
import open3d as o3d
import numpy as np
# Create scene and add the monkey model.
scene = o3d.t.geometry.RaycastingScene()
d = o3d.data.MonkeyModel()
mesh = o3d.t.io.read_triangle_mesh(d.path)
mesh_id = scene.add_triangles(mesh)
# Create an offset grid of rays.
p_min = np.min(mesh.vertex['positions'].numpy() - 1, axis=0)
p_max = np.max(mesh.vertex['positions'].numpy() - 1, axis=0)
x = np.arange(p_min[0], p_max[0], .1)
y = np.arange(p_min[1], p_max[1], .1)
xv, yv = np.meshgrid(x, y)
orig = np.vstack([xv.flatten(), yv.flatten(), np.tile(p_min[2], xv.size)]).T
dest = np.copy(orig)
dest[:, 2] = p_max[2] + 1
rays = np.hstack([orig, dest - orig]).astype('float32')
# Compute the ray intersections.
lx = scene.list_intersections(rays)
# Calculate intersection coordinates.
v = mesh.vertex['positions'].numpy()
t = mesh.triangle['indices'].numpy()
tidx = lx['primitive_ids'].numpy()
uv = lx['primitive_uvs'].numpy()
w = 1 - np.sum(uv, axis=1)
c = \
v[t[tidx, 1].flatten(), :] * uv[:, 0][:, None] + \
v[t[tidx, 2].flatten(), :] * uv[:, 1][:, None] + \
v[t[tidx, 0].flatten(), :] * w[:, None]
# Visualize the intersections.
entry = o3d.geometry.PointCloud(points = o3d.utility.Vector3dVector(orig))
target = o3d.geometry.PointCloud(points = o3d.utility.Vector3dVector(dest))
correspondence = [(i, i) for i in range(rays.shape[0])]
traj = o3d.geometry.LineSet.create_from_point_cloud_correspondences(entry , target , correspondence)
traj.colors = o3d.utility.Vector3dVector(np.tile([1, 0, 0], [rays.shape[0], 1]))
x = o3d.geometry.PointCloud(points = o3d.utility.Vector3dVector(c))
o3d.visualization.draw([mesh, traj, x])
Args:
rays (open3d.core.Tensor): A tensor with >=2 dims, shape {.., 6}, and Dtype
Expand All @@ -208,6 +252,10 @@ Lists the intersections of the rays with the scene.
primitive_ids
A tensor with the primitive IDs, which corresponds to the triangle
index. The shape is {..}.
primitive_uvs
A tensor with the barycentric coordinates of the closest points within
the triangles. The shape is {.., 2}.
t_hit
A tensor with the distance to the hit. The shape is {..}.
Expand Down

0 comments on commit 51b1e14

Please sign in to comment.