Openmesh中的網格模型相比於PCL中的網格模型複雜很多,除了常見的座標、紋理座標、法線、顏色信息之外,增加了邊、半邊以及相關的邊摺疊、邊拆分等操作,使用起來就非常簡單了,所以在這裏,簡單介紹一下里面一些基本的操作;
1、從文件中讀取的普通的點面mesh
//openmesh
#include <OpenMesh/Core/Mesh/TriConnectivity.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/Handles.hh>
#include <OpenMesh/Core/Mesh/ArrayKernel.hh>
typedef OpenMesh::TriMesh_ArrayKernelT<> meshT;
int main(){
std::string meshFile = "./data/17_ofm_64.obj";
meshT mesh;
OpenMesh::IO::read_mesh(mesh, meshFile);
return 0;
}
這裏定義的網格模型只包含一下幾個默認的屬性,
struct DefaultTraits
{
/// The default coordinate type is OpenMesh::Vec3f.
typedef Vec3f Point;
/// The default normal type is OpenMesh::Vec3f.
typedef Vec3f Normal;
/// The default 1D texture coordinate type is float.
typedef float TexCoord1D;
/// The default 2D texture coordinate type is OpenMesh::Vec2f.
typedef Vec2f TexCoord2D;
/// The default 3D texture coordinate type is OpenMesh::Vec3f.
typedef Vec3f TexCoord3D;
/// The default texture index type
typedef int TextureIndex;
/// The default color type is OpenMesh::Vec3uc.
typedef Vec3uc Color;
#ifndef DOXY_IGNORE_THIS
VertexTraits {};
HalfedgeTraits {};
EdgeTraits {};
FaceTraits {};
#endif
VertexAttributes(0);
HalfedgeAttributes(Attributes::PrevHalfedge);
EdgeAttributes(0);
FaceAttributes(0);
};
2、統計網格模型中點邊面的個數及其遍歷
int nV = mesh.n_vertices(), nE = mesh.n_edges(), nF = mesh.n_faces(),
nHe = mesh.n_halfedges();
meshT::EdgeIter eIt , eEnd = mesh.edges_end();
for (eIt = mesh.edges_begin(); eIt != eEnd; ++eIt){
meshT::HalfedgeHandle & hh = mesh.halfedge_handle(*eIt, 0);
meshT::VertexHandle & v0 = mesh.from_vertex_handle(hh);
meshT::VertexHandle & v1 = mesh.to_vertex_handle(hh);
meshT::Point vec = mesh.point(v1) - mesh.point(v0);//得到邊向量
meshT::VOHIter vhIt;//頂點相關的半邊iter
for (vhIt = mesh.voh_iter(v0); vhIt.is_valid(); ++vhIt)
//遍歷從Vo出發的每一條半邊,進行操作
}
}
}
2、頂點的法線的計算
讀取的網格模型默認只讀取頂點和麪片信息,如果模型中存在法線信息或者中沒有法線信息,需要重新計算,必須首先計算face的信息,才能計算頂點的法線信息,後者計算利用了前者的信息
mesh.request_face_normals();
mesh.request_vertex_normals();
mesh.request_halfedge_normals();
mesh.update_normals();//該函數中依次計算了面法線、頂點法線、半邊的法線,後兩個均利用了面法線的信息
//也可以依次計算face、頂點的法線信息
mesh.update_face_normals();
mesh.update_vertex_normals();
mesh.update_halfedge_normals();
mesh.release_face_normals();
mesh.release_vertex_normals();
mesh.release_halfedge_normals();
3、在mesh模型中增加其他的成員屬性
OpenMesh::VPropHandleT< meshT::Point > q;//質心屬性,增加一個質心座標(周圍頂點的平均座標)
if (!mesh.get_property_handle(q, "q Property"))
mesh.add_property(q, "q Property");
meshT::ConstVertexIter vIt=mesh.vertices_sbegin();
meshT::Point tmp(0.0, 0.0, 0.0);
uint N = 0;
meshT::VVIter vvIt;//與該操作頂點的相鄰頂點
for (vvIt = mesh.vv_iter(*vIt); vvIt.is_valid(); ++vvIt){
tmp += mesh.point(*vvIt);
N++;
}
if (N > 0)
tmp /= (double)N;
mesh.property(q, *vIt) = tmp;
新增屬性使用完畢後記得需要對應的刪除
mesh.remove_property(q);