vcglib/vcg/simplex/edge/pos.h

290 lines
7.5 KiB
C++

/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
#ifndef __VCG_EDGE_POS
#define __VCG_EDGE_POS
namespace vcg {
namespace edge {
// Needed Prototypes (pos is include before topology)
template <class EDGETYPE>
bool IsEdgeBorder(EDGETYPE const & e, const int j );
template <class EDGETYPE>
bool IsEdgeManifold(EDGETYPE const & e, const int j );
/*
Vertex_Edge: run over the fan of a vertex (no order is specified)
*/
/** Class VertexStar
@param EDGETYPE Specifies the type of the faces
*/
template <class EDGETYPE>
class VertexStar
{
public:
/// Pointer to an edge
EDGETYPE *e;
/// Local index of the vertex
int z;
/// Default Constructor
VertexStar() : e(0), z(0) {}
/// Constructor which associates the EdgePos elementet with a face and its edge
VertexStar(EDGETYPE * const ep, int const zp)
{
e=ep;
z=zp;
}
/// Function to jump on the next face of the list of vertex z
void NextF()
{
EDGETYPE * t = e;
e = (EDGETYPE *)t->VEp(z);
z = t->VEi(z);
}
};
/*
*/
/** Class Pos.
This structure is equivalent to a half-edge.
@param MFTYPE (Template-Parameter) Specifies the type of the edges
*/
template <class EDGETYPE>
class Pos
{
public:
typedef typename EDGETYPE::VertexType VertexType;
typedef Pos< EDGETYPE> POSTYPE;
/// Pointer to the edge
EDGETYPE *e;
/// Pointer to the vertex
VertexType *v;
/// Default constructor
Pos(){}
/// Constructor which associates the half-edge elementet with a face, its edge and its vertex
Pos(EDGETYPE * ep, int zp) {e=ep;v=ep->V(zp);}
Pos(EDGETYPE * ep, VertexType *vp){e=ep;v=vp;}
// Official Access functions functions
VertexType *& V(){ return v; }
EDGETYPE *& E(){ return e; }
int VInd(){
return (e->V(0)==v)?0:1;
}
/// Operator to compare two edge pos
inline bool operator == ( POSTYPE const & p ) const {
return (e==p.e &&v==p.v);
}
/// Operator to compare two edge pos
inline bool operator != ( POSTYPE const & p ) const {
return (e!=p.e || v!=p.v);
}
/// Operator to order half-edge; it's compare at the first the face pointers, then the index of the edge and finally the vertex pointers
inline bool operator <= ( POSTYPE const & p) const {
return (e!=p.e)?(e<p.e):
(v<=p.v);
}
/// Assignment operator
inline POSTYPE & operator = ( const POSTYPE & h ){
e=h.e;
v=h.v;
return *this;
}
/// Set to null the half-edge
void SetNull(){
e=0;
v=0;
}
/// Check if the half-edge is null
bool IsNull() const {
return e==0 || v==0 ;
}
/*! \brief It advances the current Pos along the edge chain.
*
* Note that a Pos implicitly encode an ordering in the chain:
* the one denoted by the classical arrow shaped icon of a pos.
* In other words
*
* o---------o
* | /
* |/
*
* Meaningful only for 1-manifold edge chain.
*/
void NextE()
{
FlipE();
FlipV();
}
/// Changes vertex maintaining the edge
void FlipV()
{
v = (e->V(0)==v)?e->V(1):e->V(0);
}
/// Changes edge maintaining the vertex
void FlipE()
{
assert( (e->V(0)==v) ||(e->V(1)==v));
e = (e->V(0)==v)?e->EEp(0):e->EEp(1);
}
// return the vertex that it should have if we make FlipV;
VertexType *VFlip()
{
return (e->V(0)==v)?e->V(1):e->V(0);
}
// Trova il prossimo half-edge di bordo (nhe)
// tale che
// --nhe.f adiacente per vertice a he.f
// --nhe.v adiacente per edge di bordo a he.v
// l'idea e' che se he e' un half edge di bordo
// si puo scorrere tutto un bordo facendo
//
// hei=he;
// do
// hei.Nextb()
// while(hei!=he);
/// Checks if the half-edge is of border
bool IsBorder()
{
return edge::IsEdgeBorder(*e,VInd());
}
bool IsManifold()
{
return edge::IsEdgeManifold(*e,VInd());
}
/** Function to inizialize an half-edge.
@param fp Puntatore alla faccia
@param zp Indice dell'edge
@param vp Puntatore al vertice
*/
void Set(EDGETYPE * const ep, VertexType * const vp)
{
e=ep;v=vp;
}
};
/** Class VEIterator.
This class is used as an iterator over the VE adjacency.
It allow to easily traverse all the edges around a given vertex v;
The edges are traversed in no particular order. No Manifoldness requirement.
typical example:
VertexPointer v;
vcg::edge::VEIterator<EdgeType> vei(v);
for (;!vei.End();++vei)
vei.E()->ClearV();
// Alternative
vcg::edge::VEIterator<EdgeType> vei(f, 1);
while (!vei.End()){
vei.E()->ClearV();
++vei;
}
See also the JumpingPos in jumping_pos.h for an iterator that loops
around the faces of a vertex using FF topology and without requiring the VF topology.
*/
template <typename EdgeType>
class VEIterator
{
public:
/// The vertex type
typedef typename EdgeType::VertexType VertexType;
/// The Base face type
typedef EdgeType VFIEdgeType;
/// The vector type
typedef typename VertexType::CoordType CoordType;
/// The scalar type
typedef typename VertexType::ScalarType ScalarType;
/// Pointer to the face of the half-edge
EdgeType *e;
/// Index of the vertex
int z;
/// Default constructor
VEIterator(){}
/// Constructor which associates the half-edge elementet with a face and its vertex
VEIterator(EdgeType * _e, const int & _z){e = _e; z = _z;}
/// Constructor which takes a pointer to vertex
VEIterator(const VertexType * _v){
e = _v->cVEp(); z = _v->cVEi();
assert(z>=0 && "VE adjacency not initialized");
}
VFIEdgeType * &E() { return e;}
int & I() { return z;}
// Access to the vertex. Having a VEIterator vfi, it corresponds to
// vfi.V() = vfi.I()->V(vfi.I())
inline VertexType *V() const { return e->V(z);}
inline VertexType * const & V0() const { return e->V0(z);}
inline VertexType * const & V1() const { return e->V1(z);}
bool End() const {return e==0;}
VFIEdgeType *operator++() {
EdgeType* t = e;
e = e->VEp(z);
z = t->VEi(z);
return e;
}
};
} // end namespace
} // end namespace
#endif