a48
2.0.2
|
This is an example of how to use the Mesh class together with items policy class.
extern "C" { #include <math.h> } #include <iostream> #include <set> #include <cstring> #include <mesht.hh> template< class Traits > class MyVertex : public a48::VertexT< Traits > { public: unsigned int id; float pos[3]; }; template< class Traits > class MyHalfedge : public a48::HalfedgeT< Traits > { public: float angle; }; template< class Traits > class MyFace : public a48::FaceT< Traits > { public: float normal[3]; }; class MyTraits { public: typedef MyVertex< MyTraits > vertex_type; typedef MyHalfedge< MyTraits > halfedge_type; typedef MyFace< MyTraits > face_type; }; typedef a48::MeshT< 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 = 8; const float _vertices[] = { 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 2.f, 0.f, 0.f, -1.f, 1.f, 0.f, 0.f, 2.f, -1.f, 2.f, 2.f, 0.f, 3.f, 1.f, -1.f, 2.f, -2.f, 0.f, 0.f, -2.f, 1.f }; const unsigned int _faces[] = { 0, 2, 1, 0, 1, 3, 3, 1, 4, 1, 2, 5, 5, 2, 6, 0, 7, 2, 0, 8, 7, 1, 5, 4 }; vertices = new float[ num_verts * 3 ]; faces = new unsigned int[ num_faces * 3 ]; memcpy( vertices, _vertices, num_verts * 3 * sizeof(float) ); memcpy( faces, _faces, num_faces * 3 * sizeof(unsigned int) ); } ~MyItemsPolicy() { delete [] vertices; delete [] faces; } void set_vertex_attributes(vertex_type *v1, const vertex_type *v0) { v1->id = v0->id; v1->pos[0] = v0->pos[0]; v1->pos[1] = v0->pos[1]; v1->pos[2] = v0->pos[2]; } 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 ]; } void set_halfedge_attributes(halfedge_type *h1, const halfedge_type *h0) { h1->angle = h0->angle; } void set_halfedge_attributes(halfedge_type *h, halfedge_type *o) { float a[3], b[3]; for (unsigned int k=0; k<3; k++) { a[k] = h->face()->normal[k]; b[k] = o->face()->normal[k]; } float dot = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; float lena = sqrt( a[0] * a[0] + a[1] * a[1] + a[2] * a[2] ); float lenb = sqrt( b[0] * b[0] + b[1] * b[1] + b[2] * b[2] ); h->angle = acos( dot / ( lena * lenb ) ); float c[3] = { 0.f, 0.f, 0.f }; for (unsigned int i=0; i<3; i++) for (unsigned int j=0; j<2; j++) c[i] += ((j%2)==0?+1:-1) * a[(((i+1)%3)+1*j)%3] * b[(((i+2)%3)+2*j)%3]; for (unsigned int k=0; k<3; k++) a[k] = h->vertex()->pos[k] - o->vertex()->pos[k]; dot = a[0] * c[0] + a[1] * c[1] + a[2] * c[2]; if( dot < 0.0 ) h->angle = M_PI - h->angle; else h->angle = M_PI + h->angle; o->angle = h->angle; } void set_halfedge_attributes(const unsigned int& i, const unsigned int& j, const unsigned int& hi, halfedge_type *h) { h->angle = 0.0; } void set_face_attributes(face_type *f1, const face_type *f0) { f1->normal[0] = f0->normal[0]; f1->normal[1] = f0->normal[1]; f1->normal[2] = f0->normal[2]; } void set_face_attributes(const unsigned int& i, face_type *f) { unsigned v0 = faces[ i*3 + 0 ], v1 = faces[ i*3 + 1 ], v2 = faces[ i*3 + 2 ]; float a[3] = { vertices[ v0*3 + 0 ], vertices[ v0*3 + 1 ], vertices[ v0*3 + 2 ] }; float b[3] = { vertices[ v1*3 + 0 ], vertices[ v1*3 + 1 ], vertices[ v1*3 + 2 ] }; float c[3] = { vertices[ v2*3 + 0 ], vertices[ v2*3 + 1 ], vertices[ v2*3 + 2 ] }; float b_a[3], c_a[3]; for (unsigned int k=0; k<3; k++) { b_a[k] = b[k] - a[k]; c_a[k] = c[k] - a[k]; } float n[3] = { 0.f, 0.f, 0.f }; for (unsigned int i=0; i<3; i++) for (unsigned int j=0; j<2; j++) n[i] += ((j%2)==0?+1:-1) * b_a[(((i+1)%3)+1*j)%3] * c_a[(((i+2)%3)+2*j)%3]; float len = sqrt( n[0] * n[0] + n[1] * n[1] + n[2] * n[2] ); for (unsigned int k=0; k<3; k++) f->normal[k] = n[k] / len; } }; int main(int argc, char* argv[]) { MyItemsPolicy< MyTraits > ip; MyMesh m( &ip ); m.set_base( ip.num_verts, ip.num_faces, ip.faces ); std::cout << "[test] 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 << std::flush; std::cout << ") [" << (*vit)->pos[0] << " " << (*vit)->pos[1] << " " << (*vit)->pos[2] << std::flush; std::cout << " " << ((*vit)->is_boundary() ? "b" : "i"); std::cout << " " << (*vit)->degree(); std::cout << "]\n"; } std::cout << "\n[test] 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)->angle*180.0/M_PI << " deg" << " ]\n"; } std::cout << "\n[test] 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") << " (" << (*fit)->normal[0] << " " << (*fit)->normal[1] << " " << (*fit)->normal[2] << ")" << " ]\n"; } std::cout << "\n[test] 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"; } return 0; }