Skip to content

sdf_utils

Utility functions to handle voxel-based signed distance fields.

sdf_to_pointcloud(sdf, position, orientation, scale, max_points=None, threshold=0)

Convert SDF to pointcloud.

Puts a point onto each cell vertex with a value < threshold.

Parameters:

Name Type Description Default
sdf array

The values of the voxelized SDF. Shape (D, D, D).

required
position array

The position of the SDF center. Shape (3,).

required
orientation array

The orientation of the SDF as a normalized quaternion. This is the quaternion that will be applied to each point. Scalar-last convention, shape (4,).

required
scale float

The half-length of the SDF.

required
max_points Optional[int]

Maximum number of points in the pointcloud.

None
threshold float

The threshold below which a voxel will be included in the pointcloud.

0

Returns:

Type Description

The pointcloud as a Nx3 array.

Source code in sdfest/initialization/sdf_utils.py
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
def sdf_to_pointcloud(
    sdf: np.array,
    position: np.array,
    orientation: np.array,
    scale: float,
    max_points: Optional[int] = None,
    threshold: float = 0,
):
    """Convert SDF to pointcloud.

    Puts a point onto each cell vertex with a value < threshold.

    Args:
        sdf: The values of the voxelized SDF. Shape (D, D, D).
        position: The position of the SDF center. Shape (3,).
        orientation:
            The orientation of the SDF as a normalized quaternion.
            This is the quaternion that will be applied to each point.
            Scalar-last convention, shape (4,).
        scale: The half-length of the SDF.
        max_points: Maximum number of points in the pointcloud.
        threshold: The threshold below which a voxel will be included in the pointcloud.

    Returns:
        The pointcloud as a Nx3 array.
    """
    grid_size = 2.0 / (sdf.shape[0] - 1.0)
    indices = np.argwhere(sdf <= threshold)
    points = (indices * grid_size - 1.0) * scale
    rot_matrix = Rotation.from_quat(orientation).as_matrix()
    points = (rot_matrix @ points.T).T
    points += position
    if max_points is not None and max_points < points.shape[0]:
        points = points[np.random.choice(points.shape[0], 2, replace=False), :]
    return points