vcglib/vcg/simplex/tetrahedron/pos.h

431 lines
9.6 KiB
C
Raw Normal View History

2004-05-14 18:04:51 +02:00
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* 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. *
* *
****************************************************************************/
/****************************************************************************
History
****************************************************************************/
#ifndef __VCG_TETRA_POS
#define __VCG_TETRA_POS
namespace vcg {
2004-05-17 17:28:35 +02:00
namespace tetra {
2004-05-14 18:04:51 +02:00
/** \addtogroup tetra */
/*@{*/
/** Class VTIterator.
This is a vertex - tetrahedron iterator
@param MTTYPE (Template Parameter) Specifies the type of the tetrahedron.
*/
template < class MTTYPE>
class VTIterator
{
public:
/// The tetrahedron type
typedef typename MTTYPE TetraType;
private:
/// Pointer to a tetrahedron
TetraType *_vt;
/// Index of one vertex
int _vi;
/// Default Constructor
public:
2004-05-17 17:28:35 +02:00
VTIterator(){}
2004-05-14 18:04:51 +02:00
/// Constructor which associates the EdgePos elementet with a face and its edge
VTIterator(TetraType * const tp, int const zp)
{
_vt=tp;
_vi=zp;
2004-05-17 17:28:35 +02:00
}
2004-05-14 18:04:51 +02:00
~VTIterator(){};
2004-05-17 17:28:35 +02:00
/// Return the tetrahedron stored in the half edge
inline TetraType & Vt()
{
return _vt;
}
2004-05-14 18:04:51 +02:00
2004-05-17 17:28:35 +02:00
/// Return the tetrahedron stored in the half edge
inline const TetraType & Vt() const
{
return _vt;
}
2004-05-14 18:04:51 +02:00
/// Return the index of vertex as seen from the tetrahedron
2004-05-17 17:28:35 +02:00
inline int & Vi()
{
return _vi;
}
2004-05-14 18:04:51 +02:00
2004-05-17 17:28:35 +02:00
/// Return the index of vertex as seen from the tetrahedron
inline const int & Vi() const
{
2004-05-14 18:04:51 +02:00
return _vi;
2004-05-17 17:28:35 +02:00
}
bool End() const {return Vt()==0;}
2004-05-14 18:04:51 +02:00
/// move on the next tetrahedron that share the vertex
2004-05-17 17:28:35 +02:00
bool operator++()
{
2004-05-14 18:04:51 +02:00
int vi=Vi();
TetraType * tw = Vt();
Vt() = tw->TVp[vi];
Vi() = tw->TVi[vi];
assert(((tw->V(vi))==(Vt()->V(Vi())))||(t==NULL));
return (Vt()!=NULL);
2004-05-17 17:28:35 +02:00
}
2004-05-14 18:04:51 +02:00
};
/** \addtogroup tetra */
/*@{*/
/** Templated over the class tetrahedron, it stores a \em position over a tetrahedron in a mesh.
It contain a pointer to the current tetrahedron,
the index of one face,edge and a edge's incident vertex.
*/
template < class MTTYPE>
class Pos
{
public:
/// The tetrahedron type
typedef typename MTTYPE TetraType;
/// The vertex type
typedef typename TetraType::MVTYPE VertexType;
/// The coordinate type
typedef typename TetraType::MVTYPE::CoordType CoordType;
///The HEdgePos type
typedef Pos<TetraType> BasePosType;
private:
/// Pointer to the tetrahedron of the half-edge
TetraType *_t;
/// Index of the face
char _f;
/// Index of the edge
char _e;
/// Pointer to the vertex
char _v;
public:
/// Default constructor
Pos(){SetNull();};
/// Constructor which associates the half-edge elementet with a face, its edge and its vertex
Pos(TetraType * const tp, char const fap,char const ep,
char const const vp){_t=tp;_f=fap;_e=ep;_v=vp;}
~Pos(){};
/// Return the tetrahedron stored in the half edge
inline TetraType & T()
2004-05-17 17:28:35 +02:00
{
2004-05-14 18:04:51 +02:00
return _t;
}
/// Return the tetrahedron stored in the half edge
inline const TetraType & T() const
{
return _t;
}
/// Return the index of face as seen from the tetrahedron
inline char & F()
{
return _f;
}
/// Return the index of face as seen from the tetrahedron
inline const char & F() const
{
return _f;
}
/// Return the index of face as seen from the tetrahedron
inline char & E()
{
return _e;
}
/// Return the index of face as seen from the tetrahedron
inline const char & E() const
{
return _e;
}
/// Return the index of vertex as seen from the tetrahedron
inline char & V()
{
return _v;
}
/// Return the index of vertex as seen from the tetrahedron
inline const char & V() const
{
return _v;
}
/// Operator to compare two half-edge
inline bool operator == ( BasePosType const & p ) const {
return (T()==p.T() && F()==p.F() && E==p.E() && V==p.V());
}
/// Operator to compare two half-edge
inline bool operator != ( BasePosType const & p ) const {
return (!((*this)==p));
}
/// Assignment operator
inline BasePosType & operator = ( const BasePosType & h ){
T()=h.T();
F()=h.F();
E()=h.E();
V()=h.V();
return *this;
}
/// Set to null the half-edge
void SetNull(){
T()=0;
F()=-1;
E()=-1;
V()=-1;
}
/// Check if the half-edge is null
bool IsNull() const {
return ((T()==0) || (F()<0) || (E()<0) || (V()<0));
}
/// Changes edge maintaining the same face and the same vertex
void FlipE()
{
//take the absolute index of the tree edges of the faces
char e0=vcg::Tetra::EofF(fa,0);
char e1=vcg::Tetra::EofF(fa,1);
char e2=vcg::Tetra::EofF(fa,2);
//eliminate the same as himself
if (e0==E())
{
e0=e1;
e1=e2;
}
else
if (e1==E())
{
e1=e2;
}
//now choose the one that preserve the same vertex
if ((vcg::Tetra::VofE(e1,0)==V())||(vcg::Tetra::VofE(e1,1)==V()))
E()=e1;
else
E()=e0;
}
/// Changes vertex maintaining the same face and the same edge
void FlipV()
{
// in the same edge choose the one that change
char v0=vcg::Tetra::VofE(E(),0);
char v1=vcg::Tetra::VofE(E(),1);
if (v0!=V())
V()=v0;
else
V()=v1;
}
/// Changes face maintaining the same vertex and the same edge
void FlipF()
{
char f0=vcg::Tetra::FofE(z,0);
char f1=vcg::Tetra::FofE(z,1);
if (f0!=F())
F()=f0;
else
F()=f1;
}
/// Changes tetrahedron maintaining the same face edge and vertex'... to finish
void FlipT()
{
//save the two vertices of the old edge
2004-05-17 17:28:35 +02:00
VertexType *v0=T()->V(vcg::Tetra::VofE(E(),0));
VertexType *v1=T()->V(vcg::Tetra::VofE(E(),1));
2004-05-14 18:04:51 +02:00
//get new tetrahedron according to faceto face topology
TetraType *nt=T()->TTp(F());
char nfa=T()->TTi(F());
if (nfa!=-1)
{
//find the right edge
char ne0=vcg::Tetra::EofF(nfa,0);
char ne1=vcg::Tetra::EofF(nfa,1);
char ne2=vcg::Tetra::EofF(nfa,2);
2004-05-17 17:28:35 +02:00
//the vertices of new edges
VertexType *vn0=nt->V(vcg::Tetra::VofE(ne0,0));
VertexType *vn1=nt->V(vcg::Tetra::VofE(ne0,1));
2004-05-14 18:04:51 +02:00
//verify that the two vertices of tetrahedron are identical
2004-05-17 17:28:35 +02:00
if (((vn0==v0)&&(vn1==v1))||((vn1==v0)&&(vn0==v1)))
E()=ne0;
2004-05-14 18:04:51 +02:00
else
2004-05-17 17:28:35 +02:00
{
vn0=nt->V(vcg::Tetra::VofE(ne1,0));
vn1=nt->V(vcg::Tetra::VofE(ne1,1));
if (((vn0==v0)&&(vn1==v1))||((vn1==v0)&&(vn0==v1)))
E()=ne1;
else
E()=ne2;
}
T()=nt;
F()=nfa;
}
}
2004-05-14 18:04:51 +02:00
2004-05-17 17:28:35 +02:00
///returns the next half edge on the same edge
void NextT( )
2004-05-14 18:04:51 +02:00
{
#ifdef _DEBUG
2004-05-17 17:28:35 +02:00
VertexType *v0old=T()->V(vcg::Tetra::VofE(E(),0));
VertexType *v1old=T()->V(vcg::Tetra::VofE(E(),1));
assert(v0old!=v1old);
2004-05-14 18:04:51 +02:00
#endif
FlipT();
FlipF();
#ifdef _DEBUG
2004-05-17 17:28:35 +02:00
VertexType *v0=T()->V(vcg::Tetra::VofE(E(),0));
VertexType *v1=T()->V(vcg::Tetra::VofE(E(),1));
2004-05-14 18:04:51 +02:00
assert(v1!=v0);
assert(((v0==v0old)&&(v1==v1old))||((v1==v0old)&&(v0==v1old)));
2004-05-17 17:28:35 +02:00
#endif
2004-05-14 18:04:51 +02:00
}
void Assert()
#ifdef _DEBUG
{
HETYPE ht=*this;
ht.FlipT();
ht.FlipT();
assert(ht==*this);
ht=*this;
ht.FlipF();
ht.FlipF();
assert(ht==*this);
ht=*this;
ht.FlipE();
ht.FlipE();
assert(ht==*this);
ht=*this;
ht.FlipV();
ht.FlipV();
assert(ht==*this);
}
#else
{}
#endif
};
2004-05-17 17:28:35 +02:00
///this pos structure jump on next tetrahedron if find an external face
2004-05-14 18:04:51 +02:00
template < class MTTYPE>
2004-05-17 17:28:35 +02:00
class PosJump:public Pos<MTTYPE>
2004-05-14 18:04:51 +02:00
{
2004-05-17 17:28:35 +02:00
private:
MTTYPE *_t_initial;
short int _back;
public :
PosJump(const TetraType* tp,const int fap,const int ep,
VertexType * vp){T()=tp;F()=fap;E()=ep;V()=vp;_t_initial=tp;_back=0;}
void NextT()
{
2004-05-14 18:04:51 +02:00
#ifdef _DEBUG
int cont=0;
#endif
2004-05-17 17:28:35 +02:00
MTTYPE *tpred=T();
Pos<MTTYPE>::NextT();
//external face
if (tpred==T())
2004-05-14 18:04:51 +02:00
{
2004-05-17 17:28:35 +02:00
while (T()!=_t_initial)
2004-05-14 18:04:51 +02:00
{
2004-05-17 17:28:35 +02:00
Pos<MTTYPE>::NextT();
2004-05-14 18:04:51 +02:00
#ifdef _DEBUG
cont++;
assert (cont<500);
#endif
}
2004-05-17 17:28:35 +02:00
_back++;
if (_back==1)
2004-05-14 18:04:51 +02:00
{
2004-05-17 17:28:35 +02:00
Pos<MTTYPE>::NextT();
}
}
2004-05-14 18:04:51 +02:00
}
2004-05-17 17:28:35 +02:00
};
2004-05-14 18:04:51 +02:00
2004-05-17 17:28:35 +02:00
///this pos structure jump on next tetrahedron in rotational sense if find an external face
template < class MTTYPE>
class PosLoop:public Pos<MTTYPE>
{
public :
void NextT()
{
MTTYPE *tpred=T();
Pos<MTTYPE>::NextT();
//external face
if (tpred==T())
{
tpred=T();
//jump on the other side
Pos<MTTYPE>::NextT();
//find the next external face
while (tpred!=T())
{
tpred=T();
Pos<MTTYPE>::NextT();
}
//reset right rotation sense
Pos<MTTYPE>::NextT();
}
}
2004-05-14 18:04:51 +02:00
};
2004-05-17 17:28:35 +02:00
}//end namespace tetra
}//end namespace vcg
2004-05-14 18:04:51 +02:00
#endif