Subversion Repositories gelsvn

Rev

Blame | Last modification | View Log | RSS feed

#include "HalfEdgeHandle.h"

#include "entities.h"

#include "Manifold.h"
#include "VertexHandle.h"
#include "FaceHandle.h"

#include "VertexCirculator.h"

namespace HMesh
{
    HalfEdgeHandle::HalfEdgeHandle(Manifold& _m, Hidx _idx)
        : m(&_m), idx(_idx)
    {}

    const VertexHandle HalfEdgeHandle::vert() const 
    { 
        return m->vertex_handle(m->halfedges[idx].vert_idx); 
    }
    const HalfEdgeHandle HalfEdgeHandle::next() const 
    { 
        return m->halfedge_handle(m->halfedges[idx].next_idx); 
    }
    const HalfEdgeHandle HalfEdgeHandle::prev() const 
    { 
        return m->halfedge_handle(m->halfedges[idx].prev_idx); 
    }
    const HalfEdgeHandle HalfEdgeHandle::opp() const
    { 
        return m->halfedge_handle(m->halfedges[idx].opp_idx); 
    }
    const FaceHandle HalfEdgeHandle::face() const 
    { 
        return m->face_handle(m->halfedges[idx].face_idx); 
    }
    
    VertexHandle HalfEdgeHandle::vert()
    { 
        return m->vertex_handle(m->halfedges[idx].vert_idx); 
    }
    HalfEdgeHandle HalfEdgeHandle::next()
    { 
        return m->halfedge_handle(m->halfedges[idx].next_idx); 
    }
    HalfEdgeHandle HalfEdgeHandle::prev()
    { 
        return m->halfedge_handle(m->halfedges[idx].prev_idx); 
    }
    HalfEdgeHandle HalfEdgeHandle::opp()
    { 
        return m->halfedge_handle(m->halfedges[idx].opp_idx); 
    }
    FaceHandle HalfEdgeHandle::face()
    { 
        return m->face_handle(m->halfedges[idx].face_idx); 
    }

    const HalfEdge& HalfEdgeHandle::get() const
    {
        return m->halfedges[idx];
    }
    HalfEdge& HalfEdgeHandle::get()
    {
        return m->halfedges[idx];
    }

    bool HalfEdgeHandle::operator==(const HalfEdgeHandle& h) const
    {
        return idx == h.get_idx();
    }
    bool HalfEdgeHandle::operator!=(const HalfEdgeHandle& h) const
    {
        return idx != h.get_idx();
    }
    void HalfEdgeHandle::operator++()
    {
        ++idx;
        while(idx < m->halfedges.size() && !m->halfedges.in_use(idx))
            ++idx;

    }
    void HalfEdgeHandle::operator++(int)
    {
        ++(*this);
    }
    void HalfEdgeHandle::operator--()
    {
        --idx;
        while(!m->halfedges.in_use(idx))
            --idx;

    }
    void HalfEdgeHandle::operator--(int)
    {
        --(*this);
    }

    bool HalfEdgeHandle::is_valid() const
    {
        return idx != NULL_HALFEDGE_IDX;
    }

    bool HalfEdgeHandle::in_use() const
    {
        return m->halfedges.in_use(idx);
    }

    Hidx HalfEdgeHandle::get_idx() const 
    { 
        return idx; 
    }

    Manifold* HalfEdgeHandle::get_manifold() const
    {
        return m;
    }

    /* namespace functions for handles */

   /* bool is_used(const HalfEdgeHandle& h)
    {
        if(h.vert().get_idx() != NULL_VERTEX_IDX)
            return true;
        return false;
    }*/

    bool is_boundary(const HalfEdgeHandle& h)
    { 
        return !h.face().is_valid() || !h.opp().face().is_valid();
    }


    float length(const HalfEdgeHandle& h)
    { 
        return (h.vert().get().pos - h.opp().vert().get().pos).length(); 
    }

    void link(HalfEdgeHandle& h0, HalfEdgeHandle& h1)
    {
        h0.get().next_idx = h1.get_idx();
        h1.get().prev_idx = h0.get_idx();
    }

    void glue(HalfEdgeHandle& h0, HalfEdgeHandle& h1)
    {
        h0.get().opp_idx = h1.get_idx();
        h1.get().opp_idx = h0.get_idx();
    }

    bool flip(HalfEdgeHandle& h)
    {
        FaceHandle f = h.face();
        HalfEdgeHandle ho = h.opp();
        FaceHandle fo = ho.face();

        if(!f.is_valid() || !fo.is_valid()){
            return false;
        }
                // We can only flip an edge if both incident polygons are triangles. 
        if(no_edges(f) != 3 || no_edges(fo) !=3){
                        return false;
        }
                // non boundary vertices with a valency of less than 4(less than 3 after operation) degenerates mesh.
        VertexHandle v = h.vert();
        VertexHandle vo = ho.vert();
        if((valency(v) < 4 && !is_boundary(v)) || (valency(vo) < 4 && !is_boundary(vo))){
            return false;
        }
                // Disallow flip if vertices being connected already are.
        VertexHandle vn = h.next().vert();
        VertexHandle von = ho.next().vert();
        if(is_connected(vn, von)){
            return false;
        }
        HalfEdgeHandle hn = h.next();
        HalfEdgeHandle hp = h.prev();
        HalfEdgeHandle hon = ho.next();
        HalfEdgeHandle hop = ho.prev();

        hop.get().face_idx = f.get_idx();
        hp.get().face_idx = fo.get_idx();
        f.get().last_idx = h.get_idx();
        fo.get().last_idx = ho.get_idx();

        link(hn, h);
        link(h, hop);
        link(hop, hn);

        link(hon, ho);
        link(ho, hp);
        link(hp, hon);

        h.get().vert_idx = von.get_idx();
        ho.get().vert_idx = vn.get_idx();

        v.get().out_idx = hn.get_idx();
        vo.get().out_idx = hon.get_idx();

        check_boundary_consistency(v);
        check_boundary_consistency(vo);

        return true;
    }
}