Raised the upper limit of the template derivation chain for face

This commit is contained in:
Paolo Cignoni 2014-07-12 10:52:59 +00:00
parent ac49d75519
commit 4cb1fbaaf8
1 changed files with 149 additions and 147 deletions
vcg/simplex/face

View File

@ -35,11 +35,11 @@ These typenames must be known form all the derived classes.
*/ */
template <class UserTypes> template <class UserTypes>
class FaceTypeHolder: public UserTypes { class FaceTypeHolder: public UserTypes {
public: public:
template <class LeftF> template <class LeftF>
void ImportData(const LeftF & ){} void ImportData(const LeftF & ){}
static void Name(std::vector<std::string> & /* name */){} static void Name(std::vector<std::string> & /* name */){}
@ -47,8 +47,8 @@ template <class UserTypes>
inline int VN() const { return 3;} inline int VN() const { return 3;}
inline int Prev(const int & i) const { return (i+(3-1))%3;} inline int Prev(const int & i) const { return (i+(3-1))%3;}
inline int Next(const int & i) const { return (i+1)%3;} inline int Next(const int & i) const { return (i+1)%3;}
inline void Alloc(const int & ){} inline void Alloc(const int & ){}
inline void Dealloc(){} inline void Dealloc(){}
}; };
/* The base class form which we start to add our components. /* The base class form which we start to add our components.
@ -65,7 +65,7 @@ we have to build the type a step a time (deriving from a single ancestor at a ti
*/ */
template <class UserTypes> template <class UserTypes>
class FaceBase: public class FaceBase: public
face::EmptyCore< FaceTypeHolder <UserTypes> > { face::EmptyCore< FaceTypeHolder <UserTypes> > {
}; };
@ -86,147 +86,148 @@ template < class UserTypes,
template <typename> class C, template <typename> class D, template <typename> class C, template <typename> class D,
template <typename> class E, template <typename> class F, template <typename> class E, template <typename> class F,
template <typename> class G, template <typename> class H, template <typename> class G, template <typename> class H,
template <typename> class I, template <typename> class J > template <typename> class I, template <typename> class J,
class FaceArityMax: public J<Arity9<FaceBase<UserTypes>, A, B, C, D, E, F, G, H, I> > { template <typename> class K, template <typename> class L >
class FaceArityMax: public L<Arity11<FaceBase<UserTypes>, A, B, C, D, E, F, G, H, I, J, K> > {
public: public:
typedef typename FaceArityMax::ScalarType ScalarType; typedef typename FaceArityMax::ScalarType ScalarType;
// ----- Flags stuff ----- // ----- Flags stuff -----
enum { enum {
DELETED = 0x00000001, // Face is deleted from the mesh DELETED = 0x00000001, // Face is deleted from the mesh
NOTREAD = 0x00000002, // Face of the mesh is not readable NOTREAD = 0x00000002, // Face of the mesh is not readable
NOTWRITE = 0x00000004, // Face of the mesh is not writable NOTWRITE = 0x00000004, // Face of the mesh is not writable
VISITED = 0x00000010, // Face has been visited. Usualy this is a per-algorithm used bit. VISITED = 0x00000010, // Face has been visited. Usualy this is a per-algorithm used bit.
SELECTED = 0x00000020, // Face is selected. Algorithms should try to work only on selected face (if explicitly requested) SELECTED = 0x00000020, // Face is selected. Algorithms should try to work only on selected face (if explicitly requested)
// Border _flags, it is assumed that BORDERi = BORDER0<<i // Border _flags, it is assumed that BORDERi = BORDER0<<i
BORDER0 = 0x00000040, BORDER0 = 0x00000040,
BORDER1 = 0x00000080, BORDER1 = 0x00000080,
BORDER2 = 0x00000100, BORDER2 = 0x00000100,
BORDER012 = BORDER0 | BORDER1 | BORDER2 , BORDER012 = BORDER0 | BORDER1 | BORDER2 ,
// Face Orientation Flags, used efficiently compute point face distance // Face Orientation Flags, used efficiently compute point face distance
NORMX = 0x00000200, NORMX = 0x00000200,
NORMY = 0x00000400, NORMY = 0x00000400,
NORMZ = 0x00000800, NORMZ = 0x00000800,
// Crease _flags, it is assumed that CREASEi = CREASE0<<i // Crease _flags, it is assumed that CREASEi = CREASE0<<i
CREASE0 = 0x00008000, CREASE0 = 0x00008000,
CREASE1 = 0x00010000, CREASE1 = 0x00010000,
CREASE2 = 0x00020000, CREASE2 = 0x00020000,
// Faux edges. (semantics: when a mesh is polygonal, edges which are inside a polygonal face are "faux" // Faux edges. (semantics: when a mesh is polygonal, edges which are inside a polygonal face are "faux"
FAUX0 = 0x00040000, FAUX0 = 0x00040000,
FAUX1 = 0x00080000, FAUX1 = 0x00080000,
FAUX2 = 0x00100000, FAUX2 = 0x00100000,
FAUX012 = FAUX0 | FAUX1 | FAUX2 , FAUX012 = FAUX0 | FAUX1 | FAUX2 ,
// First user bit // First user bit
USER0 = 0x00200000 USER0 = 0x00200000
}; };
/// checks if the Face is deleted /// checks if the Face is deleted
bool IsD() const {return (this->cFlags() & DELETED) != 0;} bool IsD() const {return (this->cFlags() & DELETED) != 0;}
/// checks if the Face is readable /// checks if the Face is readable
bool IsR() const {return (this->cFlags() & NOTREAD) == 0;} bool IsR() const {return (this->cFlags() & NOTREAD) == 0;}
/// checks if the Face is modifiable /// checks if the Face is modifiable
bool IsW() const {return (this->cFlags() & NOTWRITE)== 0;} bool IsW() const {return (this->cFlags() & NOTWRITE)== 0;}
/// This funcion checks whether the Face is both readable and modifiable /// This funcion checks whether the Face is both readable and modifiable
bool IsRW() const {return (this->cFlags() & (NOTREAD | NOTWRITE)) == 0;} bool IsRW() const {return (this->cFlags() & (NOTREAD | NOTWRITE)) == 0;}
/// checks if the Face is Modified /// checks if the Face is Modified
bool IsS() const {return (this->cFlags() & SELECTED) != 0;} bool IsS() const {return (this->cFlags() & SELECTED) != 0;}
/// checks if the Face is Modified /// checks if the Face is Modified
bool IsV() const {return (this->cFlags() & VISITED) != 0;} bool IsV() const {return (this->cFlags() & VISITED) != 0;}
/** Set the flag value /** Set the flag value
@param flagp Valore da inserire nel flag @param flagp Valore da inserire nel flag
*/ */
void SetFlags(int flagp) {this->Flags()=flagp;} void SetFlags(int flagp) {this->Flags()=flagp;}
/** Set the flag value /** Set the flag value
@param flagp Valore da inserire nel flag @param flagp Valore da inserire nel flag
*/ */
void ClearFlags() {this->Flags()=0;} void ClearFlags() {this->Flags()=0;}
/// deletes the Face from the mesh /// deletes the Face from the mesh
void SetD() {this->Flags() |=DELETED;} void SetD() {this->Flags() |=DELETED;}
/// un-delete a Face /// un-delete a Face
void ClearD() {this->Flags() &=(~DELETED);} void ClearD() {this->Flags() &=(~DELETED);}
/// marks the Face as readable /// marks the Face as readable
void SetR() {this->Flags() &=(~NOTREAD);} void SetR() {this->Flags() &=(~NOTREAD);}
/// marks the Face as not readable /// marks the Face as not readable
void ClearR() {this->Flags() |=NOTREAD;} void ClearR() {this->Flags() |=NOTREAD;}
/// marks the Face as writable /// marks the Face as writable
void SetW() {this->Flags() &=(~NOTWRITE);} void SetW() {this->Flags() &=(~NOTWRITE);}
/// marks the Face as notwritable /// marks the Face as notwritable
void ClearW() {this->Flags() |=NOTWRITE;} void ClearW() {this->Flags() |=NOTWRITE;}
/// select the Face /// select the Face
void SetS() {this->Flags() |=SELECTED;} void SetS() {this->Flags() |=SELECTED;}
/// Un-select a Face /// Un-select a Face
void ClearS() {this->Flags() &= ~SELECTED;} void ClearS() {this->Flags() &= ~SELECTED;}
/// select the Face /// select the Face
void SetV() {this->Flags() |=VISITED;} void SetV() {this->Flags() |=VISITED;}
/// Un-select a Face /// Un-select a Face
void ClearV() {this->Flags() &= ~VISITED;} void ClearV() {this->Flags() &= ~VISITED;}
/// This function checks if the face is selected /// This function checks if the face is selected
bool IsB(int i) const {return (this->cFlags() & (BORDER0<<i)) != 0;} bool IsB(int i) const {return (this->cFlags() & (BORDER0<<i)) != 0;}
/// This function select the face /// This function select the face
void SetB(int i) {this->Flags() |=(BORDER0<<i);} void SetB(int i) {this->Flags() |=(BORDER0<<i);}
/// This funcion execute the inverse operation of SetS() /// This funcion execute the inverse operation of SetS()
void ClearB(int i) {this->Flags() &= (~(BORDER0<<i));} void ClearB(int i) {this->Flags() &= (~(BORDER0<<i));}
/// This function checks if the face is selected /// This function checks if the face is selected
bool IsCrease(int i) const {return (this->cFlags() & (CREASE0<<i)) != 0;} bool IsCrease(int i) const {return (this->cFlags() & (CREASE0<<i)) != 0;}
/// This function select the face /// This function select the face
void SetCrease(int i){this->Flags() |=(CREASE0<<i);} void SetCrease(int i){this->Flags() |=(CREASE0<<i);}
/// This funcion execute the inverse operation of SetS() /// This funcion execute the inverse operation of SetS()
void ClearCrease(int i) {this->Flags() &= (~(CREASE0<<i));} void ClearCrease(int i) {this->Flags() &= (~(CREASE0<<i));}
/// This function checks if a given side of the face is a feature/internal edge /// This function checks if a given side of the face is a feature/internal edge
/// it is used by some importer to mark internal /// it is used by some importer to mark internal
/// edges of polygonal faces that have been triangulated /// edges of polygonal faces that have been triangulated
bool IsF(int i) const {return (this->cFlags() & (FAUX0<<i) ) != 0;} bool IsF(int i) const {return (this->cFlags() & (FAUX0<<i) ) != 0;}
bool IsAnyF() const {return (this->cFlags() & (FAUX0|FAUX1|FAUX2)) != 0;} bool IsAnyF() const {return (this->cFlags() & (FAUX0|FAUX1|FAUX2)) != 0;}
/// This function select the face /// This function select the face
void SetF(int i) {this->Flags() |=(FAUX0<<i);} void SetF(int i) {this->Flags() |=(FAUX0<<i);}
/// This funcion execute the inverse operation of SetS() /// This funcion execute the inverse operation of SetS()
void ClearF(int i) {this->Flags() &= (~(FAUX0<<i));} void ClearF(int i) {this->Flags() &= (~(FAUX0<<i));}
void ClearAllF() { this->Flags() &= (~(FAUX0|FAUX1|FAUX2)); } void ClearAllF() { this->Flags() &= (~(FAUX0|FAUX1|FAUX2)); }
/// Return the first bit that is not still used /// Return the first bit that is not still used
static int &FirstUnusedBitFlag() static int &FirstUnusedBitFlag()
{ {
static int b =USER0; static int b =USER0;
return b; return b;
} }
/// Allocate a bit among the flags that can be used by user. It updates the FirstUnusedBitFlag. /// Allocate a bit among the flags that can be used by user. It updates the FirstUnusedBitFlag.
static inline int NewBitFlag() static inline int NewBitFlag()
{ {
int bitForTheUser = FirstUnusedBitFlag(); int bitForTheUser = FirstUnusedBitFlag();
FirstUnusedBitFlag()=FirstUnusedBitFlag()<<1; FirstUnusedBitFlag()=FirstUnusedBitFlag()<<1;
return bitForTheUser; return bitForTheUser;
} }
/// De-allocate a pre allocated bit. It updates the FirstUnusedBitFlag. /// De-allocate a pre allocated bit. It updates the FirstUnusedBitFlag.
// Note you must deallocate bit in the inverse order of the allocation (as in a stack) // Note you must deallocate bit in the inverse order of the allocation (as in a stack)
static inline bool DeleteBitFlag(int bitval) static inline bool DeleteBitFlag(int bitval)
{ {
if(FirstUnusedBitFlag()>>1==bitval) { if(FirstUnusedBitFlag()>>1==bitval) {
FirstUnusedBitFlag() = FirstUnusedBitFlag()>>1; FirstUnusedBitFlag() = FirstUnusedBitFlag()>>1;
return true; return true;
} }
assert(0); assert(0);
return false; return false;
} }
/// This function checks if the given user bit is true /// This function checks if the given user bit is true
bool IsUserBit(int userBit){return (this->Flags() & userBit) != 0;} bool IsUserBit(int userBit){return (this->Flags() & userBit) != 0;}
/// This function set the given user bit /// This function set the given user bit
void SetUserBit(int userBit){this->Flags() |=userBit;} void SetUserBit(int userBit){this->Flags() |=userBit;}
/// This function clear the given user bit /// This function clear the given user bit
void ClearUserBit(int userBit){this->Flags() &= (~userBit);} void ClearUserBit(int userBit){this->Flags() &= (~userBit);}
void GetBBox(Box3<ScalarType>& bb ) const void GetBBox(Box3<ScalarType>& bb ) const
@ -283,9 +284,10 @@ template <class UserTypes,
template <typename> class C = DefaultDeriver, template <typename> class D = DefaultDeriver, template <typename> class C = DefaultDeriver, template <typename> class D = DefaultDeriver,
template <typename> class E = DefaultDeriver, template <typename> class F = DefaultDeriver, template <typename> class E = DefaultDeriver, template <typename> class F = DefaultDeriver,
template <typename> class G = DefaultDeriver, template <typename> class H = DefaultDeriver, template <typename> class G = DefaultDeriver, template <typename> class H = DefaultDeriver,
template <typename> class I = DefaultDeriver, template <typename> class J = DefaultDeriver > template <typename> class I = DefaultDeriver, template <typename> class J = DefaultDeriver,
class Face: public FaceArityMax<UserTypes, A, B, C, D, E, F, G, H, I, J> { template <typename> class K = DefaultDeriver, template <typename> class L = DefaultDeriver >
public: typedef AllTypes::AFaceType IAm; typedef UserTypes TypesPool;}; class Face: public FaceArityMax<UserTypes, A, B, C, D, E, F, G, H, I, J, K, L> {
public: typedef AllTypes::AFaceType IAm; typedef UserTypes TypesPool;};
}// end namespace }// end namespace