Main Content

signedDistanceMap3D

Store signed distance over variably sized 3-D region

Since R2024b

    Description

    The signedDistanceMap3D object creates and stores a truncated 3-D signed distance field over a voxelized 3-D space.

    Creation

    Description

    SDF = signedDistanceMap3D creates an empty 3-D signed distance field with default resolution and raycast settings.

    SDF = signedDistanceMap3D(Name=Value) sets properties using one or more name-value arguments. For example, Resolution=2 sets the grid resolution of the 3-D signed distance field to 2 cells per meter.

    example

    Properties

    expand all

    This property is read-only.

    Grid resolution, specified as a positive numeric scalar. Units are in cells per meter.

    You can set this property at object creation.

    This property is read-only.

    Raycasting type for voxel distance value updates, specified as 0 (false) or 1 (true):

    • true — The insertPointCloud function updates all voxels along the ray in the range [RayOrigin, RayEnd+TruncationDistance]. The distance values that the function compute depend on which segment of the range that the voxel is in:

      • [RayOrigin, RayEnd-TruncationDistance] — Distance value is TruncationDistance.

      • [RayEnd-TruncationDistance, RayEnd] — Distance values start from TruncationDistance at RayEnd-TruncationDistance and decrease to 0 at RayEnd.

      • [RayEnd, RayEnd+TruncationDistance] — Distance values start from 0 at RayEnd and decrease to -TruncationDistance at RayEnd+TruncationDistance.

    • false — The insertPointCloud object function updates only voxels along the ray in the range [RayEnd-TruncationDistance, RayEnd+TruncationDistance]. The distance values that the function assigns depend on which segment of the range that the voxel is in:

      • [RayEnd-TruncationDistance, RayEnd] — Distance values start from TruncationDistance at RayEnd-TruncationDistance and decrease to 0 at RayEnd.

      • [RayEnd, RayEnd+TruncationDistance] — Distance values start from 0 at RayEnd and decrease to -TruncationDistance at RayEnd+TruncationDistance.

      The function ignores voxels in the range [RayOrigin, RayEnd-TruncationDistance].

    Note

    Voxels retain the lowest distance value they have observed. If a voxel has already been visited, its distance value is averaged with the new distance value. If the voxel hasn't been visited before, the default value is overwritten.

    You can set this property at object creation.

    This property is read-only.

    Maximum distance from the occupied boundary, specified as a numeric scalar greater than or equal to 3/Resolution. Units are in meters.

    The default truncation distance ensures that the truncated signed distance field (TSDF) region extends at least three voxels from either side of the occupied boundary.

    TruncationDistance is also the default distance value assigned to each voxel until inserted ray changes the value of the voxel.

    When inserting rays, the map ignores voxel distance values that exceed positive TruncationDistance.

    You can set this property at object creation.

    This property is read-only.

    Number of active voxels in the map, stored as a positive integer.

    This property is read-only.

    Limits of the map that contains all active voxels, stored as a 2-by-3 matrix. The first row represents the minimum x, y, and z limits. The second row represents the maximum x-, y-, and z-limits.

    MapLimits represents the bounding box that encloses all of the current active voxels in the map. The map limits change as the voxels change.

    Object Functions

    distanceFind distance to zero-level set for query points
    activeVoxelsInformation about active voxels
    gradientFind gradient for query points in 3-D signed distance map
    insertPointCloudInsert point cloud data into 3-D signed distance map
    meshGenerate isosurface mesh from active voxels
    showDisplay 3-D signed distance map

    Examples

    collapse all

    Read and plot the triangulation data from the L-membrane STL. You can use this to compare with the signed distance map.

    triL = stlread("L-Membrane.stl");
    trisurf(triL)
    title("L-Membrane STL")
    [az,el] = view;
    axis equal

    Figure contains an axes object. The axes object with title L-Membrane STL contains an object of type patch.

    Create an empty 3-D signed distance field (SDF) and load the point cloud data for the L-membrane from a MAT file. The MAT file contains point cloud data and the sensor origin associated with each point cloud data.

    sdm3D = signedDistanceMap3D(Resolution=50);
    load LMembranePC.mat

    Insert each point cloud into the signed distance field and show the updated 3-D SDF.

    for i = 1:size(ptcloud,1)
        insertPointCloud(sdm3D,origin(i,:),ptcloud{i});
        show(sdm3D,Colorbar="on");
        view(az,el)
        axis equal
        drawnow
        pause(.25)
    end
    title(["3-D SDF of L-Membrane"])

    Figure contains an axes object. The axes object with title 3-D SDF of L-Membrane contains an object of type scatter.

    Get all active voxels in the 3-D SDF.

    vox = activeVoxels(sdm3D)
    vox = struct with fields:
               ID: 1
          Centers: [49889x3 double]
        Distances: [49889x1 double]
            Sizes: [49889x1 double]
    
    

    For demonstrative purposes, use a random xyz-offset from the voxel centers of the first three voxels as query points. Then get the distance and gradient using those query points.

    querypts = vox.Centers(1:3,:) + 0.1*rand(3,3);
    d = distance(sdm3D,querypts)
    d = 3×1
    
        0.0379
       -0.0447
        0.0600
    
    
    g = gradient(sdm3D,querypts)
    g = 3×3
    
        0.1924    1.5773   -1.4002
        0.1689    1.6524   -0.8267
       -0.0715   -0.2335    0.3677
    
    

    Generate a mesh from the 3-D signed distance field.

    [vertices,faces] = mesh(sdm3D)
    vertices = 18860×3
    
       -0.0100    0.0068    0.1500
       -0.0300    0.0059    0.1500
       -0.0100    0.0100    0.1610
       -0.0300    0.0100    0.1565
        0.0100    0.0047    0.1500
       -0.0100   -0.0100    0.1409
        0.0100   -0.0100    0.1421
        0.0100    0.0025    0.1700
       -0.0010    0.0100    0.1700
        0.0100    0.0094    0.1900
          ⋮
    
    
    faces = 37094×3
    
         2     1     3
         4     2     3
         7     1     6
         5     1     7
         9     3     1
         9     1     8
         8     1     5
         8    10    11
         9     8    11
        10    12    11
          ⋮
    
    

    Visualize the mesh data.

    meshTri = triangulation(faces,vertices);
    trisurf(meshTri)
    axis equal
    title("Mesh from 3-D SDF")

    Figure contains an axes object. The axes object with title Mesh from 3-D SDF contains an object of type patch.

    If needed, you can use this mesh data to create a collision mesh using V-HACD. See collisionVHACD (Robotics System Toolbox) for more information.

    References

    [1] Lorensen, William E., and Harvey E. Cline. “Marching Cubes: A High Resolution 3D Surface Construction Algorithm.” ACM SIGGRAPH Computer Graphics, vol. 21, no. 4, Aug. 1987, pp. 163–69. DOI.org (Crossref), https://doi.org/10.1145/37402.37422.

    [2] Museth, Ken. “VDB: High-Resolution Sparse Volumes with Dynamic Topology.” ACM Transactions on Graphics, vol. 32, no. 3, June 2013, pp. 1–22. DOI.org (Crossref), https://doi.org/10.1145/2487228.2487235.

    Extended Capabilities

    C/C++ Code Generation
    Generate C and C++ code using MATLAB® Coder™.

    Version History

    Introduced in R2024b