OpenMesh在近年来的版本中添加了许多C++11的支持,在其最基本的迭代器和循环器的使用上,C++11的接口更加的友好直观。
迭代器
OpenMesh的迭代器提供了对点、半边、边、面四种元素的线性遍历。在官网上,我们可以看到经典的接口如下所示:
MyMesh mesh;
// iterate over all vertices
for (MyMesh::VertexIter v_it=mesh.vertices_begin(); v_it!=mesh.vertices_end(); ++v_it)
...; // do something with *v_it, v_it->, or *v_it
// iterate over all halfedges
for (MyMesh::HalfedgeIter h_it=mesh.halfedges_begin(); h_it!=mesh.halfedges_end(); ++h_it)
...; // do something with *h_it, h_it->, or *h_it
// iterate over all edges
for (MyMesh::EdgeIter e_it=mesh.edges_begin(); e_it!=mesh.edges_end(); ++e_it)
...; // do something with *e_it, e_it->, or *e_it
// iterator over all faces
for (MyMesh::FaceIter f_it=mesh.faces_begin(); f_it!=mesh.faces_end(); ++f_it)
...; // do something with *f_it, f_it->, or *f_it
每个初次接触OpenMesh的人看到上述接口都难免会眉头一皱,毕竟它看起来确实不太友好;其次,由于返回的是迭代器,因此还需要操作符*或->才能转换为对相应handle的操作,这就使得代码多多少少不太美观。
实际上,在OpenMesh已经提供了等效的C++11接口:
MyMesh mesh;
// iterate over all vertices
for (MyMesh::VertexHandle v_h : mesh.vertices())
...; // do something with v_h
// iterate over all halfedges
for (MyMesh::HalfedgeHandle h_h : mesh.halfedges())
...; // do something with h_h
// iterate over all edges
for (MyMesh::EdgeHandle e_h : mesh.edges())
...; // do something with e_h
// iterator over all faces
for (MyMesh::FaceHandle f_h : mesh.faces())
...; // do something with f_h
相比之下,C++11的接口更加地简洁明了,并且返回的直接就是handle,不需要再做转换。
循环器
OpenMesh的循环器提供了通过点、半边、边、面等基本元素访问其相邻元素的功能。在官网上,以点的循环器为例,我们同样可以看到经典的接口如下所示:
/**************************************************
* Vertex circulators
**************************************************/
// Get the vertex-vertex circulator (1-ring) of vertex _vh
VertexVertexIter OpenMesh::PolyConnectivity::vv_iter (VertexHandle _vh);
// Get the vertex-incoming halfedges circulator of vertex _vh
VertexIHalfedgeIter OpenMesh::PolyConnectivity::vih_iter (VertexHandle _vh);
// Get the vertex-outgoing halfedges circulator of vertex _vh
VertexOHalfedgeIter OpenMesh::PolyConnectivity::voh_iter (VertexHandle _vh);
// Get the vertex-edge circulator of vertex _vh
VertexEdgeIter OpenMesh::PolyConnectivity::ve_iter (VertexHandle _vh);
// Get the vertex-face circulator of vertex _vh
VertexFaceIter OpenMesh::PolyConnectivity::vf_iter (VertexHandle _vh);
上面的循环器对应的经典用法以及C++11下的用法示例,分别如下所示:
MyMesh mesh;
MyMesh::VertexHandle v_h = MyMesh::VertexHandle(0);
/*
Vertex-Vertex
*/
for (MyMesh::VertexVertexIter vv_iter = mesh.vv_begin(v_h); vv_iter != mesh.vv_end(v_h); ++vv_iter) {
//Classic
//Do Something with *vv_iter
}
for (MyMesh::VertexHandle vv_h : mesh.vv_range(v_h)) {
//C++11
//Do Something with vv_h
}
/*
Vertex-IncomingHalfedge
*/
for (MyMesh::VertexIHalfedgeIter vih_iter = mesh.vih_begin(v_h); vih_iter != mesh.vih_end(v_h); ++vih_iter) {
//Classic
//Do Something with *vih_iter
}
for (MyMesh::HalfedgeHandle vih_h : mesh.vih_range(v_h)) {
//C++11
//Do Something with vih_h
}
/*
Vertex-OutcomingHalfedge
*/
for (MyMesh::VertexOHalfedgeIter voh_iter = mesh.voh_begin(v_h); voh_iter != mesh.voh_end(v_h); ++voh_iter) {
//Classic
//Do Something with *voh_iter
}
for (MyMesh::HalfedgeHandle voh_h : mesh.voh_range(v_h)) {
//C++11
//Do Something with voh_h
}
/*
Vertex-Edge
*/
for (MyMesh::VertexEdgeIter ve_iter = mesh.ve_begin(v_h); ve_iter != mesh.ve_end(v_h); ++ve_iter) {
//Classic
//Do Something with *ve_iter
}
for (MyMesh::EdgeHandle ve_h : mesh.ve_range(v_h)) {
//C++11
//Do Something with ve_h
}
/*
Vertex-Face
*/
for (MyMesh::VertexFaceIter vf_iter = mesh.vf_begin(v_h); vf_iter != mesh.vf_end(v_h); ++vf_iter) {
//Classic
//Do Something with *vf_iter
}
for (MyMesh::FaceHandle vf_h : mesh.vf_range(v_h)) {
//C++11
//Do Something with vf_h
}
其它循环器的使用也与之类似。