【问题标题】:Convex Hull to Voxel Grid凸壳到体素网格
【发布时间】:2020-08-28 02:47:09
【问题描述】:
我有一个给定的 3D 网格,它是通过获取一组随机点并找到这些点的凸包来构造的。然后我使用 open3d 和 trimesh 将 conex hull 转换为网格。我想知道如何将此网格或凸包本身转换为填充的布尔体素网格。
我可以使用 trimesh 来获得某种体素网格,但内部似乎是空心的。我想要一个布尔体素网格,它为凸包内的体积提供真值,否则为假。
【问题讨论】:
标签:
python
geometry
mesh
convex-hull
【解决方案1】:
只需栅格化凸多边形体积 ...
-
计算任何内点c
对于凸包,它足以计算平均点,因此将所有 n 点加在一起除以 n
-
计算每个面的法线
每个三角形面有3个点p0,p1,p2所以
nor = cross( p1-p0 , p2-p0 );
并选择方向,使其指向凸包之外:
if ( dot( p0-c , nor ) < 0) nor = -nor;
-
遍历所有体素
所以 3 个嵌套的 for 循环穿过您的网格。让我们调用实际的迭代点q
-
在凸包内测试
如果q-face_point 和face_normal 之间的所有点积为负或为零,则q 位于凸包内...因此遍历所有三角形/面并测试...之后填充体素或不是……
如果你想要更快的东西(以防你有太多的三角形)有这样的方法:
- 栅格化三角形和填充
- 四面体化体积并分别光栅化每个四面体
- 从外接立方体和填充的 6 个面渲染深度图
【解决方案2】:
所以我想出了一个可以使用 trimmesh 实现的简单解决方案。这个想法是生成大量坐标并查询网格以确定坐标是否在网格/凸包内。如果坐标在网格内,则在网格中表示为 1,否则为 0。 res 是一个数组,用于确定沿 x、y、z 轴的分辨率。更高的分辨率提供了更好的网格表示。
x, y, z = np.indices((res[0], res[1], res[2]))
total_voxels = np.product(res)
coords = np.concatenate((np.reshape(x/res[0], [total_voxels, 1]),
np.reshape(y/res[1], [total_voxels, 1]),
np.reshape(z/res[2], [total_voxels, 1])), axis=1)
out = mesh.contains(coords)
voxel = np.reshape(out, res)
仍然保持打开状态,以防有人有更好的解决方案。