// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2014 Daniele Panozzo // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #ifndef IGL_HALFEDGEITERATOR_H #define IGL_HALFEDGEITERATOR_H #include #include namespace igl { // HalfEdgeIterator - Fake halfedge for fast and easy navigation on triangle meshes with vertex_triangle_adjacency and // triangle_triangle adjacency template class Pos { public: // Init the HalfEdgeIterator by specifying Face,Edge Index and Orientation IGL_INLINE HalfEdgeIterator( const Eigen::PlainObjectBase* F, const Eigen::PlainObjectBase* FF, const Eigen::PlainObjectBase* FFi, int fi, int ei, bool reverse = false ) : F(F), FF(FF), FFi(FFi), fi(fi), ei(ei), reverse(reverse) {} // Change Face IGL_INLINE void flipF() { if (isBorder()) return; int fin = (*FF)(fi,ei); int ein = (*FFi)(fi,ei); int reversen = !reverse; fi = fin; ei = ein; reverse = reversen; } // Change Edge IGL_INLINE void flipE() { if (!reverse) ei = (ei+2)%3; // ei-1 else ei = (ei+1)%3; reverse = !reverse; } // Change Vertex IGL_INLINE void flipV() { reverse = !reverse; } IGL_INLINE bool isBorder() { return (*FF)(fi,ei) == -1; } /*! * Returns the next edge skipping the border * _________ * /\ c | b /\ * / \ | / \ * / d \ | / a \ * /______\|/______\ * v * In this example, if a and d are of-border and the pos is iterating counterclockwise, this method iterate through the faces incident on vertex v, * producing the sequence a, b, c, d, a, b, c, ... */ IGL_INLINE bool NextFE() { if ( isBorder() ) // we are on a border { do { flipF(); flipE(); } while (!isBorder()); flipE(); return false; } else { flipF(); flipE(); return true; } } // Get vertex index IGL_INLINE int Vi() { assert(fi >= 0); assert(fi < F->rows()); assert(ei >= 0); assert(ei <= 2); if (!reverse) return (*F)(fi,ei); else return (*F)(fi,(ei+1)%3); } // Get face index IGL_INLINE int Fi() { return fi; } // Get edge index IGL_INLINE int Ei() { return ei; } IGL_INLINE bool operator==(Pos& p2) { return ( (fi == p2.fi) && (ei == p2.ei) && (reverse == p2.reverse) && (F == p2.F) && (FF == p2.FF) && (FFi == p2.FFi) ); } private: int fi; int ei; bool reverse; const Eigen::PlainObjectBase* F; const Eigen::PlainObjectBase* FF; const Eigen::PlainObjectBase* FFi; }; } #endif