简体   繁体   English

如何使用 python 将 3D 云数据点转换为网格?

[英]How to convert 3D cloud datapoints to mesh using python?

I have a set of 3D data points that looks similar to sphere.我有一组看起来类似于球体的 3D 数据点。 I need these data points to be connected as a watertight mesh so that it can be used for simulation.我需要将这些数据点连接为防水网格,以便将其用于模拟。

I have worked with Meshlab and obtained a reasonable mesh but not watertight.我与 Meshlab 合作并获得了合理的网格,但不是防水的。

After this, I have tried with Open3D python library by using ball pivot algorithm.在此之后,我通过使用球 pivot 算法尝试了 Open3D python 库。 From this, I am unable to obtain water tight mesh as expected.由此,我无法按预期获得防水网格。 I tried to work with hole_fixer external library ( Hole_fixer ), but finding and error in installing using cmake.我尝试使用hole_fixer 外部库( Hole_fixer ),但在使用cmake 安装时发现并出错。

I have inserted the code and also "xyz" datapoints used for open3D.我已经插入了代码以及用于 open3D 的“xyz”数据点。

import numpy as np
import open3d as o3d

dataname = 'meshdata2.xyz'

point_cloud = np.loadtxt(dataname, skiprows=1)


pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(point_cloud[:,:3])
pcd.estimate_normals()



distances = pcd.compute_nearest_neighbor_distance()
avg_dist = np.mean(distances)
radius = 5*avg_dist

bpa_mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(pcd, o3d.utility.DoubleVector([radius, radius*2, radius*0.5]))
print(str(bpa_mesh.is_watertight()))
o3d.visualization.draw_geometries([bpa_mesh])

Link for "xyz file": xyz_file_link “xyz 文件”的链接: xyz_file_link

Mesh obtained from Open3D: Mesh_from_open3D从 Open3D 获得的网格: Mesh_from_open3D

I would like to know how to obtain water tight mesh for these datapoints.我想知道如何为这些数据点获取防水网格。

Any leads will be appreciated.任何线索将不胜感激。

Regards,问候,

Sunag R A. Sunag R A.

To achieve a water tight mesh, you can use o3d.geometry.TriangleMesh.create_from_point_cloud_poisson .要实现防水网格,您可以使用o3d.geometry.TriangleMesh.create_from_point_cloud_poisson

However, Poisson reconstruction requires consistent normal orientation.然而,泊松重建需要一致的法线方向。 In your case, you can just orient all normals toward the center of your point cloud.在您的情况下,您可以将所有法线定向到点云的中心。 To do that:要做到这一点:

import numpy as np
import open3d as o3d

pcd = o3d.io.read_point_cloud('./meshdata2.xyz')
pcd.estimate_normals()

# to obtain a consistent normal orientation
pcd.orient_normals_towards_camera_location(pcd.get_center())

# or you might want to flip the normals to make them point outward, not mandatory
pcd.normals = o3d.utility.Vector3dVector( - np.asarray(pcd.normals))

# surface reconstruction using Poisson reconstruction
mesh, _ = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=9)

# paint uniform color to better visualize, not mandatory
mesh.paint_uniform_color(np.array([0.7, 0.7, 0.7]))

o3d.io.write_triangle_mesh('a.ply', mesh)

Mesh obtained using the above code snippet:使用上述代码片段获得的网格: 在此处输入图像描述


For point clouds with complex topology, it might not be easy to obtain a consistent normal orientation, read my other answer for more info.对于具有复杂拓扑的点云,获得一致的法线方向可能并不容易,请阅读我的其他答案以获取更多信息。

If Open3D does not produce watertight meshes (eg due to this bug ), one can use the Python bindings of MeshLab :如果 Open3D 不生成防水网格(例如由于这个错误),可以使用MeshLab 的 Python 绑定

import pymeshlab

ms = pymeshlab.MeshSet()
ms.load_new_mesh("meshdata2.xyz")
ms.compute_normal_for_point_clouds()
ms.generate_surface_reconstruction_ball_pivoting()
# or ms.generate_surface_reconstruction_screened_poisson()
ms.meshing_remove_unreferenced_vertices()
ms.save_current_mesh("meshdata2.ply")

As already pointed out by the OP, the surface reconstruction filters of MeshLab do not seem to be favorable for the given test dataset.正如 OP 已经指出的那样,MeshLab 的表面重建过滤器似乎不适合给定的测试数据集。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM