检测几何中的孔

Detect hole in geometry

我正在使用序列化管道。我正在制作模型并将其导出。我不希望导出任何带有孔洞的模型。如何检测漏洞并报告错误?

我可以访问所有顶点、边、面等

这是我的意思的图片。

如你所见,脸上有个洞。我对几何还很陌生,所以请尝试用通俗易懂的术语进行解释。

如果一个3D物体是"simple",表示它没有孔洞,则满足Euler's Formula for PolyhedraV - E + F = 2 其中V是顶点数图中,E是边数,F是面数。如果你能很容易地得到这三个数字,你就可以计算公式V - E + F。如果结果不是 2,则对象有一个洞(或其他一些病理现象,如捏)。事实上,你可以通过V - E + F来判断这个物体有多少个洞:如果数字是0,它就有一个洞;如果数字是0,那么它有一个洞;如果数字是-2,它有两个孔;等等

计算 VEF 可能有点棘手,因为顶点通常由两条或多条边共享,而边通常由两个面共享。你不想多算;如果三个边在一个顶点相交,你只想计算顶点一次,而不是三次。

不仅如此,当形状有孔(这正是您感兴趣的情况)时,很容易计算错误。避免犯错的最简单方法是将图形分成凸部分,例如 triangulation.

该公式不会告诉您哪个面有孔,但如果您知道图形有孔,您可以将欧拉公式分别应用于每个面,再次使用三角测量。在这种情况下,没有孔的面将具有 V - E + F = 1,其中 V,E,F 现在仅限于所讨论的面。 (如果将人脸以外的区域算作另一个(无限)人脸,则与前面公式的差异得到解决)。有孔的面会有 V - E + F < 1.

例如,平面上的三角形有V=3E=3F=1(其内部表示的三角形的"face")给出V-E+F=1。另一方面,内部有一个类似形状的三角形孔的三角形,其中连接内部和外部三角形的相应顶点,将有 V=6E=9F=3 for V-E+F=0。在这种情况下,我将图形分解为三个凸四边形。

大多数关于计算机图形学的书籍都讨论了这个主题。

如果我没理解错的话,你想检测多边形有洞。现在如何表示带孔的多边形可能因每个软件而异(有些存储单独的内部轮廓列表)。但是,3D 包(包括 OBJ 等格式)中的常见表示使用平面顶点表示,它看起来像这样:

...其中 2,6 和 1,7 将是在同一多边形中存储两次的相同顶点索引(图片中的数字表示面点索引)。请注意,从 1,7 到 2,6 的这条边可能会隐藏在某些软件中,但如果软件将多边形顶点存储在 indices/pointers.

的平面列表中,即使它不可见,它仍然存在

因此,判断一个多边形是否有一个孔洞的方法是只给定面数据(例如:来自 OBJ 文件),看看它是否有重复的顶点索引条目。如果相同的顶点索引在多边形中重复多次,则它有一个洞。

现在有一种情况可以找到空内轮廓的重复顶点,如下所示:

... 其中 2,4 被焊接(相同的顶点)。如果要区分这些情况,可以在连接外部轮廓和内部轮廓的边仅重复一个顶点而不是两个顶点时检测它们。在那种情况下,内部轮廓是空的,这个多边形只是一个时髦的多边形(可能是通过 CSG/plane 切片操作创建的)。

如果你想要一个真正强大的解决方案,值得编写一个例程,将这些平面轮廓列表 "unflattens" 分成多个 interior/exterior 组,方法是将列表分开,其中重复的边缘将一个轮廓连接到另一个轮廓被发现。如果内部组的顶点少于 3 个,那么它们可能只是没有视觉上明显孔洞的时髦多边形。如果他们有 3 个或更多,则他们符合显示一个您可以目视看到的洞所需的标准。如果内部轮廓没有形成一个完整的洞,你可以扔掉内部轮廓并保留外部轮廓(在这种情况下就像只保留上图中的 3 点三角形外部,同时扔掉那些冗余顶点,有点清理过程中的几何体并为您提供由 {1, 2/4, 5}) 形成的三角形。

如果您不介意导出未焊接的几何体,只要它不时髦(没有孔或内部轮廓),您可以应用的一个简单解决方案是简单地克隆(制作唯一的)多边形中重复的顶点,基本上拆开它,像这样:

这比成熟的曲面细分解决方案要容易一些,而且它最终仍然会为您提供没有任何孔洞或单独内部结构的多边形。为了演示,我在视觉上将 2 和 4 分开,以强调它们现在是单独的顶点,但您不必这样做(它们可以重合)。

如果您的曲面细分器不支持孔,这种拆焊技术也很有用。您可以应用此技术来拆开多边形,对其进行细分,然后 weld/merge 返回重合顶点以获得最终结果。