Xiaoqing Li
Xiaoqing Li

Reputation: 11

open3d | How to calculate the volume of a mesh created by point cloud?

I create a mesh by using 'open3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape' function and wanted to calculate the volume of it. But a RuntimeError occurs as the following shows:

[Open3D WARNING] [CreateFromPointCloudAlphaShape] invalid tetra in TetraMesh
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Input In [27], in <cell line: 7>()
      3 point_cloud.points = open3d.utility.Vector3dVector(data_all)
      5 tri_mesh = open3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(point_cloud, alpha=10)
----> 7 v = open3d.geometry.TriangleMesh.get_volume(tri_mesh)
      8 print(v)

RuntimeError: [Open3D Error] (double open3d::geometry::TriangleMesh::GetVolume() const) /Users/runner/work/Open3D/Open3D/cpp/open3d/geometry/TriangleMesh.cpp:1220: The mesh is not watertight, and the volume cannot be computed.

I searched online (https://github.com/isl-org/Open3D/pull/3201) and found that the warning message (invalid tetra in TetraMesh) is a common problem and the reason is that some points are inside the mesh and not in the surface. Therefore, I exclude all the points that are not in the surface by calculating each point's distance to the surface.

Then, I recreate the mesh by using 'open3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape' function. The same issue occurs and the mesh is still not watertight.

Is there any method to solve this problem and calculate the volume?

Thanks!

Upvotes: 1

Views: 2783

Answers (2)

Sheradil
Sheradil

Reputation: 477

For people that are stumbling upon this and need help.

Open3d is not really suited for this problem. Maybe in a future release, but not now.

The issue: The poisson reconstruction is meant to reconstruct surfaces. Probably the most important parameter is the boundary condition. And in Open3D it seems to be set to "von Neumann" (static const BoundaryType BType = poisson::DEFAULT_FEM_BOUNDARY; which is earlier set to "VON_NEUMANN"). This boundary condition tries to "fit" a surface on the points. It will ONLY be a surface. Not necessarly a closed volume. To enforce a watertight volume as result, you have to choose another boundary condition, which is not available in Open3D. The boundary condition that you want to chose is "Dirichlet". Even though Open3D implements the original poisson reconstruction from https://github.com/mkazhdan/PoissonRecon the boundary parameter is not available in Python.

Furthermore, you do need normal vectors. That's the most important thing. On the normals: Open3d offers a function (estimate_normals) to estimate the normals. Not a state of the art one (in my opinion), but it is ok'ish. However you have to be careful. It estimates the normals, but kinda randomly flips them by 180 degrees. So you also have to call orient_normals_consistent_tangent_plane to tell open3d to orient normals in a neighbourhood to face in the same direction (It just multiplies some normal vectors with -1). And then the last issue. For the Dirichlet boundary condition the normals have to face outward. So sometimes you have to manually flip all of the normals that are estimated by open3d, because the face the wrong direction. And then you clone the linked git, install it locally and reconstruct meshes.

Upvotes: 3

Mikael &#214;hman
Mikael &#214;hman

Reputation: 2375

In order to compute the volume you need a watertight mesh, which means it must have no openings. This isn't something the alpha shape algorithm guarantees; f you pick a smaller alpha, eventually it will just create tiny islands or isolated triangles. The tutorial has examples of what happens with different alphas: http://www.open3d.org/html/tutorial/Advanced/surface_reconstruction.html

You can check whether you had success with tri_mesh.is_watertight().

But the core problem here is really how to make the mesh watertight, which is asked and answered in this question.

Maybe picking a larger alpha is good enough for your case, or maybe you would be better served by an alternative algorithm like create_from_point_cloud_poisson (which should be guaranteed watertight, volume would be underestimated if the shape is mostly convex) or create_from_point_cloud_ball_pivoting.

You should plot your geometries and point cloud for visual inspection, and also compare the volume from each method.

Upvotes: 1

Related Questions