-
Notifications
You must be signed in to change notification settings - Fork 4
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
creating a closed (voxelizable) mesh from delaunay-3d triangulation of 3D point cloud #178
Comments
Played around with this today and had a tough time as well getting a manifold mesh from the input cloud. There's two problems that I can see:
Both import open3d as o3d
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points3d)
pcd.estimate_normals()
radius = 2
bpa_mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(pcd, o3d.utility.DoubleVector([radius, radius * 2]))
print(bpa_mesh)
tri = np.asarray(bpa_mesh.triangles)
faces = np.empty((tri.shape[0], 4), dtype=np.int64)
faces[:, 0] = 3
faces[:, 1:] = tri
mesh = pv.PolyData(points3d, faces) Given this is similar to #170, I think this is a feature that should be improved or at least documented within |
These data appear to have originated from a regular grid. You can see a uniform grid-like structure to the points. I used to work with data like these a ton and created a nifty filter in PVGeo (PVGeo is essentially an extension package to PyVista) for creating voxelized versions of the gridded point clouds. Effectively, the algorithm evaluates the coordinates that are unique to the grid on a rotated local coordinate system then builds out voxels around every node. I would use this filter with some caution though... it is sometimes unstable but usually works for recovering voxel models from regularly gridded points like yours. See:
import pyvista as pv
import numpy as np
import PVGeo
points = np.loadtxt("points3d.txt")
pc = pv.PolyData(points)
# Use with caution
grid = PVGeo.filters.VoxelizePoints().apply(pc)
p = pv.Plotter()
p.add_mesh(grid, opacity=0.5, show_edges=True)
p.add_mesh(pc, point_size=5, color="red")
p.show_grid()
p.show() |
Many thanks to @akaszynski and @banesullivan for taking the time to reply. It's appreciated! @banesullivan these points did indeed originate from a regular grid. I already had a volumetric dataset that I thresholded to extract the points inside some iso-threshold, which is what I sent in as points3d. The issue is that I now need to voxelize the "connected" surface shown in the second plot, but as @akaszynski pointed out it looks like delaunay-3D doesn't generate manifold surfaces, so I think this may be beyond the scope of pyvista. But again, thank you! |
Did you ever find a solution to this problem? Thanks |
Hello,
I'm trying to combine two 3D pixel masks (separated by some distance) into a single mask that envelopes both features. I'm doing this by applying the delaunay-3D functionality to the ensemble of points defining both masks. The issue is that the resulting surface derived from the delaunay-3D algorithm is not "closed" so voxelizing it produces non-sensible results. I tried to fix the surface via pymeshfix, but the "repaired" surface looks nothing like the original. Here's what I have tried:
points3d.txt
I apply the delaunay-3d triangulation...
That results in a surface that makes sense to me. However, when I voxelize it, it's not closed, forcing me to use the "check_surface=False" parameterization to get it to run. It produces strange results:
I try to repair the surface via pymeshfix so that doesn't happen, but the "repaired" surface looks nothing like the original:
Any ideas how to fix this and get a new set of points within the new larger surface enveloping both original sets of points?
The text was updated successfully, but these errors were encountered: