NVIDIAGameWorks/kaolin

Attribute error in trianglemesh_to_sdf

aradhyamathur opened this issue · 5 comments

Hi, has the function trianglemesh_to_sdf been removed from conversions ? How can we now calculate the SDF of points from a SurfaceMesh in kaolin v0.14.0

Hi @aradhyamathur , you can actually compute sdf by combining check_sign and point_to_mesh_distance. Please be careful to apply torch.sqrt to point_to_mesh_distance as the output is squared

Hello, @aradhyamathur and @Caenorst. I have also been working on creating a function to convert Mesh to SDF using Kaolin. Following the advice of @aradhyamathur to apply torch.sqrt, I was able to solve the problem observed in the converted model. I am grateful for this valuable advice.

Here, I am sharing the function I developed. I hope it will be helpful to others who may face similar issues.

def mesh_to_sdf(obj_path, grid_size=64, batch_size=1):
    if torch.cuda.is_available():
        device = 'cuda'
    else:
        raise RuntimeError("CUDA is not available. Kernel error will occur without CUDA. Exiting.")

    mesh = kal.io.obj.import_mesh(obj_path).to(device)

    vertices = mesh.vertices
    faces = mesh.faces

    axis = torch.linspace(-0.5, 0.5, grid_size) # range of x, y, z axis
    x, y, z = torch.meshgrid(axis, axis, axis)
    grid_points = torch.stack([x, y, z], dim=-1).reshape(-1, 3).to(device)

    grid_points_batch = grid_points.unsqueeze(0).repeat(batch_size, 1, 1)
    vertices_batch = vertices.unsqueeze(0).repeat(batch_size, 1, 1)

    face_vertices = kal.ops.mesh.index_vertices_by_faces(vertices_batch, faces)

    squared_distance, _, _ = kal.metrics.trianglemesh.point_to_mesh_distance(grid_points_batch, face_vertices)
    distance = torch.sqrt(squared_distance)

    sign = kal.ops.mesh.check_sign(vertices_batch, faces, grid_points_batch)
    sign_num = torch.where(sign, torch.tensor(-1.0).to(device), torch.tensor(1.0).to(device))

    sdf = distance * sign_num

    sdf_field = sdf.reshape(batch_size, 1, grid_size, grid_size, grid_size)

    return sdf_field

@maeda56 this assumes the bounds of the mesh to be in the range of [-0.5, 0.5] right ? should it be based on the grid of the bounds of the mesh or are the vertices always normalized for the mesh you use.

@aradhyamathur Yes, this function targets meshes that fit within the range of [-0.5, 0.5] on all axes, x, y, and z. And before I use this function, I perform a normalization process to ensure they conform to the prescribed size.

It seems it should be: torch.where(sign, torch.tensor(1.0).to(device), torch.tensor(-1.0).to(device)) . True is the first value