半边数据结构与OpenMesh中的处理
参考:https://blog.csdn.net/jialong_chen/article/details/118497495
《Springer.3D Mesh Processing and Character Animation.With Examples Using OpenGL, OpenMesh and Assimp》
1. 半边数据结构的基本假设
1)三维模型包含顶点、边、面片三部分结构,在空间中分别是0维、1维和2维的。面即为物体表面的某一多边形区域,边是相邻两个面的交线段或一个面的边缘,顶点为相邻边的交点。
2)每条边只与最多两个面相邻
3)每个面片均有自己的朝向,以区分内侧和外侧
4)两个相邻的面片朝向相同
2.数据结构
半边数据结构中包含了三种对象:顶点、半边和面片。每个对象均为固定长度,并包含了指向其他对象的指针。
2.OpenMesh中的相关函数
2.1 拓扑关联对象
// Type declarations for handles: OpenMesh::VertexHandle verH; OpenMesh::FaceHandle facH; OpenMesh::HalfedgeHandle hedH, hedH_n, hedH_p; OpenMesh::Vec3d point; // Half-edge operations: half-edge → vert: verH = mesh.to_vertex_handle(hedH); half-edge→ pair→vert:verH = mesh.from_vertex_handle(hedH); half-edge→ next:hedH_n = mesh.next_halfedge_handle(hedH); half-edge→pair:hedH_p=mesh.opposite_halfedge_handle(hedH); half-edge → face: facH = mesh.face_handle(hedH); face → half-edge: hedH = mesh.halfedge_handle(facH); vert → half-edge: hedH = mesh.halfedge_handle(verH); vert coordinates: point = mesh.point(verH);
2.2 遍历
// vertex iterator typedef OpenMesh::TriMesh_ArrayKernelT<> MyMesh; MyMesh mesh; OpenMesh::VertexHandle verH; MyMesh::VertexIter vit; OpenMesh::Vec3d p; int valence; OpenMesh::IO::read_mesh(mesh, "cube.off") for (vit = mesh.vertices_begin(); vit != mesh.vertices_end(); vit++) { verH = *vit; p = mesh.point(verH); valence = mesh.valence(verH); cout << p[0] << " " << p[1] << " " << p[2] << " " << valence << endl; }
// face iterator typedef OpenMesh::TriMesh_ArrayKernelT<> MyMesh; MyMesh mesh; OpenMesh::FaceHandle facH; MyMesh::FaceIter fit; int nvert; OpenMesh::IO::read_mesh(mesh, "cube.off") for (fit = mesh.faces_begin(); fit != mesh.faces_end(); fit++) { facH = *fit; nvert = mesh.valence(facH); cout << "Number of vertices = " << nvert << endl; }
// edge iterator typedef OpenMesh::TriMesh_ArrayKernelT<> MyMesh; MyMesh mesh; OpenMesh::EdgeHandle edgH; MyMesh::EdgeIter eit; float len, angle; OpenMesh::IO::read_mesh(mesh, "cube.off") for (eit = mesh.edges_begin(); eit != mesh.edges_end(); eit++) { edgH = *eit; len = mesh.calc_edge_length(edgH); angle = mesh.calc_dihedral_angle(edgH); cout << "Edge length = " << len <<" Dihedral angle = " << angle << endl; }
2.3 邻接查询