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;
}
}