3d 选择由某些顶点子集包围的网格的所有面

3d 选择由某些顶点子集包围的网格的所有面,3d,geometry,mesh,connected-components,3d,Geometry,Mesh,Connected Components,我很确定这是一个经常被问到的问题,但无论我如何重新措辞,我都无法在互联网上找到任何答案 我正在制作一个用户界面,供用户通过选择多个顶点来选择网格内的区域。 更精确地说,给定一个三角形网格和一组顶点(这是网格顶点的子集),我希望得到由顶点子集包围的所有面 我查阅了一些算法,如多边形中的点、Dijkstra算法等,但它们似乎没有帮助。 非常感谢。首先,您需要在网格上嵌入一条表示轮廓的闭合多段线。一旦你有了这个轮廓,你可以填充它的内部以得到相应的面 等高线 有多种方法可以获得等高线。一种方法是使用类似

我很确定这是一个经常被问到的问题,但无论我如何重新措辞,我都无法在互联网上找到任何答案

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

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

非常感谢。

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

等高线 有多种方法可以获得等高线。一种方法是使用类似*的路径查找算法来查找选择集中两个连续顶点之间的最短路径(即
(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
首先,应该从网格本身中明确“左”和“右”的概念。面顶点通常按逆时针或顺时针顺序排列(面缠绕顺序)。因此,每个非边界边
{v1,v2}
存在于两个面中:一个面为
(v1->v2)
,另一个面为
(v2->v1)
。根据缠绕顺序,可以选择包含正确方向边的面。然后,如果你知道你的轮廓的缠绕顺序,这就是你所需要做的。也就是说,如果轮廓始终为顺时针方向,网格面始终为顺时针方向,则完成

如果轮廓可以是任意方向,事情就会变得复杂一些。然后,不清楚用户想要标记哪个部分(假设一个球体的轮廓是赤道)。有两个简单的选择:

  • 使用较小的区域
  • 让用户在目标区域内选择一个点并使用该点
  • 对于这两个选项,您需要从轮廓的两个方向执行BFS(精确地说,它们是两个单独的BFS)。出于性能方面的考虑,最好同时执行这两项操作。然后,当
    O
    (选项1,该区域将是较小的区域)中的任一区域用完开放面时,或者如果遇到附加点(选项2,仅针对该区域继续BFS),可以中止


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

    是你的轮廓顶点集是有序的还是随机散布在网格上?你的网格是流形吗?轮廓顶点集是有序的,网格是流形的。谢谢你的回复,我已经实现了A*,现在它可以在BFS上工作了,我注意到你在你的代码中写了
    add f to O add f to V
    //do BFS
    下,应该是
    add g
    calculate the face left of e