Subversion Repositories gelsvn

Rev

Rev 480 | 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
{
    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); }

    size_t 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(size_t 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);
                size_t 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(size_t 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;
        }
}