marian42 / mesh_to_sdf

Calculate signed distance fields for arbitrary meshes
https://pypi.org/project/mesh-to-sdf/
MIT License
1.03k stars 109 forks source link

Wrong scale of points after sample_sdf_near_surface #23

Closed trancelestial closed 3 years ago

trancelestial commented 3 years ago

Hi, first of all library functionality is very useful, however sampling when sample_sdf_near_surface is called, points that are returned are scaled differently then the mesh that is used. Seems that the method 'normalizes' the mesh to (-1,1)^3. I believe that this issue is similar to issue.

pbsds commented 3 years ago

The unit sphere normalization is documented. You can undo the transform manually yourself.

def compute_unit_sphere_transform(mesh: Trimesh) -> Tuple[np.ndarray, float]:
    """
    returns translation and scale, which is applied to meshes before computing their SDF cloud
    """
    # the transformation applied by mesh_to_sdf.scale_to_unit_sphere(mesh)
    translation = -mesh.bounding_box.centroid
    scale = 1 / np.max(np.linalg.norm(mesh.vertices + translation, axis=1))
    return translation, scale

points, sdf = sample_sdf_near_surface(mesh, 250000)
translation, scale = compute_unit_sphere_transform(mesh)
points = (points / scale) - translation
sdf /= scale

Perhaps this function should be added to this library.

The expectation however is that most neural networks will benefot from the SDF clouds being normalized to some canonical form. I don't think SIREN needs it, but most ReLU based models benefits from the unit sphere normalization.