Rev 479 | Blame | Last modification | View Log | RSS feed
#include "FaceHandle.h"
#include <vector>
#include <CGLA/Vec2f.h>
#include <CGLA/Vec3f.h>
#include <CGLA/Mat3x3f.h>
#include "HalfEdgeHandle.h"
#include "VertexHandle.h"
#include "Manifold.h"
#include "FaceCirculator.h"
using namespace std;
using namespace CGLA;
namespace HMesh
{
FaceHandle::FaceHandle(Manifold& _m, Fidx _idx): m(&_m), idx(_idx){}
const HalfEdgeHandle FaceHandle::last() const
{
return m->halfedge_handle(m->faces[idx].last_idx);
}
HalfEdgeHandle FaceHandle::last()
{
return m->halfedge_handle(m->faces[idx].last_idx);
}
const Face& FaceHandle::get() const
{
return m->faces[idx];
}
Face& FaceHandle::get()
{
return m->faces[idx];
}
bool FaceHandle::operator==(const FaceHandle& f) const
{
return idx == f.get_idx();
}
bool FaceHandle::operator!=(const FaceHandle& f) const
{
return idx != f.get_idx();
}
void FaceHandle::operator++()
{
++idx;
while(idx < m->faces.full_size() && !m->faces.in_use(idx))
++idx;
}
void FaceHandle::operator++(int)
{
++(*this);
}
void FaceHandle::operator--()
{
--idx;
while(!m->faces.in_use(idx))
--idx;
}
void FaceHandle::operator--(int)
{
--(*this);
}
bool FaceHandle::is_valid() const
{
return idx != NULL_FACE_IDX;
}
bool FaceHandle::in_use() const
{
return m->faces.in_use(idx);
}
Fidx FaceHandle::get_idx() const
{
return idx;
}
Manifold* FaceHandle::get_manifold() const
{
return m;
}
/*bool is_used(const FaceHandle& f)
{
if(f.last().is_valid())
return true;
return false;
}*/
uint no_edges(FaceHandle f)
{
// perform full circulation to get valency
FaceCirculator fc(f);
for(; !fc.end(); ++fc);
return fc.no_steps();
}
CGLA::Vec3f normal(FaceHandle f)
{
vector<Vec3f> vertices;
FaceCirculator fc(f);
// Assuming that a face is valid, i.e. consisting of AT LEAST 3 vertices...
for(uint i = 0; i < 3; ++i, ++fc) vertices.push_back(fc.vertex().get().pos);
Vec3f n = cross(vertices[0] - vertices[1], vertices[2] - vertices[1]);
float l = n.length();
if(l > 0.0f) return n/l;
return n;
}
float area(FaceHandle f)
{
FaceCirculator fc(f);
uint k;
// M is a matrix that projects a vector onto the orthogonal
// complement of the face normal
Vec3f n =normal(f);
Vec3f a,b;
orthogonal(n, a, b);
Mat3x3f M(a, b, n);
// Get all projected vertices
vector<Vec2f> v;
for(k = 0; !fc.end(); ++fc, ++k){
Vec3f p = M * fc.vertex().get().pos;
v.push_back(Vec2f(p[0], p[1]));
}
float area = 0;
for(uint i = 0; i < k; ++i) area += 0.5 * cross(v[i], v[(i+1 )% k]);
return abs(area);
}
CGLA::Vec3f centre(FaceHandle f)
{
Vec3f c(0);
FaceCirculator fc(f);
for(; !fc.end(); ++fc) c += fc.vertex().get().pos;
c /= fc.no_steps();
return c;
}
}