Geometry Functionals#

Mesh Poisson Disk Sample#

physicsnemo.nn.functional.mesh_poisson_disk_sample(
mesh_vertices: Tensor,
mesh_indices: Tensor,
min_distance: float = 0.02,
per_vertex_radius: Tensor | None = None,
batch_size: int = 131072,
max_points: int = 2000000,
max_iterations: int = 64,
random_seed: int = 42,
hash_grid_resolution: int | Sequence[int] | Tensor = 128,
mode: str = 'dart_throwing',
target_num_points: int | None = None,
) Tensor#

Generate Poisson-disk samples on a triangle mesh surface with Warp.

This functional supports two sampling modes on triangle meshes:

  1. dart_throwing: iterative parallel dart throwing where each iteration draws area-weighted candidates, rejects points near accepted samples, resolves candidate-candidate conflicts with random-priority MIS, and commits survivors.

  2. weighted_sample_elimination: builds an oversampled Poisson-quality pool, then downsamples to target_num_points using a radius-aware elimination pass.

Both modes produce blue-noise-like sample sets. dart_throwing emphasizes throughput and minimum-distance control; weighted_sample_elimination emphasizes distribution quality at a fixed output count.

Parameters:
  • mesh_vertices (torch.Tensor) – Mesh vertex positions with shape (n_vertices, 3).

  • mesh_indices (torch.Tensor) – Triangle connectivity in shape (n_faces, 3) or flattened shape (3 * n_faces,).

  • min_distance (float, optional) – Minimum Poisson distance for constant-radius mode. Default is 0.02. In weighted_sample_elimination mode this is treated as a lower-bound hint while the algorithm primarily targets target_num_points quality.

  • per_vertex_radius (torch.Tensor | None, optional) – Optional adaptive radius with shape (n_vertices,). If provided, candidate radius is barycentrically interpolated.

  • mode (str, optional) – Sampling mode. "dart_throwing" uses iterative parallel dart throwing. "weighted_sample_elimination" builds an oversampled Poisson pool and then downsamples to target_num_points with radius-aware elimination.

  • batch_size (int, optional) – Number of generated candidates per iteration. Default is 131072.

  • max_points (int, optional) – Maximum number of accepted samples. Default is 2_000_000. For mode="weighted_sample_elimination", this is also the default target_num_points when that argument is omitted.

  • target_num_points (int | None, optional) – Number of output points for mode="weighted_sample_elimination". If None, the mode uses max_points.

  • max_iterations (int, optional) – Iteration cap for the sampler. Default is 64.

  • random_seed (int, optional) – Base random seed for deterministic candidate generation.

  • hash_grid_resolution (int | Sequence[int], optional) – Hash-grid resolution, either scalar or (nx, ny, nz). Default is 128.

  • implementation (str | None, optional) – Explicit implementation name. Defaults to dispatch behavior.

Returns:

Accepted sample positions with shape (n_samples, 3) and dtype torch.float32.

Return type:

torch.Tensor

Notes

  • mode="weighted_sample_elimination" uses Warp kernels and follows Open3D’s Yuksel-style weighting equations.

  • per_vertex_radius is ignored in weighted elimination mode.

  • The output order is implementation-specific and not semantically meaningful.

Visualization

This visualization compares Poisson samples generated by dart_throwing and weighted_sample_elimination on the same Stanford Bunny surface mesh.

Rotating Mesh Poisson disk sampling mode comparison

Mesh To Voxel Fraction#

physicsnemo.nn.functional.mesh_to_voxel_fraction(
mesh_vertices: Tensor,
mesh_indices: Tensor,
origin: Tensor | Sequence[float],
voxel_size: float,
grid_dims: Sequence[int] | Tensor,
n_samples: int = 64,
seed: int = 42,
open_mesh: bool = False,
winding_number_threshold: float = 0.5,
winding_number_accuracy: float = 2.0,
) Tensor#

Compute mesh-voxel volume fractions on a regular 3D grid.

This functional estimates the fraction of each voxel that lies inside a triangle mesh using Warp kernels and Monte Carlo sampling.

For each voxel, it first performs an AABB-overlap query with mesh triangles. If no triangles overlap the voxel, it classifies only the voxel center as inside or outside. If triangles overlap, it uniformly samples points inside the voxel and estimates the occupancy fraction:

\[f_{ijk} \approx \frac{1}{N_s}\sum_{s=1}^{N_s}\mathbb{1}\left(x_s \in \Omega\right),\]

where \(N_s\) is n_samples and \(\Omega\) is the mesh interior.

Parameters:
  • mesh_vertices (torch.Tensor) – Vertex positions with shape (n_vertices, 3).

  • mesh_indices (torch.Tensor) – Triangle connectivity as shape (n_faces, 3) or flattened shape (3 * n_faces,).

  • origin (torch.Tensor | Sequence[float]) – Lower corner of the voxel grid as a length-3 vector.

  • voxel_size (float) – Edge length of each cubic voxel.

  • grid_dims (Sequence[int]) – Grid resolution (nx, ny, nz).

  • n_samples (int, optional) – Number of Monte Carlo samples per overlapping voxel. Default is 64.

  • seed (int, optional) – Random seed offset used per voxel. Default is 42.

  • open_mesh (bool, optional) – If True, uses winding-number sign queries for open meshes. Default is False.

  • winding_number_threshold (float, optional) – Winding-number threshold used when open_mesh=True.

  • winding_number_accuracy (float, optional) – Winding-number query accuracy used when open_mesh=True.

  • implementation (str | None, optional) – Explicit backend selection. Defaults to dispatch behavior.

Returns:

Volume fractions in [0, 1] with shape (nz, ny, nx) and dtype torch.float32.

Return type:

torch.Tensor

Notes

  • This functional provides a Warp implementation.

  • The operation is stochastic over overlapping voxels; use seed for reproducible runs.

Visualization

This visualization shows a side-by-side rotating view of the Stanford Bunny mesh and the occupied voxels inferred by mesh_to_voxel_fraction.

Mesh to voxel fraction mesh and occupied-voxel rotation animation

Ray Mesh Intersect#

physicsnemo.nn.functional.ray_mesh_intersect(
mesh_vertices: Tensor,
mesh_indices: Tensor,
ray_origins: Tensor,
ray_directions: Tensor,
max_distance: float = 100000000.0,
warp_mesh: Mesh | None = None,
return_warp_mesh: bool = False,
) tuple[Tensor, Tensor, Tensor, Tensor, Tensor] | tuple[Tensor, Tensor, Tensor, Tensor, Tensor, Mesh]#

Intersect rays with a triangle mesh using Warp.

ray_mesh_intersect builds a Warp Mesh acceleration structure from triangle vertices and indices, casts each input ray against the mesh, and returns the closest hit within max_distance. Ray directions do not need to be normalized; the Warp implementation normalizes them before querying so returned hit distances are expressed in mesh-space length units.

Parameters:
  • mesh_vertices (torch.Tensor) – Mesh vertex positions with shape (num_vertices, 3).

  • mesh_indices (torch.Tensor) – Triangle connectivity with shape (num_faces, 3) or a flattened equivalent.

  • ray_origins (torch.Tensor) – Ray origins with shape (..., 3).

  • ray_directions (torch.Tensor) – Ray directions with the same shape as ray_origins.

  • max_distance (float, optional) – Maximum ray distance. Default is 1e8.

  • warp_mesh (wp.Mesh | None, optional) – Prepared Warp mesh returned by an earlier ray_mesh_intersect call with return_warp_mesh=True. If provided, the mesh tensors are not used to rebuild a Warp Mesh.

  • return_warp_mesh (bool, optional) – If True, append the Warp Mesh used for the query to the output tuple so it can be passed back through warp_mesh on later calls.

  • implementation (str, optional) – Explicit implementation name. Currently only "warp" is registered.

Returns:

By default, a tuple (hit_mask, hit_distance, hit_points, face_ids, hit_normals). If return_warp_mesh=True, the returned tuple is (hit_mask, hit_distance, hit_points, face_ids, hit_normals, warp_mesh). Missed rays have False in hit_mask, infinite hit_distance, zero hit_points and hit_normals, and -1 face_ids.

Return type:

tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]

Notes

hit_normals are the mesh query normals returned by Warp. They preserve the mesh winding orientation and are not flipped to face the incoming ray. For repeated queries against a static mesh, call with return_warp_mesh=True once and pass the returned Warp mesh back through warp_mesh on later calls.

Visualization

This visualization shows a batch of rays intersecting a triangulated sphere, with hits, misses, hit points, and surface normals.

Ray mesh intersection overview with rays, hit points, and normals

Signed Distance Field#

physicsnemo.nn.functional.signed_distance_field(
mesh_vertices: Float[Tensor, 'num_vertices 3'],
mesh_indices: Tensor,
input_points: Float[Tensor, '... 3'],
max_dist: float = 100000000.0,
use_sign_winding_number: bool = False,
) tuple[Float[Tensor, '...'], Float[Tensor, '... 3']]#

Compute the signed distance field (SDF) for a mesh and query points.

The mesh must be a surface mesh consisting of triangles. This functional uses a Warp-backed implementation for accelerated execution.

Parameters:
  • mesh_vertices (torch.Tensor) – Coordinates of mesh vertices with shape (n_vertices, 3).

  • mesh_indices (torch.Tensor) – Triangle connectivity indexing into mesh_vertices. Expected shape is (n_faces, 3) or a flattened equivalent.

  • input_points (torch.Tensor) – Query points at which to evaluate the signed distance, with shape (..., 3).

  • max_dist (float, optional) – Maximum search distance for closest-point queries. Default is 1e8.

  • use_sign_winding_number (bool, optional) – Whether to use winding-number-based sign computation. Default is False. When False, the mesh should be watertight for reliable signs.

  • implementation (str, optional) – Explicit implementation name. Defaults to None, which uses normal dispatch (currently the Warp implementation).

Returns:

A tuple (sdf, hit_points) where: - sdf contains signed distances at each query point. - hit_points contains the closest point on the mesh for each query.

Return type:

tuple[torch.Tensor, torch.Tensor]

Examples

>>> mesh_vertices = torch.tensor(
...     [(0.0, 0.0, 0.0), (1.0, 0.0, 0.0), (0.0, 1.0, 0.0)]
... )
>>> mesh_indices = torch.tensor([(0, 1, 2)])
>>> input_points = torch.tensor([(0.5, 0.5, 0.5)])
>>> sdf, hit_points = signed_distance_field(
...     mesh_vertices, mesh_indices, input_points
... )

Visualization

This visualization shows signed-distance values on a 2D slice through the domain, with the zero level-set contour indicating the implicit surface. The animation shows a sweep plane through the mesh (left) and corresponding SDF slice image (right).

Signed distance field 2D slice visualization
Signed distance field z-slice sweep animation