python 如何正确绘制多边形集合(stl文件)?

gywdnpxw  于 2024-01-05  发布在  Python
关注(0)|答案(2)|浏览(170)

我有stl文件和numpy-stl库。通过它自己,网格类有 .x,.y,.z 属性,可以绘制

  1. my_mesh = mesh.Mesh.from_file(file)
  2. x = my_mesh.x
  3. y = my_mesh.y
  4. z = my_mesh.z
  5. mlab.points3d(x, y, z)
  6. mlab.show()

字符串
结果是缓慢和相当糟糕的视觉效果
x1c 0d1x的数据
mesh也有 vectors 属性,但我不知道如何使用它。在matplotlib中,我可以用途:

  1. figure = plt.figure()
  2. axes = mplot3d.Axes3D(figure)
  3. axes.add_collection3d(mplot3d.art3d.Poly3DCollection(my_mesh.vectors))
  4. plt.show()


结果



是工作的财产,但非常缓慢,几乎无法使用。

有没有更好的方法来解决这个问题?

4dbbbstv

4dbbbstv1#

Numpy-stl库以numpy数组的形式加载stl文件。'Vectors'属性是Nx 3x 3 numpy数组。简单地说,这个数组是形状的面的集合。因此N代表面的数量,3是定义图形面的点数,最终尺寸表示3D空间中的点坐标。
在大多数库中,要绘制3D形状,您需要定义两件事-点的坐标和点的索引以绘制图形的面。
numpy-stl简化了过程,因为所有的点都是唯一的,并且是有序的。这意味着定义面的点的索引只是顶点数组中的索引。
另外值得一提的是,你需要定义的不是点本身,而是x,y,z分别。同样的计数面。
基于此,我们冷写这个。我选择plotly,因为它快速和互动

  1. import plotly.graph_objects as go
  2. from stl import mesh # numpy-stl
  3. import numpy as np
  4. data = mesh.Mesh.from_file('fabric.stl')
  5. points = data.vectors.reshape(-1,3) # reshape Nx3x3 to N*3x3 to convert polygons to points
  6. faces_index = np.arange(len(points)) # get indexes of points
  7. fig = go.Figure(data=[
  8. go.Mesh3d(
  9. x = points[:,0], # pass first column of points array
  10. y = points[:,1], # .. second column
  11. z = points[:,2], # .. third column
  12. # i, j and k give the vertices of triangles
  13. i = faces_index[0::3], # indexes of the points. k::3 means pass every third element
  14. j = faces_index[1::3], # starting from k element
  15. k = faces_index[2::3], # for example 2::3 in arange would be 2,5,8,...
  16. opacity = .9
  17. )
  18. ])
  19. fig.show()

字符串
显示:x1c 0d1x
图片来自默认的windows stl文件查看工具:

结果看起来是正确的。请忽略绘图顶部的蓝点和顶部环附近的孔,这是文件工件,并在两个变体中呈现。

展开查看全部
c0vxltue

c0vxltue2#

由于顶点被多次使用,所以首先在向量数组中找到唯一的点可能会有所帮助。下面是一个使用pandas删除重复项并定义三角形和open3d进行可视化的示例。
df.drop_duplicates删除了重复的顶点,现在我们需要根据旧的顶点列表找到新的顶点列表的索引。我用pandas merge做到了这一点。

  1. import open3d as o3d
  2. import numpy as np
  3. import pandas as pd
  4. def extract_vertices_and_triangles(mesh_vertices):
  5. # Reshape the array to (n*3, 3)
  6. flat_vertices = mesh_vertices.reshape(-1, 3)
  7. # Create a DataFrame for easy manipulation
  8. df = pd.DataFrame(flat_vertices, columns=["x", "y", "z"])
  9. # Create a new DataFrame with unique vertices
  10. unique_df = df.drop_duplicates(subset=["x", "y", "z"]).reset_index(drop=True)
  11. # Create a mapping from old indices to unique indices
  12. merged_df = (
  13. df.reset_index()
  14. .merge(unique_df.reset_index(), on=["x", "y", "z"], how="right")
  15. .sort_values(by="index_x")
  16. )
  17. triangles = merged_df["index_y"].to_numpy()
  18. triangles = triangles.reshape(-1, 3)
  19. # Reshape the unique vertices to the original shape
  20. unique_vertices = unique_df[["x", "y", "z"]].values
  21. return unique_vertices, triangles
  22. if __name__ == "__main__":
  23. armadillo_mesh = o3d.data.ArmadilloMesh()
  24. mesh = o3d.io.read_triangle_mesh(armadillo_mesh.path)
  25. mesh.compute_vertex_normals()
  26. o3d.visualization.draw_geometries([mesh])
  27. vertices = np.array(mesh.vertices)
  28. triangles = np.array(mesh.triangles)
  29. np_vertices = vertices[triangles]
  30. vert, triangle = extract_vertices_and_triangles(np_vertices)
  31. # Create Open3D TriangleMesh
  32. mesh = o3d.geometry.TriangleMesh()
  33. mesh.vertices = o3d.utility.Vector3dVector(vert)
  34. mesh.triangles = o3d.utility.Vector3iVector(triangle)
  35. mesh.compute_vertex_normals()
  36. # Visualize the extracted mesh
  37. o3d.visualization.draw_geometries([mesh])

字符串

展开查看全部

相关问题