我正在使用序列化管道。我正在拿一个模型并将其导出。我不希望导出任何带孔的模型。我如何检测一个洞并报告错误?
我可以访问所有顶点,边,面等。
这是我的意思的图片。
你可以看到脸上有个洞。我对几何学很陌生,所以请尝试用外行术语来解释。
答案 0 :(得分:5)
如果3D对象是简单的",意味着它没有洞,则它满足Euler's Formula for Polyhedra,V - E + F = 2
其中V
是数字在图中的顶点,E
是边数,F
是面数。如果您可以轻松获得这三个数字,则可以计算公式V - E + F
。如果结果不是2,则对象有一个洞(或一些其他病理,如捏)。实际上,您可以通过V - E + F
告诉对象有多少个洞:如果数字为0,则它有一个洞;如果数字是-2,它有两个洞;等
计算V
,E
和F
可能有点棘手,因为顶点通常由两条或更多条边共享,而边通常由两条面共享。你不想超额计算;如果三个边在单个顶点相交,则只需要计算一次顶点,而不是三次。
不仅如此,当形状有洞时(这与你感兴趣的情况完全相同),很容易犯错误。避免犯错误的最简单方法是将数字分成凸起部分,例如triangulation。
公式并没有告诉你哪个面有洞,但如果你知道这个图有一个洞,你可以单独对每个面部应用欧拉公式,再次进行三角测量。在这种情况下,没有洞的面将会V - E + F = 1
,其中V,E,F
现在仅限于所讨论的面部。 (如果将面部外的区域计算为另一个(无限)面,则解析与先前公式的差异)。带孔的面将具有V - E + F < 1
。
例如,平面上的三角形有V=3
,E=3
和F=1
(由其内部表示的三角形的&#34;面&#34;){ {1}}。另一方面,内部具有类似形状的三角形孔的三角形将连接内部和外部三角形的相应顶点,V-E+F=1
,V=6
和E=9
用于{{ 1}}。在这种情况下,我把这个数字分成了三个凸四边形。
大多数关于计算机图形学的书籍都讨论过这个主题。
答案 1 :(得分:3)
如果我理解正确,你想检测带孔的多边形。现在,如何表示具有孔的多边形可以随每个软件而变化(一些存储单独的内部轮廓列表)。但是,3D包中的常见表示(包括像OBJ这样的格式)使用平面顶点表示,它们看起来像这样:
...其中2,6和1,7将是在同一多边形中存储两次的相同顶点索引(图中的数字表示面点索引)。请注意,这个从1,7到2,6的边缘可以隐藏在某些软件中,但即使软件将多边形顶点存储在索引/指针的平面列表中,它也是不可见的。
因此,快速判断多边形是否具有仅具有面数据(例如,来自OBJ文件)的此类表示的孔的方法是查看它是否具有顶点索引的重复条目。如果相同的顶点索引在多边形中重复多次,则它有一个洞。
现在有一种情况可以找到空内轮廓的重复顶点,如下所示:
......其中2,4焊接(相同的顶点)。如果要区分这些情况,可以在连接外部轮廓到内部轮廓的边只有一个顶点而不是两个顶点时检测到它们。在这种情况下,内部轮廓是空的,这个多边形只是一个时髦的(可能通过CSG /平面切片操作创建)。
如果你想要一个非常强大的解决方案,那么值得编写一个&#34; unflattens&#34;通过将列表分开,将这些平面轮廓列表分成多个内部/外部组,其中找到将一个轮廓连接到另一个轮廓的重复边缘。如果内部组的顶点少于3个,则它们可能只是没有视觉上明显的洞的时髦多边形。如果他们有3个或更多,那么他们符合显示你可以看到的洞所需的标准。如果内部轮廓不能形成一个完整的孔,你可以抛出内部轮廓并保持外部轮廓(在这种情况下,它就像保持三点三角形外观一样上面的图片,同时抛出那些冗余的顶点,清理过程中的几何形状,并给你从{1,2 / 4,5}形成的三角形。
如果您不介意导出未焊接的几何图形,只要不是很时髦(没有孔或内部轮廓)就可以简单地克隆(制作唯一的)重复的顶点,那么您可以应用一个简单的解决方案一个多边形,基本上没有焊接它,如下:
这比完整的镶嵌细分解决方案要容易一些,它最终会为您提供没有任何孔或单独内部的多边形。为了示范,我在视觉上移动了2和4,以强调他们现在分开顶点,但你不必这样做(它们可能是重合的)。
如果您的曲面细分器不支持孔,这种非焊接技术也很有用。您可以应用此技术来焊接多边形,对其进行细分,然后焊接/合并返回重合顶点以获得最终结果。