diff --git a/vcg/simplex/tetrahedron/component.h b/vcg/simplex/tetrahedron/component.h index 215f8f7e..c8e834a9 100644 --- a/vcg/simplex/tetrahedron/component.h +++ b/vcg/simplex/tetrahedron/component.h @@ -98,11 +98,13 @@ public: inline int & IMark() { assert(0); static int tmp=-1; return tmp;} inline int cIMark() const {return 0;} + inline bool IsMarkEnabled() const { return T::TetraType::HasMark(); } + static bool HasMark() { return false; } static bool HasMarkOcc() { return false; } //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 const cVTp( const int ) const { static typename T::TetraPointer const tp=0; assert(0); return tp; } diff --git a/vcg/simplex/tetrahedron/pos.h b/vcg/simplex/tetrahedron/pos.h index 59b35ae7..e469879b 100644 --- a/vcg/simplex/tetrahedron/pos.h +++ b/vcg/simplex/tetrahedron/pos.h @@ -31,334 +31,356 @@ #define __VCG_TETRA_POS namespace vcg { - namespace tetra { +namespace tetra { - /** \addtogroup tetra */ +/** \addtogroup tetra */ /*@{*/ - /** Class VTIterator. +template +void VVStarVT( typename TetraType::VertexPointer vp, std::vector & starVec) +{ + typedef typename TetraType::VertexPointer VertexPointer; + + starVec.clear(); + + tetra::VTIterator 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::iterator new_end = std::unique(starVec.begin(),starVec.end()); + starVec.resize(new_end - starVec.begin()); +} + +/** Class VTIterator. 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> class VTIterator { public: - /// The tetrahedron type - typedef MTTYPE TetraType; + /// The tetrahedron type + typedef MTTYPE TetraType; private: - /// Pointer to a tetrahedron - TetraType *_vt; - /// Index of one vertex - int _vi; - /// Default Constructor + /// Pointer to a tetrahedron + TetraType *_vt; + /// Index of one vertex + int _vi; + /// Default Constructor public: - VTIterator() : _vt(0), _vi(-1){} - /// Constructor which associates the EdgePos elementet with a face and its edge - VTIterator(TetraType * const tp, int const zp) - { - _vt=tp; - _vi=zp; - } + VTIterator() : _vt(0), _vi(-1){} + /// Constructor which associates the EdgePos elementet with a face and its edge + VTIterator(TetraType * const tp, int const zp) + { + _vt=tp; + _vi=zp; + } - ~VTIterator(){}; + ~VTIterator(){}; - /// Return the tetrahedron stored in the half edge -inline TetraType* & Vt() -{ - return _vt; -} + /// Return the tetrahedron stored in the half edge + inline TetraType* & Vt() + { + return _vt; + } - /// Return the index of vertex as seen from the tetrahedron -inline int & Vi() -{ - return _vi; -} + /// Return the index of vertex as seen from the tetrahedron + inline int & Vi() + { + return _vi; + } -/// Return the index of vertex as seen from the tetrahedron -inline const int & Vi() const -{ - return _vi; -} + /// Return the index of vertex as seen from the tetrahedron + inline const int & Vi() const + { + return _vi; + } -inline bool End(){return (Vt()==NULL);} + inline bool End(){return (Vt()==NULL);} - /// move on the next tetrahedron that share the vertex -void operator++() -{ - int vi=Vi(); - TetraType * tw = Vt(); - Vt() = tw->TVp(vi); - Vi() = tw->TVi(vi); + /// move on the next tetrahedron that share the vertex + void operator++() + { + int vi=Vi(); + TetraType * tw = Vt(); + Vt() = tw->VTp(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. - It contain a pointer to the current tetrahedron, - the index of one face,edge and a edge's incident vertex. + 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 MTTYPE TetraType; - /// The vertex type - typedef typename TetraType::VertexType VertexType; - /// The coordinate type - typedef typename TetraType::VertexType::CoordType CoordType; - ///The HEdgePos type - typedef Pos BasePosType; + /// The tetrahedron type + typedef MTTYPE TetraType; + /// The vertex type + typedef typename TetraType::VertexType VertexType; + /// The coordinate type + typedef typename TetraType::VertexType::CoordType CoordType; + ///The HEdgePos type + typedef Pos 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; + /// 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 vp){_t=tp;_f=fap;_e=ep;_v=vp;} + /// 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 vp){_t=tp;_f=fap;_e=ep;_v=vp;} - ~Pos(){}; - - /// Return the tetrahedron stored in the half edge - inline TetraType* & T() - { - return _t; - } + ~Pos(){}; - /// Return the tetrahedron stored in the half edge - inline TetraType* const & 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 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; + /// Return the tetrahedron stored in the half edge + inline TetraType* & T() + { + return _t; } - } - ///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 - } + /// Return the tetrahedron stored in the half edge + inline TetraType* const & T() const + { + return _t; + } - void Assert() - #ifdef _DEBUG - { - HETYPE ht=*this; - ht.FlipT(); - ht.FlipT(); - assert(ht==*this); + /// Return the index of face as seen from the tetrahedron + inline char & F() + { + return _f; + } - ht=*this; - ht.FlipF(); - ht.FlipF(); - assert(ht==*this); + /// Return the index of face as seen from the tetrahedron + inline const char & F() const + { + return _f; + } - ht=*this; - ht.FlipE(); - ht.FlipE(); - assert(ht==*this); + /// Return the index of face as seen from the tetrahedron + inline char & E() + { + return _e; + } - ht=*this; - ht.FlipV(); - ht.FlipV(); - assert(ht==*this); - } - #else - {} - #endif + /// 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 + 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 @@ -366,38 +388,38 @@ template < class MTTYPE> class PosJump:public Pos { private: - MTTYPE *_t_initial; - short int _back; + MTTYPE *_t_initial; + short int _back; public : - typedef MTTYPE TetraType; - 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;} + typedef MTTYPE TetraType; + 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;} - void NextT() - { + void NextT() + { #ifdef _DEBUG - int cont=0; + int cont=0; #endif - MTTYPE *tpred=this->T(); - Pos::NextT(); - //external face - if (tpred==this->T()) - { - while (this->T()!=_t_initial) - { - Pos::NextT(); - #ifdef _DEBUG - cont++; - assert (cont<500); - #endif - } - _back++; - if (_back==1) - { - Pos::NextT(); - } + MTTYPE *tpred=this->T(); + Pos::NextT(); + //external face + if (tpred==this->T()) + { + while (this->T()!=_t_initial) + { + Pos::NextT(); +#ifdef _DEBUG + cont++; + assert (cont<500); +#endif + } + _back++; + if (_back==1) + { + Pos::NextT(); + } + } } - } }; ///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 { private: - MTTYPE *_t_initial; - bool _jump; - bool _loop; + MTTYPE *_t_initial; + bool _jump; + bool _loop; public : - typedef MTTYPE TetraType; -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;} + typedef MTTYPE TetraType; + 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;} - bool LoopEnd() - { - return (_loop); - } - - bool Jump() - { - return(_jump); - } - - void Reset() - { - _loop=false; - _jump=false; - } + bool LoopEnd() + { + return (_loop); + } - void NextT() - { + bool Jump() + { + return(_jump); + } + + void Reset() + { + _loop=false; + _jump=false; + } + + void NextT() + { #ifdef _DEBUG - TetraType *t_old=this->T(); + TetraType *t_old=this->T(); #endif - TetraType *tpred=this->T(); - Pos::NextT(); - _loop=false; - _jump=false; + TetraType *tpred=this->T(); + Pos::NextT(); + _loop=false; + _jump=false; - //external face - if (tpred==this->T()) - { - tpred=this->T(); - //jump next one - Pos::NextT(); - //find the next external face - while (tpred!=this->T()) - { - tpred=this->T(); - Pos::NextT(); - } - ////reset right rotation sense - // Pos::NextT(); - _jump=true; - } - if (this->T()==_t_initial) - _loop=true; + //external face + if (tpred==this->T()) + { + tpred=this->T(); + //jump next one + Pos::NextT(); + //find the next external face + while (tpred!=this->T()) + { + tpred=this->T(); + Pos::NextT(); + } + ////reset right rotation sense + // Pos::NextT(); + _jump=true; + } + if (this->T()==_t_initial) + _loop=true; #ifdef _DEBUG - if (_loop==false) - assert(t_old!=this->T()); + if (_loop==false) + assert(t_old!=this->T()); #endif - } + } }; //@} - }//end namespace tetra +}//end namespace tetra }//end namespace vcg #endif diff --git a/vcg/space/tetra3.h b/vcg/space/tetra3.h index ca39220e..54882db6 100644 --- a/vcg/space/tetra3.h +++ b/vcg/space/tetra3.h @@ -315,7 +315,8 @@ class Tetra return edgesface[indexE0][indexE1]; } - // compute the barycenter + /** @brief Computes the tetrahedron barycenter + */ template static Point3 Barycenter(const TetraType &t) {