a48  2.0.2
example_adaptivepolicy.cc

This is an example of how to use the Adaptive Policy paradigm using the a48 halfedge datastructure classes.

See also:
adaptivemesht.hh
#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 );
}
 All Classes Namespaces Files Functions Typedefs