a48  2.0.2
example_meshalgorithms.cc

This is an example of how to use the functions in the mesh algorithms header.

See also:
meshalgorithms.hh
#include <cmath>
#include <limits>
#include <sstream>

#include <mesh.hh>

template< class Traits >
class GeometryVertex : public a48::AdaptiveVertexT< Traits > {
public: unsigned int id; float pos[3]; 
};

class GeometryTraits {
public:
    typedef GeometryVertex< GeometryTraits > vertex_type;
    typedef a48::AdaptiveHalfedgeT< GeometryTraits > halfedge_type;
    typedef a48::AdaptiveFaceT< GeometryTraits > face_type;
};

typedef a48::AdaptiveMeshT< GeometryTraits > GeometryMesh; 

typedef GeometryMesh::vertex_type vertex_type;
typedef GeometryMesh::halfedge_type halfedge_type;
typedef GeometryMesh::face_type face_type;
typedef GeometryMesh::face_iterator face_iterator;


static GeometryMesh m;


void set_vertex_geometry(vertex_type *v, const std::string& str) {

    std::stringstream ss(std::stringstream::in | std::stringstream::out);
    ss << str;
    ss >> v->pos[0] >> v->pos[1] >> v->pos[2];

}

void set_vertex_index(vertex_type *v, const unsigned& id) {

    v->id = id;

}

float rank(halfedge_type *h) {

    if( h->is_boundary() ) return std::numeric_limits<float>::max();

    vertex_type *v0 = h->next()->vertex(), *v1 = h->vertex(), *v2 = h->from_vertex(),
    *v3 = h->opposite()->next()->vertex(), *v4 = h->opposite()->vertex(), *v5 = h->opposite()->from_vertex();

    float v_01[3], v_02[3], v_34[3], v_35[3],
    l_01 = 0.f, l_02 = 0.f, l_34 = 0.f, l_35 = 0.f,
    dot_012 = 0.f, dot_345 = 0.f;

    for (unsigned int k = 0; k < 3; ++k) {
        v_01[k] = v1->pos[k] - v0->pos[k];
        v_02[k] = v2->pos[k] - v0->pos[k];
        v_34[k] = v4->pos[k] - v3->pos[k];
        v_35[k] = v5->pos[k] - v3->pos[k];
        l_01 += (v_01[k] * v_01[k]);
        l_02 += (v_02[k] * v_02[k]);
        l_34 += (v_34[k] * v_34[k]);
        l_35 += (v_35[k] * v_35[k]);
    }

    if( l_01*l_02*l_34*l_35 == 0.f ) return std::numeric_limits<float>::max();

    l_01 = sqrt( l_01 );
    l_02 = sqrt( l_02 );
    l_34 = sqrt( l_34 );
    l_35 = sqrt( l_35 );

    for (unsigned int k = 0; k < 3; ++k) {
        dot_012 += (v_01[k] / l_01) * (v_02[k] / l_02);
        dot_345 += (v_34[k] / l_34) * (v_35[k] / l_35);
    }

    return fabs(dot_012) + fabs(dot_345);

}

int main(int argc, char* argv[]) {

    if( argc != 2 ) { std::cerr << "Usage: " << argv[0] << " file.off\n"; return 1; }

    std::cout << "[GeometryMesh] Reading OFF: " << argv[1] << " ... " << std::flush;

    if( !a48::read_off_mesh( m, argv[1], set_vertex_geometry, set_vertex_index ) ) return 1;

    std::cout << "done!\n";

    std::cout << "[GeometryMesh] Vertices: " << m.size_of_vertices() << std::endl;
    std::cout << "[GeometryMesh] Halfedges: " << m.size_of_halfedges() << std::endl;
    std::cout << "[GeometryMesh] Faces: " << m.size_of_faces() << std::endl;

    std::cout << "[GeometryMesh] The input mesh is" << (m.is_valid()?" ":" not ") << "valid.\n";
    std::cout << "[GeometryMesh] The input mesh is" << (m.is_closed()?" ":" not ") << "closed.\n";
    std::cout << "[GeometryMesh] The input mesh is" << (m.is_consistent()?" ":" not ") << "consistent.\n";
    std::cout << "[GeometryMesh] The input mesh is" << (m.is_manifold()?" ":" not ") << "a manifold.\n";
    std::cout << "[GeometryMesh] The input mesh is" << (m.is_tri()?" ":" not ") << "a triangulated mesh.\n";
    std::cout << "[GeometryMesh] The input mesh is" << (m.is_triquad()?" ":" not ") << "a tri-quad mesh.\n";

    srand( time(0) );

    unsigned int r; // random value to determine face flip

    std::cout << "[GeometryMesh] Flipping indices of the mesh ... " << std::flush;

    for (face_iterator fit = m.faces_begin(); fit != m.faces_end(); ++fit) {

        r = rand() % 4;
        if( r == 0 ) continue;

        flip_orientation( (*fit)->halfedge() );

    }

    std::cout << "done!\n";

    std::cout << "[GeometryMesh] The input mesh is" << (a48::make_consistent(m)?" ":" non-") << "orientable.\n";

    std::cout << "[GeometryMesh] Making triquad mesh: " << (make_triquad( m, rank, 1 ) ? "success" : "failure") << "!\n";

    std::cout << "[GeometryMesh] Now mesh is" << (m.is_triquad()?" ":" not ") << "a tri-quad mesh.\n";

    std::cout << "[GeometryMesh] Now mesh is" << (m.is_consistent()?" ":" not ") << "consistent.\n";

    std::cout << "[GeometryMesh] Now mesh is" << (m.is_valid()?" ":" not ") << "valid.\n";

    return 0;

}
 All Classes Namespaces Files Functions Typedefs