marian42/mesh_to_sdf

How to get normals together with points and sdf?

wangzheallen opened this issue · 3 comments

I can use mesh_to_sdf.sample_sdf_near_surface like:

points, sdf = mesh_to_sdf.sample_sdf_near_surface(mesh, number_of_points=SDF_CLOUD_SAMPLE_SIZE, surface_point_method='scan', sign_method='normal', scan_count=100, scan_resolution=400, sample_point_count=10000000, normal_sample_count=11, min_size=0)`

But miss the normal for the points?
How can I get the normals?

Thanks!

You could try to get the closest surface using the surface point cloud, take the vector from each point to the closest surface point and normalize it.

Here is an example (I haven't tested it):

point_cloud = mesh_to_sdf.get_surface_point_cloud(mesh, surface_point_method='scan', bounding_radius=None, scan_count=100, scan_resolution=400, sample_point_count=10000000, calculate_normals=True)

points, sdf = point_cloud.get_sdf_in_batches(query_points, use_depth_buffer=False)

distances, indices = point_cloud.kd_tree.query(points, k=1)

closest_points = point_cloud.points[indices]
direction_from_surface = closest_points - points
normals = direction_from_surface / np.linalg.norm(direction_from_surface)

The kd tree query and the direction_from_surface are also calculated by get_sdf_in_batches, so you could modify that function to return these values and this would make it faster.

Thanks for the detailed reply! :-)
I assume query points and sdf can be calculated directly from
query_points, sdf = sample_sdf_near_surface(mesh, number_of_points=number_of_points)
and sample_sdf_near_surface should sample points both near surface and uniformly in the scene.
May I ask why the normal is in opposite direction?
do we need
direction_from_surface = points - closest_points ??

You're right, it should be direction_from_surface = points - closest_points. However, that is only for points outside the object. For points inside, they need to be inverted. You could achieve this by multiplying with the sign of the SDF.