Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attribute error in trianglemesh_to_sdf #761

Open
aradhyamathur opened this issue Oct 23, 2023 · 5 comments
Open

Attribute error in trianglemesh_to_sdf #761

aradhyamathur opened this issue Oct 23, 2023 · 5 comments

Comments

@aradhyamathur
Copy link

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

@Caenorst
Copy link
Collaborator

Caenorst commented Nov 2, 2023

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

@maeda56
Copy link

maeda56 commented Nov 25, 2023

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

@aradhyamathur
Copy link
Author

@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.

@maeda56
Copy link

maeda56 commented Nov 27, 2023

@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.

@Kairobo
Copy link

Kairobo commented Jul 19, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants