将网格拆分为Openmesh中的连接组件

时间:2014-02-01 19:20:20

标签: c++ mesh openmesh

我有一个obj文件网格,我想通过OpenMesh从中提取连接的组件。我可以找到边界顶点和边,但有没有办法直接将网格分割成Openmesh中的连通组件?

2 个答案:

答案 0 :(得分:2)

OpenMesh不提供此功能(库的目标仅是提供网格数据结构)。构建在OpenMesh之上的网格处理库OpenFlipper是更合适的候选者,但也不提供此功能。但是,您可以在代码库中找到MeshTools/MeshInfoT.cc一个componentCount函数,该函数计算连接组件的数量(它只是在顶点图上进行深度优先搜索)。

基于此功能,您应该能够编写代码以将网格分割为其连接的组件:

  1. 为每个顶点添加连接的组件编号属性(例如,初始化为-1,这意味着尚未访问顶点)。
  2. 使用深度优先搜索(或广度优先搜索..)遍历网格顶点,并为每个顶点设置此组件编号:
    1. 找到未访问的顶点时,增加当前连接的组件编号并创建新的连接组件。找到的顶点用作此组件的种子顶点。
    2. 设置从连接组件的种子顶点遍历的所有顶点的组件编号。
  3. 遍历完成后,已知连接组件的总数,对于每个顶点,其组件编号也是已知的。根据此信息,可以构建连通的组件网格(属于组件的所有顶点都是已知的,并且可以使用顶点的半边参考来识别面)。对于每个连接的组件:
    1. 为此连接组件创建新网格。
    2. 添加来自同一连接组件的所有顶点。创建从初始网格中的顶点句柄到连接组件的新网格中相应顶点句柄的映射。
    3. 找到组件的所有面:为了实现这一点,一种简单的方法可以迭代组件的所有顶点,并且每个顶点迭代它所属的所有面。对于每个新遍历的面,在引用新顶点句柄的新组件网格中创建一个面(使用从旧顶点句柄到新顶点句柄的映射)。

答案 1 :(得分:0)

实际上,我通过使用网格的对偶图来解决此问题。由于如果您直接在原始图形上进行图形搜索(BFS或DFS等),则无论您在每个顶点或每个边上标记连通性,都始终需要处理一些特殊情况,例如两个循环:这两个环重合,除了一个顶点不重合,只剩下一个面: Yellow and blue loops leaves one Face out

因此,要检查网格是否被切片,我们实际上将重点放在 face 连接上。因此,我只需要执行对偶运算(在Openmesh中迭代并建立对偶关系即可。) Dual relation

然后,在对偶图中执行DFS / BFS。每当将下一个顶点放入待处理列表时,都要检查该边是否是一个循环上的边的对偶(请注意该边必须在一个循环上,而不是在两个循环上分别是两个顶点)。最后,只需简单地检查顶点数量(如果循环未对网格进行切片,则该数量应与对偶图中的原始顶点数量相同。)

您还可以在执行BFS / DFS时添加标签以标识不同的连接部分。