重建三角形网格中的所有边

时间:2014-03-05 17:19:15

标签: c++ graphics hash map mesh

我有一个包含数百万个三角形的三角形网格。目前在我的数据结构中只存储三角形和顶点。我想重建所有边缘并将它们存储在数据容器中。这个想法可能是这样的:遍历所有三角形,得到它的每两个顶点,并在它们之间创建一条边。问题是共享边缘可能会创建两次。所以为了解决这个问题,我需要一个数据容器EdgeContainer来存储边缘,它应该有一个函数来检查是否已经创建了这个边缘。所以它就像一张有多个键的地图,但根据我的问题,这张地图还应该有以下功能:

  1. EdgeContainer(v1, v2)应返回与EdgeContainer(v2, v1)相同的结果,其中v1v2是指向两个顶点的指针。
  2. EdgeContainer应该有EdgeContainer::Remove(v1)之类的函数,它会删除发生在顶点v1的所有边。
  3. 实施应尽可能高效。
  4. 是否有可以处理此问题的现有库?

3 个答案:

答案 0 :(得分:1)

首先我建议你看一下这个概念 它是在CGAL和OpenMesh中使用的半边http://www.flipcode.com/archives/The_Half-Edge_Data_Structure.shtml网格,你应该知道你将使用其中任何一个的概念。 我的slef推荐OpenMesh http://openmesh.org/Documentation/OpenMesh-2.0-Documentation/tutorial_01.html它是免费的开源软件,您可以轻松地从顶点和索引集创建网格,在创建网格后,您可以轻松地遍历所有边缘。

答案 1 :(得分:0)

您最简单的选择是使用Cgal库,它基本上是为此而设计的。

http://doc.cgal.org/latest/Triangulation_2/index.html

它提供了用于迭代面,边和顶点的自然迭代器。

请注意,在Cgal中,它们实际上并不显式存储边缘,而是生成它们 每次迭代结构。这可以使用一些聪明的规则有效地完成 阻止你计算两次事物:看代码,看起来每个面孔 迭代一次,并为每个相邻面添加一条边到当前面, 在面部列表中比当前面部更早出现。

请注意,以这种方式访问​​边缘只需要每个边缘有恒定的时间(取决于您存储面部的方式),这样您就不太可能从单独存储它们中受益。还要注意,边缘由两个相邻的面定义,而不是两个相邻的顶点。你可以在恒定的时间内改变它们。

答案 2 :(得分:0)

简单的解决方案是使用排序的索引对:

struct _edge_desc : public std::pair<int,int> {
    _edge_desc(int a, int b): std::pair<int,int>(a<b?a:b, a<b?b:a) {}
};
std::set<_edge_desc> Edges;

如果需要有关边的其他信息,而不是存储在单独的向量中,而不是使用set来存储边,请使用映射到向量中的索引的地图。

std::vector<some_struct> EdgesInfo;
std::map<_edge_desc, int> EdgesMap;