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

View File

@ -8,7 +8,7 @@
* \ * * \ *
* All rights reserved. * * All rights reserved. *
* * * *
* This program is free software; you can redistribute it and/or modify * * 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 * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
@ -28,18 +28,18 @@
namespace vcg { namespace vcg {
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/* /*
The base class of all the recusive definition chain. It is just a container of the typenames of the various simplexes. The base class of all the recusive definition chain. It is just a container of the typenames of the various simplexes.
These typenames must be known form all the derived classes. 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,186 +47,187 @@ 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.
it has the empty definition for all the standard members (coords, color flags) it has the empty definition for all the standard members (coords, color flags)
Note: Note:
in order to avoid both virtual classes and ambiguous definitions all in order to avoid both virtual classes and ambiguous definitions all
the subsequent overrides must be done in a sequence of derivation. the subsequent overrides must be done in a sequence of derivation.
In other words we cannot derive and add in a single derivation step In other words we cannot derive and add in a single derivation step
(with multiple ancestor), both the real (non-empty) normal and color but (with multiple ancestor), both the real (non-empty) normal and color but
we have to build the type a step a time (deriving from a single ancestor at a time). we have to build the type a step a time (deriving from a single ancestor at a time).
*/ */
template <class UserTypes> template <class UserTypes>
class FaceBase: public class FaceBase: public
face::EmptyCore< FaceTypeHolder <UserTypes> > { face::EmptyCore< FaceTypeHolder <UserTypes> > {
}; };
/* The Real Big Face class; /* The Real Big Face class;
The class __FaceArityMax__ is the one that is the Last to be derived, The class __FaceArityMax__ is the one that is the Last to be derived,
and therefore is the only one to know the real members and therefore is the only one to know the real members
(after the many overrides) so all the functions with common behaviour (after the many overrides) so all the functions with common behaviour
using the members defined in the various Empty/nonEmpty component classes using the members defined in the various Empty/nonEmpty component classes
MUST be defined here. MUST be defined here.
I.e. IsD() that uses the overridden Flags() member must be defined here. I.e. IsD() that uses the overridden Flags() member must be defined here.
*/ */
template < class UserTypes, template < class UserTypes,
template <typename> class A, template <typename> class B, template <typename> class A, template <typename> class B,
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
NOTREAD = 0x00000002, // Face of the mesh is not readable
NOTWRITE = 0x00000004, // Face of the mesh is not writable
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)
// Border _flags, it is assumed that BORDERi = BORDER0<<i
BORDER0 = 0x00000040,
BORDER1 = 0x00000080,
BORDER2 = 0x00000100,
BORDER012 = BORDER0 | BORDER1 | BORDER2 ,
// Face Orientation Flags, used efficiently compute point face distance
NORMX = 0x00000200,
NORMY = 0x00000400,
NORMZ = 0x00000800,
// Crease _flags, it is assumed that CREASEi = CREASE0<<i
CREASE0 = 0x00008000,
CREASE1 = 0x00010000,
CREASE2 = 0x00020000,
// Faux edges. (semantics: when a mesh is polygonal, edges which are inside a polygonal face are "faux"
FAUX0 = 0x00040000,
FAUX1 = 0x00080000,
FAUX2 = 0x00100000,
FAUX012 = FAUX0 | FAUX1 | FAUX2 ,
// First user bit
USER0 = 0x00200000
};
DELETED = 0x00000001, // Face is deleted from the mesh
/// checks if the Face is deleted NOTREAD = 0x00000002, // Face of the mesh is not readable
NOTWRITE = 0x00000004, // Face of the mesh is not writable
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)
// Border _flags, it is assumed that BORDERi = BORDER0<<i
BORDER0 = 0x00000040,
BORDER1 = 0x00000080,
BORDER2 = 0x00000100,
BORDER012 = BORDER0 | BORDER1 | BORDER2 ,
// Face Orientation Flags, used efficiently compute point face distance
NORMX = 0x00000200,
NORMY = 0x00000400,
NORMZ = 0x00000800,
// Crease _flags, it is assumed that CREASEi = CREASE0<<i
CREASE0 = 0x00008000,
CREASE1 = 0x00010000,
CREASE2 = 0x00020000,
// Faux edges. (semantics: when a mesh is polygonal, edges which are inside a polygonal face are "faux"
FAUX0 = 0x00040000,
FAUX1 = 0x00080000,
FAUX2 = 0x00100000,
FAUX012 = FAUX0 | FAUX1 | FAUX2 ,
// First user bit
USER0 = 0x00200000
};
/// 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
@param flagp Valore da inserire nel flag
*/
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 SetFlags(int flagp) {this->Flags()=flagp;}
/// deletes the Face from the mesh /** Set the flag value
void SetD() {this->Flags() |=DELETED;} @param flagp Valore da inserire nel flag
/// un-delete a Face */
void ClearD() {this->Flags() &=(~DELETED);} void ClearFlags() {this->Flags()=0;}
/// marks the Face as readable
void SetR() {this->Flags() &=(~NOTREAD);} /// deletes the Face from the mesh
/// marks the Face as not readable void SetD() {this->Flags() |=DELETED;}
void ClearR() {this->Flags() |=NOTREAD;} /// un-delete a Face
/// marks the Face as writable void ClearD() {this->Flags() &=(~DELETED);}
void SetW() {this->Flags() &=(~NOTWRITE);} /// marks the Face as readable
/// marks the Face as notwritable void SetR() {this->Flags() &=(~NOTREAD);}
void ClearW() {this->Flags() |=NOTWRITE;} /// marks the Face as not readable
/// select the Face void ClearR() {this->Flags() |=NOTREAD;}
void SetS() {this->Flags() |=SELECTED;} /// marks the Face as writable
/// Un-select a Face void SetW() {this->Flags() &=(~NOTWRITE);}
/// marks the Face as notwritable
void ClearW() {this->Flags() |=NOTWRITE;}
/// select the Face
void SetS() {this->Flags() |=SELECTED;}
/// 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
static int &FirstUnusedBitFlag()
{
static int b =USER0;
return b;
}
/// Allocate a bit among the flags that can be used by user. It updates the FirstUnusedBitFlag. /// Return the first bit that is not still used
static inline int NewBitFlag() static int &FirstUnusedBitFlag()
{ {
int bitForTheUser = FirstUnusedBitFlag(); static int b =USER0;
FirstUnusedBitFlag()=FirstUnusedBitFlag()<<1; return b;
return bitForTheUser; }
}
/// De-allocate a pre allocated bit. It updates the FirstUnusedBitFlag. /// Allocate a bit among the flags that can be used by user. It updates the FirstUnusedBitFlag.
// Note you must deallocate bit in the inverse order of the allocation (as in a stack) static inline int NewBitFlag()
static inline bool DeleteBitFlag(int bitval) {
{ int bitForTheUser = FirstUnusedBitFlag();
if(FirstUnusedBitFlag()>>1==bitval) { FirstUnusedBitFlag()=FirstUnusedBitFlag()<<1;
FirstUnusedBitFlag() = FirstUnusedBitFlag()>>1; return bitForTheUser;
return true; }
}
assert(0);
return false;
}
/// This function checks if the given user bit is true /// De-allocate a pre allocated bit. It updates the FirstUnusedBitFlag.
bool IsUserBit(int userBit){return (this->Flags() & userBit) != 0;} // Note you must deallocate bit in the inverse order of the allocation (as in a stack)
static inline bool DeleteBitFlag(int bitval)
{
if(FirstUnusedBitFlag()>>1==bitval) {
FirstUnusedBitFlag() = FirstUnusedBitFlag()>>1;
return true;
}
assert(0);
return false;
}
/// This function set the given user bit /// This function checks if the given user bit is true
void SetUserBit(int userBit){this->Flags() |=userBit;} bool IsUserBit(int userBit){return (this->Flags() & userBit) != 0;}
/// This function clear the given user bit /// This function set the given user bit
void ClearUserBit(int userBit){this->Flags() &= (~userBit);} void SetUserBit(int userBit){this->Flags() |=userBit;}
/// This function clear the given user bit
void ClearUserBit(int userBit){this->Flags() &= (~userBit);}
void GetBBox(Box3<ScalarType>& bb ) const void GetBBox(Box3<ScalarType>& bb ) const
@ -262,7 +263,7 @@ class TetraFace : public FaceSimp3< VertProto, EdgeProto, TetraFace, TetraProt
A summary of the components that can be added to a face (see components.h for details): A summary of the components that can be added to a face (see components.h for details):
VertexRef VertexRef
NormalFromVert, WedgeNormal NormalFromVert, WedgeNormal
Normal3s, Normal3f, Normal3d Normal3s, Normal3f, Normal3d
@ -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