凸包到体素网格
Convex Hull to Voxel Grid
我有一个给定的 3D 网格,它是通过获取一组随机点并找到这些点的凸包来构建的。然后我使用 open3d 和 trimesh 将 conex 船体转换为网格。我想知道如何将此网格或凸包本身转换为填充的布尔体素网格。
我可以使用 trimesh 获得某种体素网格,但内部似乎是空心的。我想要一个布尔体素网格,它为凸包内的体积给出 true,否则为 false。
简单地栅格化你的凸多边形体积...
计算任意内点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
就在你的凸包内......所以遍历所有 triangles/faces 并测试...之后要么填充体素要么不填充...
如果你想要更快的东西(以防你有太多三角形),有如下方法:
- 栅格化三角形并填充
- 四面体化体积并分别光栅化每个四面体
- 从外描立方体和填充的 6 个面渲染深度图
所以我想出了一个可以使用 trimmesh 实现的简单解决方案。这个想法是生成大量坐标并查询网格以确定坐标是否在 mesh/convex 船体内。如果坐标在网格内,则在网格中指示为 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)
我有一个给定的 3D 网格,它是通过获取一组随机点并找到这些点的凸包来构建的。然后我使用 open3d 和 trimesh 将 conex 船体转换为网格。我想知道如何将此网格或凸包本身转换为填充的布尔体素网格。
我可以使用 trimesh 获得某种体素网格,但内部似乎是空心的。我想要一个布尔体素网格,它为凸包内的体积给出 true,否则为 false。
简单地栅格化你的凸多边形体积...
计算任意内点
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
就在你的凸包内......所以遍历所有 triangles/faces 并测试...之后要么填充体素要么不填充...
如果你想要更快的东西(以防你有太多三角形),有如下方法:
- 栅格化三角形并填充
- 四面体化体积并分别光栅化每个四面体
- 从外描立方体和填充的 6 个面渲染深度图
所以我想出了一个可以使用 trimmesh 实现的简单解决方案。这个想法是生成大量坐标并查询网格以确定坐标是否在 mesh/convex 船体内。如果坐标在网格内,则在网格中指示为 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)