diff --git a/vcg/simplex/face/topology.h b/vcg/simplex/face/topology.h new file mode 100644 index 00000000..896260d6 --- /dev/null +++ b/vcg/simplex/face/topology.h @@ -0,0 +1,254 @@ + +/*#******************* +* Adjacency Members * +**********************/ + + +/** Return a boolean that indicate if the face is complex. + @param j Index of the edge + @return true se la faccia e' manifold, false altrimenti +*/ +inline bool IsManifold( const int j ) const +{ +#if (defined(__VCGLIB_FACE_A) || defined(__VCGLIB_FACE_S)) + return ( F(j)==this || this == F(j)->F(Z(j)) ); +#endif + return true; + assert(0); +} + +/** Return a boolean that indicate if the j-th edge of the face is a border. + @param j Index of the edge + @return true if j is an edge of border, false otherwise +*/ +inline bool IsBorder( const int j ) const +{ +#if (defined(__VCGLIB_FACE_A) || defined(__VCGLIB_FACE_S)) + return F(j)==this; +#endif + return true; + assert(0); +} + + +/// This function counts the boreders of the face +inline int BorderCount() const +{ +#if (defined(__VCGLIB_FACE_A) || defined(__VCGLIB_FACE_S)) + int t = 0; + if( IsBorder(0) ) ++t; + if( IsBorder(1) ) ++t; + if( IsBorder(2) ) ++t; + return t; +#endif + assert(0); + return 3; +} + + +/// This function counts the number of incident faces in a complex edge +inline int ComplexSize(const int e) const +{ +#if (defined(__VCGLIB_FACE_A) || defined(__VCGLIB_FACE_S)) + int cnt=0; + FACE_TYPE *fi=(FACE_TYPE *)this; + int nzi,zi=e; + do + { + nzi=fi->Z(zi); + fi=fi->F(zi); + zi=nzi; + ++cnt; + } + while(fi!=this); + return cnt; +#endif + assert(0); + return 2; +} + +/*Funzione di detach che scollega una faccia da un ciclo +(eventualmente costituito da due soli elementi) incidente su un edge*/ +/** This function detach the face from the adjacent face via the edge e. It's possible to use it also in non-two manifold situation. + The function cannot be applicated if the adjacencies among faces aren't define. + @param e Index of the edge +*/ +void Detach(const int e) +{ + typedef FEdgePosB< FACE_TYPE > ETYPE; + + assert(!IsBorder(e)); + ETYPE EPB(this,e); // la faccia dall'altra parte + EPB.NextF(); + int cnt=0; + while ( EPB.f->F(EPB.z) != this) + { + assert(!IsManifold(e)); // Si entra in questo loop solo se siamo in una situazione non manifold. + assert(!EPB.f->IsBorder(EPB.z)); + EPB.NextF(); + cnt++; + } + assert(EPB.f->F(EPB.z)==this); + + EPB.f->F(EPB.z) = F(e); + EPB.f->Z(EPB.z) = Z(e); + + F(e) = this; + Z(e) = e; + + EPB.f->SetM(); + this->SetM(); +} + +void OldDetach(const int e) +{ + typedef EdgePosB< FACE_TYPE > ETYPE; + + assert(!IsBorder(e)); + ETYPE EPB(this,e); + ETYPE TEPB(0,-1); + EPB.NextF(); + while ( EPB.f != this) + { + TEPB = EPB; + assert(!EPB.f->IsBorder(EPB.z)); + EPB.NextF(); + } + assert(TEPB.f->F(TEPB.z)==this); + TEPB.f->F(TEPB.z) = F(e); + TEPB.f->Z(TEPB.z) = Z(e); + F(e) = this; + Z(e) = e; + TEPB.f->SetM(); + this->SetM(); +} + + +/** This function attach the face (via the edge z1) to another face (via the edge z2). It's possible to use it also in non-two manifold situation. + The function cannot be applicated if the adjacencies among faces aren't define. + @param z1 Index of the edge + @param f2 Pointer to the face + @param z2 The edge of the face f2 +*/ +void Attach(int z1, face_base *&f2, int z2) +{ + typedef FEdgePosB< FACE_TYPE > ETYPE; + ETYPE EPB(f2,z2); + ETYPE TEPB; + TEPB = EPB; + EPB.NextF(); + while( EPB.f != f2) //Alla fine del ciclo TEPB contiene la faccia che precede f2 + { + TEPB = EPB; + EPB.NextF(); + } + //Salvo i dati di f1 prima di sovrascrivere + face_base *f1prec = this->F(z1); + int z1prec = this->Z(z1); + //Aggiorno f1 + this->F(z1) = TEPB.f->F(TEPB.z); + this->Z(z1) = TEPB.f->Z(TEPB.z); + //Aggiorno la faccia che precede f2 + TEPB.f->F(TEPB.z) = f1prec; + TEPB.f->Z(TEPB.z) = z1prec; +} + + +void AssertAdj() +{ + assert(F(0)->F(Z(0))==this); + assert(F(1)->F(Z(1))==this); + assert(F(2)->F(Z(2))==this); + + assert(F(0)->Z(Z(0))==0); + assert(F(1)->Z(Z(1))==1); + assert(F(2)->Z(Z(2))==2); +} +// Funzione di supporto +inline void Nexts( face_base *&f,int &z ) +{ + int t; + t = z; + z = (*f).Z(z); + f = (*f).F(t); +} + +/** This function change the orientation of the face. Inverting the index of two vertex +@param z Index of the edge +*/ +void Swap ( const int z ) +{ + + int i; + face_base *tmp, *prec; + int t, precz; + + swap ( V((z )%3),V((z+1)%3)); + + if( OBJ_TYPE & (OBJ_TYPE_A|OBJ_TYPE_S ) ) + { + swap ( F((z+1)%3),F((z+2)%3)); + swap ( Z((z+1)%3),Z((z+2)%3)); + + for(i = 1; i < 3; i++) + { + + tmp = this; + t = (z+i)%3; + do { + prec = tmp; + precz = t; + Nexts(tmp,t); + } + while (tmp != this); + + (*prec).Z(precz) = (z+i)%3; + } + } +} + + + +// Stacca la faccia corrente dalla catena di facce incidenti sul vertice z, +// NOTA funziona SOLO per la topologia VF!!! +// usata nelle classi di collapse +void VFDetach(int z) +{ + + if(V(z)->Fp()==this ) + { + int fz = V(z)->Zp(); + V(z)->Fp() = (face_from_vert_type *) F(fz); + V(z)->Zp() = Z(fz); + } + else + { + VEdgePosB x,y; + + x.f = V(z)->Fp(); + x.z = V(z)->Zp(); + + for(;;) + { + y = x; + x.NextF(); + assert(x.f!=0); + if(x.f==this) + { + y.f->F(y.z) = F(z); + y.f->Z(y.z) = Z(z); + break; + } + } + } +} + + + + + +} // end namespace + + +#endif +