// This code is in the public domain -- castanyo@yahoo.es #pragma once #ifndef NV_MESH_HALFEDGE_VERTEX_H #define NV_MESH_HALFEDGE_VERTEX_H #include "nvmesh/halfedge/Edge.h" namespace nv { namespace HalfEdge { class Vertex; class Face; class Edge; } // Half edge vertex. class HalfEdge::Vertex { NV_FORBID_COPY(Vertex); public: uint id; Edge * edge; Vertex * next; Vertex * prev; Vector3 pos; Vector3 nor; Vector2 tex; Vector4 col; Vertex(uint id) : id(id), edge(NULL), pos(0.0f), nor(0.0f), tex(0.0f), col(0.0f) { next = this; prev = this; } void setEdge(Edge * e); void setPos(const Vector3 & p); uint colocalCount() const; uint valence() const; bool isFirstColocal() const; const Vertex * firstColocal() const; Vertex * firstColocal(); bool isColocal(const Vertex * v) const; void linkColocal(Vertex * v) { next->prev = v; v->next = next; next = v; v->prev = this; } void unlinkColocal() { next->prev = prev; prev->next = next; next = this; prev = this; } // @@ Note: This only works if linkBoundary has been called. bool isBoundary() const { return (edge && !edge->face); } // for(EdgeIterator it(iterator()); !it.isDone(); it.advance()) { ... } // // EdgeIterator it(iterator()); // while(!it.isDone()) { // ... // id.advance(); // } // Iterator that visits the edges around this vertex in counterclockwise order. class EdgeIterator //: public Iterator { public: EdgeIterator(Edge * e) : m_end(NULL), m_current(e) { } virtual void advance() { if (m_end == NULL) m_end = m_current; m_current = m_current->pair->next; //m_current = m_current->prev->pair; } virtual bool isDone() const { return m_end == m_current; } virtual Edge * current() const { return m_current; } Vertex * vertex() const { return m_current->vertex; } private: Edge * m_end; Edge * m_current; }; EdgeIterator edges() { return EdgeIterator(edge); } EdgeIterator edges(Edge * e) { return EdgeIterator(e); } // Iterator that visits the edges around this vertex in counterclockwise order. class ConstEdgeIterator //: public Iterator { public: ConstEdgeIterator(const Edge * e) : m_end(NULL), m_current(e) { } ConstEdgeIterator(EdgeIterator it) : m_end(NULL), m_current(it.current()) { } virtual void advance() { if (m_end == NULL) m_end = m_current; m_current = m_current->pair->next; //m_current = m_current->prev->pair; } virtual bool isDone() const { return m_end == m_current; } virtual const Edge * current() const { return m_current; } const Vertex * vertex() const { return m_current->to(); } private: const Edge * m_end; const Edge * m_current; }; ConstEdgeIterator edges() const { return ConstEdgeIterator(edge); } ConstEdgeIterator edges(const Edge * e) const { return ConstEdgeIterator(e); } // Iterator that visits the edges around this vertex in counterclockwise order. class ReverseEdgeIterator //: public Iterator { public: ReverseEdgeIterator(Edge * e) : m_end(NULL), m_current(e) { } virtual void advance() { if (m_end == NULL) m_end = m_current; m_current = m_current->prev->pair; } virtual bool isDone() const { return m_end == m_current; } virtual Edge * current() const { return m_current; } Vertex * vertex() const { return m_current->vertex; } private: Edge * m_end; Edge * m_current; }; // Iterator that visits the edges around this vertex in counterclockwise order. class ReverseConstEdgeIterator //: public Iterator { public: ReverseConstEdgeIterator(const Edge * e) : m_end(NULL), m_current(e) { } virtual void advance() { if (m_end == NULL) m_end = m_current; m_current = m_current->prev->pair; } virtual bool isDone() const { return m_end == m_current; } virtual const Edge * current() const { return m_current; } const Vertex * vertex() const { return m_current->to(); } private: const Edge * m_end; const Edge * m_current; }; // Iterator that visits all the colocal vertices. class VertexIterator //: public Iterator { public: VertexIterator(Vertex * v) : m_end(NULL), m_current(v) { } virtual void advance() { if (m_end == NULL) m_end = m_current; m_current = m_current->next; } virtual bool isDone() const { return m_end == m_current; } virtual Vertex * current() const { return m_current; } private: Vertex * m_end; Vertex * m_current; }; VertexIterator colocals() { return VertexIterator(this); } // Iterator that visits all the colocal vertices. class ConstVertexIterator //: public Iterator { public: ConstVertexIterator(const Vertex * v) : m_end(NULL), m_current(v) { } virtual void advance() { if (m_end == NULL) m_end = m_current; m_current = m_current->next; } virtual bool isDone() const { return m_end == m_current; } virtual const Vertex * current() const { return m_current; } private: const Vertex * m_end; const Vertex * m_current; }; ConstVertexIterator colocals() const { return ConstVertexIterator(this); } }; } // nv namespace #endif // NV_MESH_HALFEDGE_VERTEX_H