Rev 489 | Blame | Last modification | View Log | RSS feed
#include "VertexHandle.h"
#include <vector>
#include <CGLA/Vec3f.h>
#include "entities.h"
#include "Manifold.h"
#include "HalfEdgeHandle.h"
#include "FaceHandle.h"
#include "VertexCirculator.h"
using namespace std;
using namespace CGLA;
namespace HMesh
{
/************************************
* VertexHandle functions
*************************************/
HalfEdgeHandle VertexHandle::out()
{
return HalfEdgeHandle(*m, m->vertices[idx].out_idx);
}
void VertexHandle::operator++()
{
++idx;
while(idx < m->vertices.full_size() && !m->vertices.in_use(idx))
++idx;
}
void VertexHandle::operator++(int)
{
++(*this);
}
void check_boundary_consistency(VertexHandle v)
{
// boundary consistency check by performing two vertex circulations
HalfEdgeHandle h = v.out();
HalfEdgeHandle last = h;
int flaf = 0;
// step 1: circle through edges pointing away from vertex until reaching a null face
while(h.face() != NULL_FH){
h = h.prev().opp();
//std::cout << h.get_idx() << std::endl;
if(h == last)
return;
}
// null face encountered, we update our vertex with half edge index and prepare for step 2
v.get().out_idx = h.get_idx();
HalfEdgeHandle h_opp = h.opp();
// step 2: circle through edges pointing towards vertex until reaching a null face
while(h_opp.face() != NULL_FH){
h_opp = h_opp.next().opp();
}
// null face encountered again, we update our edge with vertex index
h_opp.get().vert_idx = v.get_idx();
// remaining step is to make the in and out going edges link to each other
link(h_opp, h);
}
/************************************
* ConstVertexHandle functions
*************************************/
ConstHalfEdgeHandle ConstVertexHandle::out() const
{
return ConstHalfEdgeHandle(*m, m->vertices[idx].out_idx);
}
void ConstVertexHandle::operator++()
{
++idx;
while(idx < m->vertices.full_size() && !m->vertices.in_use(idx))
++idx;
}
void ConstVertexHandle::operator++(int)
{
++(*this);
}
bool is_boundary(ConstVertexHandle v)
{
return is_boundary(v.out());
}
IndexType valency(ConstVertexHandle v)
{
// perform full circulation to get valency
ConstVertexCirculator vc(v);
while(!vc.end()) ++vc;
return vc.no_steps();
}
CGLA::Vec3f normal(ConstVertexHandle v)
{
Vec3f p0 = v.get().pos;
vector<Vec3f> one_ring;
// run through outgoing edges, and store them normalized
for(ConstVertexCirculator vc(v); !vc.end(); ++vc){
Vec3f edge = p0 - vc.vertex().get().pos;
float l = length(edge);
if(l > 0.0f) one_ring.push_back(edge/l);
}
Vec3f n(0);
IndexType N = one_ring.size();
// sum up the normals of each face surrounding the vertex
for(IndexType i = 0; i < N; ++i){
Vec3f e1 = one_ring[i];
Vec3f e0 = one_ring[(i+1) % N];
Vec3f n_part = normalize(cross(e0, e1));
n += n_part * acos(max(-1.0f, min(1.0f, dot(e0, e1))));
}
// normalize and return the normal
float sqr_l = sqr_length(n);
if(sqr_l > 0.0f) return n / sqrt(sqr_l);
return n;
}
bool is_connected(ConstVertexHandle v0, ConstVertexHandle v1)
{
for(ConstVertexCirculator vc(v0); !vc.end(); ++vc){
if(vc.vertex() == v1)
return true;
}
return false;
}
}