Rev 129 | 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
{
FaceIter get_null_face_iter()
{
static FaceList l;
return l.end();
}
template<class R>
Face_template<R>::Face_template():
last(NULL_HALFEDGE_ITER),
touched(0)
{}
int no_edges(FaceIter f)
{
FaceCirculator fc(f);
while(!fc.end()) ++fc;
return fc.no_steps();
}
Vec3f normal(FaceIter f)
{
vector<Vec3f> v;
FaceCirculator fc(f);
int k;
for(k=0;!fc.end();++fc,++k)
{
Vec3f p = fc.get_vertex()->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 area(FaceIter f)
{
FaceCirculator fc(f);
int 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.get_vertex()->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 centre(FaceIter f)
{
Vec3f c(0);
FaceCirculator fc(f);
while(!fc.end())
{
c += fc.get_vertex()->pos;
++fc;
}
c /= fc.no_steps();
return c;
}
template struct Face_template<Iters>;
}