vert tetra iterator

This commit is contained in:
T.Alderighi 2018-06-07 10:56:14 +02:00
parent bb2d190b88
commit d37d9cdbfc
3 changed files with 390 additions and 365 deletions

View File

@ -98,11 +98,13 @@ public:
inline int & IMark() { assert(0); static int tmp=-1; return tmp;} inline int & IMark() { assert(0); static int tmp=-1; return tmp;}
inline int cIMark() const {return 0;} inline int cIMark() const {return 0;}
inline bool IsMarkEnabled() const { return T::TetraType::HasMark(); }
static bool HasMark() { return false; } static bool HasMark() { return false; }
static bool HasMarkOcc() { return false; } static bool HasMarkOcc() { return false; }
//Empty Adjacency //Empty Adjacency
typedef int VFAdjType; typedef int VTAdjType;
typename T::TetraPointer & VTp ( const int ) { static typename T::TetraPointer tp=0; assert(0); return tp; } typename T::TetraPointer & VTp ( const int ) { static typename T::TetraPointer tp=0; assert(0); return tp; }
typename T::TetraPointer const cVTp( const int ) const { static typename T::TetraPointer const tp=0; assert(0); return tp; } typename T::TetraPointer const cVTp( const int ) const { static typename T::TetraPointer const tp=0; assert(0); return tp; }

View File

@ -31,334 +31,356 @@
#define __VCG_TETRA_POS #define __VCG_TETRA_POS
namespace vcg { namespace vcg {
namespace tetra { namespace tetra {
/** \addtogroup tetra */ /** \addtogroup tetra */
/*@{*/ /*@{*/
/** Class VTIterator. template <class TetraType>
void VVStarVT( typename TetraType::VertexPointer vp, std::vector<typename TetraType::VertexPointer> & starVec)
{
typedef typename TetraType::VertexPointer VertexPointer;
starVec.clear();
tetra::VTIterator<TetraType> vti(vp->VTp(), vp->VTi());
while (!vti.End())
{
starVec.push_back(vti.Vt()->V1(vti.Vi()));
starVec.push_back(vti.Vt()->V2(vti.Vi()));
starVec.push_back(vti.Vt()->V3(vti.Vi()));
++vti;
}
std::sort(starVec.begin(), starVec.end());
typename std::vector<VertexPointer>::iterator new_end = std::unique(starVec.begin(),starVec.end());
starVec.resize(new_end - starVec.begin());
}
/** Class VTIterator.
This is a vertex - tetrahedron iterator This is a vertex - tetrahedron iterator
@param MTTYPE (Template Parameter) Specifies the type of the tetrahedron. @param MTTYPE (Template Parameter) Specifies the type of the tetrahedron.
*/ */
template < class MTTYPE> template < class MTTYPE>
class VTIterator class VTIterator
{ {
public: public:
/// The tetrahedron type /// The tetrahedron type
typedef MTTYPE TetraType; typedef MTTYPE TetraType;
private: private:
/// Pointer to a tetrahedron /// Pointer to a tetrahedron
TetraType *_vt; TetraType *_vt;
/// Index of one vertex /// Index of one vertex
int _vi; int _vi;
/// Default Constructor /// Default Constructor
public: public:
VTIterator() : _vt(0), _vi(-1){} VTIterator() : _vt(0), _vi(-1){}
/// Constructor which associates the EdgePos elementet with a face and its edge /// Constructor which associates the EdgePos elementet with a face and its edge
VTIterator(TetraType * const tp, int const zp) VTIterator(TetraType * const tp, int const zp)
{ {
_vt=tp; _vt=tp;
_vi=zp; _vi=zp;
} }
~VTIterator(){}; ~VTIterator(){};
/// Return the tetrahedron stored in the half edge /// Return the tetrahedron stored in the half edge
inline TetraType* & Vt() inline TetraType* & Vt()
{ {
return _vt; return _vt;
} }
/// Return the index of vertex as seen from the tetrahedron /// Return the index of vertex as seen from the tetrahedron
inline int & Vi() inline int & Vi()
{ {
return _vi; return _vi;
} }
/// Return the index of vertex as seen from the tetrahedron /// Return the index of vertex as seen from the tetrahedron
inline const int & Vi() const inline const int & Vi() const
{ {
return _vi; return _vi;
} }
inline bool End(){return (Vt()==NULL);} inline bool End(){return (Vt()==NULL);}
/// move on the next tetrahedron that share the vertex /// move on the next tetrahedron that share the vertex
void operator++() void operator++()
{ {
int vi=Vi(); int vi=Vi();
TetraType * tw = Vt(); TetraType * tw = Vt();
Vt() = tw->TVp(vi); Vt() = tw->VTp(vi);
Vi() = tw->TVi(vi); Vi() = tw->VTi(vi);
assert((Vt()==NULL)||((tw->V(vi))==(Vt()->V(Vi())))); assert((Vt()==NULL)||((tw->V(vi))==(Vt()->V(Vi()))));
} }
}; };
/** Templated over the class tetrahedron, it stores a \em position over a tetrahedron in a mesh. /** Templated over the class tetrahedron, it stores a \em position over a tetrahedron in a mesh.
It contain a pointer to the current tetrahedron, It contain a pointer to the current tetrahedron,
the index of one face,edge and a edge's incident vertex. the index of one face,edge and a edge's incident vertex.
*/ */
template < class MTTYPE> template < class MTTYPE>
class Pos class Pos
{ {
public: public:
/// The tetrahedron type /// The tetrahedron type
typedef MTTYPE TetraType; typedef MTTYPE TetraType;
/// The vertex type /// The vertex type
typedef typename TetraType::VertexType VertexType; typedef typename TetraType::VertexType VertexType;
/// The coordinate type /// The coordinate type
typedef typename TetraType::VertexType::CoordType CoordType; typedef typename TetraType::VertexType::CoordType CoordType;
///The HEdgePos type ///The HEdgePos type
typedef Pos<TetraType> BasePosType; typedef Pos<TetraType> BasePosType;
private: private:
/// Pointer to the tetrahedron of the half-edge /// Pointer to the tetrahedron of the half-edge
TetraType *_t; TetraType *_t;
/// Index of the face /// Index of the face
char _f; char _f;
/// Index of the edge /// Index of the edge
char _e; char _e;
/// Pointer to the vertex /// Pointer to the vertex
char _v; char _v;
public: public:
/// Default constructor /// Default constructor
Pos(){SetNull();}; Pos(){SetNull();};
/// Constructor which associates the half-edge elementet with a face, its edge and its vertex /// 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, Pos(TetraType * const tp, char const fap,char const ep,
char const vp){_t=tp;_f=fap;_e=ep;_v=vp;} char const vp){_t=tp;_f=fap;_e=ep;_v=vp;}
~Pos(){}; ~Pos(){};
/// Return the tetrahedron stored in the half edge
inline TetraType* & T()
{
return _t;
}
/// Return the tetrahedron stored in the half edge /// Return the tetrahedron stored in the half edge
inline TetraType* const & T() const inline TetraType* & T()
{ {
return _t; 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 edge 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));
}
/// 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(_f ,0);
char e1=vcg::Tetra::EofF(_f ,1);
char e2=vcg::Tetra::EofF(_f ,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(E(),0);
char f1=vcg::Tetra::FofE(E(),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
VertexType *v0=T()->V(vcg::Tetra::VofE(E(),0));
VertexType *v1=T()->V(vcg::Tetra::VofE(E(),1));
//get the current vertex
VertexType *vcurr=T()->V(V());
//get new tetrahedron according to tetra to tetra 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);
//the vertices of new edges
VertexType *vn0=nt->V(vcg::Tetra::VofE(ne0,0));
VertexType *vn1=nt->V(vcg::Tetra::VofE(ne0,1));
//verify that the two vertices of tetrahedron are identical
if (((vn0==v0)&&(vn1==v1))||((vn1==v0)&&(vn0==v1)))
E()=ne0;
else
{
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
{
#ifdef _DEBUG
vn0=nt->V(vcg::Tetra::VofE(ne2,0));
vn1=nt->V(vcg::Tetra::VofE(ne2,1));
assert(((vn0==v0)&&(vn1==v1))||((vn1==v0)&&(vn0==v1)));
#endif
E()=ne2;
}
}
//find the right vertex
vn0=nt->V(vcg::Tetra::VofE(E(),0));
#ifdef _DEBUG
vn1=nt->V(vcg::Tetra::VofE(E(),1));
assert((vn0==vcurr)||(vn1==vcurr));
#endif
if (vn0==vcurr)
V()=vcg::Tetra::VofE(E(),0);
else
V()=vcg::Tetra::VofE(E(),1);
T()=nt;
assert(T()->V(V())==vcurr);
F()=nfa;
} }
}
///returns the next half edge on the same edge /// Return the tetrahedron stored in the half edge
void NextT( ) inline TetraType* const & T() const
{ {
#ifdef _DEBUG return _t;
VertexType *vold=T()->V(V()); }
#endif
FlipT();
FlipF();
#ifdef _DEBUG
VertexType *vnew=T()->V(V());
assert(vold==vnew);
#endif
}
void Assert() /// Return the index of face as seen from the tetrahedron
#ifdef _DEBUG inline char & F()
{ {
HETYPE ht=*this; return _f;
ht.FlipT(); }
ht.FlipT();
assert(ht==*this);
ht=*this; /// Return the index of face as seen from the tetrahedron
ht.FlipF(); inline const char & F() const
ht.FlipF(); {
assert(ht==*this); return _f;
}
ht=*this; /// Return the index of face as seen from the tetrahedron
ht.FlipE(); inline char & E()
ht.FlipE(); {
assert(ht==*this); return _e;
}
ht=*this; /// Return the index of edge as seen from the tetrahedron
ht.FlipV(); inline const char & E() const
ht.FlipV(); {
assert(ht==*this); return _e;
} }
#else
{} /// Return the index of vertex as seen from the tetrahedron
#endif 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));
}
/// 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(_f ,0);
char e1=vcg::Tetra::EofF(_f ,1);
char e2=vcg::Tetra::EofF(_f ,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(E(),0);
char f1=vcg::Tetra::FofE(E(),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
VertexType *v0=T()->V(vcg::Tetra::VofE(E(),0));
VertexType *v1=T()->V(vcg::Tetra::VofE(E(),1));
//get the current vertex
VertexType *vcurr=T()->V(V());
//get new tetrahedron according to tetra to tetra 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);
//the vertices of new edges
VertexType *vn0=nt->V(vcg::Tetra::VofE(ne0,0));
VertexType *vn1=nt->V(vcg::Tetra::VofE(ne0,1));
//verify that the two vertices of tetrahedron are identical
if (((vn0==v0)&&(vn1==v1))||((vn1==v0)&&(vn0==v1)))
E()=ne0;
else
{
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
{
#ifdef _DEBUG
vn0=nt->V(vcg::Tetra::VofE(ne2,0));
vn1=nt->V(vcg::Tetra::VofE(ne2,1));
assert(((vn0==v0)&&(vn1==v1))||((vn1==v0)&&(vn0==v1)));
#endif
E()=ne2;
}
}
//find the right vertex
vn0=nt->V(vcg::Tetra::VofE(E(),0));
#ifdef _DEBUG
vn1=nt->V(vcg::Tetra::VofE(E(),1));
assert((vn0==vcurr)||(vn1==vcurr));
#endif
if (vn0==vcurr)
V()=vcg::Tetra::VofE(E(),0);
else
V()=vcg::Tetra::VofE(E(),1);
T()=nt;
assert(T()->V(V())==vcurr);
F()=nfa;
}
}
///returns the next half edge on the same edge
void NextT( )
{
#ifdef _DEBUG
VertexType *vold=T()->V(V());
#endif
FlipT();
FlipF();
#ifdef _DEBUG
VertexType *vnew=T()->V(V());
assert(vold==vnew);
#endif
}
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
}; };
///this pos structure jump on next tetrahedron if find an external face ///this pos structure jump on next tetrahedron if find an external face
@ -366,38 +388,38 @@ template < class MTTYPE>
class PosJump:public Pos<MTTYPE> class PosJump:public Pos<MTTYPE>
{ {
private: private:
MTTYPE *_t_initial; MTTYPE *_t_initial;
short int _back; short int _back;
public : public :
typedef MTTYPE TetraType; typedef MTTYPE TetraType;
PosJump(const TetraType* tp,const int fap,const int ep, PosJump(const TetraType* tp,const int fap,const int ep,
int vp){this->T()=tp;this->F()=fap;this->E()=ep;this->V()=vp;_t_initial=tp;_back=0;} int vp){this->T()=tp;this->F()=fap;this->E()=ep;this->V()=vp;_t_initial=tp;_back=0;}
void NextT() void NextT()
{ {
#ifdef _DEBUG #ifdef _DEBUG
int cont=0; int cont=0;
#endif #endif
MTTYPE *tpred=this->T(); MTTYPE *tpred=this->T();
Pos<MTTYPE>::NextT(); Pos<MTTYPE>::NextT();
//external face //external face
if (tpred==this->T()) if (tpred==this->T())
{ {
while (this->T()!=_t_initial) while (this->T()!=_t_initial)
{ {
Pos<MTTYPE>::NextT(); Pos<MTTYPE>::NextT();
#ifdef _DEBUG #ifdef _DEBUG
cont++; cont++;
assert (cont<500); assert (cont<500);
#endif #endif
} }
_back++; _back++;
if (_back==1) if (_back==1)
{ {
Pos<MTTYPE>::NextT(); Pos<MTTYPE>::NextT();
} }
}
} }
}
}; };
///this pos structure jump on next tetrahedron in rotational sense if find an external face ///this pos structure jump on next tetrahedron in rotational sense if find an external face
@ -405,67 +427,67 @@ template < class MTTYPE>
class PosLoop:public Pos<MTTYPE> class PosLoop:public Pos<MTTYPE>
{ {
private: private:
MTTYPE *_t_initial; MTTYPE *_t_initial;
bool _jump; bool _jump;
bool _loop; bool _loop;
public : public :
typedef MTTYPE TetraType; typedef MTTYPE TetraType;
PosLoop(TetraType* tp,const int fap,const int ep, PosLoop(TetraType* tp,const int fap,const int ep,
int vp){this->T()=tp;this->F()=fap;this->E()=ep;this->V()=vp;_t_initial=tp;_jump=false;_loop=false;} int vp){this->T()=tp;this->F()=fap;this->E()=ep;this->V()=vp;_t_initial=tp;_jump=false;_loop=false;}
bool LoopEnd() bool LoopEnd()
{ {
return (_loop); return (_loop);
} }
bool Jump()
{
return(_jump);
}
void Reset()
{
_loop=false;
_jump=false;
}
void NextT() bool Jump()
{ {
return(_jump);
}
void Reset()
{
_loop=false;
_jump=false;
}
void NextT()
{
#ifdef _DEBUG #ifdef _DEBUG
TetraType *t_old=this->T(); TetraType *t_old=this->T();
#endif #endif
TetraType *tpred=this->T(); TetraType *tpred=this->T();
Pos<TetraType>::NextT(); Pos<TetraType>::NextT();
_loop=false; _loop=false;
_jump=false; _jump=false;
//external face //external face
if (tpred==this->T()) if (tpred==this->T())
{ {
tpred=this->T(); tpred=this->T();
//jump next one //jump next one
Pos<TetraType>::NextT(); Pos<TetraType>::NextT();
//find the next external face //find the next external face
while (tpred!=this->T()) while (tpred!=this->T())
{ {
tpred=this->T(); tpred=this->T();
Pos<TetraType>::NextT(); Pos<TetraType>::NextT();
} }
////reset right rotation sense ////reset right rotation sense
// Pos<TetraType>::NextT(); // Pos<TetraType>::NextT();
_jump=true; _jump=true;
} }
if (this->T()==_t_initial) if (this->T()==_t_initial)
_loop=true; _loop=true;
#ifdef _DEBUG #ifdef _DEBUG
if (_loop==false) if (_loop==false)
assert(t_old!=this->T()); assert(t_old!=this->T());
#endif #endif
} }
}; };
//@} //@}
}//end namespace tetra }//end namespace tetra
}//end namespace vcg }//end namespace vcg
#endif #endif

View File

@ -315,7 +315,8 @@ class Tetra
return edgesface[indexE0][indexE1]; return edgesface[indexE0][indexE1];
} }
// compute the barycenter /** @brief Computes the tetrahedron barycenter
*/
template <class TetraType> template <class TetraType>
static Point3<typename TetraType::ScalarType> Barycenter(const TetraType &t) static Point3<typename TetraType::ScalarType> Barycenter(const TetraType &t)
{ {