Edge Queries
Nearest-edge and visibility queries in RayD
Overview#
RayD maintains a scene-global edge BVH for nearest-edge queries and visibility tests. These are useful for edge sampling, visibility-boundary terms, and geometric diffraction models.
Nearest Edge — Point Query#
Find the nearest scene edge to each query point:
import rayd as rd
import drjit as dr
rd.set_device(0)
queries = dr.cuda.Array3f(
[0.25, 1.20, -0.15],
[0.25, 0.50, 0.70],
[0.10, 0.00, 0.00],
)
result = scene.nearest_edge(queries)
for i, valid in enumerate(list(result.is_valid())):
if valid:
print(f"distance={float(result.distance[i]):.4f}, "
f"edge_id={int(result.edge_id[i])}, "
f"boundary={bool(result.is_boundary[i])}")NearestPointEdge fields#
| Field | Description |
|---|---|
distance | Distance from query point to nearest edge |
point | The query point |
edge_t | Parameter along the edge at the closest point |
edge_point | Closest point on the edge |
shape_id | Mesh index of the edge |
edge_id | Local edge index within the mesh |
global_edge_id | Global edge index across all meshes |
is_boundary | True if this is a boundary edge |
result.is_valid() — Boolean mask for valid query results.
Nearest Edge — Ray Query#
Find the nearest scene edge to each query ray:
result = scene.nearest_edge(ray)Returns NearestRayEdge with the same fields as NearestPointEdge plus:
| Field | Description |
|---|---|
ray_t | Parameter along the ray at the closest point |
Top-K Nearest Edges#
Find the k nearest edges per query point (k ≤ 16):
result = scene.nearest_edges(points, k=4)Returns NearestEdgesTopK with:
| Field | Description |
|---|---|
query_count | Number of queries |
k | Number of results per query |
is_valid | Per-result validity mask |
distances | Per-result distances |
edge_points | Per-result closest edge points |
shape_ids | Per-result mesh indices |
edge_ids | Per-result local edge indices |
global_edge_ids | Per-result global edge indices |
is_boundary | Per-result boundary mask |
Segment Visibility#
Test whether two endpoints can see each other:
result = scene.visible(start, end, ignore_prim_ids=rd.Int(), active=True)Returns SegmentVisibility with:
| Field | Description |
|---|---|
ray_count | Number of queries |
visible | Boolean mask — True if the segment is unoccluded |
Shared-origin pair visibility#
Test two segments from the same origin simultaneously:
result = scene.visible_pair(start, end_a, end_b)Returns SegmentPairVisibility with visible_a and visible_b.
Polyline chain visibility#
Test a polyline chain of segments:
result = scene.visible_chain(points, chain_length)Returns SegmentChainVisibility with:
| Field | Description |
|---|---|
all_visible | True if all segments in the chain are unoccluded |
first_blocked_segment | Index of the first blocked segment |
first_blocked_prim | Primitive that caused the first blockage |
Edge visibility#
Test visibility toward an edge with multiple sample fractions:
result = scene.visible_edge(
src, edge_pos, edge_dir, edge_t_min, edge_t_max,
sample_fractions=[0.0, 0.25, 0.5, 0.75, 1.0],
)Returns AxialEdgeVisibility with any_visible.
Edge Mask#
Filter the edge BVH to a subset of edges:
mask = dr.cuda.Bool([True, False, True, ...])
scene.set_edge_mask(mask)Note
set_edge_mask() filters the secondary-edge BVH in scene-global edge index space. It does not modify scene.edge_info(), scene.edge_topology(), or scene.mesh_edge_offsets().
AD Support#
All nearest-edge and visibility queries accept both non-AD and AD inputs. Pass dr.cuda.ad.Array3f to get differentiable outputs. Visibility queries return boolean masks and are always detached.
Next Steps#
- Multipath — reflection and diffraction path tracing
- Nearest edge tutorial — worked example