Subversion Repositories gelsvn

Rev

Rev 506 | Blame | Last modification | View Log | RSS feed

#include "HalfEdgeHandle.h"

#include <iterator>

#include "entities.h"

#include "Manifold.h"
#include "VertexHandle.h"
#include "FaceHandle.h"

#include "VertexCirculator.h"

namespace HMesh
{  
    using namespace std;

    /************************************
    * ConstHalfEdgeHandle functions
    ************************************/
    bool boundary(ConstHalfEdgeHandle h)
    { 
        return h.face() == NULL_CFHANDLE || h.opp().face() == NULL_CFHANDLE;
    }
    float length(ConstHalfEdgeHandle h)
    { 
        return (h.vert().get().pos - h.opp().vert().get().pos).length(); 
    }

    bool precond_collapse_halfedge(ConstHalfEdgeHandle h)
    {
        // get the two vertices of the edge being tested
        ConstVertexHandle v0 = h.opp().vert();
        ConstVertexHandle v1 = h.vert();

        // get the one-ring of v0
        vector<VertexIndex> link0; 
        for(ConstVertexCirculator vc0(v0); !vc0.end(); ++vc0){
            link0.push_back(vc0.vertex().get_idx());
        }
        assert(link0.size() > 1);

        // get the one-ring of v1
        vector<VertexIndex> link1;
        for(ConstVertexCirculator vc1(v1); !vc1.end(); ++vc1){
            link1.push_back(vc1.vertex().get_idx());
        }
        assert(link1.size() > 1);

        // sort the vertices of the two rings
        sort(link0.begin(), link0.end());
        sort(link1.begin(), link1.end());

        // get the intersection of the shared vertices from both rings
        vector<VertexIndex> lisect;
        std::back_insert_iterator<vector<VertexIndex> > lii(lisect);
        set_intersection(link0.begin(), link0.end(),
            link1.begin(), link1.end(),
            lii);


        int k = 0;
        // if the adjacent face is a triangle (see 2)
        if(h.next().next().next() == h){
            ConstVertexHandle v = h.next().vert();

            // valency test (see 5)
            if(valency(v) < 4)
                return false;

            // remove the vertex shared by the two rings from the intersection
            vector<VertexIndex>::iterator iter;
            iter = find(lisect.begin(), lisect.end(), v.get_idx());
            assert(iter != lisect.end());
            lisect.erase(iter);
            ++k;
        }
        // if the adjacent face is a triangle (see 2)
        if(h.opp().next().next().next() == h.opp()){
            ConstVertexHandle v = h.opp().next().vert();

            // valency test (see 5)
            if(valency(v) < 4)
                return false;

            // remove the vertex shared by the two rings from the intersection
            vector<VertexIndex>::iterator iter;
            iter = find(lisect.begin(), lisect.end(), v.get_idx());
            assert(iter != lisect.end());
            lisect.erase(iter);
            ++k;
        }
        // double edge test (see 3)
        if(lisect.size() != 0)
            return false;

        // tetrahedon test (see 4)
        if(k == 2 && (link0.size() + link1.size() == 6))
            return false;

        // test that we do not merge holes (see 6)
        if(boundary(v0) && boundary(v1) && h.face() != NULL_FHANDLE && h.opp().face() != NULL_FHANDLE)
            return false;

        return true;
    }
}