OpenMesh遍历网格:C++11新特性下迭代器和循环器的使用

OpenMesh在近年来的版本中添加了许多C++11的支持,在其最基本的迭代器和循环器的使用上,C++11的接口更加的友好直观。

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
}

其它循环器的使用也与之类似。

称谓(*)
邮箱
留言(*)