CGAL 5.6 - Surface Mesh: User Manual
Surface_mesh 类是半边数据结构的实现,可用来表示多面体表面。它是半边数据结构(Halfedge Data Structures)和三维多面体表面(3D Polyhedral Surface)这两个 CGAL 软件包的替代品。其主要区别在于它是基于索引的,而不是基于指针的。此外,向顶点、半边、边和面添加信息的机制要简单得多,而且是在运行时而不是编译时完成的。
由于数据结构使用整数索引作为顶点、半边、边和面的描述符,因此它的内存占用比基于指针的 64 位版本更少。由于索引是连续的,因此可用作存储属性的向量索引。
当元素被移除时,它们只会被标记为已移除,必须调用垃圾回收函数才能真正移除它们。
Surface_mesh 提供了四个嵌套类,分别代表半边数据结构的基本元素:
Surface_mesh::Vertex_index曲面网格::顶点索引
Surface_mesh::Halfedge_index曲面网格::半边索引
Surface_mesh::Face_index曲面网格::面索引
Surface_mesh::Edge_index曲面网格::边索引
1、新建Surface_mesh结构
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/self_intersections.h>typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh; //mesh结构
typedef Mesh::Vertex_index vertex_descriptor;
typedef Mesh::Face_index face_descriptor;int main()
{Mesh m;// Add the points as verticesvertex_descriptor u = m.add_vertex(K::Point_3(0, 1, 0));vertex_descriptor v = m.add_vertex(K::Point_3(0, 0, 0));vertex_descriptor w = m.add_vertex(K::Point_3(1, 1, 0));m.add_face(u, v, w);int num = num_faces(m); //结果num = 1return 0;
}
2、自相交判断
在很多算法中,对于输入的Mesh都要求是非自相交的模型。现在来检查以下上述模型是否自相交
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/self_intersections.h>typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh; //mesh结构
typedef Mesh::Vertex_index vertex_descriptor;
typedef Mesh::Face_index face_descriptor;int main()
{Mesh m;// Add the points as verticesvertex_descriptor u = m.add_vertex(K::Point_3(0, 1, 0));vertex_descriptor v = m.add_vertex(K::Point_3(0, 0, 0));vertex_descriptor w = m.add_vertex(K::Point_3(1, 1, 0));vertex_descriptor x = m.add_vertex(K::Point_3(1, 0, 0));m.add_face(u, v, w);int num = num_faces(m); //结果num = 1face_descriptor f = m.add_face(u, v, x);if (f == Mesh::null_face()){std::cerr << "The face could not be added because of an orientation error." << std::endl;//结果intersect = true; 即当前模型为自相交模型bool intersect = CGAL::Polygon_mesh_processing::does_self_intersect(m);std::cout << "intersect:"<< intersect << std::endl;assert(f != Mesh::null_face());f = m.add_face(u, x, v);num = num_faces(m);//结果intersect = true; 即当前模型为自相交模型intersect = CGAL::Polygon_mesh_processing::does_self_intersect(m);std::cout << "intersect:" << intersect << std::endl;assert(f != Mesh::null_face());}std::cout << num << std::endl;return 0;
}
3、获取Surface_Mesh的所有点
#include <vector>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
typedef Mesh::Vertex_index vertex_descriptor;
typedef Mesh::Face_index face_descriptor;
int main()
{Mesh m;// u x// +------------+// | |// | |// | f |// | |// | |// +------------+// v w// Add the points as verticesvertex_descriptor u = m.add_vertex(K::Point_3(0, 1, 0));vertex_descriptor v = m.add_vertex(K::Point_3(0, 0, 0));vertex_descriptor w = m.add_vertex(K::Point_3(1, 0, 0));vertex_descriptor x = m.add_vertex(K::Point_3(1, 1, 0));/* face_descriptor f = */ m.add_face(u, v, w, x);{std::cout << "all vertices " << std::endl;// The vertex iterator type is a nested type of the Vertex_rangeMesh::Vertex_range::iterator vb, ve;Mesh::Vertex_range r = m.vertices();// The iterators can be accessed through the C++ range APIvb = r.begin();ve = r.end();// or with boost::tie, as the CGAL range derives from std::pairfor (boost::tie(vb, ve) = m.vertices(); vb != ve; ++vb) {std::cout << *vb << std::endl;}// Instead of the classical for loop one can use// the boost macro for a rangefor (vertex_descriptor vd : m.vertices()) {std::cout << vd << std::endl;}}return 0;
}
4、获取Surface_Mesh点、边、面的关联点
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>#include <vector>typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
typedef Mesh::Vertex_index vertex_descriptor;
typedef Mesh::Face_index face_descriptor;int main()
{Mesh m;// u x// +------------+// | |// | |// | f |// | |// | |// +------------+// v w// Add the points as verticesvertex_descriptor u = m.add_vertex(K::Point_3(0, 1, 0));vertex_descriptor v = m.add_vertex(K::Point_3(0, 0, 0));vertex_descriptor w = m.add_vertex(K::Point_3(1, 0, 0));vertex_descriptor x = m.add_vertex(K::Point_3(1, 1, 0));face_descriptor f = m.add_face(u, v, w, x);{std::cout << "vertices around vertex " << v << std::endl;CGAL::Vertex_around_target_circulator<Mesh> vbegin(m.halfedge(v), m), done(vbegin);do {std::cout << *vbegin++ << std::endl;} while (vbegin != done);}{std::cout << "vertices around face " << f << std::endl;CGAL::Vertex_around_face_iterator<Mesh> vbegin, vend;for (boost::tie(vbegin, vend) = vertices_around_face(m.halfedge(f), m);vbegin != vend;++vbegin) {std::cout << *vbegin << std::endl;}}std::cout << "=====" << std::endl;// or the same again, but directly with a range based loopfor (vertex_descriptor vd : vertices_around_face(m.halfedge(f), m)) {std::cout << vd << std::endl;}return 0;
}
【CGAL系列】---了解Surface_Mesh-CSDN博客