a48
2.0.2
|
This is an example of how to use the Stellar Mesh class together with items and stellar policy classes.
#include <iostream> #include <set> #include <map> #include <cstring> #include <mesh.hh> typedef unsigned int uint; template< class Traits > class MyVertex : public a48::VertexT< Traits > { public: uint id; float pos[3]; }; class MyTraits { public: typedef MyVertex< MyTraits > vertex_type; typedef a48::HalfedgeT< MyTraits > halfedge_type; typedef a48::FaceT< MyTraits > face_type; }; typedef a48::StellarMeshT< MyTraits > MyMesh; template< class Traits > class MyItemsPolicy : public virtual a48::BaseItemsPolicy< Traits > { typedef typename Traits::vertex_type vertex_type; typedef typename Traits::halfedge_type halfedge_type; typedef typename Traits::face_type face_type; public: unsigned int num_verts, num_faces; float *vertices; unsigned int *faces; MyItemsPolicy() { num_verts = 9; num_faces = 9; const float _vertices[] = { 0.f, 0.f, 0.f, -1.f, -1.f, 0.f, 1.f, -1.f, 0.f, 1.f, 1.f, 0.f, -1.f, 1.f, 0.f, 2.f, 0.f, 0.f, 2.f, 1.f, 0.f, -2.f, 0.f, 0.f, -3.f, 1.f, 0.f }; const uint _faces[] = { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 1, 2, 5, 3, 3, 5, 6, 7, 1, 4, 7, 8, 1, 8, 7, 4 }; vertices = new float[ num_verts * 3 ]; faces = new uint[ num_faces * 3 ]; memcpy( vertices, _vertices, num_verts * 3 * sizeof(float) ); memcpy( faces, _faces, num_faces * 3 * sizeof(uint) ); } void set_vertex_attributes(const unsigned int& i, vertex_type *v) { v->id = i; v->pos[0] = vertices[ i*3 + 0 ]; v->pos[1] = vertices[ i*3 + 1 ]; v->pos[2] = vertices[ i*3 + 2 ]; } ~MyItemsPolicy() { delete [] vertices; delete [] faces; } void set_vertex_attributes(vertex_type *v1, const vertex_type *v0) { } void set_halfedge_attributes(halfedge_type *h1, const halfedge_type *h0) { } void set_halfedge_attributes(halfedge_type *h, halfedge_type *o) { } void set_halfedge_attributes(const unsigned int& i, const unsigned int& j, const unsigned int& hi, halfedge_type *h) { } void set_face_attributes(face_type *f1, const face_type *f0) { } void set_face_attributes(const unsigned int& i, face_type *f) { } }; template< class Traits > class MyStellarPolicy : public virtual a48::BaseStellarPolicy< Traits > { typedef typename Traits::vertex_type vertex_type; typedef typename Traits::halfedge_type halfedge_type; typedef typename Traits::face_type face_type; typedef std::pair< uint, uint > edge_pair; typedef std::map< edge_pair, vertex_type > edge_map; public: edge_map emap; void sample_vertex(const halfedge_type *h, vertex_type *v) { uint id0 = h->vertex()->id; uint id1 = h->previous()->vertex()->id; if( id1 < id0 ) { uint idt = id0; id0 = id1; id1 = idt; } edge_pair e( id0, id1 ); if( emap.find( e ) != emap.end() ) { v->id = emap[e].id; for (uint k=0; k<3; ++k) v->pos[k] = emap[e].pos[k]; std::cout << "SAMPLING VERTEX\t(" << emap[e].id << ") [" << emap[e].pos[0] << " " << emap[e].pos[1] << " " << emap[e].pos[2] << " " << (emap[e].is_boundary() ? "b" : "i") << " " << emap[e].degree() << "]\n"; } } void sample_vertex(const face_type *f, vertex_type *v) { sample_vertex( f->halfedge(), v ); sample_vertex( f->halfedge()->next(), v ); sample_vertex( f->halfedge()->previous(), v ); } void remove_vertex(const halfedge_type *h, const vertex_type *v) { uint id0 = h->next()->opposite()->next()->vertex()->id; uint id1 = h->previous()->vertex()->id; if( id1 < id0 ) { uint idt = id0; id0 = id1; id1 = idt; } edge_pair e( id0, id1 ); emap[e] = *v; std::cout << "REMOVE VERTEX (edge " << id0 << " " << id1; std::cout << ") (" << v->id << ") [" << emap[e].pos[0] << " " << emap[e].pos[1] << " " << emap[e].pos[2] << " " << (v->is_boundary() ? "b" : "i") << " " << v->degree() << "]\n"; } void remove_vertex(const face_type *f, const vertex_type *v) { remove_vertex( f->halfedge(), v ); } void flip_halfedge(const halfedge_type *h) { uint id0 = h->vertex()->id; uint id1 = h->previous()->vertex()->id; if( id1 < id0 ) { uint idt = id0; id0 = id1; id1 = idt; } edge_pair e( id0, id1 ); if( emap.find( e ) != emap.end() ) { std::cout << "FLIPPING EDGE (edge " << id0 << " " << id1 << ")" << std::flush; id0 = h->next()->vertex()->id; id1 = h->opposite()->next()->vertex()->id; if( id1 < id0 ) { uint idt = id0; id0 = id1; id1 = idt; } edge_pair ne( id0, id1 ); std::cout << " TO (edge " << id0 << " " << id1 << ")\n"; emap[ne] = emap[e]; emap.erase(e); } } }; void show_mesh(const MyMesh& m) { std::cout << "_mesh_ Vertices: " << m.size_of_vertices() << std::endl; for (MyMesh::vertex_const_iterator vit = m.vertices_begin(); vit != m.vertices_end(); ++vit) { std::cout << "\t(" << (*vit)->id << ") [" << (*vit)->pos[0] << " " << (*vit)->pos[1] << " " << (*vit)->pos[2] << " " << ((*vit)->is_boundary() ? "b" : "i") << " " << (*vit)->degree() << "]\n"; } std::cout << "_mesh_ Halfedges: " << m.size_of_halfedges() << std::endl; for (MyMesh::halfedge_const_iterator hit = m.halfedges_begin(); hit != m.halfedges_end(); ++hit) { std::cout << "\t[ " << (*hit)->from_vertex()->id << ":" << (*hit)->vertex()->id << " " << ((*hit)->is_boundary() ? "b" : "i") << " (" << (*hit)->face()->halfedge()->previous()->vertex()->id << ", " << (*hit)->face()->halfedge()->vertex()->id << ", " << (*hit)->face()->halfedge()->next()->vertex()->id << ") ]"; if( !(*hit)->is_boundary() ) { std::cout << " / [ " << (*hit)->opposite()->from_vertex()->id << ":" << (*hit)->opposite()->vertex()->id << " " << ((*hit)->opposite()->is_boundary() ? "b" : "i") << "]"; } std::cout << "\n"; } std::cout << "_mesh_ Faces: " << m.size_of_faces() << std::endl; for (MyMesh::face_const_iterator fit = m.faces_begin(); fit != m.faces_end(); ++fit) { std::cout << "\t[ " << (*fit)->halfedge()->previous()->vertex()->id << ", " << (*fit)->halfedge()->vertex()->id << ", " << (*fit)->halfedge()->next()->vertex()->id << " " << ((*fit)->is_boundary() ? "b" : "i") << " ]\n"; } std::cout << "_mesh_ Vertices stars:" << std::endl; for (MyMesh::vertex_const_iterator vit = m.vertices_begin(); vit != m.vertices_end(); ++vit) { std::cout << "\t(" << (*vit)->id << ")" << std::flush; for (const MyTraits::halfedge_type *hcurr = (*vit)->halfedge(); hcurr != 0; hcurr = (*vit)->star_next(hcurr)) { std::cout << " [" << hcurr->from_vertex()->id << ":" << hcurr->vertex()->id << "]" << std::flush; } std::cout << "\n"; } } int main(int argc, char* argv[]) { MyItemsPolicy< MyTraits > ip; MyStellarPolicy< MyTraits > sp; MyMesh m( &ip, &sp ); m.set_base( ip.num_verts, ip.num_faces, ip.faces ); show_mesh( m ); const uint weld_ids[3] = { 0, 5, 7 }; std::cout << "[test] Welding vertex: " << weld_ids[0] << "\n"; for (MyMesh::vertex_const_iterator vit = m.vertices_begin(); vit != m.vertices_end(); ++vit) if( (*vit)->id == weld_ids[0] ) { m.weld( *vit ); break; } show_mesh( m ); std::cout << "[test] Welding vertex: " << weld_ids[1] << "\n"; for (MyMesh::vertex_const_iterator vit = m.vertices_begin(); vit != m.vertices_end(); ++vit) if( (*vit)->id == weld_ids[1] ) { m.weld( *vit ); break; } show_mesh( m ); std::cout << "[test] Welding vertex: " << weld_ids[2] << "\n"; for (MyMesh::vertex_const_iterator vit = m.vertices_begin(); vit != m.vertices_end(); ++vit) if( (*vit)->id == weld_ids[2] ) { m.weld( *vit ); break; } show_mesh( m ); uint fh_from_id = 1, fh_to_id = 3; std::cout << "[test] Flipping halfedge: " << fh_from_id << ":" << fh_to_id << "\n"; for (MyMesh::halfedge_const_iterator hit = m.halfedges_begin(); hit != m.halfedges_end(); ++hit) { if( (*hit)->from_vertex()->id == fh_from_id and (*hit)->vertex()->id == fh_to_id ) { m.flip( *hit ); break; } } show_mesh( m ); uint sh_from_id = 2, sh_to_id = 6; std::cout << "[test] Splitting halfedge: " << sh_from_id << ":" << sh_to_id << "\n"; for (MyMesh::halfedge_const_iterator hit = m.halfedges_begin(); hit != m.halfedges_end(); ++hit) { if( (*hit)->from_vertex()->id == sh_from_id and (*hit)->vertex()->id == sh_to_id ) { m.split( *hit ); break; } } show_mesh( m ); sh_from_id = 2; sh_to_id = 4; std::cout << "[test] Splitting halfedge: " << sh_from_id << ":" << sh_to_id << "\n"; for (MyMesh::halfedge_const_iterator hit = m.halfedges_begin(); hit != m.halfedges_end(); ++hit) { if( (*hit)->from_vertex()->id == sh_from_id and (*hit)->vertex()->id == sh_to_id ) { m.split( *hit ); break; } } show_mesh( m ); uint sf_id[3] = { 8, 1, 4 }; std::cout << "[test] Splitting face: [ " << sf_id[0] << ", " << sf_id[1] << ", " << sf_id[2] << " ]\n"; for (MyMesh::face_const_iterator fit = m.faces_begin(); fit != m.faces_end(); ++fit) { for (uint j = 0; j < 3; ++j) if( (*fit)->halfedge()->previous()->vertex()->id == sf_id[j] and (*fit)->halfedge()->vertex()->id == sf_id[(j+1)%3] and (*fit)->halfedge()->next()->vertex()->id == sf_id[(j+2)%3] ) { m.split( *fit ); break; } } show_mesh( m ); return 0; }