a48
2.0.2
|
This is an example of how to use the Adaptive Policy paradigm using the a48 halfedge datastructure classes.
#include <iostream> #include <cstring> #include <mesh.hh> typedef unsigned int uint; template< class Traits > class MyVertex : public a48::AdaptiveVertexT< Traits > { public: uint id; float pos[2]; }; class MyTraits { public: typedef MyVertex< MyTraits > vertex_type; typedef a48::AdaptiveHalfedgeT< MyTraits > halfedge_type; typedef a48::AdaptiveFaceT< MyTraits > face_type; }; typedef a48::AdaptiveMeshT< 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 = 4; num_faces = 2; const float _vertices[] = { 0.f, 0.f, 10.f, 0.f, 10.f, 10.f, 0.f, 10.f }; const uint _faces[] = { 2, 0, 1, 0, 2, 3 }; vertices = new float[ num_verts * 2 ]; faces = new uint[ num_faces * 3 ]; memcpy( vertices, _vertices, num_verts * 2 * sizeof(float) ); memcpy( faces, _faces, num_faces * 3 * sizeof(uint) ); } ~MyItemsPolicy() { delete [] vertices; delete [] faces; } void set_vertex_attributes(unsigned int i, vertex_type *v) { v->id = i; v->pos[0] = vertices[ i*2 + 0 ]; v->pos[1] = vertices[ i*2 + 1 ]; } 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; public: // Simple sampling and removal processes with average vertices void sample_vertex(const halfedge_type *h, vertex_type *v) { v->pos[0] = ( h->vertex()->pos[0] + h->from_vertex()->pos[0] ) / 2.f; v->pos[1] = ( h->vertex()->pos[1] + h->from_vertex()->pos[1] ) / 2.f; v->id = ip.num_verts; ++ip.num_verts; } void sample_vertex(const face_type *f, vertex_type *v) { v->pos[0] = ( f->halfedge()->vertex()->pos[0] + f->halfedge()->next()->vertex()->pos[0] + f->halfedge()->previous()->vertex()->pos[0] ) / 3.f; v->pos[1] = ( f->halfedge()->vertex()->pos[1] + f->halfedge()->next()->vertex()->pos[1] + f->halfedge()->previous()->vertex()->pos[1] ) / 3.f; v->id = ip.num_verts; ++ip.num_verts; } void remove_vertex(const halfedge_type *h, const vertex_type *v) { --ip.num_verts; } void remove_vertex(const face_type *f, const vertex_type *v) { --ip.num_verts; } void flip_halfedge(const halfedge_type *h) { } // Items policy must be inside of stellar policy to access the // current number of vertices of the mesh MyItemsPolicy< Traits > ip; }; template< class Traits > class MyAdaptivePolicy : public virtual a48::BaseAdaptivePolicy< Traits > { typedef typename Traits::vertex_type vertex_type; typedef typename Traits::halfedge_type halfedge_type; typedef typename Traits::face_type face_type; typedef typename std::vector< vertex_type* > simplification_list; typedef typename simplification_list::iterator simplification_iterator; typedef typename std::vector< halfedge_type* > refinement_list; typedef typename refinement_list::iterator refinement_iterator; MyMesh *m; int target_level, maximum_level; simplification_list s; refinement_list r; inline bool needs_simplification(const vertex_type *v) { return v->level() > target_level; } inline bool needs_refinement(const halfedge_type *h) { return h->is_split() && h->level() < target_level; } public: MyAdaptivePolicy(MyMesh *_m, const int& _tl = 0, const int& _ml = 10) : m(_m), target_level(_tl), maximum_level(_ml) { if( target_level > maximum_level ) target_level = maximum_level; } ~MyAdaptivePolicy() { s.clear(); r.clear(); } void increase_target_level() { if(target_level < maximum_level) ++target_level; } void decrease_target_level() { if(target_level > 0) --target_level; } void update_simplification(vertex_type *v) { } void update_simplification(halfedge_type *h) { } void update_simplification(void) { s.clear(); for (MyMesh::vertex_iterator vit = m->vertices_begin(); vit != m->vertices_end(); ++vit) if( needs_simplification( *vit ) ) s.push_back( *vit ); } void update_refinement(halfedge_type *h) { refinement_iterator rit = std::find( r.begin(), r.end(), h->opposite() ); if( rit != r.end() ) r.erase( rit ); } void update_refinement(vertex_type *v) { } void update_refinement(void) { r.clear(); for (MyMesh::halfedge_iterator hit = m->halfedges_begin(); hit != m->halfedges_end(); ++hit) if( needs_refinement( *hit ) ) r.push_back( *hit ); } vertex_type* next_simplify_vertex(void) { if( s.empty() ) { update_simplification(); if( s.empty() ) return 0; } vertex_type *v = s.back(); s.pop_back(); return v; } halfedge_type* next_refine_halfedge(void) { if( r.empty() ){ update_refinement(); if( r.empty() ) return 0; } halfedge_type *h = r.back(); r.pop_back(); return h; } }; void example(void) { MyStellarPolicy< MyTraits > sp; MyMesh m( &sp.ip, &sp ); m.set_base( sp.ip.num_verts, sp.ip.num_faces, sp.ip.faces ); MyAdaptivePolicy< MyTraits > ap( &m ); m.set_adaptive_policy( &ap ); }