differt.rt.triangles_visible_from_vertex#
- triangles_visible_from_vertex(vertex, 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_latticeto 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_frustumto only launch rays in a spatial region that contains triangles.Note
This function has a faster and more memory-efficient equivalent method:
TriangleMesh.triangles_visible_from_vertex, as long as smoothing is not required.- Parameters:
vertex (
Float[ArrayLike, '*#batch 3']) –Vertex, used as origin of the rays.
Usually, this would be transmitter position.
triangle_vertices (
Float[ArrayLike, '*#batch num_triangles 3 3']) – Triangle vertices.active_triangles (
Bool[ArrayLike, '*#batch num_triangles']|None) – Optional active triangle mask.num_rays (
int) –The number of rays to launch.
The larger, the more accurate.
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 toray_intersect_triangle.
- Return type:
- Returns:
Boolean mask,
Trueif each triangle is visible from the corresponding vertex.
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_vertex, ... ) >>> 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_vertex( ... 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_vertex( ... 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