Program Listing for File HalfEdge.hpp

Return to documentation for file (include/lvr2/geometry/HalfEdge.hpp)

/*
 * HalfEdge.hpp
 *
 *  @date 02.06.2017
 *  @author Lukas Kalbertodt <lukas.kalbertodt@gmail.com>
 */

#ifndef LVR2_GEOMETRY_HALFEDGE_H_
#define LVR2_GEOMETRY_HALFEDGE_H_

#include <utility>

#include "BaseMesh.hpp"
#include "Handles.hpp"

namespace lvr2
{

// We need a specific handle for half edges. The `BaseMesh` interface talks
// about simple (full) edges. To avoid confusion, this HalfEdgeHandle is used
// internally in the HEM. The edge handles given out by the HEM implementation
// are handles to the half edge with the lower index.

class HalfEdgeHandle : public BaseHandle
{
public:
    using BaseHandle::BaseHandle;

    static HalfEdgeHandle oneHalfOf(EdgeHandle eH)
    {
        // The index of an edge handle is always the index of the handle of
        // one of its half edges
        return HalfEdgeHandle(eH.idx());
    }
};

class OptionalHalfEdgeHandle : public BaseOptionalHandle<HalfEdgeHandle>
{
public:
    using BaseOptionalHandle<HalfEdgeHandle>::BaseOptionalHandle;
    OptionalHalfEdgeHandle(EdgeHandle eH) : OptionalHalfEdgeHandle(eH.idx()) {}
};

struct HalfEdge
{
    OptionalFaceHandle face;

    VertexHandle target;

    HalfEdgeHandle next;

    HalfEdgeHandle twin;

private:
    HalfEdge() : target(0), next(0), twin(0) {}

    template <typename BaseVecT>
    friend class HalfEdgeMesh;
};


inline std::ostream& operator<<(std::ostream& os, const HalfEdgeHandle& h)
{
    os << "HE" << h.idx();
    return os;
}

inline std::ostream& operator<<(std::ostream& os, const OptionalHalfEdgeHandle& h)
{
    if (h)
    {
        os << "HE" << h.unwrap().idx();
    }
    else
    {
        os << "HE⊥";
    }
    return os;
}

} // namespace lvr2

namespace std
{

template<>
struct hash<lvr2::HalfEdgeHandle> {
    size_t operator()(const lvr2::HalfEdgeHandle& h) const
    {
        return std::hash<lvr2::Index>()(h.idx());
    }
};

} // namespace std

#endif /* LVR2_GEOMETRY_HALFEDGE_H_ */