warp.geometry.swept_volume_mesh#
- warp.geometry.swept_volume_mesh(
- meshes,
- transforms,
- voxel_size=None,
- *,
- resolution=None,
- lower=None,
- upper=None,
- threshold=0.0,
- sign_mode=SweptVolumeSignMode.WINDING_NUMBER,
- device=None,
Extract the swept volume (motion envelope) of animated rigid meshes.
Samples the swept-volume signed-distance field with
swept_volume_field()and extracts itsthresholdisosurface with marching cubes, returning a single triangle mesh in world coordinates that traces the union of every input mesh over every sampled pose.The field is evaluated by brute force at the provided pose samples. At low temporal sample rates relative to mesh speeds or thicknesses, the extracted swept volume will exhibit known “stroboscopic” defects.
- Parameters:
meshes (Sequence[warp.Mesh]) – Sequence of rest-pose
warp.Meshobjects.transforms (warp.array2d[warp.transform] | npt.ArrayLike) – Per-mesh, per-sample rigid poses; see
swept_volume_field().voxel_size (float | None) – Edge length of a grid cell in world units; see
swept_volume_field().resolution (tuple[int, int, int] | None) – Node counts
(nx, ny, nz); seeswept_volume_field().lower (warp.vec3 | tuple[float, float, float] | None) – World coordinate that node
(0, 0, 0)maps to. Defaults to the swept bounds padded bythresholdplus roughly two cells, so the extracted level stays inside the domain. Supplying the corners makes that padding your responsibility.upper (warp.vec3 | tuple[float, float, float] | None) – World coordinate that node
(nx-1, ny-1, nz-1)maps to.threshold (float) – Field level to extract.
threshold = 0.0traces the envelope through the sampled poses; a positive value dilates it outward. Due to grid sampling, the extracted marching cubes mesh is only guaranteed to enclose all sampled poses whenthreshold > 0.5 * hypot(hx, hy, hz).sign_mode (SweptVolumeSignMode) – Inside/outside classification method; see
SweptVolumeSignMode.SweptVolumeSignMode.NO_SIGNrequires a positivethresholdto result in a non-empty surface, since the field is positive everywhere.device (DeviceLike | None) – Device on which to run. Defaults to the device of the first mesh.
- Returns:
A tuple
(vertices, indices)whereverticesis awarp.array(dtype=warp.vec3)in world coordinates andindicesis a flatwarp.array(dtype=warp.int32)with three entries per triangle.- Return type:
Examples
Sweep a tetrahedron one unit along x. The swept solid spans
(0, 0, 0)to(2, 1, 1), and extracting at the conservativethresholdguarantees the envelope encloses it.>>> import numpy as np >>> import warp as wp >>> import warp.geometry as geo >>> points = np.array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]) >>> faces = [0, 2, 1, 0, 3, 2, 0, 1, 3, 1, 2, 3] >>> tet = wp.Mesh(wp.array(points, dtype=wp.vec3), wp.array(faces, dtype=wp.int32), support_winding_number=True) >>> xforms = np.zeros((1, 8, 7), dtype=np.float32) # one mesh, eight poses >>> xforms[..., 6] = 1.0 # identity quaternions >>> xforms[0, :, 0] = np.linspace(0.0, 1.0, 8) # translate along x >>> voxel_size = 0.05 >>> vertices, indices = geo.swept_volume_mesh( ... [tet], xforms, voxel_size=voxel_size, threshold=0.5 * np.sqrt(3.0) * voxel_size ... ) >>> v = vertices.numpy() >>> bool(np.all(v.min(axis=0) <= 0.0) and np.all(v.max(axis=0) >= [2.0, 1.0, 1.0])) True