python - 使用 python 从 3d .stl 文件中查找 2D 横截面中的材料和空气
问题描述
我想从 3D 文件创建 2D 横截面,而不会丢失什么是材料和什么是空气的信息。
最后,我想获得一个字典,其中包含构成材料和空气夹杂物的最外点(可以是多个),即
"material" : [[x1,y1],[x2,y2]...]
"air_inclusions": [[[x11,y11],[x12,y12],...],[[x21,y21],[x22,y22],...],[[x31,y31],[x32,y32],...]]
这是我如何尝试的示例:
我有以下 .stl 文件,您可以在此处下载https://filebin.net/c9o0zy4bnv8dvuew
使用神奇的 python 包trimesh,我可以导入 .stl 文件
import trimesh
import numpy as np
mesh = trimesh.load_mesh(r"PATH_TO_FILE")
# give it a color
mesh.visual.face_colors = [100, 100, 100, 255]
# and show it
mesh.show(viewer='gl')
创建 2D 幻灯片
# I can create a 2D slice of the geometry at origin [0,0,5] and slice-plane with normal direction [0,0,1]
slice = mesh.section(plane_origin=[0,0,5],
plane_normal=[0,0,1])
slice.show(viewer='gl')
提取顶点
# take 2D slice (before was still 3D)
slice_2D, to_3D = slice.to_planar()
# get vertices
vertices = np.asanyarray(slice_2D.vertices)
# plot
import matplotlib.pyplot as plt
x,y = vertices.T
plt.scatter(x,y,s=0.4)
plt.show()
我检索有关什么是物质和什么是空气的信息的方法
我的假设
最外面的点定义了材质的边界。内的所有点都定义了空气夹杂物的边界。
我得到最外点 - >凸包
from scipy.spatial import ConvexHull
# compute the hull
hull = ConvexHull(vertices)
# plot
plt.plot(vertices[:,0], vertices[:,1], 'o')
for simplex in hull.simplices:
plt.plot(vertices[simplex, 0], vertices[simplex, 1], 'k-')
要知道外壳内的所有点,我使用这个答案What's an effective way to find if a point is in the convex hull of a point cloud?
# Source: https://stackoverflow.com/questions/16750618/whats-an-efficient-way-to-find-if-a-point-lies-in-the-convex-hull-of-a-point-cl
def in_hull(p, hull):
"""
Test if points in `p` are in `hull`
`p` should be a `NxK` coordinates of `N` points in `K` dimensions
`hull` is either a scipy.spatial.Delaunay object or the `MxK` array of the
coordinates of `M` points in `K`dimensions for which Delaunay triangulation
will be computed
"""
from scipy.spatial import Delaunay
if not isinstance(hull,Delaunay):
hull = Delaunay(hull)
return hull.find_simplex(p)>=0
我收集剩余的积分
# Remaining points
remaining = []
for i,in_hull in enumerate(in_hull(vertices,hull.simplices)):
if in_hull:
remaining.append(vertices[i])
问题
剩下的点只有两点,但应该更多,如上图所示。为什么会这样,我该如何解决?
[TrackedArray([21.60581633, 8.99397324]), TrackedArray([12.95590211, 23.97608075])]
如果有多个空气夹杂物,你知道我如何找到所有的空气夹杂物吗? IE
你可以在这里找到文件:https ://filebin.net/6blzvrrwhanv0jib
解决方案
多亏了形状优美的多边形,在其上构建了 trimesh,您无需遍历顶点。您可以使用一些内置功能。创建 2D 路径后,您就快到了。路径有两个属性:polygons_full
和polygons_closed
。第一个是最外面的多边形,没有内部的多边形,第二个是路径的所有多边形。
你可以简单地做:
slice_2D, to_3D = slice.to_planar()
# create a new figure to which you can attach patches
fig = plt.figure(1)
ax = fig.add_subplot(111)
# Here you get your outmost polygons and add them as patches to your plot
for p in slice_2D.polygons_full:
ax.add_patch(PolygonPatch(p))
# this is needed due to the differences of polygons_full and polygons_closed to check, if the polygon is one of the outer polygons
outer_polys = [x.exterior for x in slice_2D.polygons_full]
# iterate over all polygons and check, whether they are one of the outmost polygons. If not plot it (the outmost ones have already been added as patches).
for p in (slice_2D.polygons_closed):
if p.exterior not in outer_polys:
plt.plot(*(p.exterior.xy), 'r')
# show the plot
plt.show()
interior
或者您可以使用多边形的属性来缩短它:
slice_2D, to_3D = slice.to_planar()
for p in slice_2D.polygons_full:
plt.plot(*(p.exterior.xy),'k')
for r in p.interiors:
plt.plot(*zip(*r.coords), 'b')
内部是填充多边形的“洞”,所以这应该正是您想要的。它们是一个LinearRing
,因此您不能直接使用 Polygon 属性。
推荐阅读
- angular - 路由不起作用我的代码有什么问题
- spring-boot - 无法将 HTTP 请求发送到另一个 docker 容器
- mysql - 引用的文件包含 STS 中的错误
- asp.net-core - 在 ASPNetCore 2.2 Startup.cs 中,Configure 属性只有 {get},但它被分配了一个引用。为什么是这样?
- c# - 替代非 ASP.NET 特定的全局静态数据
- apache - Apache AH01903:配置 CA 证书链失败!重启解决了
- r - 错误:找不到 Python 模块 tensorflow.python.keras
- python - 如何(/如果)使用 dask 转置分布式 3D numpy 数组?
- c# - 如何使用 NSwag 为 Web 套接字生成客户端代码
- android - 更新后对回收站视图进行排序的好方法和一些疑问