OpenMesh provides dynamic properties, which can be attached to each mesh entity (vertex, face, edge, halfedge, and the mesh itself). We distinguish between custom and standard properties. A custom property is any user-defined property and is accessed via the member function property(..)
, a handle and an entity handle (e.g. VertexHandle). Whereas the standard properties are accessed via special member functions, e.g. the vertex position is accessed with point(..)
and a vertex handle.
In this example we will store the cog-value
(see previous example) in an additional vertex property instead of keeping it in a separate array. To do so we define first a so-called property handle with the desired type (MyMesh::Point)
and register the handle at the mesh:
// this vertex property stores the computed centers of gravity OpenMesh::VPropHandleT<MyMesh::Point> cogs; mesh.add_property(cogs);
mesh
allocates enough memory to hold as many elements of type MyMesh::Point
as number of vertices exist, and of course the mesh synchronizes all insert and delete operations on the vertices with the vertex properties.
Once the wanted property is registered we can use the property to calculate the barycenter of the neighborhood of each vertex v_it
for (vv_it=mesh.vv_iter( v_it ); vv_it; ++vv_it)
{
mesh.property(cogs,v_it) += mesh.point( vv_it );
++valence;
}
mesh.property(cogs,v_it) /= valence;
v_it
mesh.set_point( v_it, mesh.property(cogs,v_it) );
#include <iostream> #include <vector> // -------------------- #include <OpenMesh/Core/IO/MeshIO.hh> #include <OpenMesh/Core/Mesh/Types/TriMesh_ArrayKernelT.hh> typedef OpenMesh::TriMesh_ArrayKernelT<> MyMesh; int main(int argc, char **argv) { MyMesh mesh; // check command line options if (argc != 4) { std::cerr << "Usage: " << argv[0] << " #iterations infile outfile\n"; return 1; } // read mesh from stdin if ( ! OpenMesh::IO::read_mesh(mesh, argv[2]) ) { std::cerr << "Error: Cannot read mesh from " << argv[2] << std::endl; return 1; } // this vertex property stores the computed centers of gravity OpenMesh::VPropHandleT<MyMesh::Point> cogs; mesh.add_property(cogs); // smoothing mesh argv[1] times MyMesh::VertexIter v_it, v_end(mesh.vertices_end()); MyMesh::VertexVertexIter vv_it; MyMesh::Point cog; MyMesh::Scalar valence; unsigned int i, N(atoi(argv[1])); for (i=0; i < N; ++i) { for (v_it=mesh.vertices_begin(); v_it!=v_end; ++v_it) { mesh.property(cogs,v_it).vectorize(0.0f); valence = 0; for (vv_it=mesh.vv_iter( v_it ); vv_it; ++vv_it) { mesh.property(cogs,v_it) += mesh.point( vv_it ); ++valence; } mesh.property(cogs,v_it) /= valence; } for (v_it=mesh.vertices_begin(); v_it!=v_end; ++v_it) if ( !mesh.is_boundary( v_it ) ) mesh.set_point( v_it, mesh.property(cogs,v_it) ); } // write mesh to stdout if ( ! OpenMesh::IO::write_mesh(mesh, argv[3]) ) { std::cerr << "Error: cannot write mesh to " << argv[3] << std::endl; return 1; } return 0; }