def sparse_to_dense_volume(coords, feature, vol_dims, interval, device=None):
    """
    convert the sparse volume into dense volume to enable trilinear sampling
    to save GPU memory;
    :param coords: [num_pts, 3]
    :param feature: [num_pts, C]
    :param vol_dims: [3]  dX, dY, dZ
    :param interval:
    :return:
    """

    # * assume batch size is 1
    if device is None:
        device = feature.device

    coords_int = (coords / interval).to(torch.int64)
    vol_dims = (vol_dims / interval).to(torch.int64)

    # - if stored in CPU, too slow
    dense_volume = sparse_to_dense_channel(
        coords_int.to(device), feature.to(device), vol_dims.to(device),
        feature.shape[1], 0, device)  # [X, Y, Z, C]

    valid_mask_volume = sparse_to_dense_channel(
        coords_int.to(device),
        torch.ones([feature.shape[0], 1]).to(feature.device),
        vol_dims.to(device),
        1, 0, device)  # [X, Y, Z, 1]

    dense_volume = dense_volume.permute(3, 0, 1, 2).contiguous().unsqueeze(0)  # [1, C, X, Y, Z]
    valid_mask_volume = valid_mask_volume.permute(3, 0, 1, 2).contiguous().unsqueeze(0)  # [1, 1, X, Y, Z]

    return dense_volume, valid_mask_volume

    convert the sparse volume into dense volume to enable trilinear sampling
    to save GPU memory;
    :param coords: [num_pts, 3]
    :param feature: [num_pts, C]
    :param vol_dims: [3]  dX, dY, dZ
    :param interval:
    :return:
    
mv-diffusion/One-2-3-45/reconstruction/models/sparse_sdf_network.py