Files
igl/include/igl/HalfEdgeIterator.h
T
2014-10-24 21:13:07 +02:00

158 lines
3.2 KiB
C++

// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2014 Daniele Panozzo <daniele.panozzo@gmail.com>
//
// 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 <Eigen/Core>
#include <vector>
#include <igl/igl_inline.h>
namespace igl
{
// HalfEdgeIterator - Fake halfedge for fast and easy navigation on triangle meshes with vertex_triangle_adjacency and
// triangle_triangle adjacency
template <typename DerivedF>
class HalfEdgeIterator
{
public:
// Init the HalfEdgeIterator by specifying Face,Edge Index and Orientation
IGL_INLINE HalfEdgeIterator(
const Eigen::PlainObjectBase<DerivedF>* F,
const Eigen::PlainObjectBase<DerivedF>* FF,
const Eigen::PlainObjectBase<DerivedF>* 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==(HalfEdgeIterator& 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<DerivedF>* F;
const Eigen::PlainObjectBase<DerivedF>* FF;
const Eigen::PlainObjectBase<DerivedF>* FFi;
};
}
#endif