Subversion Repositories gelsvn

Rev

Rev 480 | Blame | Last modification | View Log | RSS feed

#ifndef __HMESH_HALFEDGEHANDLE_H__
#define __HMESH_HALFEDGEHANDLE_H__

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

namespace HMesh
{
    // forward declarations
    class Manifold;

    class HalfEdgeHandle
    {
    public:
       HalfEdgeHandle();
       HalfEdgeHandle(Manifold& _m, HIDX _idx);

        /// Get a handle to vertex pointed to by this halfedge
        const VertexHandle vert() const;
        /// Get a handle to the next halfedge in face loop
        const HalfEdgeHandle next() const;
        /// Get a handle to the previous halfedge in face loop
        const HalfEdgeHandle prev() const;
        /// Get a handle to the opposite halfedge
        const HalfEdgeHandle opp() const;
        /// Get a handle to the face this halfedge belongs to
        const FaceHandle face() const; 

        /// Get a handle to vertex pointed to by this halfedge
        VertexHandle vert();
        /// Get a handle to the next halfedge in face loop
        HalfEdgeHandle next();
        /// Get a handle to the previous halfedge in face loop
        HalfEdgeHandle prev();
        /// Get a handle to the opposite halfedge
        HalfEdgeHandle opp();
        /// Get a handle to the face this halfedge belongs to
        FaceHandle face();

        /// Get a const reference to the halfedge
        const HalfEdge& get() const;
        /// Get a reference to the halfedge
        HalfEdge& get();

        bool operator==(const HalfEdgeHandle& f) const;
        bool operator!=(const HalfEdgeHandle& f) const;

        void operator++();
        void operator++(int);

        /// Get index of halfedge
        HIDX get_idx() const;
    private:
        /// ID of halfedge
        HIDX idx;
        /// pointer to manifold storing the halfege
        Manifold* m;
    };
    
    inline HalfEdgeHandle::HalfEdgeHandle(): m(NULL), idx(NULL_HALFEDGE_IDX){}
    inline HalfEdgeHandle::HalfEdgeHandle(Manifold& _m, HIDX _idx): m(&_m), idx(_idx){}
    
    inline const VertexHandle HalfEdgeHandle::vert() const{ return m->vertex_handle(m->halfedges[idx].vert_idx); }
    inline const HalfEdgeHandle HalfEdgeHandle::next() const{ return m->halfedge_handle(m->halfedges[idx].next_idx); }
    inline const HalfEdgeHandle HalfEdgeHandle::prev() const{ return m->halfedge_handle(m->halfedges[idx].prev_idx); }
    inline const HalfEdgeHandle HalfEdgeHandle::opp() const{ return m->halfedge_handle(m->halfedges[idx].opp_idx); }
    inline const FaceHandle HalfEdgeHandle::face() const{ return m->face_handle(m->halfedges[idx].face_idx); }

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

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

    inline bool HalfEdgeHandle::operator==(const HalfEdgeHandle& h) const{ return idx == h.get_idx(); }
    inline bool HalfEdgeHandle::operator!=(const HalfEdgeHandle& h) const{ return idx != h.get_idx(); }

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

    inline HIDX HalfEdgeHandle::get_idx() const{ return idx; }

#define NULL_HALFEDGE_HANDLE HalfEdgeHandle()

    /// Returns true if the halfedge is a boundary halfedge.
    bool is_boundary(HalfEdgeHandle h);

    /// Return the geometric length of a halfedge.
    float length(HalfEdgeHandle h);

    /// Set the next and prev indices of the first and second argument respectively.
    void link(HalfEdgeHandle h0, HalfEdgeHandle h1);

    /// Glue halfedges by letting the opp indices point to each other.
    void glue(HalfEdgeHandle h0, HalfEdgeHandle h1);

        /** \brief Flip an edge h. 
        Returns false if flipping cannot be performed. This is due to one of following: 
        1.  one of the two adjacent faces is not a triangle. 
        2.  Either end point has valency three.
        3.  The vertices that will be connected already are. */
    bool flip(HalfEdgeHandle h);
}

#endif __HMESH_HALFEDGEHANDLE_H__