在 Openmesh 中将网格分割成连接的组件[关闭]

问题描述 投票:0回答:2

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

c++ mesh openmesh
2个回答
3
投票

OpenMesh 不提供此功能(该库的目标只是提供网格数据结构)。 OpenFlipper 是一个构建在 OpenMesh 之上的网格处理库,是更合适的候选者,但也不提供此功能。不过,您可以在 MeshTools/MeshInfoT.cc 的代码库中找到

componentCount
函数,用于计算连接组件的数量(它只是在顶点图上进行深度优先搜索)。

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

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

0
投票

实际上,我是通过使用网格的对偶图来解决这个问题的。因为如果你直接在原始图上进行图搜索(BFS或DFS等),无论你在每个顶点或每条边上标记连通性,你总是需要处理一些特殊情况,比如两个循环:两个环重合,只是有一个顶点不重合,留下一个面: Yellow and blue loops leaves one Face out

因此,为了检查网格是否被切片,我们实际上关注于face连接。因此,我只进行对偶操作(在 Openmesh 中迭代面并构建对偶关系。) Dual relation

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

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

© www.soinside.com 2019 - 2024. All rights reserved.