Subversion Repositories gelsvn

Rev

Rev 489 | 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 HalfEdgeHandle;
    class ConstHalfEdgeHandle;
    class VertexHandle;
    class ConstVertexHandle;
    class Facehandle;
    class ConstFacehandle;

    /************************************
    * HalfEdgeHandle + functions
    *************************************/

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

        /// 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 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
        HalfedgeIndex get_idx() const;
    private:
        friend class ConstHalfEdgeHandle;

        /// ID of halfedge
        HalfedgeIndex idx;
        /// pointer to manifold storing the halfege
        Manifold* m;
    };
    
    inline HalfEdgeHandle::HalfEdgeHandle()
        : m(NULL), idx(NULL_HIDX)
    {}
    inline HalfEdgeHandle::HalfEdgeHandle(Manifold& _m, HalfedgeIndex _idx)
        : m(&_m), idx(_idx)
    {} 
    inline VertexHandle HalfEdgeHandle::vert()
    { 
        return VertexHandle(*m, m->halfedges[idx].vert_idx); 
    }
    inline HalfEdgeHandle HalfEdgeHandle::next()
    { 
        return HalfEdgeHandle(*m, m->halfedges[idx].next_idx); 
    }
    inline HalfEdgeHandle HalfEdgeHandle::prev()
    { 
        return HalfEdgeHandle(*m, m->halfedges[idx].prev_idx); 
    }
    inline HalfEdgeHandle HalfEdgeHandle::opp()
    { 
        return HalfEdgeHandle(*m, m->halfedges[idx].opp_idx); 
    }
    inline FaceHandle HalfEdgeHandle::face()
    { 
        return FaceHandle(*m, m->halfedges[idx].face_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 HalfedgeIndex HalfEdgeHandle::get_idx() const
    { 
        return idx; 
    }

#define NULL_HH HalfEdgeHandle()

    /// 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);

    /************************************
    * ConstHalfEdgeHandle + functions
    *************************************/
    class ConstHalfEdgeHandle
    {
    public:
       ConstHalfEdgeHandle();
       ConstHalfEdgeHandle(const Manifold& _m, HalfedgeIndex _idx);

       ConstHalfEdgeHandle(const ConstHalfEdgeHandle& che);
       ConstHalfEdgeHandle(const HalfEdgeHandle& he);

       ConstHalfEdgeHandle& operator=(const ConstHalfEdgeHandle& che);
       ConstHalfEdgeHandle& operator=(const HalfEdgeHandle& he);

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

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

        bool operator==(const ConstHalfEdgeHandle& h) const;
        bool operator!=(const ConstHalfEdgeHandle& h) const;

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

        /// Get index of halfedge
        HalfedgeIndex get_idx() const;
    private:
        /// ID of halfedge
        HalfedgeIndex idx;
        /// pointer to manifold storing the halfege
        const Manifold* m;
    };
#define NULL_CHH ConstHalfEdgeHandle()

    inline ConstHalfEdgeHandle::ConstHalfEdgeHandle()
        : m(NULL), idx(NULL_HIDX)
    {}
    inline ConstHalfEdgeHandle::ConstHalfEdgeHandle(const Manifold& _m, HalfedgeIndex _idx)
        : m(&_m), idx(_idx)
    {} 
    inline ConstHalfEdgeHandle::ConstHalfEdgeHandle(const ConstHalfEdgeHandle& ch)
        : m(ch.m), idx(ch.idx)
    {}
    inline ConstHalfEdgeHandle::ConstHalfEdgeHandle(const HalfEdgeHandle& h)
        : m(h.m), idx(h.idx)
    {}
    inline ConstHalfEdgeHandle& ConstHalfEdgeHandle::operator=(const ConstHalfEdgeHandle& ch)
    {
        m = ch.m;
        idx = ch.idx;
        return *this;
    }
    inline ConstHalfEdgeHandle& ConstHalfEdgeHandle::operator=(const HalfEdgeHandle& h)
    {
        m = h.m;
        idx = h.idx;
        return *this;
    }

    inline ConstVertexHandle ConstHalfEdgeHandle::vert() const
    { 
        return ConstVertexHandle(*m, m->halfedges[idx].vert_idx); 
    }
    inline ConstHalfEdgeHandle ConstHalfEdgeHandle::next() const
    { 
        return ConstHalfEdgeHandle(*m, m->halfedges[idx].next_idx); 
    }
    inline ConstHalfEdgeHandle ConstHalfEdgeHandle::prev() const
    { 
        return ConstHalfEdgeHandle(*m, m->halfedges[idx].prev_idx); 
    }
    inline ConstHalfEdgeHandle ConstHalfEdgeHandle::opp() const
    { 
        return ConstHalfEdgeHandle(*m, m->halfedges[idx].opp_idx); 
    }
    inline ConstFaceHandle ConstHalfEdgeHandle::face() const
    { 
        return ConstFaceHandle(*m, m->halfedges[idx].face_idx); 
    }
    inline const HalfEdge& ConstHalfEdgeHandle::get() const
    { 
        return m->halfedges[idx]; 
    }

    inline bool ConstHalfEdgeHandle::operator==(const ConstHalfEdgeHandle& h) const
    { 
        return idx == h.get_idx(); 
    }
    inline bool ConstHalfEdgeHandle::operator!=(const ConstHalfEdgeHandle& h) const
    { 
        return idx != h.get_idx(); 
    }
    inline void ConstHalfEdgeHandle::operator++()
    { 
        do{ 
            ++idx; 
        } 
        while(idx < m->halfedges.full_size() && !m->halfedges.in_use(idx)); 
    }
    inline void ConstHalfEdgeHandle::operator++(int)
    { 
        ++(*this); 
    }
    inline HalfedgeIndex ConstHalfEdgeHandle::get_idx() const
    { 
        return idx; 
    }

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

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

#endif __HMESH_HALFEDGEHANDLE_H__