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#

FieldDescription
distanceDistance from query point to nearest edge
pointThe query point
edge_tParameter along the edge at the closest point
edge_pointClosest point on the edge
shape_idMesh index of the edge
edge_idLocal edge index within the mesh
global_edge_idGlobal edge index across all meshes
is_boundaryTrue 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:

FieldDescription
ray_tParameter 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:

FieldDescription
query_countNumber of queries
kNumber of results per query
is_validPer-result validity mask
distancesPer-result distances
edge_pointsPer-result closest edge points
shape_idsPer-result mesh indices
edge_idsPer-result local edge indices
global_edge_idsPer-result global edge indices
is_boundaryPer-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:

FieldDescription
ray_countNumber of queries
visibleBoolean 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:

FieldDescription
all_visibleTrue if all segments in the chain are unoccluded
first_blocked_segmentIndex of the first blocked segment
first_blocked_primPrimitive 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#