Rev 500 | 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
{
HalfEdgeHandle FaceHandle::last()
{
return HalfEdgeHandle(*m, m->faces[idx].last_idx);
}
IndexType no_edges(ConstFaceHandle f)
{
// perform full circulation to get valency
ConstFaceCirculator fc(f);
for(; !fc.end(); ++fc);
return fc.no_steps();
}
CGLA::Vec3f normal(ConstFaceHandle f)
{
vector<Vec3f> vertices;
ConstFaceCirculator fc(f);
// Assuming that a face is valid, i.e. consisting of AT LEAST 3 vertices...
for(IndexType 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 = sqr_length(n);
if(l > 0.0f) return n/sqrt(l);
return Vec3f(0);
}
ConstHalfEdgeHandle ConstFaceHandle::last()
{
return ConstHalfEdgeHandle(*m, m->faces[idx].last_idx);
}
float area(ConstFaceHandle f)
{
ConstFaceCirculator fc(f);
IndexType k;
// M is a matrix that projects a vector onto the orthogonal
// complement of the face normal
Vec3f n =normal(f);
if(sqr_length(n)<0.1) // actually this number is arbitrary - the normal is unit length or zero length
return 0; // threshold .1 just to avoid floating point issues.
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(IndexType i = 0; i < k; ++i) area += 0.5 * cross(v[i], v[(i+1 )% k]);
return abs(area);
}
CGLA::Vec3f centre(ConstFaceHandle f)
{
Vec3f c(0);
ConstFaceCirculator fc(f);
for(; !fc.end(); ++fc) c += fc.vertex().get().pos;
c /= fc.no_steps();
return c;
}
}