【问题标题】:Selecting all faces of a mesh surrounded by some vertex subset选择由某个顶点子集包围的网格的所有面
【发布时间】:2018-09-16 13:42:59
【问题描述】:

我很确定这是一个常见问题,但无论我如何改写它,我都无法在互联网上找到任何答案。

我正在制作一个用户界面,供用户通过选择多个顶点来选择网格内的区域。
更准确地说,给定一个三角形网格和一组顶点(它是网格顶点的子集),我想得到所有被顶点子集包围的面。

我查找了一些算法,例如多边形中的点、Dijkstra 算法等,但它们似乎没有帮助。
非常感谢。

【问题讨论】:

  • 你的轮廓顶点集是有序的还是随机散布在网格上的?你的网格是歧管吗?
  • 轮廓顶点集是有序的,网格是流形的。

标签: 3d geometry mesh connected-components


【解决方案1】:

首先,您需要在网格上嵌入一条闭合折线来表示轮廓。一旦你有了这个轮廓,你就可以填充它的内部来得到对应的面。

等高线

有多种方法可以获得等高线。一种方法是使用像 A* 这样的路径查找算法来查找选择集中两个连续顶点之间的最短路径(即(v0 -> v1), (v1 -> v2) ... (vn -> v0))。这将为您提供一条折线,表示为网格的定向边缘。

根据用户选择的表现,您可能需要稍微清理一下轮廓。例如,如果轮廓包含一个在两个方向上都遍历的边(例如v1 -> v2 -> v3 -> v2 -> v4 -> ...),您可以直接杀死这对边。如果您有自交点,则需要进行类似的清理。

填充内部

一旦有了定向轮廓线,就可以通过广度优先遍历来填充其内部。这个想法是从轮廓边缘开始,然后迭代地添加入射面。一个基本的算法可以概括如下:

Input:
    E: directed edges of the contour

O <- empty list of faces to examine
V <- empty list of visited faces    

// Initialization
for every e in E:
    calculate the face left of e (-> f)
    add f to O
    add f to V

// Do BFS
while O is not empty:
    take the first element out of O (-> f)
    for all faces g adjacent to f and not in V:
        add g to O
        add g to V

在此过程之后,选定的面将位于V。然而,有一个关键部分:

calculate the face left of e

首先,left ofright of 的概念应该从网格本身清楚。面的顶点通常按逆时针或顺时针顺序排列(面缠绕顺序)。因此,每条非边界边{v1, v2} 都存在于两个面上:一次为(v1 -&gt; v2),一次为(v2 -&gt; v1)。根据缠绕顺序,您可以选择包含正确方向边的面。然后,如果您知道轮廓的缠绕顺序,这就是您需要做的一切。 IE。如果你的轮廓总是顺时针,而你的网格面总是顺时针,你就完成了。

如果轮廓可以在任一方向上,事情就会变得更加复杂。然后,不清楚用户想要标记的部分(考虑轮廓为赤道的球体)。有两个简单的选择:

  1. 使用较小的区域
  2. 让用户在目标区域内选择一个点并使用该点。

对于这两个选项,您需要在轮廓的两个方向上进行 BFS(准确地说,它们是两个独立的 BFS)。出于性能原因,最好同时执行这两项操作。然后,只要任一区域用完 O 中的开放面(选项 1,此区域将是较小的区域)或遇到附加点(选项 2,仅针对此区域继续 BFS),您就可以中止.

要有效地执行此 BFS,您需要一种将边映射到其相应面和/或网格上的邻域数据结构的方法。如果你想使用后者,你可能需要考虑一个半边数据结构

【讨论】:

  • 感谢您的回复,我已经实现了 A*,它现在可以在 BFS 上工作,我注意到在您的代码中您在 //do BFS 下编写了 add f to O add f to V,应该是 add g
猜你喜欢
  • 2019-08-21
  • 1970-01-01
  • 2019-04-21
  • 2016-05-17
  • 1970-01-01
  • 1970-01-01
  • 2011-06-30
  • 1970-01-01
  • 2015-07-21
相关资源
最近更新 更多