【问题标题】:Convex Hull to Voxel Grid凸壳到体素网格
【发布时间】:2020-08-28 02:47:09
【问题描述】:

我有一个给定的 3D 网格,它是通过获取一组随机点并找到这些点的凸包来构造的。然后我使用 open3d 和 trimesh 将 conex hull 转换为网格。我想知道如何将此网格或凸包本身转换为填充的布尔体素网格。

我可以使用 trimesh 来获得某种体素网格,但内部似乎是空心的。我想要一个布尔体素网格,它为凸包内的体积提供真值,否则为假。

【问题讨论】:

    标签: python geometry mesh convex-hull


    【解决方案1】:

    只需栅格化凸多边形体积 ...

    1. 计算任何内点c

      对于凸包,它足以计算平均点,因此将所有 n 点加在一起除以 n

    2. 计算每个面的法线

      每个三角形面有3个点p0,p1,p2所以

      nor = cross( p1-p0 , p2-p0 );
      

      并选择方向,使其指向凸包之外:

      if ( dot( p0-c , nor ) < 0) nor = -nor;
      
    3. 遍历所有体素

      所以 3 个嵌套的 for 循环穿过您的网格。让我们调用实际的迭代点q

    4. 在凸包内测试

      如果q-face_pointface_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)
      

      仍然保持打开状态,以防有人有更好的解决方案。

      【讨论】:

        猜你喜欢
        • 2015-02-07
        • 2016-09-28
        • 1970-01-01
        • 2012-06-28
        • 2018-05-17
        • 1970-01-01
        • 2021-11-04
        • 2012-06-13
        • 2017-11-09
        相关资源
        最近更新 更多