我有一个 obj 文件网格,我想通过OpenMesh从中提取连接的组件。我可以找到边界顶点和边,但是有没有办法在 Openmesh 中直接将网格分割成连接的组件?
问问题
3400 次
2 回答
2
OpenMesh 不提供此功能(该库的目标只是提供网格数据结构)。OpenFlipper是一个建立在OpenMesh 之上的网格处理库,是更合适的候选者,但也不提供此功能。但是,您可以在MeshTools/MeshInfoT.cc的代码库中找到一个componentCount
计算连接组件数量的函数(它只是在顶点图上进行深度优先搜索)。
基于此函数,您应该能够编写代码将网格拆分为其连接的组件:
- 为每个顶点添加一个连接组件编号属性(例如初始化为 -1,这意味着尚未访问该顶点)。
- 使用深度优先搜索(或广度优先搜索..)遍历网格顶点,并为每个顶点设置此组件编号:
- 当找到未访问的顶点时,增加当前连接的组件编号并创建一个新的连接组件。找到的顶点用作该组件的种子顶点。
- 设置从连通组件的种子顶点开始遍历的所有顶点的组件编号。
- 遍历完成后,连接组件的总数是已知的,并且对于每个顶点,其组件编号也是已知的。从这些信息可以构建连接的组件网格(属于一个组件的所有顶点都是已知的,并且可以使用顶点的半边参考来识别面)。对于每个连接的组件:
- 为这个连接的组件创建一个新的网格。
- 添加来自同一个连接组件的所有顶点。为连接的组件创建从初始网格中的顶点句柄到新网格中的相应顶点句柄的映射。
- 查找组件的所有面:要实现这一点,一种简单的方法是迭代组件的所有顶点,并为每个顶点迭代它所属的所有面。对于每个新遍历的面,在新的组件网格中创建一个引用新顶点句柄的面(使用从旧顶点到新顶点句柄的映射)。
于 2014-02-02T16:52:24.020 回答
0
实际上,我通过使用网格的对偶图来解决这个问题。因为如果直接在原图上做图搜索(BFS 或 DFS 等),无论是在每个顶点还是边上标记连通性,总是需要处理一些特殊情况,比如两个循环:两个环重合,除了一个顶点不重合,留下一个面: 黄色和蓝色环留下一个面
因此,为了检查网格是否被切片,我们实际上关注的是面连接。因此,我只做对偶操作(在 Openmesh 中迭代面并建立对偶关系。)对 偶关系
然后,在对偶图上做 DFS/BFS。每当您将下一个顶点放入待处理列表时,请检查此边是否是一个循环上的边的对偶(注意边必须在一个循环上,而不是两个循环上的两个顶点分别)。最后,只需简单地检查顶点的数量(如果循环没有对网格进行切片,则该数量应与对偶图中的原始顶点数量相同。)
您还可以在执行 BFS/DFS 时添加标签以识别不同的连接部分。
于 2020-02-14T03:21:38.957 回答