MCPcopy Create free account
hub / github.com/apple/ml-pointersect / grid_ray_intersection

Function grid_ray_intersection

pointersect/pr/cpp/pr.cpp:313–512  ·  view source on GitHub ↗

Compute the intersection between grid cells and the ray. Args: ray_origins: (b, m, 3) ray_directions: (b, m, 3) ray_radius: (b,) grid_size: (b, 3) long, xyz grid_center: (b, 3), xyz grid_width: (b, 3), xyz Returns: list of list of list: b -> ray_idx -> grid_idx (including -1, outside the grid) Algorithm: for each ray (px, py, pz, dx, dy, dz) if dx.abs() < 1e-8: # use y=c plane else: # use x=c

Source from the content-addressed store, hash-verified

311// surrounding the point.
312//
313std::vector<idxmap> grid_ray_intersection(
314 const torch::Tensor & ray_origins, // (b, m, 3), float
315 const torch::Tensor & ray_directions, // (b, m, 3), float
316 const torch::Tensor & ray_radius, // (b, )m float
317 const torch::Tensor & grid_size, // (b, 3), long
318 const torch::Tensor & grid_center, // (b, 3) float
319 const torch::Tensor & grid_width // (b, 3) float
320) {
321
322 assert(grid_size.dtype() == torch::kLong);
323
324 auto batch_size = ray_origins.size(0);
325 auto n_rays = ray_origins.size(1);
326 auto device = ray_origins.device();
327
328 auto grid_from = grid_center - grid_width * 0.5; // (b, 3)
329 auto cell_width = grid_width / grid_size; // (b, 3)
330 auto total_cells = torch::prod(grid_size, -1); // (b,)
331
332 // determine whether to intersect with x=c plane, y=c plane, or z=c plane.
333 // It is important to select a direction so that the intersection point on two nearby planes
334 // do not exceed one grid in one of the rest of the two directions.
335 // Fortunately, it can be shown that it will always happen when we select wisely.
336
337 // Let inv_tx = |dx / wx| (1 / time to travel one x grid)
338 // inv_ty = |dy / wy| (1 / time to travel one y grid)
339 // inv_tz = |dz / wz| (1 / time to travel one z grid)
340 // If inv_tx is the largest of (inv_tx, inv_ty, inv_tz) -> we will intersect with x=c planes.
341 // vise versa for inv_ty and inv_tz.
342 // When we select inv_tx, it ensures we move in the x direction in 1 grid, y and z in <= 1 grid.
343
344 auto inv_t = (ray_directions / cell_width.unsqueeze(-2)).abs(); // (b, m, 3)
345 auto idx_to_use = torch::argmax(inv_t, -1); // (b, m) (0, 1, 2)
346
347 // create accessors to each tensor
348 // auto start = high_resolution_clock::now();
349 auto a_grid_from = grid_from.accessor<float, 2>(); // (b, 3)
350 auto a_cell_width = cell_width.accessor<float, 2>(); // (b, 3)
351 auto a_grid_size = grid_size.accessor<int64_t, 2>(); // (b, 3)
352 auto a_idx_to_use = idx_to_use.accessor<int64_t, 2>(); // (b, m) 0, 1, 2
353 // auto stop = high_resolution_clock::now();
354 // auto duration = duration_cast<microseconds>(stop - start);
355 // std::cout<<"accessor_time: "<<duration.count()<<std::endl;
356
357 auto l_options = torch::TensorOptions().dtype(torch::kLong).device(device);
358 auto f_options = torch::TensorOptions().dtype(torch::kFloat32).device(device);
359
360
361 std::vector<idxmap> all_grid_idxs;
362 all_grid_idxs.reserve(batch_size);
363 for (auto b = 0; b < batch_size; ++b) {
364
365 auto a_grid_size_b = a_grid_size[b];
366
367 // build a meshgrid for local grid idx. This will determine the neighboring grids to gather.
368 // the local grid width = 2 * local_grid_radius
369 auto local_grid_radius = (torch::ceil(ray_radius.index({b, None}) / cell_width[b] + 1)).to(torch::kLong); // (3,) long, xyz
370 auto grid_idx_from = -1 * local_grid_radius; // (3,) long, xyz

Callers 1

Calls 8

sub2ind_cFunction · 0.85
dtypeMethod · 0.80
sizeMethod · 0.80
deviceMethod · 0.80
insertMethod · 0.80
get_grid_idxFunction · 0.70
toMethod · 0.45
reshapeMethod · 0.45

Tested by

no test coverage detected