a48  2.0.2
example_mesht.cc

This is an example of how to use the Mesh class together with items policy class.

See also:
mesht.hh
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;

}
 All Classes Namespaces Files Functions Typedefs