Blame | Last modification | View Log | RSS feed
#include <vector>
#include "CGLA/Mat3x3f.h"
#include "CGLA/Vec2f.h"
#include "Face.h"
#include "Manifold.h"
#include "FaceCirculator.h"
using namespace CGLA;
using namespace std;
namespace HMesh
{
template<class R>
Face_template<R>::Face_template():
last(NULL_HALFEDGE_ITER),
touched(0)
{}
FaceIter NULL_FACE_ITER(0);
template class Face_template<Iters>;
int no_edges(FaceIter f)
{
FaceCirculator fc(f);
while(!fc.end()) ++fc;
return fc.no_steps();
}
Vec3f get_normal(FaceIter f)
{
vector<Vec3f> v;
FaceCirculator fc(f);
int k;
for(k=0;!fc.end();++fc,++k)
{
Vec3f p = fc.get_vertex()->get_pos();
v.push_back(p);
}
Vec3f norm(0);
for(int i=0;i<k;++i)
{
norm[0] += (v[i][1]-v[(i+1)%k][1])*(v[i][2]+v[(i+1)%k][2]);
norm[1] += (v[i][2]-v[(i+1)%k][2])*(v[i][0]+v[(i+1)%k][0]);
norm[2] += (v[i][0]-v[(i+1)%k][0])*(v[i][1]+v[(i+1)%k][1]);
}
float l = norm.length();
if(l>0.0f)
norm /= l;
return norm;
}
float get_area(FaceIter f)
{
FaceCirculator fc(f);
int k;
// M is a matrix that projects a vector onto the orthogonal
// complement of the face normal
Mat3x3f M;
Vec3f n = get_normal(f);
outer_product(n,n,M);
M = identity_Mat3x3f() - M;
// Get all projected vertices
vector<Vec2f> v;
for(k=0;!fc.end();++fc,++k)
{
Vec3f p = M * fc.get_vertex()->get_pos();
v.push_back(Vec2f(p[0], p[1]));
}
float area = 0;
for(int i=0;i<k;++i)
{
area += 0.5 * cross(v[i], v[(i+1)%k]);
}
return fabs(area);
}
Vec3f get_centre(FaceIter f)
{
Vec3f c(0);
FaceCirculator fc(f);
while(!fc.end())
{
c += fc.get_vertex()->get_pos();
++fc;
}
c /= fc.no_steps();
return c;
}
}