differt.rt.triangles_visible_from_vertices

differt.rt.triangles_visible_from_vertices#

triangles_visible_from_vertices(vertices, triangle_vertices, active_triangles=None, num_rays=1000000, batch_size=512, **kwargs)[source]#

Return whether triangles are visible from vertex positions.

This function uses ray launching and fibonacci_lattice to estimate whether a given triangle can be reached from a specific vertex, i.e., with a ray path, without interacting with any other triangle facet.

It also uses viewing_frustum to only launch rays in a spatial region that contains triangles.

Parameters:
  • vertices (Float[ArrayLike, '*#batch 3']) –

    An array of vertices, used as origins of the rays.

    Usually, this would be an array of transmitter positions.

  • triangle_vertices (Float[ArrayLike, '*#batch num_triangles 3 3']) – An array of triangle vertices.

  • active_triangles (Bool[ArrayLike, '*#batch num_triangles'] | None) –

    An optional array of boolean values indicating which triangles are active, i.e., should be considered for intersection.

    If not specified, all triangles are considered active.

  • num_rays (int) –

    The number of rays to launch.

    The larger, the more accurate.

  • batch_size (int | None) –

    The number of rays to process in a single batch. This allows to make a trade-off between memory usage and performance.

    The batch size is automatically adjusted to be the minimum of the number of rays and the specified batch size.

    If None, the batch size is set to the number of rays.

  • kwargs (Any) – Keyword arguments passed to rays_intersect_triangles.

Return type:

Bool[Array, '*batch num_triangles']

Returns:

For each triangle, whether it intersects with any of the rays.

Examples

The following example shows how to identify triangles as visible from a given transmitter, coloring them in dark gray.

>>> import equinox as eqx
>>> from differt.rt import (
...     triangles_visible_from_vertices,
... )
>>> from differt.scene import (
...     TriangleScene,
...     get_sionna_scene,
...     download_sionna_scenes,
... )
>>>
>>> download_sionna_scenes()
>>> file = get_sionna_scene("simple_street_canyon")
>>> scene = TriangleScene.load_xml(file)
>>> scene = eqx.tree_at(
...     lambda s: s.transmitters, scene, jnp.array([-33, 0, 32.0])
... )
>>> visible_triangles = triangles_visible_from_vertices(
...     scene.transmitters,
...     scene.mesh.triangle_vertices,
... )
>>> visible_color = jnp.array([0.2, 0.2, 0.2])
>>> scene = eqx.tree_at(
...     lambda s: s.mesh.face_colors,
...     scene,
...     scene.mesh.face_colors.at[visible_triangles, :].set(visible_color),
... )
>>> fig = scene.plot(backend="plotly")
>>> fig

In this example, a receiver is placed at the opposite side of the street canyon, and its visible triangles are colored in blue. Triangles that are visible from both the transmitter and the receiver are colored in yellow.

>>> scene = eqx.tree_at(
...     lambda s: s.receivers, scene, jnp.array([33, 0, 1.5])
... )
>>> visible_triangles = triangles_visible_from_vertices(
...     jnp.stack((scene.transmitters, scene.receivers)),
...     scene.mesh.triangle_vertices,
... )
>>> triangles_visible_from_tx = visible_triangles[0, :]
>>> triangles_visible_from_rx = visible_triangles[1, :]
>>> visible_by_tx_color = jnp.array([0.2, 0.2, 0.2])
>>> visible_by_rx_color = jnp.array([0.2, 0.8, 0.2])
>>> visible_by_both_color = jnp.array([0.8, 0.8, 0.2])
>>> scene = eqx.tree_at(
...     lambda s: s.mesh.face_colors,
...     scene,
...     scene.mesh.face_colors.at[triangles_visible_from_tx, :].set(
...         visible_by_tx_color
...     ),
... )
>>> scene = eqx.tree_at(
...     lambda s: s.mesh.face_colors,
...     scene,
...     scene.mesh.face_colors.at[triangles_visible_from_rx, :].set(
...         visible_by_rx_color
...     ),
... )
>>> scene = eqx.tree_at(
...     lambda s: s.mesh.face_colors,
...     scene,
...     scene.mesh.face_colors.at[
...         triangles_visible_from_tx & triangles_visible_from_rx, :
...     ].set(visible_by_both_color),
... )
>>> fig = scene.plot(backend="plotly")
>>> fig