0

我正在开发一个 3D 建筑应用程序。该建筑是在 3D 网格(如魔方)上完成的,网格的每个单元格都是实心立方体或 45 度坡度。为了说明,这是我从谷歌图片中提取的倒角立方体的图片:

在此处输入图像描述

忽略右边的图像,焦点是左边的那个。目前,在构建阶段,我分别绘制了每个单元格的每个面。但是,在导出它时,我想对其进行简化。所以在上面的立方体中,我希望上下左右后正面分别由一个四边形(两个三角形)组成,并且边缘将从两个四边形减少到单个四边形。

我最近一直在尝试做的事情如下:

从各个方向逐层迭代形状,并为每一层找出一个很好的简化(删除重叠边以创建单个多边形,然后分割多边形以避免孔,使用耳朵剪裁进行三角剖分)。

显然把事情复杂化了(至少我希望是这样)。如果我有一个顶点、法线和索引列表(目前有很多重复的顶点),是否有一些简洁的方法来简化?限制是索引不能在面之间共享(因为我需要法线指向不同的方向),但否则我不介意它不是最快或最佳的解决方案,我宁愿它很容易实现和维护。

编辑:为了进一步澄清,我已经执行了隐藏面移除,这不是问题。其次,最重要的是没有质量下降,只是简化了面本身(我需要保留锋利的边缘)。

4

3 回答 3

0

感谢 Roger Rowland 的精彩提示!如果其他人偶然发现了这个问题,以下是我所做工作的简短摘要:

首先要解决的问题:确保您尝试简化的网格是流形网格!这是遍历半边数据结构的要求。我遇到问题的一个例子是重叠的四边形和三角形;我最初决定只保留整个四边形,而不是将它们分成三角形,因为这样更容易,但这会导致边缘破坏半边网格。

一旦网格是多方面的,从顶点和面创建一个半边网格。

完成后,抽取网格。我通过边缘折叠来做到这一点,确定哪些边缘通过法线偏差折叠(在我的情况下,如果折叠产生的面的法线不等于它们的原始值,则不执行折叠)。

起初我是通过自己的实现来做到这一点的,但我开始遇到令人沮丧的错误,因此选择使用 OpenMesh(它很容易上手)。

还有一个问题我还没有解决:如果有两个相互斜对角的立方体,相互接触,结果是一条边连接着四个面:一条复杂的边!我怀疑遍历边检查连接的面数,然后通过复制适当的顶点来解决是微不足道的。但话虽如此,我不会花时间修复它,除非它以后成为一个关键问题。

于 2014-02-05T22:17:54.070 回答
0

我给出一个理论上的答案。

对于左图,找到所有具有相同法线(相同 x、y、z 坐标)的“边缘共享三角形”(使其单位法线,因为矢量的正缩放方向不受影响)。合并它们。然后用最大纵横比对其进行三角剖分将给出您想要的解决方案。

我现在提出了另一种简化网格的简单可行的方法。取NORMALS并除以幅度(坐标平方和的根),给出单位法线向量。并取相邻三角形并在它们之间取DOT PRODUCT(将 x、y、z 坐标相乘并相加)。它给出了这些法线或三角形之间角度的余弦值。取一个范围(如 0.99-1)并考虑该范围内的所有相邻三角形相对于引用三角形并将它们合并并重新三角化。我们绝对可以忽略一些面积较小的奇怪方向的三角形。

还有另一个建议是更简单的网格减少,例如您的左图或建筑图。定义一个预定义的面数(这里 6+8 = 14)表示法线的值,并根据接近这些面的方向(按点积)对所有面进行分类并合并和重新三角化。

于 2018-10-24T12:45:14.077 回答
-1

谷歌“网格简化”。您会发现这个问题是一个巨大的问题,并且需要大量研究。看看这些介绍性资源:链接(第 11 页开始好东西)和链接。CGAL 也有一个很好的讨论:链接

一旦熟悉了这些问题,您就会做出一些对问题应用简化的决定。简化应该多快?准确性有多重要?(迭代顶点聚类是一种快速而肮脏的方法,但它的结果可能是任意丑陋的。)你能依赖第 3 方库吗?(即 CGAL?GTS似乎不再活动,但还有其他活动)。

于 2014-01-27T15:21:21.107 回答