isl-org / Open3D

Open3D: A Modern Library for 3D Data Processing
http://www.open3d.org
Other
11.56k stars 2.32k forks source link

Spurious Self Intersection Reported for Mesh #5525

Open LemonPi opened 2 years ago

LemonPi commented 2 years ago

Checklist

Describe the issue

I want to generate signed distance fields for a set of YCB objects using open3d's RaycastingScene(); however, one of the requirements is that the input mesh is watertight. I am able to satisfy all conditions of watertightness except for it being non-intersecting. I am testing with a Blender QuadriFlow remeshed mesh from the high-poly scan of a YCB mustard bottle that I then triangulate. The remeshing ensures that the mesh is closed, which I further confirm with V + F - E = 2 (V = 314, E = 936, F = 624). The image below shows me viewing it in Blender (3.2) with surface orientations on to check if any normals are flipped.

After loading the mesh, I see that there are 3284 pairs of intersecting triangles according to o3d

len(np.asarray(mesh.get_self_intersecting_triangles()))

The mesh in .obj format is included: https://pastebin.com/nfVApbvx

Selection_035

Possibly related issue to #5117

Steps to reproduce the bug

import open3d as o3d
import numpy as np

mesh = o3d.io.read_triangle_mesh("remeshed.obj")
print(len(np.asarray(mesh.get_self_intersecting_triangles())))

Error message

No response

Expected behavior

It should not have any self-intersecting triangles

Open3D, Python and System information

- Operating system: Ubuntu 20.04
- Python version: Python 3.9 / output from `import sys; print(sys.version)`
- Open3D version: output from python: 1.5.2
- System architecture: x86 
- Is this a remote workstation?: no
- How did you install Open3D?: pip

Additional information

No response

LemonPi commented 2 years ago

Strangely, if I treat the mesh as a legacy mesh then it will let me construct it with the RaycastingScene():

mesh = o3d.t.geometry.TriangleMesh.from_legacy(mesh)
# # mesh.compute_vertex_normals()
scene = o3d.t.geometry.RaycastingScene()

The mesh is the same as before that reports it has self-intersecting triangles...

LemonPi commented 2 years ago

Using the check_properties function from http://www.open3d.org/docs/latest/tutorial/geometry/mesh.html I see a lot of spurious boundaries (green lines) and non-manifold vertices (blue points), but none of the reported intersecting triangles (pink lines).

Selection_052

hennels commented 2 years ago

I believe I am having the same issue. I produce a mesh like this by using scikit-image's marching cubes which I then pass to Open3D as shown below.

import numpy as np
from skimage import measure
import open3d as o3d

verts, faces, normals, _ = measure.marching_cubes(
    distance_field,
    level=level_set,
    allow_degenerate=False,
)

mesh = o3d.geometry.TriangleMesh()
mesh.vertices = o3d.utility.Vector3dVector(verts.astype(np.float64))
mesh.triangles = o3d.utility.Vector3iVector(faces)
mesh.vertex_normals = o3d.utility.Vector3dVector(normals.astype(np.float64))

Open3D reports self intersections in the resulting mesh when other tools like Meshlab report no self intersections. And upon close inspection the triangles are not even shown to be touching in Open3D's renderer. intersecting_triangles

I second that this is probably related to https://github.com/isl-org/Open3D/issues/5117 because it does seem to happen more commonly when one triangle is significantly larger than the other as is shown in the above image, although I have seen cases of triangles with similar area also being mistakenly reported as intersecting. Is this possibly a numerical issue in IntersectionTest::TriangleTriangle3d?