diff --git a/vcg/simplex/face/base.h b/vcg/simplex/face/base.h index 9ff4894d..f688f3c0 100644 --- a/vcg/simplex/face/base.h +++ b/vcg/simplex/face/base.h @@ -24,867 +24,252 @@ History $Log: not supported by cvs2svn $ -Revision 1.43 2007/03/12 15:37:19 tarini +Revision 1.13 2008/02/03 23:49:42 cignoni +Important Change. Now GetBBox return a null bbox if called on a deleted face (instead of crashing) + +Revision 1.12 2007/05/04 16:40:11 ganovelli +changes to comply "plus" types + +Revision 1.11 2007/03/27 09:22:11 cignoni +Added Visited flags + +Revision 1.10 2007/03/12 15:37:19 tarini Texture coord name change! "TCoord" and "Texture" are BAD. "TexCoord" is GOOD. -Revision 1.42 2007/02/20 14:07:53 ganovelli -added QualityType to comply faceplus type +Revision 1.9 2007/02/12 19:01:23 ganovelli +added Name(std:vector& n) that fills n with the names of the attribute of the face type -Revision 1.41 2007/01/13 00:25:36 cignoni -Added #ifdefs to guarantee that ComputeNormal would be defined only once +Revision 1.8 2006/10/09 20:20:18 cignoni +Increased the maximum number of possible template args from 8 to 9 -Revision 1.40 2007/01/11 10:13:11 cignoni -Rewrote the template of ComputeNormal functions to a more readable form. +Revision 1.7 2006/02/27 17:58:11 ponchio +Added some documentation -Revision 1.39 2006/07/12 12:14:31 zifnab1974 -changes for compilation on linux. Not sure about using either SphereOfTriangle or SphereOfTetra, please check. +Revision 1.6 2005/12/16 13:28:09 cignoni +Increased the maximum number of possible template args from 7 to 8 -Revision 1.38 2006/07/06 12:45:08 ganovelli -added SmallestEnclosingSphere +Revision 1.5 2005/12/02 00:41:38 cignoni +Added and removed typenames for gcc compiling. +Added this-> qualifier for referencing the elemntes of the templated base class +(e.g. to refer the possibly overridden flags()) it seems to be needed by the standard -Revision 1.37 2006/01/22 10:00:43 cignoni -Very Important Change: Area->DoubleArea (and no more Area function) +Revision 1.4 2005/11/16 22:56:32 cignoni +Added EmptyMark to base class +Standardized name of flags. It is plural becouse each simplex has many flag. -Revision 1.36 2005/12/16 11:42:23 corsini -Add some user bit +Revision 1.3 2005/11/12 18:42:18 cignoni +Added ClearS and GetBBox -Revision 1.35 2005/12/01 23:54:29 cignoni -Added HasFlags +Revision 1.2 2005/10/14 13:26:57 cignoni +First Really Working version -Revision 1.34 2005/11/23 14:40:09 pietroni -added cFFi function +Revision 1.2 2004/04/03 13:33:55 cignoni +Missing include -Revision 1.33 2005/11/22 15:47:35 cignoni -Moved ComputeNormal and ComputeNormalizedNormal out of the face class (no more a member function!) +Revision 1.1 2004/03/29 08:36:26 cignoni +First working version! -Revision 1.32 2005/11/12 18:39:54 cignoni -Added dummy static member for avoiding annoying warning in empty functions... - -Revision 1.31 2005/11/01 18:16:36 cignoni -Added intialization of _flags to zero in the default constructor of face - -Revision 1.30 2005/10/13 09:25:43 cignoni -Added cFFp and cVFp const member functions - -Revision 1.29 2005/09/28 19:32:09 m_di_benedetto -Added const qualifier in GetBBox method. - -Revision 1.28 2005/06/17 00:43:34 cignoni -Added a named typedef for the per wedge TexCoordinate - -Revision 1.27 2005/03/18 16:35:53 fiorin -minor changes to comply gcc compiler - -Revision 1.26 2005/03/11 14:14:14 ganovelli -_ffi was a 4 for positions vector (only 3 used) - -Revision 1.25 2005/01/28 17:53:13 pietroni -added HasEdgePlane function - -Revision 1.24 2004/10/28 00:50:48 cignoni -Better Doxygen documentation - -Revision 1.23 2004/10/25 08:22:40 ganovelli -IsBOrder (typecast on return type) - -Revision 1.22 2004/10/20 08:28:31 fiorin -Added constant access function FFp and renamed F1 F2 to FFp1 FFp2 - -Revision 1.21 2004/10/18 17:13:50 ganovelli -added ::IsBorder - -Revision 1.20 2004/09/15 11:20:15 ganovelli -changed P() to cP() - -Revision 1.19 2004/09/14 19:47:02 ganovelli -removed "&" in FFp - -Revision 1.18 2004/08/25 15:15:27 ganovelli -minor changes to comply gcc compiler (typename's and stuff) - -Revision 1.17 2004/07/15 12:03:07 ganovelli -minor changes - -Revision 1.16 2004/07/15 11:31:59 ganovelli -minor changes - -Revision 1.15 2004/07/12 12:17:09 pietroni -added function NormalizedNormal - -Revision 1.14 2004/05/13 11:01:06 turini -Changed ComputeMormalizedNormal() using Triangle3 - -Revision 1.13 2004/05/12 18:49:05 ganovelli -dist and coputeRT removed (see distance.h and updateEdges) - -Revision 1.12 2004/05/12 14:43:36 cignoni -removed warning of unused variables - -Revision 1.11 2004/05/12 12:50:20 turini -include color4 - -Revision 1.10 2004/05/10 14:01:09 ganovelli -assert(i*0) for using "i" and preventing the compiler warning for unreferenced variable - -Revision 1.9 2004/05/10 13:19:38 cignoni -Added mandatory template params for edge and face class names to the face class -Changed type of return face pointer to the one passed by templ params -Changed name of func FV to VF (it stores Vertex-Face Topology) - -Revision 1.8 2004/05/06 09:06:59 pietroni -changed names to topology functions - -Revision 1.7 2004/05/04 02:46:23 ganovelli -added function Dist - -Revision 1.5 2004/04/05 11:51:22 cignoni -wrong define FACE_N instead of FACE_FN - -Revision 1.4 2004/03/29 08:37:09 cignoni -missing include - -Revision 1.3 2004/03/10 00:52:38 cignoni -Moved geometric stuff to the space/triangle class - -Revision 1.2 2004/03/03 16:08:38 cignoni -First working version - -Revision 1.1 2004/02/13 00:44:45 cignoni -First commit... ****************************************************************************/ +#ifndef __VCG_FACE_PLUS +#define __VCG_FACE_PLUS -#pragma message("[VCGLIB Warning] this way to define the simplex face is DEPRECATED and no more SUPPORTED") -#pragma message("[VCGLIB Warning] use vcg/simplex/faceplus instead ") - -#ifndef FACE_TYPE -#pragma error message("\nYou should never directly include this file\n") -#else - - -#include -#include +#include #include -#include -#include #include -#include -#include -#include +#include +#include +#include namespace vcg { -class DUMMYEDGETYPE; -class DUMMYFACETYPE; -class DUMMYTETRATYPE; -/** \addtogroup face */ -//@{ -/*! - * This class represent the generic configurable Face; - * Usually you never direclty use this class with this name but you build - * your own type by directly including one of the .h files under the face/with - * directory. Each file specify a class type with the desired fields. So for example - * including 'vcg/simplex/face/with/FCFN.h' allow you to use the class FaceFCFN that has per-face color and normal stored inside. - */ -template > class FACE_TYPE -{ -public: - /// The base type of the face - typedef FACE_TYPE BaseFaceType; - /// The base type of the face itself - typedef FFTYPE FaceType; - /// The vertex type - typedef FVTYPE VertexType; - /// The vertex type - typedef FETYPE EdgeType; - /// The Texture Coordinate type - typedef TCTYPE TexCoordType; - /// The type of the scalar field of the vertex coordinate +/*------------------------------------------------------------------*/ +/* +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. +*/ + +template +class FaceTypeHolder{ + public: + typedef BVT VertexType; + typedef typename VertexType::CoordType CoordType; typedef typename VertexType::ScalarType ScalarType; - /// The type of the the vertex coordinate - typedef Point3< ScalarType > CoordType; - typedef Point3< ScalarType > NormalType; - /// The geometric type of the face - typedef Triangle3 GeometricType; - /// The type of the quality (same as scalar) - typedef ScalarType QualityType; - - typedef typename FVTYPE::FaceType FaceFromVertType; - /// The bounding box type - typedef Box3 BoxType; - - /// Default Empty Costructor - inline FACE_TYPE(){_flags=0;} - - /// This are the _flags of face, the default value is 0 - int _flags; - -/***********************************************/ -/** @name Vertex Pointer -Functions to access to the vertexes of the face; -**/ - //@{ -protected: - /// Vector of vertex pointer incident in the face - VertexType *v[3]; -public: - /** Return the pointer to the j-th vertex of the face. - @param j Index of the face vertex. - */ - inline VertexType * & V( const int j ) - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert( (_flags & NOTWRITE) == 0 ); - assert(j >= 0); - assert(j < 3); - return v[j]; - } - - inline VertexType * const & V( const int j ) const - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert(j>=0); - assert(j<3); - return v[j]; - } - inline VertexType * const cV( const int j ) const - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert(j>=0); - assert(j<3); - return v[j]; - } - - // Shortcut per accedere ai punti delle facce - inline CoordType & P( const int j ) - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert( (_flags & NOTWRITE) == 0 ); - assert(j>=0); - assert(j<3); - return v[j]->P(); - } - - inline const CoordType & P( const int j ) const - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert(j>=0); - assert(j<3); - return v[j]->cP(); - } - inline const CoordType & cP( const int j ) const - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert(j>=0); - assert(j<3); - return v[j]->cP(); - } - - /** Return the pointer to the ((j+1)%3)-th vertex of the face. - @param j Index of the face vertex. - */ - inline VertexType * & V0( const int j ) { return V(j);} - inline VertexType * & V1( const int j ) { return V((j+1)%3);} - inline VertexType * & V2( const int j ) { return V((j+2)%3);} - inline const VertexType * const & V0( const int j ) const { return V(j);} - inline const VertexType * const & V1( const int j ) const { return V((j+1)%3);} - inline const VertexType * const & V2( const int j ) const { return V((j+2)%3);} - inline const VertexType * const & cV0( const int j ) const { return cV(j);} - inline const VertexType * const & cV1( const int j ) const { return cV((j+1)%3);} - inline const VertexType * const & cV2( const int j ) const { return cV((j+2)%3);} - - /// Shortcut per accedere ai punti delle facce - inline CoordType & P0( const int j ) { return V(j)->P();} - inline CoordType & P1( const int j ) { return V((j+1)%3)->P();} - inline CoordType & P2( const int j ) { return V((j+2)%3)->P();} - inline const CoordType & P0( const int j ) const { return V(j)->P();} - inline const CoordType & P1( const int j ) const { return V((j+1)%3)->P();} - inline const CoordType & P2( const int j ) const { return V((j+2)%3)->P();} - inline const CoordType & cP0( const int j ) const { return cV(j)->P();} - inline const CoordType & cP1( const int j ) const { return cV((j+1)%3)->P();} - inline const CoordType & cP2( const int j ) const { return cV((j+2)%3)->P();} - - inline VertexType * & UberV( const int j ) - { - assert(j>=0); - assert(j<3); - return v[j]; - } - - inline const VertexType * const & UberV( const int j ) const - { - assert(j>=0); - assert(j<3); - return v[j]; - } + typedef BET EdgeType; + typedef BFT FaceType; + typedef BTT TetraType; + typedef BVT *VertPointer; + typedef BET *EdgePointer; + typedef BFT *FacePointer; + typedef BTT *TetraPointer; + template + void ImportLocal(const LeftF & l){} + static void Name(std::vector & name){} - //@} + // prot + const int VN() const { return 3;} + inline const int Prev(const int & i) const { return (i+(3-1))%3;} + inline const int Next(const int & i) const { return (i+1)%3;} + inline void Alloc(const int & ){} + inline void Dealloc(){} +}; -/***********************************************/ -/** @name Normal - blah - blah -**/ - //@{ +/* The base class form which we start to add our components. +it has the empty definition for all the standard members (coords, color flags) +Note: +in order to avoid both virtual classes and ambiguous definitions all +the subsequent overrides must be done in a sequence of derivation. -#ifdef __VCGLIB_FACE_FN - /// This vector indicates the normal of the face (defines if FACE_N is defined) -protected: - CoordType _n; -public: -#endif - - /// Return the reference of the normal to the face (if __VCGLIB_FACE_FN is defined). - inline CoordType & N() - { -#ifdef __VCGLIB_FACE_FN - return _n; -#else - assert(0); - return *(CoordType *)0; -#endif - } - /// Return the reference of the normal to the face (if __VCGLIB_FACE_FN is defined). - inline const CoordType & N() const - { -#ifdef __VCGLIB_FACE_FN - return _n; -#else - return *(CoordType *)0; -#endif - } - /// Return the reference of the normal to the face (if __VCGLIB_FACE_FN is defined). - inline const CoordType cN() const - { -#ifdef __VCGLIB_FACE_FN - return _n; -#else - return *(CoordType *)0; -#endif - } - -/// Return the value of the face normal as it correspond to the current geometry. -/// it is always computed and never stored. -const CoordType Normal() const -{ - return vcg::Normal(*this); -} - -/// Return the value of the face normal as it correspond to the current geometry. -/// it is always computed and never stored. -const CoordType NormalizedNormal() const -{ - return vcg::NormalizedNormal(*this); -} - -#ifdef __VCGLIB_FACE_WN - /// This vector indicates per wedge normal - CoordType _wn[3]; -#endif - -public: - CoordType & WN(const int i) - { -#ifdef __VCGLIB_FACE_WN - return _wn[i]; -#else - assert(0); - return *(CoordType *)(&_flags); -#endif - } - -const CoordType & WN(const int i) const - { -#ifdef __VCGLIB_FACE_WN - return _wn[i]; -#else - return CoordType(); -#endif - } - - //@} - -/***********************************************/ -/** @name Quality - blah - blah -**/ - //@{ - -#ifdef __VCGLIB_FACE_FQ -protected: - float _q; -#endif -public: - float & Q() - { -#ifdef __VCGLIB_FACE_FQ - return _q; -#else - assert(0); - return *(float*)(&_flags); -#endif - } - -const float & Q() const - { -#ifdef __VCGLIB_FACE_FQ - return _q; -#else - assert(0); - return *(float*)(&_flags); -#endif - } - - //@} - -/***********************************************/ -/** @name Texture - blah - blah -**/ - //@{ - -// Per Wedge Texture Coords -protected: -#ifdef __VCGLIB_FACE_WT - TCTYPE _wt[3]; -#endif -public: - TCTYPE & WT(const int i) - { -#ifdef __VCGLIB_FACE_WT - return _wt[i]; -#else - assert(0); - return *(TCTYPE*)(&_flags +i) ; -#endif - } - - const TCTYPE & WT(const int i) const - { -#ifdef __VCGLIB_FACE_WT - return _wt[i]; -#else - assert(0); - return *(TCTYPE*)(&_flags); -#endif - } +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 +we have to build the type a step a time (deriving from a single ancestor at a time). - //@} +*/ +template +class FaceBase: public face::EmptyPolyInfo< + face::EmptyVertexRef< + face::EmptyAdj< + face::EmptyColorMarkQuality< + face::EmptyNormal< + face::EmptyBitFlags< + face::EmptyWedgeTexCoord< + FaceTypeHolder > > > > > > > { -/***********************************************/ -/** @name Colors - blah - blah -**/ - //@{ -protected: -#ifdef __VCGLIB_FACE_FC - Color4b _c; -#endif - -public: - Color4b & C() - { -#ifdef __VCGLIB_FACE_FC - return _c; -#else - assert(0); - return *(Color4b*)(&_flags); -#endif - } - - const Color4b C() const - { -#ifdef __VCGLIB_FACE_FC - return _c; -#else - return Color4b(Color4b::White); -#endif - } - -protected: -#ifdef __VCGLIB_FACE_WC - Color4b _wc[3]; -#endif -public: - Color4b & WC(const int i) - { -#ifdef __VCGLIB_FACE_WC - return _wc[i]; -#else - assert(0); - return *(Color4b*)(&_flags + i); -#endif - } - -const Color4b WC(const int i) const - { -#ifdef __VCGLIB_FACE_WC - return _wc[i]; -#else - assert(0); - return Color4b(Color4b::White); -#endif - } +}; +/* The Real Big Face class; +The class __FaceArityMax__ is the one that is the Last to be derived, +and therefore is the only one to know the real members +(after the many overrides) so all the functions with common behaviour +using the members defined in the various Empty/nonEmpty component classes +MUST be defined here. - //@} +I.e. IsD() that uses the overridden Flags() member must be defined here. -/***********************************************/ -/** @name Adjacency - blah - blah -**/ - //@{ +*/ -#if (defined(__VCGLIB_FACE_AF) && defined(__VCGLIB_FACE_AS)) - #error Error: You cannot specify face-to-face and shared topology together -#endif +template class A, template class B, + template class C, template class D, + template class E, template class F, + template class G, template class H, + template class I, template class J > + class FaceArityMax: public I > { -#if (defined(__VCGLIB_FACE_AV) && defined(__VCGLIB_FACE_AS)) - #error Error: You cannot specify vertex-face and shared topology together -#endif - -protected: -#if defined(__VCGLIB_FACE_AF) - /// Vector of face pointer, it's used to indicate the adjacency relations (defines if FACE_A is defined) - FFTYPE *_ffp[3]; // Facce adiacenti - /// Index of the face in the arrival face - char _ffi[3]; -#endif - -#ifdef __VCGLIB_FACE_AV - ///Vettore di puntatori a faccia, utilizzato per indicare le adiacenze vertice faccia - FFTYPE *_fvp[3]; - char _fvi[3]; -#endif - -#ifdef __VCGLIB_FACE_AS - ///Vettore di puntatori a faccia, utilizzato per indicare le adiacenze vertice faccia - FFTYPE *fs[3]; - char zs[3]; -#endif +// ----- Flags stuff ----- public: - - - - /** Return the pointer to the j-th adjacent face. - @param j Index of the edge. - */ - inline FFTYPE * & FFp( const int j ) - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert( (_flags & NOTWRITE) == 0 ); - assert(j>=0); - assert(j<3); -#if defined(__VCGLIB_FACE_AF) - return _ffp[j]; -#elif defined(__VCGLIB_FACE_AS) - return fs[j]; -#else - assert(0); - static FFTYPE *dum=0; dum+=j; - return dum; - -#endif + inline int & UberFlags () + { + return this->Flags(); } - - inline const FFTYPE * FFp( const int j ) const + inline const int UberFlags() const { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert(j>=0 && j<3); - -#if defined(__VCGLIB_FACE_AF) - return _ffp[j]; -#elif defined(__VCGLIB_FACE_AS) - return fs[j]; -#else - assert(0); - static FFTYPE *dum=0; dum+=j; - return dum; -#endif + return this->Flags(); } - inline const FFTYPE * cFFp( const int j ) const {return FFp(j);} - - inline FFTYPE * & FFp1( const int j ) { return FFp((j+1)%3);} - inline FFTYPE * & FFp2( const int j ) { return FFp((j+2)%3);} - inline const FFTYPE * const& FFp1( const int j ) const { return FFp((j+1)%3);} - inline const FFTYPE * const& FFp2( const int j ) const { return FFp((j+2)%3);} - - - -/** Return the pointer to the j-th adjacent face. - @param j Index of the edge. - */ - inline FFTYPE * & UberF( const int j ) - { - assert(j>=0); - assert(j<3); -#if defined(__VCGLIB_FACE_AF) - return _ffp[j]; -#elif defined(__VCGLIB_FACE_AS) - return fs[j]; -#else - assert(0); // if you stop here you are probably trying to use FF topology in a face without it - return *((FFTYPE **)(_flags)); -#endif - } - - inline const FFTYPE * const & UberF( const int j ) const - { - assert(j>=0); - assert(j<3); -#if defined(__VCGLIB_FACE_AF) - return _ffp[j]; -#elif defined(__VCGLIB_FACE_AS) - return fs[j]; -#else - assert(0); // if you stop here you are probably trying to use FF topology in a face without it - return *((FFTYPE **)(_flags)); -#endif - } - - - inline FFTYPE * & VFp( const int j ) - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert( (_flags & NOTWRITE) == 0 ); - assert(j>=0); - assert(j<3); -#ifdef __VCGLIB_FACE_AV - return _fvp[j]; -#elif defined(__VCGLIB_FACE_AS) - return fs[j]; -#else - assert(0); // you are probably trying to use VF topology in a vertex without it - return *((FFTYPE **)(_flags)); -#endif - } - - inline const FFTYPE * const VFp( const int j ) const - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert(j>=0); - assert(j<3); -#ifdef __VCGLIB_FACE_AV - return _fvp[j]; -#elif defined(__VCGLIB_FACE_AS) - return fs[j]; -#else - assert(0); - static FFTYPE * const DummyVal=0; - return DummyVal; -#endif - } - inline const FFTYPE * cVFp( const int j ) const {return VFp(j);} - - - /** Return the index that the face have in the j-th adjacent face. - @param j Index of the edge. - */ - inline char & FFi( const int j ) - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert( (_flags & NOTWRITE) == 0 ); - assert(j>=0); - assert(j<3); -#if defined(__VCGLIB_FACE_AF) - return _ffi[j]; -#elif defined(__VCGLIB_FACE_AS) - return zs[j]; -#else - assert(0); - return *(char *)&_flags; // tanto per farlo compilare... -#endif - } - - inline const char & FFi( const int j ) const - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert(j>=0); - assert(j<3); -#if defined(__VCGLIB_FACE_AF) - return _ffi[j]; -#elif defined(__VCGLIB_FACE_AS) - return zs[j]; -#else - assert(0); - return *(char *)&_flags; -#endif - } - - inline const char & cFFi( const int j ) const {return FFi(j);} - - /** Return the index that the face have in the j-th adjacent face. - @param j Index of the edge. - */ - inline char & UberZ( const int j ) - { - assert(j>=0); - assert(j<3); -#if defined(__VCGLIB_FACE_AF) - return _ffi[j]; -#elif defined(__VCGLIB_FACE_AS) - return zs[j]; -#else - assert(0); - return *(char *)&_flags; -#endif - } - - inline const char & UberZ( const int j ) const - { - assert(j>=0); - assert(j<3); -#if defined(__VCGLIB_FACE_AF) - return _ffi[j]; -#elif defined(__VCGLIB_FACE_AS) - return zs[j]; -#else - assert(0); - return *(char *)&_flags; -#endif - } - - - inline char & VFi( const int j ) - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert( (_flags & NOTWRITE) == 0 ); - assert(j>=0); - assert(j<3); -#ifdef __VCGLIB_FACE_AV - return _fvi[j]; -#elif defined(__VCGLIB_FACE_AS) - return zs[j]; -#else - assert(0); - return *(char *)&_flags; -#endif - } - - inline const char & VFi( const int j ) const - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert(j>=0); - assert(j<3); -#ifdef __VCGLIB_FACE_AV - return _fvi[j]; -#elif defined(__VCGLIB_FACE_AS) - return zs[j]; -#else - assert(0); - return *(char *)&_flags; -#endif - } - - //@} - -/***********************************************/ -/** @name Mark - blah - blah -**/ - //@{ - - -#ifdef __VCGLIB_FACE_FM - /// Incremental mark (defines if FACE_I is defined) - int imark; - inline int & IMark() - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - assert( (_flags & NOTWRITE) == 0 ); - return imark; - } - - inline const int & IMark() const - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - return imark; - } -#endif // Mark - - /// Initialize the imark system of the face - inline void InitIMark() - { -#ifdef __VCGLIB_FACE_FM - imark = 0; -#endif - } - - - //@} -/***********************************************/ -/** @name Flags - blah - blah -**/ - //@{ - - - enum { - // This bit indicate that the face is deleted from the mesh - DELETED = 0x00000001, // cancellato - // This bit indicate that the face of the mesh is not readable - NOTREAD = 0x00000002, // non leggibile (ma forse modificabile) - // This bit indicate that the face is not modifiable - NOTWRITE = 0x00000004, // non modificabile (ma forse leggibile) - // This bit indicate that the face is modified - SELECTED = 0x00000020, // Selection _flags + 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<Flags() & DELETED) != 0;} + /// checks if the Face is readable + bool IsR() const {return (this->Flags() & NOTREAD) == 0;} + /// checks if the Face is modifiable + bool IsW() const {return (this->Flags() & NOTWRITE)== 0;} + /// This funcion checks whether the Face is both readable and modifiable + bool IsRW() const {return (this->Flags() & (NOTREAD | NOTWRITE)) == 0;} + /// checks if the Face is Modified + bool IsS() const {return (this->Flags() & SELECTED) != 0;} + /// checks if the Face is Modified + bool IsV() const {return (this->Flags() & VISITED) != 0;} + + /** Set the flag value + @param flagp Valore da inserire nel flag + */ + void SetFlags(int flagp) {this->Flags()=flagp;} + + /** Set the flag value + @param flagp Valore da inserire nel flag + */ + void ClearFlags() {this->Flags()=0;} + + /// deletes the Face from the mesh + void SetD() {this->Flags() |=DELETED;} + /// un-delete a Face + void ClearD() {this->Flags() &=(~DELETED);} + /// marks the Face as readable + void SetR() {this->Flags() &=(~NOTREAD);} + /// marks the Face as not readable + void ClearR() {this->Flags() |=NOTREAD;} + /// marks the Face as writable + 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;} + /// select the Face + void SetV() {this->Flags() |=VISITED;} + /// Un-select a Face + void ClearV() {this->Flags() &= ~VISITED;} + + /// This function checks if the face is selected + bool IsB(int i) const {return (this->Flags() & (BORDER0<Flags() |=(BORDER0<Flags() &= (~(BORDER0<Flags() & (FEATURE0<Flags() |=(FEATURE0<Flags() &= (~(FEATURE0<>1; @@ -893,410 +278,83 @@ public: assert(0); return false; } - - void ClearFlags() {_flags=0;} - - /// Return the _flags. - inline int & Flags () - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - return _flags; - } - - inline const int & Flags () const - { - assert( (_flags & DELETED) == 0 ); - assert( (_flags & NOTREAD) == 0 ); - return _flags; - } - /// Ritorna il _flags senza effettuare alcun controllo sui relativi bit - inline int & UberFlags() - { - return _flags; - } - - inline const int UberFlags() const - { - return _flags; - } - - /// This function checks if the face is deleted - bool IsD() const {return (_flags & DELETED) != 0;} - /// This function mark the face as deleted - void SetD() {_flags |=DELETED;} - /// This function mark the face as not deleted - void ClearD() {_flags &= (~DELETED);} - /// This function checks if the face is deleted - bool IsDeleted() const {return IsD();} - - /// This function checks if the face is readable - bool IsR() const {return (_flags & NOTREAD) == 0;} - /// This function marks the face as readable - void SetR() {_flags &= (~NOTREAD);} - /// This function marks the face as not readable - void ClearR() {_flags |=NOTREAD;} - - /// This function checks if the face is readable - bool IsW() const {return (_flags & NOTWRITE)== 0;} - /// This function marks the vertex as not writable - void SetW() {_flags &=(~NOTWRITE);} - /// This function marks the face as not writable - void ClearW() {_flags |=NOTWRITE;} - - /// This funcion checks whether the face is both readable and modifiable - bool IsRW() const {return (_flags & (NOTREAD | NOTWRITE)) == 0;} - - - /// This function checks if the face is selected - bool IsS() const {return (_flags & SELECTED) != 0;} - /// This function select the face - void SetS() {_flags |=SELECTED;} - /// This funcion execute the inverse operation of SetS() - void ClearS() {_flags &= (~SELECTED);} - - /// This function checks if the face is selected - bool IsB(int i) const {return (_flags & (BORDER0<Flags() & userBit) != 0;} /// This function set the given user bit - void SetUserBit(int userBit){_flags |=userBit;} + void SetUserBit(int userBit){this->Flags() |=userBit;} /// This function clear the given user bit - void ClearUserBit(int userBit){_flags &= (~userBit);} + void ClearUserBit(int userBit){this->Flags() &= (~userBit);} + + template + void GetBBox( BoxType & bb ) const + { + if(this->IsD()) + { + bb.SetNull(); + return; + } + bb.Set(this->P(0)); + bb.Add(this->P(1)); + bb.Add(this->P(2)); + } -//@} -/*#******************* -* Bounding box * -**********************/ +}; -void GetBBox( BoxType & bb ) const -{ - bb.Set( v[0]->P() ); - bb.Add( v[1]->P() ); - bb.Add( v[2]->P() ); -} +template < typename T=int> +class FaceDefaultDeriver : public T {}; + +/* - /***********************************************/ - /** @name Reflection Functions - Static functions that give information about the current vertex type. -Reflection is a mechanism making it possible to investigate yourself. Reflection is used to investigate format of objects at runtime, invoke methods and access fields of these objects. Here we provide static const functions that are resolved at compile time and they give information about the data (normal, color etc.) supported by the current vertex type. - **/ - //@{ -static bool HasFlags() { - return true; -} -static bool HasFaceNormal() { -#ifdef __VCGLIB_FACE_FN - return true; -#else - return false; -#endif -} -static bool HasFaceQuality() { -#ifdef __VCGLIB_FACE_FQ - return true; -#else - return false; -#endif -} -static bool HasFaceColor() { -#ifdef __VCGLIB_FACE_FC - return true; -#else - return false; -#endif -} -static bool HasEdgePlane() { -#ifdef __VCGLIB_FACE_RT - return true; -#else - return false; -#endif -} -static bool HasFFAdjacency() { -#if (defined(__VCGLIB_FACE_AF) || defined(__VCGLIB_FACE_AS)) - return true; -#else - return false; -#endif -} -static bool HasVFAdjacency() { -#if (defined(__VCGLIB_FACE_AV) || defined(__VCGLIB_FACE_AS)) - return true; -#else - return false; -#endif -} -static bool HasSharedAdjacency() { -#if defined(__VCGLIB_FACE_AS) - return true; -#else - return false; -#endif -} -static bool HasFaceMark() { -#ifdef __VCGLIB_FACE_FC - return true; -#else - return false; -#endif -} -static bool HasWedgeColor() { -#ifdef __VCGLIB_FACE_WC - return true; -#else - return false; -#endif -} -static bool HasWedgeTexCoord() { -#ifdef __VCGLIB_FACE_WT - return true; -#else - return false; -#endif -} -static bool HasWedgeNormal() { -#ifdef __VCGLIB_FACE_WN - return true; -#else - return false; -#endif -} +These are the three main classes that are used by the library user to define its own Facees. +The user MUST specify the names of all the type involved in a generic complex. +so for example when defining a Face of a trimesh you must know the name of the type of the edge and of the face. +Typical usage example: -//@} +A Face with coords, flags and normal for use in a standard trimesh: - /// operator to compare two faces - inline bool operator == ( const FFTYPE & f ) const { - for(int i=0; i<3; ++i) - if( (V(i) != f.V(0)) && (V(i) != f.V(1)) && (V(i) != f.V(2)) ) - return false; - return true; - } +class MyFaceNf : public FaceSimp2< VertProto, EdgeProto, MyFaceNf, face::Flag, face::Normal3f > {}; + + +A Face with coords, and normal for use in a tetrahedral mesh AND in a standard trimesh: + +class TetraFace : public FaceSimp3< VertProto, EdgeProto, TetraFace, TetraProto, face::Coord3d, face::Normal3f > {}; + + +A summary of the components that can be added to a face (see components.h for details): + +VertexRef +NormalFromVert, WedgeNormal +Normal3s, Normal3f, Normal3d +WedgeTexCoord2s, WedgeTexCoord2f, WedgeTexCoord2d +BitFlags +WedgeColor, Color4b +Qualitys, Qualityf, Qualityd +Mark //Incremental mark (int) +VFAdj //Topology vertex face adjacency + (pointers to next face in the ring of the vertex +FFAdj //topology: face face adj + pointers to adjacent faces -/** Calcola i coefficienti della combinazione convessa. - @param bq Punto appartenente alla faccia - @param a Valore di ritorno per il vertice V(0) - @param b Valore di ritorno per il vertice V(1) - @param _c Valore di ritorno per il vertice V(2) - @return true se bq appartiene alla faccia, false altrimenti */ -bool InterpolationParameters(const CoordType & bq, ScalarType &a, ScalarType &b, ScalarType &_c ) const -{ -const ScalarType EPSILON = ScalarType(0.000001); - - -#define x1 (cV(0)->P()[0]) -#define y1 (cV(0)->P()[1]) -#define z1 (cV(0)->P()[2]) -#define x2 (cV(1)->P()[0]) -#define y2 (cV(1)->P()[1]) -#define z2 (cV(1)->P()[2]) -#define x3 (cV(2)->P()[0]) -#define y3 (cV(2)->P()[1]) -#define z3 (cV(2)->P()[2]) -#define px (bq[0]) -#define py (bq[1]) -#define pz (bq[2]) - - ScalarType t1 = px*y2; - ScalarType t2 = px*y3; - ScalarType t3 = py*x2; - ScalarType t4 = py*x3; - ScalarType t5 = x2*y3; - ScalarType t6 = x3*y2; - ScalarType t8 = x1*y2; - ScalarType t9 = x1*y3; - ScalarType t10 = y1*x2; - ScalarType t11 = y1*x3; - ScalarType t13 = t8-t9-t10+t11+t5-t6; - if(fabs(t13)>=EPSILON) - { - ScalarType t15 = px*y1; - ScalarType t16 = py*x1; - a = (t1 -t2-t3 +t4+t5-t6 )/t13; - b = -(t15-t2-t16+t4+t9-t11)/t13; - _c = (t15-t1-t16+t3+t8-t10)/t13; - return true; - } - - t1 = px*z2; - t2 = px*z3; - t3 = pz*x2; - t4 = pz*x3; - t5 = x2*z3; - t6 = x3*z2; - t8 = x1*z2; - t9 = x1*z3; - t10 = z1*x2; - t11 = z1*x3; - t13 = t8-t9-t10+t11+t5-t6; - if(fabs(t13)>=EPSILON) - { - ScalarType t15 = px*z1; - ScalarType t16 = pz*x1; - a = (t1 -t2-t3 +t4+t5-t6 )/t13; - b = -(t15-t2-t16+t4+t9-t11)/t13; - _c = (t15-t1-t16+t3+t8-t10)/t13; - return true; - } - - t1 = pz*y2; t2 = pz*y3; - t3 = py*z2; t4 = py*z3; - t5 = z2*y3; t6 = z3*y2; - t8 = z1*y2; t9 = z1*y3; - t10 = y1*z2; t11 = y1*z3; - t13 = t8-t9-t10+t11+t5-t6; - if(fabs(t13)>=EPSILON) - { - ScalarType t15 = pz*y1; - ScalarType t16 = py*z1; - a = (t1 -t2-t3 +t4+t5-t6 )/t13; - b = -(t15-t2-t16+t4+t9-t11)/t13; - _c = (t15-t1-t16+t3+t8-t10)/t13; - return true; - } - -#undef x1 -#undef y1 -#undef z1 -#undef x2 -#undef y2 -#undef z2 -#undef x3 -#undef y3 -#undef z3 -#undef px -#undef py -#undef pz - - return false; -} - - - -/// Return the DOUBLE of the area of the face -// NOTE the old Area function has been removed to intentionally -// cause compiling error that will help people to check their code... -// A some people used Area assuming that it returns the double and some not. -// So please check your codes!!! -// And please DO NOT Insert any Area named function here! -ScalarType DoubleArea() const -{ - return ( (V(1)->cP() - V(0)->cP()) ^ (V(2)->cP() - V(0)->P()) ).Norm(); -} - -CoordType Barycenter() const -{ - return (V(0)->P()+V(1)->P()+V(2)->P())/ScalarType(3.0); -} - -Sphere3 SmallestEnclosingSphere() const -{ - return SmallestEnclosing::SphereOfTriangle(*this); -} - -ScalarType Perimeter() const -{ - return Distance(V(0)->P(),V(1)->P())+ - Distance(V(1)->P(),V(2)->P())+ - Distance(V(2)->P(),V(0)->P()); -} - -/// Return the _q of the face, the return value is in [0,sqrt(3)/2] = [0 - 0.866.. ] -ScalarType QualityFace( ) const -{ - - return Quality(V(0)->cP(), V(1)->cP(), V(2)->cP()); - /* - CoordType d10 = V(1)->P() - V(0)->P(); - CoordType d20 = V(2)->P() - V(0)->P(); - CoordType d12 = V(1)->P() - V(2)->P(); - - CoordType x = d10^d20; - - ScalarType a = Norm( x ); // doppio dell' Area - ScalarType b; - - b = Norm2( d10 ); - ScalarType t = b; - t = Norm2( d20 ); if( b & Plane(){return plane;}; - Plane3 cPlane()const{return plane;}; - - - CoordType edges[3];; - Plane3 plane; -#endif - - /// return the index [0..2] of a vertex in a face - inline int VertexIndex( const VertexType * w ) const - { - if( v[0]==w ) return 0; - else if( v[1]==w ) return 1; - else if( v[2]==w ) return 2; - else return -1; - } - - -}; //end Class - - -#ifndef __VCG_FACE_BASE_SINGLE -#define __VCG_FACE_BASE_SINGLE -// Note that while the whole file can be included more than once, this portion of the file MUST be included once - -/// Calculate the normal to the face, the value is store in the field _n of the face -namespace face -{ - -template -void ComputeNormal(FaceType &f) { f.N() = vcg::Normal< FaceType >(f); } - -template -void ComputeNormalizedNormal(FaceType &f) { f.N() = vcg::NormalizedNormal< FaceType >(f); } - -} // end namespace face -//@} -#endif - -} // end namespace vcg + +template class A = FaceDefaultDeriver, template class B = FaceDefaultDeriver, + template class C = FaceDefaultDeriver, template class D = FaceDefaultDeriver, + template class E = FaceDefaultDeriver, template class F = FaceDefaultDeriver, + template class G = FaceDefaultDeriver, template class H = FaceDefaultDeriver, + template class I = FaceDefaultDeriver, template class J = FaceDefaultDeriver > + class FaceSimp3: public FaceArityMax {}; +class DumTT; +template class A = FaceDefaultDeriver, template class B = FaceDefaultDeriver, + template class C = FaceDefaultDeriver, template class D = FaceDefaultDeriver, + template class E = FaceDefaultDeriver, template class F = FaceDefaultDeriver, + template class G = FaceDefaultDeriver, template class H = FaceDefaultDeriver, + template class I = FaceDefaultDeriver, template class J = FaceDefaultDeriver > + class FaceSimp2: public FaceArityMax {}; +}// end namespace #endif diff --git a/vcg/simplex/face/base_old.h b/vcg/simplex/face/base_old.h new file mode 100644 index 00000000..9ff4894d --- /dev/null +++ b/vcg/simplex/face/base_old.h @@ -0,0 +1,1302 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* 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 * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ +/**************************************************************************** + History + +$Log: not supported by cvs2svn $ +Revision 1.43 2007/03/12 15:37:19 tarini +Texture coord name change! "TCoord" and "Texture" are BAD. "TexCoord" is GOOD. + +Revision 1.42 2007/02/20 14:07:53 ganovelli +added QualityType to comply faceplus type + +Revision 1.41 2007/01/13 00:25:36 cignoni +Added #ifdefs to guarantee that ComputeNormal would be defined only once + +Revision 1.40 2007/01/11 10:13:11 cignoni +Rewrote the template of ComputeNormal functions to a more readable form. + +Revision 1.39 2006/07/12 12:14:31 zifnab1974 +changes for compilation on linux. Not sure about using either SphereOfTriangle or SphereOfTetra, please check. + +Revision 1.38 2006/07/06 12:45:08 ganovelli +added SmallestEnclosingSphere + +Revision 1.37 2006/01/22 10:00:43 cignoni +Very Important Change: Area->DoubleArea (and no more Area function) + +Revision 1.36 2005/12/16 11:42:23 corsini +Add some user bit + +Revision 1.35 2005/12/01 23:54:29 cignoni +Added HasFlags + +Revision 1.34 2005/11/23 14:40:09 pietroni +added cFFi function + +Revision 1.33 2005/11/22 15:47:35 cignoni +Moved ComputeNormal and ComputeNormalizedNormal out of the face class (no more a member function!) + +Revision 1.32 2005/11/12 18:39:54 cignoni +Added dummy static member for avoiding annoying warning in empty functions... + +Revision 1.31 2005/11/01 18:16:36 cignoni +Added intialization of _flags to zero in the default constructor of face + +Revision 1.30 2005/10/13 09:25:43 cignoni +Added cFFp and cVFp const member functions + +Revision 1.29 2005/09/28 19:32:09 m_di_benedetto +Added const qualifier in GetBBox method. + +Revision 1.28 2005/06/17 00:43:34 cignoni +Added a named typedef for the per wedge TexCoordinate + +Revision 1.27 2005/03/18 16:35:53 fiorin +minor changes to comply gcc compiler + +Revision 1.26 2005/03/11 14:14:14 ganovelli +_ffi was a 4 for positions vector (only 3 used) + +Revision 1.25 2005/01/28 17:53:13 pietroni +added HasEdgePlane function + +Revision 1.24 2004/10/28 00:50:48 cignoni +Better Doxygen documentation + +Revision 1.23 2004/10/25 08:22:40 ganovelli +IsBOrder (typecast on return type) + +Revision 1.22 2004/10/20 08:28:31 fiorin +Added constant access function FFp and renamed F1 F2 to FFp1 FFp2 + +Revision 1.21 2004/10/18 17:13:50 ganovelli +added ::IsBorder + +Revision 1.20 2004/09/15 11:20:15 ganovelli +changed P() to cP() + +Revision 1.19 2004/09/14 19:47:02 ganovelli +removed "&" in FFp + +Revision 1.18 2004/08/25 15:15:27 ganovelli +minor changes to comply gcc compiler (typename's and stuff) + +Revision 1.17 2004/07/15 12:03:07 ganovelli +minor changes + +Revision 1.16 2004/07/15 11:31:59 ganovelli +minor changes + +Revision 1.15 2004/07/12 12:17:09 pietroni +added function NormalizedNormal + +Revision 1.14 2004/05/13 11:01:06 turini +Changed ComputeMormalizedNormal() using Triangle3 + +Revision 1.13 2004/05/12 18:49:05 ganovelli +dist and coputeRT removed (see distance.h and updateEdges) + +Revision 1.12 2004/05/12 14:43:36 cignoni +removed warning of unused variables + +Revision 1.11 2004/05/12 12:50:20 turini +include color4 + +Revision 1.10 2004/05/10 14:01:09 ganovelli +assert(i*0) for using "i" and preventing the compiler warning for unreferenced variable + +Revision 1.9 2004/05/10 13:19:38 cignoni +Added mandatory template params for edge and face class names to the face class +Changed type of return face pointer to the one passed by templ params +Changed name of func FV to VF (it stores Vertex-Face Topology) + +Revision 1.8 2004/05/06 09:06:59 pietroni +changed names to topology functions + +Revision 1.7 2004/05/04 02:46:23 ganovelli +added function Dist + +Revision 1.5 2004/04/05 11:51:22 cignoni +wrong define FACE_N instead of FACE_FN + +Revision 1.4 2004/03/29 08:37:09 cignoni +missing include + +Revision 1.3 2004/03/10 00:52:38 cignoni +Moved geometric stuff to the space/triangle class + +Revision 1.2 2004/03/03 16:08:38 cignoni +First working version + +Revision 1.1 2004/02/13 00:44:45 cignoni +First commit... + +****************************************************************************/ + +#pragma message("[VCGLIB Warning] this way to define the simplex face is DEPRECATED and no more SUPPORTED") +#pragma message("[VCGLIB Warning] use vcg/simplex/faceplus instead ") + +#ifndef FACE_TYPE +#pragma error message("\nYou should never directly include this file\n") +#else + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace vcg { +class DUMMYEDGETYPE; +class DUMMYFACETYPE; +class DUMMYTETRATYPE; + +/** \addtogroup face */ +//@{ +/*! + * This class represent the generic configurable Face; + * Usually you never direclty use this class with this name but you build + * your own type by directly including one of the .h files under the face/with + * directory. Each file specify a class type with the desired fields. So for example + * including 'vcg/simplex/face/with/FCFN.h' allow you to use the class FaceFCFN that has per-face color and normal stored inside. + */ +template > class FACE_TYPE +{ +public: + /// The base type of the face + typedef FACE_TYPE BaseFaceType; + /// The base type of the face itself + typedef FFTYPE FaceType; + /// The vertex type + typedef FVTYPE VertexType; + /// The vertex type + typedef FETYPE EdgeType; + /// The Texture Coordinate type + typedef TCTYPE TexCoordType; + /// The type of the scalar field of the vertex coordinate + typedef typename VertexType::ScalarType ScalarType; + /// The type of the the vertex coordinate + typedef Point3< ScalarType > CoordType; + typedef Point3< ScalarType > NormalType; + /// The geometric type of the face + typedef Triangle3 GeometricType; + /// The type of the quality (same as scalar) + typedef ScalarType QualityType; + + typedef typename FVTYPE::FaceType FaceFromVertType; + /// The bounding box type + typedef Box3 BoxType; + + /// Default Empty Costructor + inline FACE_TYPE(){_flags=0;} + + /// This are the _flags of face, the default value is 0 + int _flags; + +/***********************************************/ +/** @name Vertex Pointer +Functions to access to the vertexes of the face; +**/ + //@{ +protected: + /// Vector of vertex pointer incident in the face + VertexType *v[3]; +public: + /** Return the pointer to the j-th vertex of the face. + @param j Index of the face vertex. + */ + inline VertexType * & V( const int j ) + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert( (_flags & NOTWRITE) == 0 ); + assert(j >= 0); + assert(j < 3); + return v[j]; + } + + inline VertexType * const & V( const int j ) const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert(j>=0); + assert(j<3); + return v[j]; + } + inline VertexType * const cV( const int j ) const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert(j>=0); + assert(j<3); + return v[j]; + } + + // Shortcut per accedere ai punti delle facce + inline CoordType & P( const int j ) + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert( (_flags & NOTWRITE) == 0 ); + assert(j>=0); + assert(j<3); + return v[j]->P(); + } + + inline const CoordType & P( const int j ) const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert(j>=0); + assert(j<3); + return v[j]->cP(); + } + inline const CoordType & cP( const int j ) const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert(j>=0); + assert(j<3); + return v[j]->cP(); + } + + /** Return the pointer to the ((j+1)%3)-th vertex of the face. + @param j Index of the face vertex. + */ + inline VertexType * & V0( const int j ) { return V(j);} + inline VertexType * & V1( const int j ) { return V((j+1)%3);} + inline VertexType * & V2( const int j ) { return V((j+2)%3);} + inline const VertexType * const & V0( const int j ) const { return V(j);} + inline const VertexType * const & V1( const int j ) const { return V((j+1)%3);} + inline const VertexType * const & V2( const int j ) const { return V((j+2)%3);} + inline const VertexType * const & cV0( const int j ) const { return cV(j);} + inline const VertexType * const & cV1( const int j ) const { return cV((j+1)%3);} + inline const VertexType * const & cV2( const int j ) const { return cV((j+2)%3);} + + /// Shortcut per accedere ai punti delle facce + inline CoordType & P0( const int j ) { return V(j)->P();} + inline CoordType & P1( const int j ) { return V((j+1)%3)->P();} + inline CoordType & P2( const int j ) { return V((j+2)%3)->P();} + inline const CoordType & P0( const int j ) const { return V(j)->P();} + inline const CoordType & P1( const int j ) const { return V((j+1)%3)->P();} + inline const CoordType & P2( const int j ) const { return V((j+2)%3)->P();} + inline const CoordType & cP0( const int j ) const { return cV(j)->P();} + inline const CoordType & cP1( const int j ) const { return cV((j+1)%3)->P();} + inline const CoordType & cP2( const int j ) const { return cV((j+2)%3)->P();} + + inline VertexType * & UberV( const int j ) + { + assert(j>=0); + assert(j<3); + return v[j]; + } + + inline const VertexType * const & UberV( const int j ) const + { + assert(j>=0); + assert(j<3); + return v[j]; + } + + + //@} + +/***********************************************/ +/** @name Normal + blah + blah +**/ + //@{ + +#ifdef __VCGLIB_FACE_FN + /// This vector indicates the normal of the face (defines if FACE_N is defined) +protected: + CoordType _n; +public: +#endif + + /// Return the reference of the normal to the face (if __VCGLIB_FACE_FN is defined). + inline CoordType & N() + { +#ifdef __VCGLIB_FACE_FN + return _n; +#else + assert(0); + return *(CoordType *)0; +#endif + } + /// Return the reference of the normal to the face (if __VCGLIB_FACE_FN is defined). + inline const CoordType & N() const + { +#ifdef __VCGLIB_FACE_FN + return _n; +#else + return *(CoordType *)0; +#endif + } + /// Return the reference of the normal to the face (if __VCGLIB_FACE_FN is defined). + inline const CoordType cN() const + { +#ifdef __VCGLIB_FACE_FN + return _n; +#else + return *(CoordType *)0; +#endif + } + +/// Return the value of the face normal as it correspond to the current geometry. +/// it is always computed and never stored. +const CoordType Normal() const +{ + return vcg::Normal(*this); +} + +/// Return the value of the face normal as it correspond to the current geometry. +/// it is always computed and never stored. +const CoordType NormalizedNormal() const +{ + return vcg::NormalizedNormal(*this); +} + +#ifdef __VCGLIB_FACE_WN + /// This vector indicates per wedge normal + CoordType _wn[3]; +#endif + +public: + CoordType & WN(const int i) + { +#ifdef __VCGLIB_FACE_WN + return _wn[i]; +#else + assert(0); + return *(CoordType *)(&_flags); +#endif + } + +const CoordType & WN(const int i) const + { +#ifdef __VCGLIB_FACE_WN + return _wn[i]; +#else + return CoordType(); +#endif + } + + //@} + +/***********************************************/ +/** @name Quality + blah + blah +**/ + //@{ + +#ifdef __VCGLIB_FACE_FQ +protected: + float _q; +#endif +public: + float & Q() + { +#ifdef __VCGLIB_FACE_FQ + return _q; +#else + assert(0); + return *(float*)(&_flags); +#endif + } + +const float & Q() const + { +#ifdef __VCGLIB_FACE_FQ + return _q; +#else + assert(0); + return *(float*)(&_flags); +#endif + } + + //@} + +/***********************************************/ +/** @name Texture + blah + blah +**/ + //@{ + +// Per Wedge Texture Coords +protected: +#ifdef __VCGLIB_FACE_WT + TCTYPE _wt[3]; +#endif +public: + TCTYPE & WT(const int i) + { +#ifdef __VCGLIB_FACE_WT + return _wt[i]; +#else + assert(0); + return *(TCTYPE*)(&_flags +i) ; +#endif + } + + const TCTYPE & WT(const int i) const + { +#ifdef __VCGLIB_FACE_WT + return _wt[i]; +#else + assert(0); + return *(TCTYPE*)(&_flags); +#endif + } + + + //@} + +/***********************************************/ +/** @name Colors + blah + blah +**/ + //@{ +protected: +#ifdef __VCGLIB_FACE_FC + Color4b _c; +#endif + +public: + Color4b & C() + { +#ifdef __VCGLIB_FACE_FC + return _c; +#else + assert(0); + return *(Color4b*)(&_flags); +#endif + } + + const Color4b C() const + { +#ifdef __VCGLIB_FACE_FC + return _c; +#else + return Color4b(Color4b::White); +#endif + } + +protected: +#ifdef __VCGLIB_FACE_WC + Color4b _wc[3]; +#endif +public: + Color4b & WC(const int i) + { +#ifdef __VCGLIB_FACE_WC + return _wc[i]; +#else + assert(0); + return *(Color4b*)(&_flags + i); +#endif + } + +const Color4b WC(const int i) const + { +#ifdef __VCGLIB_FACE_WC + return _wc[i]; +#else + assert(0); + return Color4b(Color4b::White); +#endif + } + + + + + //@} + +/***********************************************/ +/** @name Adjacency + blah + blah +**/ + //@{ + +#if (defined(__VCGLIB_FACE_AF) && defined(__VCGLIB_FACE_AS)) + #error Error: You cannot specify face-to-face and shared topology together +#endif + +#if (defined(__VCGLIB_FACE_AV) && defined(__VCGLIB_FACE_AS)) + #error Error: You cannot specify vertex-face and shared topology together +#endif + +protected: +#if defined(__VCGLIB_FACE_AF) + /// Vector of face pointer, it's used to indicate the adjacency relations (defines if FACE_A is defined) + FFTYPE *_ffp[3]; // Facce adiacenti + /// Index of the face in the arrival face + char _ffi[3]; +#endif + +#ifdef __VCGLIB_FACE_AV + ///Vettore di puntatori a faccia, utilizzato per indicare le adiacenze vertice faccia + FFTYPE *_fvp[3]; + char _fvi[3]; +#endif + +#ifdef __VCGLIB_FACE_AS + ///Vettore di puntatori a faccia, utilizzato per indicare le adiacenze vertice faccia + FFTYPE *fs[3]; + char zs[3]; +#endif +public: + + + + + /** Return the pointer to the j-th adjacent face. + @param j Index of the edge. + */ + inline FFTYPE * & FFp( const int j ) + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert( (_flags & NOTWRITE) == 0 ); + assert(j>=0); + assert(j<3); +#if defined(__VCGLIB_FACE_AF) + return _ffp[j]; +#elif defined(__VCGLIB_FACE_AS) + return fs[j]; +#else + assert(0); + static FFTYPE *dum=0; dum+=j; + return dum; + +#endif + } + + inline const FFTYPE * FFp( const int j ) const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert(j>=0 && j<3); + +#if defined(__VCGLIB_FACE_AF) + return _ffp[j]; +#elif defined(__VCGLIB_FACE_AS) + return fs[j]; +#else + assert(0); + static FFTYPE *dum=0; dum+=j; + return dum; +#endif + } + inline const FFTYPE * cFFp( const int j ) const {return FFp(j);} + + inline FFTYPE * & FFp1( const int j ) { return FFp((j+1)%3);} + inline FFTYPE * & FFp2( const int j ) { return FFp((j+2)%3);} + inline const FFTYPE * const& FFp1( const int j ) const { return FFp((j+1)%3);} + inline const FFTYPE * const& FFp2( const int j ) const { return FFp((j+2)%3);} + + + +/** Return the pointer to the j-th adjacent face. + @param j Index of the edge. + */ + inline FFTYPE * & UberF( const int j ) + { + assert(j>=0); + assert(j<3); +#if defined(__VCGLIB_FACE_AF) + return _ffp[j]; +#elif defined(__VCGLIB_FACE_AS) + return fs[j]; +#else + assert(0); // if you stop here you are probably trying to use FF topology in a face without it + return *((FFTYPE **)(_flags)); +#endif + } + + inline const FFTYPE * const & UberF( const int j ) const + { + assert(j>=0); + assert(j<3); +#if defined(__VCGLIB_FACE_AF) + return _ffp[j]; +#elif defined(__VCGLIB_FACE_AS) + return fs[j]; +#else + assert(0); // if you stop here you are probably trying to use FF topology in a face without it + return *((FFTYPE **)(_flags)); +#endif + } + + + inline FFTYPE * & VFp( const int j ) + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert( (_flags & NOTWRITE) == 0 ); + assert(j>=0); + assert(j<3); +#ifdef __VCGLIB_FACE_AV + return _fvp[j]; +#elif defined(__VCGLIB_FACE_AS) + return fs[j]; +#else + assert(0); // you are probably trying to use VF topology in a vertex without it + return *((FFTYPE **)(_flags)); +#endif + } + + inline const FFTYPE * const VFp( const int j ) const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert(j>=0); + assert(j<3); +#ifdef __VCGLIB_FACE_AV + return _fvp[j]; +#elif defined(__VCGLIB_FACE_AS) + return fs[j]; +#else + assert(0); + static FFTYPE * const DummyVal=0; + return DummyVal; +#endif + } + inline const FFTYPE * cVFp( const int j ) const {return VFp(j);} + + + /** Return the index that the face have in the j-th adjacent face. + @param j Index of the edge. + */ + inline char & FFi( const int j ) + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert( (_flags & NOTWRITE) == 0 ); + assert(j>=0); + assert(j<3); +#if defined(__VCGLIB_FACE_AF) + return _ffi[j]; +#elif defined(__VCGLIB_FACE_AS) + return zs[j]; +#else + assert(0); + return *(char *)&_flags; // tanto per farlo compilare... +#endif + } + + inline const char & FFi( const int j ) const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert(j>=0); + assert(j<3); +#if defined(__VCGLIB_FACE_AF) + return _ffi[j]; +#elif defined(__VCGLIB_FACE_AS) + return zs[j]; +#else + assert(0); + return *(char *)&_flags; +#endif + } + + inline const char & cFFi( const int j ) const {return FFi(j);} + + /** Return the index that the face have in the j-th adjacent face. + @param j Index of the edge. + */ + inline char & UberZ( const int j ) + { + assert(j>=0); + assert(j<3); +#if defined(__VCGLIB_FACE_AF) + return _ffi[j]; +#elif defined(__VCGLIB_FACE_AS) + return zs[j]; +#else + assert(0); + return *(char *)&_flags; +#endif + } + + inline const char & UberZ( const int j ) const + { + assert(j>=0); + assert(j<3); +#if defined(__VCGLIB_FACE_AF) + return _ffi[j]; +#elif defined(__VCGLIB_FACE_AS) + return zs[j]; +#else + assert(0); + return *(char *)&_flags; +#endif + } + + + inline char & VFi( const int j ) + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert( (_flags & NOTWRITE) == 0 ); + assert(j>=0); + assert(j<3); +#ifdef __VCGLIB_FACE_AV + return _fvi[j]; +#elif defined(__VCGLIB_FACE_AS) + return zs[j]; +#else + assert(0); + return *(char *)&_flags; +#endif + } + + inline const char & VFi( const int j ) const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert(j>=0); + assert(j<3); +#ifdef __VCGLIB_FACE_AV + return _fvi[j]; +#elif defined(__VCGLIB_FACE_AS) + return zs[j]; +#else + assert(0); + return *(char *)&_flags; +#endif + } + + //@} + +/***********************************************/ +/** @name Mark + blah + blah +**/ + //@{ + + +#ifdef __VCGLIB_FACE_FM + /// Incremental mark (defines if FACE_I is defined) + int imark; + inline int & IMark() + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert( (_flags & NOTWRITE) == 0 ); + return imark; + } + + inline const int & IMark() const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + return imark; + } +#endif // Mark + + /// Initialize the imark system of the face + inline void InitIMark() + { +#ifdef __VCGLIB_FACE_FM + imark = 0; +#endif + } + + + //@} +/***********************************************/ +/** @name Flags + blah + blah +**/ + //@{ + + + enum { + // This bit indicate that the face is deleted from the mesh + DELETED = 0x00000001, // cancellato + // This bit indicate that the face of the mesh is not readable + NOTREAD = 0x00000002, // non leggibile (ma forse modificabile) + // This bit indicate that the face is not modifiable + NOTWRITE = 0x00000004, // non modificabile (ma forse leggibile) + // This bit indicate that the face is modified + SELECTED = 0x00000020, // Selection _flags + // Border _flags, it is assumed that BORDERi = BORDER0<>1; + return true; + } + assert(0); + return false; + } + + void ClearFlags() {_flags=0;} + + /// Return the _flags. + inline int & Flags () + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + return _flags; + } + + inline const int & Flags () const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + return _flags; + } + /// Ritorna il _flags senza effettuare alcun controllo sui relativi bit + inline int & UberFlags() + { + return _flags; + } + + inline const int UberFlags() const + { + return _flags; + } + + /// This function checks if the face is deleted + bool IsD() const {return (_flags & DELETED) != 0;} + /// This function mark the face as deleted + void SetD() {_flags |=DELETED;} + /// This function mark the face as not deleted + void ClearD() {_flags &= (~DELETED);} + /// This function checks if the face is deleted + bool IsDeleted() const {return IsD();} + + /// This function checks if the face is readable + bool IsR() const {return (_flags & NOTREAD) == 0;} + /// This function marks the face as readable + void SetR() {_flags &= (~NOTREAD);} + /// This function marks the face as not readable + void ClearR() {_flags |=NOTREAD;} + + /// This function checks if the face is readable + bool IsW() const {return (_flags & NOTWRITE)== 0;} + /// This function marks the vertex as not writable + void SetW() {_flags &=(~NOTWRITE);} + /// This function marks the face as not writable + void ClearW() {_flags |=NOTWRITE;} + + /// This funcion checks whether the face is both readable and modifiable + bool IsRW() const {return (_flags & (NOTREAD | NOTWRITE)) == 0;} + + + /// This function checks if the face is selected + bool IsS() const {return (_flags & SELECTED) != 0;} + /// This function select the face + void SetS() {_flags |=SELECTED;} + /// This funcion execute the inverse operation of SetS() + void ClearS() {_flags &= (~SELECTED);} + + /// This function checks if the face is selected + bool IsB(int i) const {return (_flags & (BORDER0<P() ); + bb.Add( v[1]->P() ); + bb.Add( v[2]->P() ); +} + + /***********************************************/ + /** @name Reflection Functions + Static functions that give information about the current vertex type. +Reflection is a mechanism making it possible to investigate yourself. Reflection is used to investigate format of objects at runtime, invoke methods and access fields of these objects. Here we provide static const functions that are resolved at compile time and they give information about the data (normal, color etc.) supported by the current vertex type. + **/ + //@{ +static bool HasFlags() { + return true; +} +static bool HasFaceNormal() { +#ifdef __VCGLIB_FACE_FN + return true; +#else + return false; +#endif +} +static bool HasFaceQuality() { +#ifdef __VCGLIB_FACE_FQ + return true; +#else + return false; +#endif +} +static bool HasFaceColor() { +#ifdef __VCGLIB_FACE_FC + return true; +#else + return false; +#endif +} +static bool HasEdgePlane() { +#ifdef __VCGLIB_FACE_RT + return true; +#else + return false; +#endif +} +static bool HasFFAdjacency() { +#if (defined(__VCGLIB_FACE_AF) || defined(__VCGLIB_FACE_AS)) + return true; +#else + return false; +#endif +} +static bool HasVFAdjacency() { +#if (defined(__VCGLIB_FACE_AV) || defined(__VCGLIB_FACE_AS)) + return true; +#else + return false; +#endif +} +static bool HasSharedAdjacency() { +#if defined(__VCGLIB_FACE_AS) + return true; +#else + return false; +#endif +} +static bool HasFaceMark() { +#ifdef __VCGLIB_FACE_FC + return true; +#else + return false; +#endif +} +static bool HasWedgeColor() { +#ifdef __VCGLIB_FACE_WC + return true; +#else + return false; +#endif +} +static bool HasWedgeTexCoord() { +#ifdef __VCGLIB_FACE_WT + return true; +#else + return false; +#endif +} +static bool HasWedgeNormal() { +#ifdef __VCGLIB_FACE_WN + return true; +#else + return false; +#endif +} + +//@} + + /// operator to compare two faces + inline bool operator == ( const FFTYPE & f ) const { + for(int i=0; i<3; ++i) + if( (V(i) != f.V(0)) && (V(i) != f.V(1)) && (V(i) != f.V(2)) ) + return false; + return true; + } + +/** Calcola i coefficienti della combinazione convessa. + @param bq Punto appartenente alla faccia + @param a Valore di ritorno per il vertice V(0) + @param b Valore di ritorno per il vertice V(1) + @param _c Valore di ritorno per il vertice V(2) + @return true se bq appartiene alla faccia, false altrimenti +*/ +bool InterpolationParameters(const CoordType & bq, ScalarType &a, ScalarType &b, ScalarType &_c ) const +{ +const ScalarType EPSILON = ScalarType(0.000001); + + +#define x1 (cV(0)->P()[0]) +#define y1 (cV(0)->P()[1]) +#define z1 (cV(0)->P()[2]) +#define x2 (cV(1)->P()[0]) +#define y2 (cV(1)->P()[1]) +#define z2 (cV(1)->P()[2]) +#define x3 (cV(2)->P()[0]) +#define y3 (cV(2)->P()[1]) +#define z3 (cV(2)->P()[2]) +#define px (bq[0]) +#define py (bq[1]) +#define pz (bq[2]) + + ScalarType t1 = px*y2; + ScalarType t2 = px*y3; + ScalarType t3 = py*x2; + ScalarType t4 = py*x3; + ScalarType t5 = x2*y3; + ScalarType t6 = x3*y2; + ScalarType t8 = x1*y2; + ScalarType t9 = x1*y3; + ScalarType t10 = y1*x2; + ScalarType t11 = y1*x3; + ScalarType t13 = t8-t9-t10+t11+t5-t6; + if(fabs(t13)>=EPSILON) + { + ScalarType t15 = px*y1; + ScalarType t16 = py*x1; + a = (t1 -t2-t3 +t4+t5-t6 )/t13; + b = -(t15-t2-t16+t4+t9-t11)/t13; + _c = (t15-t1-t16+t3+t8-t10)/t13; + return true; + } + + t1 = px*z2; + t2 = px*z3; + t3 = pz*x2; + t4 = pz*x3; + t5 = x2*z3; + t6 = x3*z2; + t8 = x1*z2; + t9 = x1*z3; + t10 = z1*x2; + t11 = z1*x3; + t13 = t8-t9-t10+t11+t5-t6; + if(fabs(t13)>=EPSILON) + { + ScalarType t15 = px*z1; + ScalarType t16 = pz*x1; + a = (t1 -t2-t3 +t4+t5-t6 )/t13; + b = -(t15-t2-t16+t4+t9-t11)/t13; + _c = (t15-t1-t16+t3+t8-t10)/t13; + return true; + } + + t1 = pz*y2; t2 = pz*y3; + t3 = py*z2; t4 = py*z3; + t5 = z2*y3; t6 = z3*y2; + t8 = z1*y2; t9 = z1*y3; + t10 = y1*z2; t11 = y1*z3; + t13 = t8-t9-t10+t11+t5-t6; + if(fabs(t13)>=EPSILON) + { + ScalarType t15 = pz*y1; + ScalarType t16 = py*z1; + a = (t1 -t2-t3 +t4+t5-t6 )/t13; + b = -(t15-t2-t16+t4+t9-t11)/t13; + _c = (t15-t1-t16+t3+t8-t10)/t13; + return true; + } + +#undef x1 +#undef y1 +#undef z1 +#undef x2 +#undef y2 +#undef z2 +#undef x3 +#undef y3 +#undef z3 +#undef px +#undef py +#undef pz + + return false; +} + + + +/// Return the DOUBLE of the area of the face +// NOTE the old Area function has been removed to intentionally +// cause compiling error that will help people to check their code... +// A some people used Area assuming that it returns the double and some not. +// So please check your codes!!! +// And please DO NOT Insert any Area named function here! +ScalarType DoubleArea() const +{ + return ( (V(1)->cP() - V(0)->cP()) ^ (V(2)->cP() - V(0)->P()) ).Norm(); +} + +CoordType Barycenter() const +{ + return (V(0)->P()+V(1)->P()+V(2)->P())/ScalarType(3.0); +} + +Sphere3 SmallestEnclosingSphere() const +{ + return SmallestEnclosing::SphereOfTriangle(*this); +} + +ScalarType Perimeter() const +{ + return Distance(V(0)->P(),V(1)->P())+ + Distance(V(1)->P(),V(2)->P())+ + Distance(V(2)->P(),V(0)->P()); +} + +/// Return the _q of the face, the return value is in [0,sqrt(3)/2] = [0 - 0.866.. ] +ScalarType QualityFace( ) const +{ + + return Quality(V(0)->cP(), V(1)->cP(), V(2)->cP()); + /* + CoordType d10 = V(1)->P() - V(0)->P(); + CoordType d20 = V(2)->P() - V(0)->P(); + CoordType d12 = V(1)->P() - V(2)->P(); + + CoordType x = d10^d20; + + ScalarType a = Norm( x ); // doppio dell' Area + ScalarType b; + + b = Norm2( d10 ); + ScalarType t = b; + t = Norm2( d20 ); if( b & Plane(){return plane;}; + Plane3 cPlane()const{return plane;}; + + + CoordType edges[3];; + Plane3 plane; +#endif + + /// return the index [0..2] of a vertex in a face + inline int VertexIndex( const VertexType * w ) const + { + if( v[0]==w ) return 0; + else if( v[1]==w ) return 1; + else if( v[2]==w ) return 2; + else return -1; + } + + +}; //end Class + + +#ifndef __VCG_FACE_BASE_SINGLE +#define __VCG_FACE_BASE_SINGLE +// Note that while the whole file can be included more than once, this portion of the file MUST be included once + +/// Calculate the normal to the face, the value is store in the field _n of the face +namespace face +{ + +template +void ComputeNormal(FaceType &f) { f.N() = vcg::Normal< FaceType >(f); } + +template +void ComputeNormalizedNormal(FaceType &f) { f.N() = vcg::NormalizedNormal< FaceType >(f); } + +} // end namespace face +//@} +#endif + +} // end namespace vcg + + +#endif + diff --git a/vcg/simplex/face/component.h b/vcg/simplex/face/component.h new file mode 100644 index 00000000..27be9156 --- /dev/null +++ b/vcg/simplex/face/component.h @@ -0,0 +1,596 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* 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 * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ +/**************************************************************************** + History + +$Log: not supported by cvs2svn $ +Revision 1.21 2008/02/04 21:26:45 ganovelli +added ImportLocal which imports all local attributes into vertexplus and faceplus. +A local attribute is everything (N(), C(), Q()....) except pointers to other simplices +(i.e. FFAdj, VFAdj, VertexRef) which are set to NULL. +Added some function for const attributes + +Revision 1.20 2008/01/28 08:42:51 cignoni +added assert when writing on empty data members + +Revision 1.19 2008/01/19 17:49:05 ganovelli +missing const cVF added + +Revision 1.18 2007/11/20 09:43:53 ganovelli +added missing include to color4 + +Revision 1.17 2007/05/04 16:16:04 ganovelli +added include to texcoor2 + +Revision 1.16 2007/03/12 15:42:11 tarini +Texture coord name change! "TCoord" and "Texture" are BAD. "TexCoord" is GOOD. + +Revision 1.15 2007/03/12 15:37:19 tarini +Texture coord name change! "TCoord" and "Texture" are BAD. "TexCoord" is GOOD. + +Revision 1.14 2007/02/27 09:32:00 cignoni +Added constructor to the VFadj component to comply to the allocator needs + +Revision 1.13 2007/02/12 19:01:23 ganovelli +added Name(std:vector& n) that fills n with the names of the attribute of the face type + +Revision 1.12 2007/01/11 10:22:39 cignoni +Added intialization of vertexRef to 0. + +Revision 1.11 2006/12/06 00:08:57 cignoni +Added FFp1 and FFp2 shortcuts + +Revision 1.10 2006/12/04 11:00:02 ganovelli +Cambiate Has*Opt in Has*Occ e aggiunti typedef per la compilazione di Occ + +Revision 1.9 2006/11/28 22:34:28 cignoni +Added default constructor with null initialization to adjacency members. +AddFaces and AddVertices NEED to know if the topology is correctly computed to update it. + +Revision 1.8 2006/10/07 09:59:42 cignoni +Added missing const to EmptyFF + +Revision 1.7 2006/01/09 13:58:55 cignoni +Added Initialization of Color in Vertex and Face Components + +Revision 1.6 2005/11/22 15:49:39 cignoni +removed two spurious computenormal + +Revision 1.5 2005/11/21 21:44:47 cignoni +Moved ComputeNormal and ComputeNormalizedNormal out of the face class (no more a member function!) + +Revision 1.4 2005/11/18 15:44:49 cignoni +Access to constant normal changed from by val to by reference + +Revision 1.3 2005/11/16 22:58:17 cignoni +Added IncrementalMark and WedgeTexCoord +Standardized name of flags. It is plural becouse each simplex has many flag. + +Revision 1.2 2005/11/12 18:43:14 cignoni +added missing cFFi + +Revision 1.1 2005/10/14 15:07:58 cignoni +First Really Working version + + +****************************************************************************/ +#ifndef __VCG_FACE_PLUS_COMPONENT +#define __VCG_FACE_PLUS_COMPONENT + +#include +#include +#include +#include + +namespace vcg { + namespace face { +/* +Some naming Rules +All the Components that can be added to a vertex should be defined in the namespace vert: + +*/ + +/*-------------------------- VERTEX ----------------------------------------*/ +template class EmptyVertexRef: public T { +public: + // typedef typename T::VertexType VertexType; + // typedef typename T::CoordType CoordType; + inline typename T::VertexType * & V( const int j ) { assert(0); static typename T::VertexType *vp=0; return vp; } + inline typename T::VertexType * const & V( const int j ) const { assert(0); static typename T::VertexType *vp=0; return vp; } + inline typename T::VertexType * const cV( const int j ) const { assert(0); static typename T::VertexType *vp=0; return vp; } + inline typename T::CoordType & P( const int j ) { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; } + inline const typename T::CoordType & P( const int j ) const { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; } + inline const typename T::CoordType &cP( const int j ) const { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; } + template + void ImportLocal(const LeftF & leftF) {T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + static bool HasVertexRef() { return false; } + static void Name(std::vector & name){T::Name(name);} + +}; +template class VertexRef: public T { +public: + VertexRef(){ + v[0]=0; + v[1]=0; + v[2]=0; + } + + inline typename T::VertexType * & V( const int j ) { assert(j>=0 && j<3); return v[j]; } + inline typename T::VertexType * const & V( const int j ) const { assert(j>=0 && j<3); return v[j]; } + inline typename T::VertexType * const cV( const int j ) const { assert(j>=0 && j<3); return v[j]; } + + // Shortcut per accedere ai punti delle facce + inline typename T::CoordType & P( const int j ) { assert(j>=0 && j<3); return v[j]->P(); } + inline const typename T::CoordType & P( const int j ) const { assert(j>=0 && j<3); return v[j]->cP(); } + inline const typename T::CoordType &cP( const int j ) const { assert(j>=0 && j<3); return v[j]->cP(); } + + /** Return the pointer to the ((j+1)%3)-th vertex of the face. + @param j Index of the face vertex. + */ + inline typename T::VertexType * & V0( const int j ) { return V(j);} + inline typename T::VertexType * & V1( const int j ) { return V((j+1)%3);} + inline typename T::VertexType * & V2( const int j ) { return V((j+2)%3);} + inline const typename T::VertexType * const & V0( const int j ) const { return V(j);} + inline const typename T::VertexType * const & V1( const int j ) const { return V((j+1)%3);} + inline const typename T::VertexType * const & V2( const int j ) const { return V((j+2)%3);} + inline const typename T::VertexType * const & cV0( const int j ) const { return cV(j);} + inline const typename T::VertexType * const & cV1( const int j ) const { return cV((j+1)%3);} + inline const typename T::VertexType * const & cV2( const int j ) const { return cV((j+2)%3);} + + /// Shortcut per accedere ai punti delle facce + inline typename T::CoordType & P0( const int j ) { return V(j)->P();} + inline typename T::CoordType & P1( const int j ) { return V((j+1)%3)->P();} + inline typename T::CoordType & P2( const int j ) { return V((j+2)%3)->P();} + inline const typename T::CoordType & P0( const int j ) const { return V(j)->P();} + inline const typename T::CoordType & P1( const int j ) const { return V((j+1)%3)->P();} + inline const typename T::CoordType & P2( const int j ) const { return V((j+2)%3)->P();} + inline const typename T::CoordType & cP0( const int j ) const { return cV(j)->P();} + inline const typename T::CoordType & cP1( const int j ) const { return cV((j+1)%3)->P();} + inline const typename T::CoordType & cP2( const int j ) const { return cV((j+2)%3)->P();} + + inline typename T::VertexType * & UberV( const int j ) { assert(j>=0 && j<3); return v[j]; } + inline const typename T::VertexType * const & UberV( const int j ) const { assert(j>=0 && j<3); return v[j]; } + + template + void ImportLocal(const LeftF & leftF){ V(0) = NULL; V(1) = NULL; V(2) = NULL; T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + + static bool HasVertexRef() { return true; } + static void Name(std::vector & name){name.push_back(std::string("VertexRef"));T::Name(name);} + + + private: + typename T::VertexType *v[3]; +}; + + + +/*-------------------------- NORMAL ----------------------------------------*/ + +template class EmptyNormal: public T { +public: + //typedef vcg::Point3s NormalType; + typedef typename T::VertexType::NormalType NormalType; + NormalType &N() { static NormalType dummy_normal(0, 0, 0); assert(0); return dummy_normal; } + const NormalType &cN() const { static NormalType dummy_normal(0, 0, 0); return dummy_normal; } + NormalType &WN(int) { static NormalType dummy_normal(0, 0, 0); assert(0); return dummy_normal; } + const NormalType cWN(int) const { static NormalType dummy_normal(0, 0, 0); return dummy_normal; } + + template + void ImportLocal(const LeftF & leftF){ T::ImportLocal(leftF);} + static bool HasWedgeNormal() { return false; } + static bool HasFaceNormal() { return false; } + static bool HasWedgeNormalOcc() { return false; } + static bool HasFaceNormalOcc() { return false; } +// void ComputeNormal() {assert(0);} +// void ComputeNormalizedNormal() {assert(0);} + static void Name(std::vector & name){ T::Name(name);} + +}; +template class NormalFromVert: public T { +public: + typedef typename T::VertexType::NormalType NormalType; + NormalType &N() { return _norm; } + NormalType &cN() const { return _norm; } + template + void ImportLocal(const LeftF & leftF){ N() = leftF.cN(); T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + static bool HasFaceNormal() { return true; } +// void ComputeNormal() { _norm = vcg::Normal(*(static_cast(this))); } +// void ComputeNormalizedNormal() { _norm = vcg::NormalizedNormal(*this);} + static void Name(std::vector & name){name.push_back(std::string("NormalFromVert"));T::Name(name);} + +private: + NormalType _norm; +}; + + +template +void ComputeNormal(T &f) { f.N() = vcg::Normal(f); } + +template +void ComputeNormalizedNormal(T &f) { f.N() = vcg::NormalizedNormal(f); } + +template class NormalAbs: public T { +public: + typedef A NormalType; + NormalType &N() { return _norm; } + NormalType cN() const { return _norm; } + template + void ImportLocal(const LeftF & leftF){ N() = leftF.cN(); T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + static bool HasFaceNormal() { return true; } + static void Name(std::vector & name){name.push_back(std::string("NormalAbs"));T::Name(name);} + +private: + NormalType _norm; +}; + +template class WedgeNormal: public T { +public: + typedef typename T::VertexType::NormalType NormalType; + NormalType &WN(const int j) { return _wnorm[j]; } + const NormalType cWN(const int j) const { return _wnorm[j]; } + template + void ImportLocal(const LeftF & leftF){ WN() = leftF.cWN(); T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + static bool HasWedgeNormal() { return true; } + static void Name(std::vector & name){name.push_back(std::string("WedgeNormal"));T::Name(name);} + +private: + NormalType _wnorm[3]; +}; + + +template class Normal3s: public NormalAbs { +public:static void Name(std::vector & name){name.push_back(std::string("Normal3s"));T::Name(name);} +}; +template class Normal3f: public NormalAbs { +public: static void Name(std::vector & name){name.push_back(std::string("Normal3f"));T::Name(name);} +}; +template class Normal3d: public NormalAbs { +public: static void Name(std::vector & name){name.push_back(std::string("Normal3d"));T::Name(name);} +}; + + +/*-------------------------- TexCoord ----------------------------------------*/ + +template class EmptyWedgeTexCoord: public T { +public: + typedef int WedgeTexCoordType; + typedef vcg::TexCoord2 TexCoordType; + TexCoordType &WT(const int) { static TexCoordType dummy_texture; assert(0); return dummy_texture;} + TexCoordType const &cWT(const int) const { static TexCoordType dummy_texture; return dummy_texture;} + template + void ImportLocal(const LeftF & leftF){ T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + static bool HasWedgeTexCoord() { return false; } + static bool HasWedgeTexCoordOcc() { return false; } + static void Name(std::vector & name){T::Name(name);} + +}; +template class WedgeTexCoord: public T { +public: + typedef int WedgeTexCoordType; + typedef A TexCoordType; + TexCoordType &WT(const int i) { return _wt[i]; } + TexCoordType const &cWT(const int i) const { return _wt[i]; } + template + void ImportLocal(const LeftF & leftF){ WT() = leftF.cWT();T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + static bool HasWedgeTexCoord() { return true; } + static void Name(std::vector & name){name.push_back(std::string("WedgeTexCoord"));T::Name(name);} + +private: + TexCoordType _wt[3]; +}; + +template class WedgeTexCoord2s: public WedgeTexCoord, TT> { +public: static void Name(std::vector & name){name.push_back(std::string("WedgeTexCoord2s"));TT::Name(name);} +}; +template class WedgeTexCoord2f: public WedgeTexCoord, TT> { +public: static void Name(std::vector & name){name.push_back(std::string("WedgeTexCoord2f"));TT::Name(name);} +}; +template class WedgeTexCoord2d: public WedgeTexCoord, TT> { +public: static void Name(std::vector & name){name.push_back(std::string("WedgeTexCoord2d"));TT::Name(name);} +}; + +/*------------------------- FLAGS -----------------------------------------*/ +template class EmptyBitFlags: public T { +public: + /// Return the vector of Flags(), senza effettuare controlli sui bit + int &Flags() { static int dummyflags(0); assert(0); return dummyflags; } + const int Flags() const { return 0; } + template + void ImportLocal(const LeftF & leftF){ T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + static bool HasFlags() { return false; } + static bool HasFlagsOcc() { return false; } + static void Name(std::vector & name){T::Name(name);} + +}; + +template class BitFlags: public T { +public: + BitFlags(){_flags=0;} + int &Flags() {return _flags; } + const int Flags() const {return _flags; } + const int & cFlags() const {return _flags; } + template + void ImportLocal(const LeftF & leftF){ Flags() = leftF.cFlags();T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + static bool HasFlags() { return true; } + static void Name(std::vector & name){name.push_back(std::string("BitFlags"));T::Name(name);} + + +private: + int _flags; +}; + +/*-------------------------- COLOR ----------------------------------*/ + +template class EmptyColorMarkQuality: public T { +public: + typedef int MarkType; + inline void InitIMark() { } + inline int & IMark() { assert(0); static int tmp=-1; return tmp;} + inline const int IMark() const {return 0;} + + typedef float QualityType; + typedef vcg::Color4b ColorType; + ColorType &C() { static ColorType dumcolor(vcg::Color4b::White); assert(0); return dumcolor; } + const ColorType &cC() const { static ColorType dumcolor(vcg::Color4b::White); assert(0); return dumcolor; } + ColorType &WC(const int) { static ColorType dumcolor(vcg::Color4b::White); assert(0); return dumcolor; } + QualityType &Q() { static QualityType dummyQuality(0); assert(0); return dummyQuality; } + + static bool HasFaceColor() { return false; } + static bool HasWedgeColor() { return false; } + static bool HasFaceQuality() { return false; } + static bool HasFaceQualityOcf() { return false;} + static bool HasFaceColorOcc() { return false;} + static bool HasMark() { return false; } + static bool HasMarkOcc() { return false; } + + static void Name(std::vector & name){T::Name(name);} + template + void ImportLocal(const LeftF & leftF){ T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + +}; +template class Color: public T { +public: + typedef A ColorType; + Color():_color(vcg::Color4b::White) {} + ColorType &C() { return _color; } + const ColorType &cC() const { return _color; } + template + void ImportLocal(const LeftF & leftF){ C() = leftF.cC();T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + static bool HasFaceColor() { return true; } + static void Name(std::vector & name){name.push_back(std::string("Color"));T::Name(name);} + +private: + ColorType _color; +}; + +template class WedgeColor: public T { +public: + typedef A ColorType; + ColorType &WC(const int i) { return _color[i]; } + const ColorType &WC(const int i) const { return _color[i]; } + + template + void ImportLocal(const LeftF & leftF){ WC() = leftF.cWC();T::ImportLocal(leftF);} + static bool HasFaceColor() { return true; } + static void Name(std::vector & name){name.push_back(std::string("WedgeColor"));T::Name(name);} + +private: + ColorType _color[3]; +}; + +template class Color4b: public Color { + static void Name(std::vector & name){name.push_back(std::string("Color4b"));T::Name(name);} +}; + +/*-------------------------- Quality ----------------------------------*/ + +template class Quality: public T { +public: + typedef A QualityType; + QualityType &Q() { return _quality; } + const QualityType &cQ() const { return _quality; } + template + void ImportLocal(const LeftF & leftF){ Q() = leftF.cQ();T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + static bool HasFaceQuality() { return true; } + static bool HasFaceQualityOcc() { return true; } + static void Name(std::vector & name){name.push_back(std::string("Quality"));T::Name(name);} +private: + QualityType _quality; +}; + +template class Qualitys: public Quality { +public: static void Name(std::vector & name){name.push_back(std::string("Qualitys"));T::Name(name);} +}; +template class Qualityf: public Quality { +public: static void Name(std::vector & name){name.push_back(std::string("Qualityf"));T::Name(name);} +}; +template class Qualityd: public Quality { +public: static void Name(std::vector & name){name.push_back(std::string("Qualityd"));T::Name(name);} +}; +/*-------------------------- INCREMENTAL MARK ----------------------------------------*/ + +template class Mark: public T { +public: + static bool HasMark() { return true; } + static bool HasMarkOcc() { return true; } + inline void InitIMark() { _imark = 0; } + inline int & IMark() { return _imark;} + inline const int & IMark() const {return _imark;} + template + void ImportLocal(const LeftF & leftF){ IMark() = leftF.IMark();T::ImportLocal(leftF);} + static void Name(std::vector & name){name.push_back(std::string("Mark"));T::Name(name);} + + private: + int _imark; +}; + + +/*----------------------------- VFADJ ------------------------------*/ + + +template class EmptyAdj: public T { +public: + typedef int VFAdjType; + typename T::FacePointer &VFp(const int) { static typename T::FacePointer fp=0; assert(0); return fp; } + typename T::FacePointer const cVFp(const int) const { static typename T::FacePointer const fp=0; return fp; } + typename T::FacePointer &FFp(const int) { static typename T::FacePointer fp=0; assert(0); return fp; } + typename T::FacePointer const cFFp(const int) const { static typename T::FacePointer const fp=0; return fp; } + typename T::EdgePointer &FEp(const int) { static typename T::EdgePointer fp=0; assert(0); return fp; } + typename T::EdgePointer const cFEp(const int) const { static typename T::EdgePointer const fp=0; return fp; } + char &VFi(const int j){static char z=0; assert(0); return z;}; + char &FFi(const int j){static char z=0; assert(0); return z;}; + const char &cVFi(const int j){static char z=0; return z;}; + const char &cFFi(const int j){static char z=0; return z;}; + template + void ImportLocal(const LeftF & leftF){ T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + static bool HasVFAdjacency() { return false; } + static bool HasFFAdjacency() { return false; } + static bool HasFEAdjacency() { return false; } + + static bool HasFFAdjacencyOcc() { return false; } + static bool HasVFAdjacencyOcc() { return false; } + static bool HasFEAdjacencyOcc() { return false; } + + static void Name(std::vector & name){T::Name(name);} + +}; + +template class VFAdj: public T { +public: + VFAdj(){ + _vfp[0]=0; + _vfp[1]=0; + _vfp[2]=0; + } + typename T::FacePointer &VFp(const int j) { assert(j>=0 && j<3); return _vfp[j]; } + typename T::FacePointer const VFp(const int j) const { assert(j>=0 && j<3); return _vfp[j]; } + typename T::FacePointer const cVFp(const int j) const { assert(j>=0 && j<3); return _vfp[j]; } + char &VFi(const int j) {return _vfi[j]; } + template + void ImportLocal(const LeftF & leftF){T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + static bool HasVFAdjacency() { return true; } + static bool HasVFAdjacencyOcc() { return false; } + static void Name(std::vector & name){name.push_back(std::string("VFAdj"));T::Name(name);} + +private: + typename T::FacePointer _vfp[3] ; + char _vfi[3] ; +}; + +/*----------------------------- FFADJ ------------------------------*/ + +template class FFAdj: public T { +public: + FFAdj(){ + _ffp[0]=0; + _ffp[1]=0; + _ffp[2]=0; + } + typename T::FacePointer &FFp(const int j) { assert(j>=0 && j<3); return _ffp[j]; } + typename T::FacePointer const FFp(const int j) const { assert(j>=0 && j<3); return _ffp[j]; } + typename T::FacePointer const cFFp(const int j) const { assert(j>=0 && j<3); return _ffp[j]; } + char &FFi(const int j) { return _ffi[j]; } + const char &cFFi(const int j) const { return _ffi[j]; } + + typename T::FacePointer &FFp1( const int j ) { return FFp((j+1)%3);} + typename T::FacePointer &FFp2( const int j ) { return FFp((j+2)%3);} + typename T::FacePointer const FFp1( const int j ) const { return FFp((j+1)%3);} + typename T::FacePointer const FFp2( const int j ) const { return FFp((j+2)%3);} + + template + void ImportLocal(const LeftF & leftF){T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + static bool HasFFAdjacency() { return true; } + static bool HasFFAdjacencyOcc() { return false; } + static void Name(std::vector & name){name.push_back(std::string("FFAdj"));T::Name(name);} + +private: + typename T::FacePointer _ffp[3] ; + char _ffi[3] ; +}; + + +/*----------------------------- FEADJ ------------------------------*/ + +template class FEAdj: public T { +public: + FEAdj(){ + _fep[0]=0; + _fep[1]=0; + _fep[2]=0; + } + typename T::FacePointer &FEp(const int j) { assert(j>=0 && j<3); return _fep[j]; } + typename T::FacePointer const FEp(const int j) const { assert(j>=0 && j<3); return _fep[j]; } + typename T::FacePointer const cFEp(const int j) const { assert(j>=0 && j<3); return _fep[j]; } + char &FEi(const int j) { return _fei[j]; } + const char &cFEi(const int j) const { return _fei[j]; } + + typename T::FacePointer &FEp1( const int j ) { return FEp((j+1)%3);} + typename T::FacePointer &FEp2( const int j ) { return FEp((j+2)%3);} + typename T::FacePointer const FEp1( const int j ) const { return FEp((j+1)%3);} + typename T::FacePointer const FEp2( const int j ) const { return FEp((j+2)%3);} + + template + void ImportLocal(const LeftF & leftF){T::ImportLocal(leftF);} + inline void Alloc(const int & ns){T::Alloc(ns);} + inline void Dealloc(){T::Dealloc();} + static bool HasFEAdjacency() { return true; } + static void Name(std::vector & name){name.push_back(std::string("FEAdj"));T::Name(name);} + +private: + typename T::FacePointer _fep[3] ; + char _fei[3] ; +}; + + } // end namespace face +}// end namespace vcg +#endif diff --git a/vcg/simplex/face/component_occ.h b/vcg/simplex/face/component_occ.h new file mode 100644 index 00000000..4d180772 --- /dev/null +++ b/vcg/simplex/face/component_occ.h @@ -0,0 +1,295 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* 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 * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ +/**************************************************************************** + History + +$Log: not supported by cvs2svn $ +Revision 1.6 2007/03/12 15:37:19 tarini +Texture coord name change! "TCoord" and "Texture" are BAD. "TexCoord" is GOOD. + +Revision 1.5 2007/01/18 01:29:48 cignoni +commented UberP access method (syntax errors) + +Revision 1.4 2006/12/04 10:59:15 ganovelli +aggiunte funzioni di override per Has* + +Revision 1.3 2006/06/08 20:32:10 ganovelli +aggiunte wedge coord + +Revision 1.2 2005/10/18 14:27:22 ganovelli +EdgePLaneType added (_RT) + +Revision 1.1 2005/10/15 16:23:39 ganovelli +Working release (compilata solo su MSVC), component_occ � migrato da component_opt + + +****************************************************************************/ + +/* +Note +OCC = Optional Component Compact +compare with OCF(Optional Component Fast) + +****************************************************************************/ +#ifndef __VCG_FACE_PLUS_COMPONENT_OCC +#define __VCG_FACE_PLUS_COMPONENT_OCC + +#include +#include +#include + + +namespace vcg { + namespace face { + + ///*-------------------------- WedgeTexCoordOcc ----------------------------------------*/ + + template class WedgeTexCoordOcc: public T { + public: + typedef A WedgeTexCoordType; + typedef typename T::FaceType FaceType; + WedgeTexCoordType &WT(const int&i) {return CAT< vector_occ,WedgeTexCoordType>::Instance()->Get((FaceType*)this);} + static bool HasWedgeTexCoord() { return true; } + static bool HasWedgeTexCoordOcc() { return true; } + }; + + template class WedgeTexCoordfOcc: public WedgeTexCoordOcc, T> {}; + + ///*-------------------------- FACEINFO ----------------------------------------*/ + + template class InfoOccBase: public T { + public: + typedef A InfoType; + typedef typename T::FaceType FaceType; + InfoType &N() {return CAT< vector_occ,InfoType>::Instance()->Get((FaceType*)this);} + static bool HasInfo() { return true; } + static bool HasInfoOcc() { return true; } + }; + + template class InfoOcc: public InfoOccBase {}; + +///*-------------------------- NORMAL ----------------------------------------*/ + + template class NormalOcc: public T { + public: + typedef A NormalType; + typedef typename T::FaceType FaceType; + NormalType &N() {return CAT< vector_occ,NormalType>::Instance()->Get((FaceType*)this);} + static bool HasFaceNormal() { return true; } + static bool HasFaceNormalOcc() { return true; } + }; + + template class Normal3sOcc: public NormalOcc {}; + template class Normal3fOcc: public NormalOcc {}; + template class Normal3dOcc: public NormalOcc {}; + +///*-------------------------- MARK ----------------------------------------*/ + + template class MarkOcc: public T { + public: + typedef int MarkType; + typedef typename T::FaceType FaceType; + int &IMark() {return CAT< vector_occ,MarkType>::Instance()->Get((MarkType*)this);} + static bool HasFaceMark() { return true; } + static bool HasFaceMarkOcc() { return true; } + inline void InitIMark() { IMark() = 0; } + }; + +///*-------------------------- COLOR ----------------------------------------*/ + +template class ColorOcc: public T { +public: + typedef A ColorType; + typedef typename T::FaceType FaceType; + ColorType &C() { return CAT< vector_occ,ColorType>::Instance()->Get((FaceType*)this); } + static bool HasFaceColor() { return true; } + static bool HasfaceColorOcc() { return true; } +}; + +template class Color4bOcc: public ColorOcc {}; + +/*----------------------------- VFADJ ---------------------------------------*/ + +// questo tipo serve per tenere tutte le informazioni sull'adiacenza dentro una +// singola classe +template +struct VFAdjTypeSup { + FP _vfp[3]; + char _vfi[3]; + }; + +template class VFAdjOccBase: public T { +public: +// typedef A VFAdjType; + typedef VFAdjTypeSup VFAdjType; + typedef typename T::FaceType FaceType; + typedef typename T::FacePointer FacePointer; + + FacePointer &VFp(const int j) { + return (CAT< vector_occ,VFAdjTypeSup >::Instance()->Get((FaceType*)this))._vfp[j];} + + FacePointer cVFp(const int j) const { + return (CAT< vector_occ,VFAdjTypeSup >::Instance()->Get((FaceType*)this))._vfp[j];} + + char &VFi(const int j) { return (CAT< vector_occ,VFAdjTypeSup >::Instance()->Get((FaceType*)this))._vfi[j];} + + static bool HasVFAdjacency() { return true; } + static bool HasVFAdjacencyOcc() { return true; } +}; + +template class VFAdjOcc : public VFAdjOccBase,T>{}; + +/*----------------------------- FFADJ -----------------------------------*/ + +// questo tipo serve per tenere tutte le informazioni sull'adiacenza dentro una +// singola classe +template +struct FFAdjTypeSup { + FP _ffp[3]; + char _ffi[3]; + }; + +template class FFAdjOccBase: public T { +public: + +// typedef A FFAdjType; + typedef FFAdjTypeSup FFAdjType; + typedef typename T::FaceType FaceType; + typedef typename T::FacePointer FacePointer; + + FacePointer &FFp(const int j) { + return (CAT< vector_occ,FFAdjTypeSup >::Instance()->Get((FaceType*)this))._ffp[j];} + + FacePointer const FFp(const int j) const { + return (CAT< vector_occ,FFAdjTypeSup >::Instance()->Get((FaceType*)this))._ffp[j];} + + FacePointer const cFFp(const int j) const { + return (CAT< vector_occ,FFAdjTypeSup >::Instance()->Get((FaceType*)this))._ffp[j];} + + char &FFi(const int j) { + return (CAT< vector_occ,FFAdjTypeSup >::Instance()->Get((FaceType*)this))._ffi[j];} + + char cFFi(const int j) const{ + return (CAT< vector_occ,FFAdjTypeSup >::Instance()->Get((FaceType*)this ))._ffi[j]; + } + + static bool HasFFAdjacency() { return true; } + static bool HasFFAdjacencyOcc() { return true; } + +}; + +template class FFAdjOcc : public FFAdjOccBase,T>{}; + +template class VertexRefOcc: public T { +public: + + typedef typename T::VertexType VertexType; + typedef typename T::FaceType FaceType; + typedef typename T::CoordType CoordType; + + inline typename T::VertexType * & V( const int j ) { assert(j>=0 && j<3); + return (CAT< vector_occ,VertexRef >::Instance()->Get((FaceType*)this)).V(j); } + + inline typename T::VertexType * const & V( const int j ) const { assert(j>=0 && j<3); + return (CAT< vector_occ,VertexRef >::Instance()->Get((FaceType*)this)).V(j); } + + inline typename T::VertexType * const cV( const int j ) const { assert(j>=0 && j<3); + return (CAT< vector_occ,VertexRef >::Instance()->Get((FaceType*)this)).V(j); } + + // Shortcut per accedere ai punti delle facce + inline typename T::CoordType & P( const int j ) { assert(j>=0 && j<3); return V(j)->P(); } + inline const typename T::CoordType & P( const int j ) const { assert(j>=0 && j<3); return V(j)->cP(); } + inline const typename T::CoordType &cP( const int j ) const { assert(j>=0 && j<3); return V(j)->cP(); } + + /** Return the pointer to the ((j+1)%3)-th vertex of the face. + @param j Index of the face vertex. + */ + inline VertexType * & V0( const int j ) { return V(j);} + inline VertexType * & V1( const int j ) { return V((j+1)%3);} + inline VertexType * & V2( const int j ) { return V((j+2)%3);} + inline const VertexType * const & V0( const int j ) const { return V(j);} + inline const VertexType * const & V1( const int j ) const { return V((j+1)%3);} + inline const VertexType * const & V2( const int j ) const { return V((j+2)%3);} + inline const VertexType * const & cV0( const int j ) const { return cV(j);} + inline const VertexType * const & cV1( const int j ) const { return cV((j+1)%3);} + inline const VertexType * const & cV2( const int j ) const { return cV((j+2)%3);} + + /// Shortcut per accedere ai punti delle facce + inline CoordType & P0( const int j ) { return V(j)->P();} + inline CoordType & P1( const int j ) { return V((j+1)%3)->P();} + inline CoordType & P2( const int j ) { return V((j+2)%3)->P();} + inline const CoordType & P0( const int j ) const { return V(j)->P();} + inline const CoordType & P1( const int j ) const { return V((j+1)%3)->P();} + inline const CoordType & P2( const int j ) const { return V((j+2)%3)->P();} + inline const CoordType & cP0( const int j ) const { return cV(j)->P();} + inline const CoordType & cP1( const int j ) const { return cV((j+1)%3)->P();} + inline const CoordType & cP2( const int j ) const { return cV((j+2)%3)->P();} + + //inline typename T::VertexType * & UberV( const int j ) { assert(j>=0 && j<3); return v[j]; } + //inline const typename T::VertexType * const & UberV( const int j ) const { assert(j>=0 && j<3); return v[j]; } + static bool HasVertexRef() { return true; } +}; + } // end namespace face + + template < class, class, class > class TriMesh; + + namespace tri + { +/* template < class VertContainerType, class FaceType > + bool HasVFAdjacency (const TriMesh < VertContainerType , vector_occ< FaceType > > & m) + { + if( FaceType::HasVFAdjacencyOcc()) return m.face.IsEnabledAttribute< typename FaceType::VFAdjType >(); + else return FaceType::HasVFAdjacency(); + } + + template < class VertContainerType, class FaceType > + bool HasFFAdjacency (const TriMesh < VertContainerType , vector_occ< FaceType > > & m) + { + if(FaceType::HasFFAdjacencyOcc()) return m.face.IsEnabledAttribute(); + else return FaceType::HasFFAdjacency(); + } + + template < class VertContainerType, class FaceType > + bool HasPerWedgeTexCoord (const TriMesh < VertContainerType , vector_occ< FaceType > > & m) + { + if(FaceType::HasWedgeTexCoordOcc()) return m.face.IsEnabledAttribute(); + else return FaceType::HasWedgeTexCoord(); + } + + template < class VertContainerType, class FaceType > + bool HasPerFaceColor (const TriMesh < VertContainerType , vector_occ< FaceType > > & m) + { + if(FaceType::HasFaceColorOcc()) return m.face.IsEnabledAttribute(); + else return FaceType::HasFaceColor(); + } + + template < class VertContainerType, class FaceType > + bool HasPerFaceMark (const TriMesh < VertContainerType , vector_occ< FaceType > > & m) + { + if(FaceType::HasFaceMarkOcc()) return m.face.IsEnabledAttribute(); + else return FaceType::HasFaceMark(); + } +*/ + }; // end namesace tri +}// end namespace vcg +#endif diff --git a/vcg/simplex/face/component_ocf.h b/vcg/simplex/face/component_ocf.h new file mode 100644 index 00000000..b969931d --- /dev/null +++ b/vcg/simplex/face/component_ocf.h @@ -0,0 +1,685 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* 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 * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ +/**************************************************************************** + History + +$Log: not supported by cvs2svn $ +Revision 1.25 2008/03/11 09:22:07 cignoni +Completed the garbage collecting functions CompactVertexVector and CompactFaceVector. + +Revision 1.24 2008/02/28 15:41:17 cignoni +Added FFpi methods and better init of texture coords + +Revision 1.23 2008/02/05 10:11:34 cignoni +A small typo (a T:: instead of TT::) + +Revision 1.22 2008/02/04 21:26:45 ganovelli +added ImportLocal which imports all local attributes into vertexplus and faceplus. +A local attribute is everything (N(), C(), Q()....) except pointers to other simplices +(i.e. FFAdj, VFAdj, VertexRef) which are set to NULL. +Added some function for const attributes + +Revision 1.21 2007/10/09 12:03:13 corsini +remove signed/unsigned warning + +Revision 1.20 2007/03/12 15:37:19 tarini +Texture coord name change! "TCoord" and "Texture" are BAD. "TexCoord" is GOOD. + +Revision 1.19 2006/11/28 22:34:28 cignoni +Added default constructor with null initialization to adjacency members. +AddFaces and AddVertices NEED to know if the topology is correctly computed to update it. + +Revision 1.18 2006/11/07 11:29:24 cignoni +Corrected some errors in the reflections Has*** functions + +Revision 1.17 2006/10/31 16:02:18 ganovelli +vesione 2005 compliant + +Revision 1.16 2006/10/27 14:15:10 ganovelli +added overrides to HasFFAddAdjacency and HasVFAddAdjacency + +Revision 1.15 2006/10/16 08:49:29 cignoni +Better managment of resize overloading when reducing the size of a vector + +Revision 1.14 2006/10/09 20:20:55 cignoni +Added some missing Add***Ocf() for the default case. + +Revision 1.13 2006/05/25 09:39:09 cignoni +missing std and other gcc detected syntax errors + +Revision 1.12 2006/05/03 21:37:02 cignoni +Added Optional Mark + +Revision 1.11 2006/02/28 11:59:39 ponchio +g++ compliance: + +begin() -> (*this).begin() and for end(), size(), Base(), Index() + +Revision 1.10 2006/01/30 08:47:40 cignoni +Corrected HasPerWedgeTexture + +Revision 1.9 2006/01/05 15:46:06 cignoni +Removed a syntax error (double >) in HasPerWedgeTexture/HasPerFaceColor + +Revision 1.8 2006/01/04 18:46:25 cignoni +Corrected push_back (did not worked at all!) +added missing cFFi + +Revision 1.7 2006/01/03 10:54:21 cignoni +Corrected HasPerFaceColor and HasPerWedgeTexture to comply gcc + +Revision 1.6 2005/12/12 11:17:32 cignoni +Corrected update function, now only the needed simplexes should be updated. + +Revision 1.5 2005/11/26 00:16:44 cignoni +Corrected a lot of bugs about the use of enabled entities + +Revision 1.4 2005/11/21 21:46:20 cignoni +Changed HasColor -> HasFaceColor and HasNormal ->HasFaceNormal + +Revision 1.3 2005/11/16 22:43:36 cignoni +Added WedgeTexture component + +Revision 1.2 2005/10/22 13:16:46 cignoni +Added a missing ';' in FFAdjOcf (thanks to Mario Latronico). + +Revision 1.1 2005/10/14 15:07:58 cignoni +First Really Working version + + +****************************************************************************/ + +/* +Note +OCF = Optional Component Fast (hopefully) +compare with OCC(Optional Component Compact) + +Mainly the trick here is to store a base pointer in each simplex... + +****************************************************************************/ +#ifndef __VCG_FACE_PLUS_COMPONENT_OCF +#define __VCG_FACE_PLUS_COMPONENT_OCF + +#include +#include +#include + + +namespace vcg { + namespace face { +/* +All the Components that can be added to a faceex should be defined in the namespace face: + +*/ + +template +class vector_ocf: public std::vector { + typedef std::vector BaseType; + typedef typename vector_ocf::iterator ThisTypeIterator; + +public: + vector_ocf():std::vector(){ + ColorEnabled=false; + QualityEnabled=false; + MarkEnabled=false; + NormalEnabled=false; + WedgeTexEnabled=false; + VFAdjacencyEnabled=false; + FFAdjacencyEnabled=false; + } + +// Auxiliary types to build internal vectors +struct AdjTypePack { + typename VALUE_TYPE::FacePointer _fp[3] ; + char _zp[3] ; + + // Default constructor. + // Needed because we need to know if adjacency is initialized or not + // when resizing vectors and during an allocate face. + AdjTypePack() { + _fp[0]=0; + _fp[1]=0; + _fp[2]=0; + } + }; + +//template +class WedgeTexTypePack { +public: + WedgeTexTypePack() { + wt[0].U()=.5;wt[0].V()=.5; + wt[1].U()=.5;wt[1].V()=.5; + wt[2].U()=.5;wt[2].V()=.5; + wt[0].N()=-1; + wt[1].N()=-1; + wt[2].N()=-1; + } + + typename VALUE_TYPE::TexCoordType wt[3]; +}; + + + + + // override di tutte le funzioni che possono spostare + // l'allocazione in memoria del container + void push_back(const VALUE_TYPE & v) + { + BaseType::push_back(v); + BaseType::back()._ovp = this; + if (QualityEnabled) QV.push_back(0); + if (ColorEnabled) CV.push_back(vcg::Color4b(vcg::Color4b::White)); + if (MarkEnabled) MV.push_back(0); + if (NormalEnabled) NV.push_back(typename VALUE_TYPE::NormalType()); + if (VFAdjacencyEnabled) AV.push_back(AdjTypePack()); + if (FFAdjacencyEnabled) AF.push_back(AdjTypePack()); + if (WedgeTexEnabled) WTV.push_back(WedgeTexTypePack()); + } + void pop_back(); + void resize(const unsigned int & _size) + { + unsigned int oldsize = BaseType::size(); + BaseType::resize(_size); + if(oldsize<_size){ + ThisTypeIterator firstnew = BaseType::begin(); + advance(firstnew,oldsize); + _updateOVP(firstnew,(*this).end()); + } + if (QualityEnabled) QV.resize(_size); + if (ColorEnabled) CV.resize(_size); + if (MarkEnabled) MV.resize(_size); + if (NormalEnabled) NV.resize(_size); + if (VFAdjacencyEnabled) AV.resize(_size); + if (FFAdjacencyEnabled) AF.resize(_size); + if (WedgeTexEnabled) WTV.resize(_size,WedgeTexTypePack()); + + } + void reserve(const unsigned int & _size) + { + ThisTypeIterator oldbegin=(*this).begin(); + BaseType::reserve(_size); + + if (QualityEnabled) QV.reserve(_size); + if (ColorEnabled) CV.reserve(_size); + if (MarkEnabled) MV.reserve(_size); + if (NormalEnabled) NV.reserve(_size); + if (VFAdjacencyEnabled) AV.reserve(_size); + if (FFAdjacencyEnabled) AF.reserve(_size); + if (WedgeTexEnabled) WTV.reserve(_size); + + if(oldbegin!=(*this).begin()) _updateOVP((*this).begin(),(*this).end()); + } + + void _updateOVP(ThisTypeIterator lbegin, ThisTypeIterator lend) +{ + ThisTypeIterator fi; + //for(fi=(*this).begin();vi!=(*this).end();++vi) + for(fi=lbegin;fi!=lend;++fi) + (*fi)._ovp=this; + } + + + +// this function is called by the specialized Reorder function, that is called whenever someone call the allocator::CompactVertVector +void ReorderFace(std::vector &newFaceIndex ) +{ + size_t i=0; + if (QualityEnabled) assert( QV.size() == newFaceIndex.size() ); + if (ColorEnabled) assert( CV.size() == newFaceIndex.size() ); + if (MarkEnabled) assert( MV.size() == newFaceIndex.size() ); + if (NormalEnabled) assert( NV.size() == newFaceIndex.size() ); + if (VFAdjacencyEnabled)assert( AV.size() == newFaceIndex.size() ); + if (FFAdjacencyEnabled)assert( AF.size() == newFaceIndex.size() ); + if (WedgeTexEnabled) assert(WTV.size() == newFaceIndex.size() ); + + for(i=0;i::max() ) + { + assert(newFaceIndex[i] <= i); + if (QualityEnabled) QV[newFaceIndex[i]] = QV[i]; + if (ColorEnabled) CV[newFaceIndex[i]] = CV[i]; + if (MarkEnabled) MV[newFaceIndex[i]] = MV[i]; + if (NormalEnabled) NV[newFaceIndex[i]] = NV[i]; + if (VFAdjacencyEnabled) AV[newFaceIndex[i]] = AV[i]; + if (FFAdjacencyEnabled) AF[newFaceIndex[i]] = AF[i]; + if (WedgeTexEnabled) WTV[newFaceIndex[i]] = WTV[i]; + } + } + + if (QualityEnabled) QV.resize(BaseType::size()); + if (ColorEnabled) CV.resize(BaseType::size()); + if (MarkEnabled) MV.resize(BaseType::size()); + if (NormalEnabled) NV.resize(BaseType::size()); + if (VFAdjacencyEnabled) AV.resize(BaseType::size()); + if (FFAdjacencyEnabled) AF.resize(BaseType::size()); + if (WedgeTexEnabled) WTV.resize(BaseType::size()); +} + +//////////////////////////////////////// +// Enabling Functions + +bool IsQualityEnabled() const {return QualityEnabled;} +void EnableQuality() { + assert(VALUE_TYPE::HasFaceQualityOcf()); + QualityEnabled=true; + QV.resize((*this).size()); +} + +void DisableQuality() { + assert(VALUE_TYPE::HasFaceQualityOcf()); + QualityEnabled=false; + QV.clear(); +} + +bool IsColorEnabled() const {return ColorEnabled;} +void EnableColor() { + assert(VALUE_TYPE::HasFaceColorOcf()); + ColorEnabled=true; + CV.resize((*this).size()); +} + +void DisableColor() { + assert(VALUE_TYPE::HasFaceColorOcf()); + ColorEnabled=false; + CV.clear(); +} + +bool IsMarkEnabled() const {return MarkEnabled;} +void EnableMark() { + assert(VALUE_TYPE::HasFaceMarkOcf()); + MarkEnabled=true; + MV.resize((*this).size()); +} + +void DisableMark() { + assert(VALUE_TYPE::HasFaceMarkOcf()); + MarkEnabled=false; + MV.clear(); +} + +bool IsNormalEnabled() const {return NormalEnabled;} +void EnableNormal() { + assert(VALUE_TYPE::HasFaceNormalOcf()); + NormalEnabled=true; + NV.resize((*this).size()); +} + +void DisableNormal() { + assert(VALUE_TYPE::HasFaceNormalOcf()); + NormalEnabled=false; + NV.clear(); +} + +bool IsVFAdjacencyEnabled() const {return VFAdjacencyEnabled;} +void EnableVFAdjacency() { + assert(VALUE_TYPE::HasVFAdjacencyOcf()); + VFAdjacencyEnabled=true; + AV.resize((*this).size()); +} + +void DisableVFAdjacency() { + assert(VALUE_TYPE::HasVFAdjacencyOcf()); + VFAdjacencyEnabled=false; + AV.clear(); +} + + +bool IsFFAdjacencyEnabled() const {return FFAdjacencyEnabled;} +void EnableFFAdjacency() { + assert(VALUE_TYPE::HasFFAdjacencyOcf()); + FFAdjacencyEnabled=true; + AF.resize((*this).size()); +} + +void DisableFFAdjacency() { + assert(VALUE_TYPE::HasFFAdjacencyOcf()); + FFAdjacencyEnabled=false; + AF.clear(); +} + +bool IsWedgeTexEnabled() const {return WedgeTexEnabled;} +void EnableWedgeTex() { + assert(VALUE_TYPE::HasWedgeTexCoordOcf()); + WedgeTexEnabled=true; + WTV.resize((*this).size(),WedgeTexTypePack()); +} + +void DisableWedgeTex() { + assert(VALUE_TYPE::HasWedgeTexCoordOcf()); + WedgeTexEnabled=false; + WTV.clear(); +} + +public: + std::vector QV; + std::vector CV; + std::vector MV; + std::vector NV; + std::vector AV; + std::vector AF; + std::vector WTV; + + bool QualityEnabled; + bool ColorEnabled; + bool MarkEnabled; + bool NormalEnabled; + bool WedgeTexEnabled; + bool VFAdjacencyEnabled; + bool FFAdjacencyEnabled; +}; // end class vector_ocf + + +//template<> void EnableAttribute(){ NormalEnabled=true;} + +/*------------------------- COORD -----------------------------------------*/ +/*----------------------------- VFADJ ------------------------------*/ + + +template class VFAdjOcf: public T { +public: + typename T::FacePointer &VFp(const int j) { + assert((*this).Base().VFAdjacencyEnabled); + return (*this).Base().AV[(*this).Index()]._fp[j]; + } + + typename T::FacePointer cVFp(const int j) const { + if(! (*this).Base().VFAdjacencyEnabled ) return 0; + else return (*this).Base().AV[(*this).Index()]._fp[j]; + } + + char &VFi(const int j) { + assert((*this).Base().VFAdjacencyEnabled); + return (*this).Base().AV[(*this).Index()]._zp[j]; + } + + template + void ImportLocal(const LeftF & leftF){ + if(leftF.Base().VFAdjacencyEnabled && this->Base().VFAdjacencyEnabled){ + VFp(0) = NULL; VFp(1) = NULL; VFp(2) = NULL; + VFi(0) = -1; VFi(1) = -1; VFi(2) = -1; + } + T::ImportLocal(leftF); + } + static bool HasVFAdjacency() { return true; } + static bool HasVFAdjacencyOcf() { return true; } + +private: +}; +/*----------------------------- FFADJ ------------------------------*/ + + +template class FFAdjOcf: public T { +public: + typename T::FacePointer &FFp(const int j) { + assert((*this).Base().FFAdjacencyEnabled); + return (*this).Base().AF[(*this).Index()]._fp[j]; + } + + typename T::FacePointer const FFp(const int j) const { return cFFp(j);} + typename T::FacePointer const cFFp(const int j) const { + if(! (*this).Base().FFAdjacencyEnabled ) return 0; + else return (*this).Base().AF[(*this).Index()]._fp[j]; + } + + char &FFi(const int j) { + assert((*this).Base().FFAdjacencyEnabled); + return (*this).Base().AF[(*this).Index()]._zp[j]; + } + const char cFFi(const int j) const { + assert((*this).Base().FFAdjacencyEnabled); + return (*this).Base().AF[(*this).Index()]._zp[j]; + } + + typename T::FacePointer &FFp1( const int j ) { return FFp((j+1)%3);} + typename T::FacePointer &FFp2( const int j ) { return FFp((j+2)%3);} + typename T::FacePointer const FFp1( const int j ) const { return FFp((j+1)%3);} + typename T::FacePointer const FFp2( const int j ) const { return FFp((j+2)%3);} + + template + void ImportLocal(const LeftF & leftF){ + if(leftF.Base().FFAdjacencyEnabled && this->Base().FFAdjacencyEnabled) { + FFp(0) = NULL; FFp(1) = NULL; FFp(2) = NULL; + FFi(0) = -1; FFi(1) = -1; FFi(2) = -1; + } + T::ImportLocal(leftF); + } + static bool HasFFAdjacency() { return true; } + static bool HasFFAdjacencyOcf() { return true; } + +private: +}; + +/*------------------------- Normal -----------------------------------------*/ + +template class NormalOcf: public T { +public: + typedef A NormalType; + static bool HasFaceNormal() { return true; } + static bool HasFaceNormalOcf() { return true; } + + NormalType &N() { + // you cannot use Normals before enabling them with: yourmesh.face.EnableNormal() + assert((*this).Base().NormalEnabled); + return (*this).Base().NV[(*this).Index()]; } + const NormalType &cN() const { + // you cannot use Normals before enabling them with: yourmesh.face.EnableNormal() + assert((*this).Base().NormalEnabled); + return (*this).Base().NV[(*this).Index()]; } + + template + void ImportLocal(const LeftF & leftF){ + if((*this).Base().NormalEnabled && leftF.Base().NormalEnabled) + N() = leftF.cN(); + T::ImportLocal(leftF); + } + +}; + +template class Normal3sOcf: public NormalOcf {}; +template class Normal3fOcf: public NormalOcf {}; +template class Normal3dOcf: public NormalOcf {}; + +///*-------------------------- QUALITY ----------------------------------*/ + +template class QualityOcf: public T { +public: + typedef A QualityType; + QualityType &Q() { + assert((*this).Base().QualityEnabled); + return (*this).Base().QV[(*this).Index()]; + } + const QualityType Q() const { + assert((*this).Base().QualityEnabled); + return (*this).Base().QV[(*this).Index()]; + } + + template + void ImportLocal(const LeftF & leftF){ + if((*this).Base().QualityEnabled && leftF.Base().QualityEnabled) + Q() = leftF.Q(); + T::ImportLocal(leftF); + } + static bool HasFaceQuality() { return true; } + static bool HasFaceQualityOcf() { return true; } +}; + +template class QualityfOcf: public QualityOcf {}; + +///*-------------------------- COLOR ----------------------------------*/ + +template class ColorOcf: public T { +public: + typedef A ColorType; + ColorType &C() { + assert((*this).Base().ColorEnabled); + return (*this).Base().CV[(*this).Index()]; + } + const ColorType C() const { + assert((*this).Base().ColorEnabled); + return (*this).Base().CV[(*this).Index()]; + } + + template + void ImportLocal(const LeftF & leftF){ + if((*this).Base().ColorEnabled && leftF.Base().ColorEnabled) + C() = leftF.C(); + T::ImportLocal(leftF); + } + static bool HasFaceColor() { return true; } + static bool HasFaceColorOcf() { return true; } +}; + +template class Color4bOcf: public ColorOcf {}; + +///*-------------------------- MARK ----------------------------------*/ + +template class MarkOcf: public T { +public: + inline int & IMark() { + assert((*this).Base().MarkEnabled); + return (*this).Base().MV[(*this).Index()]; + } + + inline int IMark() const { + assert((*this).Base().MarkEnabled); + return (*this).Base().MV[(*this).Index()]; + } ; + + template + void ImportLocal(const LeftF & leftF){ + if((*this).Base().MarkEnabled && leftF.Base().MarkEnabled) + IMark() = leftF.IMark(); + T::ImportLocal(leftF); + } + static bool HasFaceMark() { return true; } + static bool HasFaceMarkOcf() { return true; } + inline void InitIMark() { IMark() = 0; } +}; + +///*-------------------------- WEDGE TEXCOORD ----------------------------------*/ + +template class WedgeTexCoordOcf: public TT { +public: + WedgeTexCoordOcf(){ } + typedef A TexCoordType; + TexCoordType &WT(const int i) { assert((*this).Base().WedgeTexEnabled); return (*this).Base().WTV[(*this).Index()].wt[i]; } + TexCoordType const &cWT(const int i) const { assert((*this).Base().WedgeTexEnabled); return (*this).Base().WTV[(*this).Index()].wt[i]; } + template + void ImportLocal(const LeftF & leftF){ + if(this->Base().WedgeTexEnabled && leftF.Base().WedgeTexEnabled) + { WT(0) = leftF.cWT(0); WT(1) = leftF.cWT(1); WT(2) = leftF.cWT(2); } + TT::ImportLocal(leftF); + } + static bool HasWedgeTexCoord() { return true; } + static bool HasWedgeTexCoordOcf() { return true; } +}; + +template class WedgeTexCoordfOcf: public WedgeTexCoordOcf, T> {}; + +///*-------------------------- InfoOpt ----------------------------------*/ + +template < class T> class InfoOcf: public T { +public: + vector_ocf &Base() const { return *_ovp;} + + template + void ImportLocal(const LeftF & leftF){T::ImportLocal(leftF);} + + static bool HasFaceColorOcf() { return false; } + static bool HasFaceNormalOcf() { return false; } + static bool HasFaceMarkOcf() { return false; } + static bool HasWedgeTexCoordOcf() { return false; } + static bool HasFFAdjacencyOcf() { return false; } + static bool HasVFAdjacencyOcf() { return false; } + //static bool HasFaceQualityOcf() { return false; } + + inline int Index() const { + typename T::FaceType const *tp=static_cast(this); + int tt2=tp- &*(_ovp->begin()); + return tt2; + } +public: + // ovp Optional Vector Pointer + // Pointer to the base vector where each face element is stored. + // used to access to the vectors of the other optional members. + vector_ocf *_ovp; +}; + + } // end namespace face + + template < class, class,class > class TriMesh; + + namespace tri + { + template < class VertContainerType, class FaceType, class EdgeContainerType > + bool HasVFAdjacency (const TriMesh < VertContainerType , face::vector_ocf< FaceType >, EdgeContainerType > & m) + { + if(FaceType::HasVFAdjacencyOcf()) return m.face.IsVFAdjacencyEnabled(); + else return FaceType::FaceType::HasVFAdjacency(); + } + + template < class VertContainerType, class FaceType, class EdgeContainerType> + bool HasFFAdjacency (const TriMesh < VertContainerType , face::vector_ocf< FaceType >, EdgeContainerType > & m) + { + if(FaceType::HasFFAdjacencyOcf()) return m.face.IsFFAdjacencyEnabled(); + else return FaceType::FaceType::HasFFAdjacency(); + } + + template < class VertContainerType, class FaceType, class EdgeContainerType > + bool HasPerWedgeTexCoord (const TriMesh < VertContainerType , face::vector_ocf< FaceType >, EdgeContainerType > & m) + { + if(FaceType::HasWedgeTexCoordOcf()) return m.face.IsWedgeTexEnabled(); + else return FaceType::HasWedgeTexCoord(); + } + + template < class VertContainerType, class FaceType, class EdgeContainerType > + bool HasPerFaceColor (const TriMesh < VertContainerType , face::vector_ocf< FaceType >, EdgeContainerType > & m) + { + if(FaceType::HasFaceColorOcf()) return m.face.IsColorEnabled(); + else return FaceType::HasFaceColor(); + } + + template < class VertContainerType, class FaceType, class EdgeContainerType > + bool HasPerFaceQuality (const TriMesh < VertContainerType , face::vector_ocf< FaceType >, EdgeContainerType > & m) + { + if(FaceType::HasFaceQualityOcf()) return m.face.IsQualityEnabled(); + else return FaceType::HasFaceQuality(); + } + + template < class VertContainerType, class FaceType, class EdgeContainerType > + bool HasPerFaceMark (const TriMesh < VertContainerType , face::vector_ocf< FaceType >, EdgeContainerType > & m) + { + if(FaceType::HasFaceMarkOcf()) return m.face.IsMarkEnabled(); + else return FaceType::HasFaceMark(); + } + + template < class FaceType > + void ReorderFace( std::vector &newFaceIndex, face::vector_ocf< FaceType > &faceVec) + { + faceVec.ReorderFace(newFaceIndex); + } + + } +}// end namespace vcg +#endif diff --git a/vcg/simplex/face/component_polygon.h b/vcg/simplex/face/component_polygon.h new file mode 100644 index 00000000..297c1ad4 --- /dev/null +++ b/vcg/simplex/face/component_polygon.h @@ -0,0 +1,315 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* 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 * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ + +#ifndef __VCG_POLYGON_COMPONENT +#define __VCG_POLYGON_COMPONENT + +//#include +//#include +//#include +//#include + +namespace vcg { + namespace face { +/* +Some naming Rules +All the Components that can be added to a vertex should be defined in the namespace vert: + +*/ + +/*-------------------------- PolInfo -------------------------------------------*/ +template class EmptyPolyInfo: public T { +protected: + inline void SetVN(const int & n) {assert(0);} +public: + /* Note: the destructor will not be called in general because there are no virtual destructors. + Instead, the job of deallocating the memory will be done bu the edge allocator. + This destructor is only done for those who istance a face alone (outside a mesh) + */ + static bool HasPolyInfo() { return false; } + inline void Alloc(const int & ns){T::Alloc(ns);};// it should be useless + inline void Dealloc(){T::Dealloc();};// it should be useless +}; + + +template class PolyInfo: public T { +protected: + inline void SetVN(const int & n) {_ns = n;} +public: + PolyInfo(){ _ns = -1; } + /* Note: the destructor will not be called in general because there are no virtual destructors. + Instead, the job of deallocating the memory will be done bu the face allocator. + This destructor is only done for those who istance a face alone (outside a mesh) + */ + static bool HasPolyInfo() { return true; } + inline const int & VN() const { return _ns;} + inline int Prev(const int & i){ return (i+(VN()-1))%VN();} + inline int Next(const int & i){ return (i+1)%VN();} + inline void Alloc(const int & ns){}; + inline void Dealloc(){}; +private: + int _ns; +}; + +/*-------------------------- VERTEX ----------------------------------------*/ +template class PEmptyFVAdj: public T { +public: + typedef typename T::VertexType VertexType; + // typedef typename T::CoordType CoordType; + inline typename T::VertexType * & V( const int j ) { assert(0); static typename T::VertexType *vp=0; return vp; } + inline typename T::VertexType * const & V( const int j ) const { assert(0); static typename T::VertexType *vp=0; return vp; } + inline typename T::VertexType * const cV( const int j ) const { assert(0); static typename T::VertexType *vp=0; return vp; } + inline typename T::CoordType & P( const int j ) { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; } + inline const typename T::CoordType & P( const int j ) const { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; } + inline const typename T::CoordType &cP( const int j ) const { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; } + template + void ImportLocal(const LeftF & leftF) {T::ImportLocal(leftF);} + static bool HasFVAdjN() { return false; } + static void Name(std::vector & name){T::Name(name);} + inline void Alloc(const int & ns){T::Alloc();}; + inline void Dealloc(){T::Dealloc();} + +}; +template class PFVAdj: public T { +public: + PFVAdj(){_vpoly = NULL;} + inline typename T::VertexType * & V( const int j ) { assert(j>=0 && jVN()); return _vpoly[j]; } + inline typename T::VertexType * const & V( const int j ) const { assert(j>=0 && jVN()); return _vpoly[j]; } + inline typename T::VertexType * const cV( const int j ) const { assert(j>=0 && jVN()); return _vpoly[j]; } + + + /** Return the pointer to the ((j+1)%3)-th vertex of the face. + @param j Index of the face vertex. + */ + inline typename T::VertexType * & V0( const int j ) { return V(j);} + inline typename T::VertexType * & V1( const int j ) { return V((j+1)%this->VN());} + inline typename T::VertexType * & V2( const int j ) { return V((j+2)%this->VN());} + inline const typename T::VertexType * const & V0( const int j ) const { return V(j);} + inline const typename T::VertexType * const & V1( const int j ) const { return V((j+1)%this->VN());} + inline const typename T::VertexType * const & V2( const int j ) const { return V((j+2)%this->VN());} + inline const typename T::VertexType * const & cV0( const int j ) const { return cV(j);} + inline const typename T::VertexType * const & cV1( const int j ) const { return cV((j+1)%this->VN());} + inline const typename T::VertexType * const & cV2( const int j ) const { return cV((j+2)%this->VN());} + + // Shortcut per accedere ai punti delle facce + inline typename T::CoordType & P( const int j ) { assert(j>=0 && jVN()); return _vpoly[j]->P(); } + inline const typename T::CoordType & P( const int j ) const { assert(j>=0 && jVN()); return _vpoly[j]->cP(); } + inline const typename T::CoordType &cP( const int j ) const { assert(j>=0 && jVN()); return _vpoly[j]->cP(); } + + /// Shortcut per accedere ai punti delle facce + inline typename T::CoordType & P0( const int j ) { return V(j)->P();} + inline typename T::CoordType & P1( const int j ) { return V((j+1)%this->VN())->P();} + inline typename T::CoordType & P2( const int j ) { return V((j+2)%this->VN())->P();} + inline const typename T::CoordType & P0( const int j ) const { return V(j)->P();} + inline const typename T::CoordType & P1( const int j ) const { return V((j+1)%this->VN())->P();} + inline const typename T::CoordType & P2( const int j ) const { return V((j+2)%this->VN())->P();} + inline const typename T::CoordType & cP0( const int j ) const { return cV(j)->P();} + inline const typename T::CoordType & cP1( const int j ) const { return cV((j+1)%this->VN())->P();} + inline const typename T::CoordType & cP2( const int j ) const { return cV((j+2)%this->VN())->P();} + + template + void ImportLocal(const LeftF & leftF){ for(int i =0; i < this->VN(); ++i) V(i) = NULL; T::ImportLocal(leftF);} + inline void Alloc(const int & ns) { + if(_vpoly == NULL){this->SetVN(ns); + _vpoly = new typename T::VertexType*[this->VN()]; + for(int i = 0; i < this->VN(); ++i) _vpoly[i] = 0; + } + T::Alloc(ns); + } + inline void Dealloc() { if(_vpoly!=NULL){ + delete [] _vpoly; + _vpoly = NULL; + } + T::Dealloc(); + } + + static bool HasFVAdjacency() { return true; } + static void Name(std::vector & name){name.push_back(std::string("PFVAdj"));T::Name(name);} + + private: + typename T::VertPointer *_vpoly; +}; + +/*----------------------------- PVFADJ ------------------------------*/ +template class EmptyPVFAdj: public T { +public: + typedef typename T::VertexType VertexType; + typedef int VFAdjType; + typename T::FacePointer &VFp(const int) { static typename T::FacePointer fp=0; assert(0); return fp; } + typename T::FacePointer const cVFp(const int) const { static typename T::FacePointer const fp=0; return fp; } + typename T::FacePointer &FFp(const int) { static typename T::FacePointer fp=0; assert(0); return fp; } + typename T::FacePointer const cFFp(const int) const { static typename T::FacePointer const fp=0; return fp; } + char &VFi(const int j){static char z=0; assert(0); return z;}; + char &FFi(const int j){static char z=0; assert(0); return z;}; + const char &cVFi(const int j){static char z=0; return z;}; + const char &cFFi(const int j){static char z=0; return z;}; + template + void ImportLocal(const LeftF & leftF){ T::ImportLocal(leftF);} + void Alloc(const int & ns){T::Alloc(ns);} + void Dealloc(){T::Dealloc();} + static bool HasVFAdjacency() { return false; } + static bool HasFFAdjacency() { return false; } + static bool HasFFAdjacencyOcc() { return false; } + static bool HasVFAdjacencyOcc() { return false; } + static void Name(std::vector & name){T::Name(name);} + +}; + +template class PVFAdj: public T { +public: + + PVFAdj(){_vfiP = NULL; _vfiP = NULL;} + /* Note: the destructor will not be called in general because there are no virtual destructors. + Instead, the job of deallocating the memory will be done bu the edge allocator. + This destructor is only done for those who istance a face alone (outside a mesh) + */ + typedef typename T::VertexType VertexType; + typedef typename T::FaceType FaceType; + typename T::FacePointer &VFp(const int j) { assert(j>=0 && jVN()); return _vfpP[j]; } + typename T::FacePointer const VFp(const int j) const { assert(j>=0 && jVN()); return _vfpP[j]; } + typename T::FacePointer const cVFp(const int j) const { assert(j>=0 && jVN()); return _vfpP[j]; } + char &VFi(const int j) {return _vfiP[j]; } + template + void ImportLocal(const LeftF & leftF){T::ImportLocal(leftF);} + inline void Alloc(const int & ns) { + if(_vfpP == NULL){ + this->SetVN(ns); + _vfpP = new FaceType*[this->VN()]; + _vfiP = new char[this->VN()]; + for(int i = 0; i < this->VN(); ++i) {_vfpP[i] = 0;_vfiP = -1;} + } + T::Alloc(ns); + + } + inline void Dealloc() { if(_vfpP!=NULL){ + delete [] _vfpP; _vfpP = NULL; + delete [] _vfiP; _vfiP = NULL; + } + T::Dealloc(); + } + + static bool HasVFAdjacency() { return true; } + static bool HasVFAdjacencyOcc() { return false; } + static void Name(std::vector & name){name.push_back(std::string("PVFAdj"));T::Name(name);} + +private: + typename T::FacePointer *_vfpP ; + char *_vfiP ; +}; + +/*----------------------------- FFADJ ------------------------------*/ + +template class PFFAdj: public T { +public: + typedef typename T::FaceType FaceType; + PFFAdj(){_ffpP = NULL; _ffiP = NULL; } + typename T::FacePointer &FFp(const int j) { assert(j>=0 && jVN()); return _ffpP[j]; } + typename T::FacePointer const FFp(const int j) const { assert(j>=0 && jVN()); return _ffpP[j]; } + typename T::FacePointer const cFFp(const int j) const { assert(j>=0 && jVN()); return _ffpP[j]; } + char &FFi(const int j) { return _ffiP[j]; } + const char &cFFi(const int j) const { return _ffiP[j]; } + + template + void ImportLocal(const LeftF & leftF){T::ImportLocal(leftF);} + inline void Alloc(const int & ns) { + if( _ffpP == NULL){ + this->SetVN(ns); + _ffpP = new FaceType*[this->VN()]; + _ffiP = new char[this->VN()]; + for(int i = 0; i < this->VN(); ++i) {_ffpP[i] = 0;_ffiP[i] = 0;} + } + T::Alloc(ns); + } + inline void Dealloc() { if(_ffpP!=NULL){ + delete [] _ffpP; _ffpP = NULL; + delete [] _ffiP; _ffiP = NULL; + } + T::Dealloc(); + } + + static bool HasFFAdjacency() { return true; } + static bool HasFFAdjacencyOcc() { return false; } + static void Name(std::vector & name){name.push_back(std::string("PFFAdj"));T::Name(name);} + +//private: + typename T::FacePointer *_ffpP ; + char *_ffiP ; +}; + +/*----------------------------- PFEADJ ------------------------------*/ + +template class PFEAdj: public T { +public: + typedef typename T::EdgeType EdgeType; + PFEAdj(){_fepP = NULL; } + typename T::EdgePointer &FEp(const int j) { assert(j>=0 && jVN()); return _fepP[j]; } + typename T::EdgePointer const FEp(const int j) const { assert(j>=0 && jVN()); return _fepP[j]; } + typename T::EdgePointer const cFEp(const int j) const { assert(j>=0 && jVN()); return _fepP[j]; } + + template + void ImportLocal(const LeftF & leftF){T::ImportLocal(leftF);} + inline void Alloc(const int & ns) { + if( _fepP == NULL){ + this->SetVN(ns); + _fepP = new EdgeType *[this->VN()]; + for(int i = 0; i < this->VN(); ++i) {_fepP[i] = 0;} + } + T::Alloc(ns); + } + inline void Dealloc() { if(_fepP!=NULL) {delete [] _fepP; _fepP = NULL;} T::Dealloc();} + + static bool HasFEAdjacency() { return true; } + static bool HasFEAdjacencyOcc() { return false; } + static void Name(std::vector & name){name.push_back(std::string("PFEAdj"));T::Name(name);} + +//private: + typename T::EdgePointer *_fepP ; +}; + +/*----------------------------- PFEADJ ------------------------------*/ + +template class PFHEAdj: public T { +public: + typedef typename T::EdgeType EdgeType; + PFHEAdj(){_fhepP = NULL; } + typename T::EdgePointer &FHEp() { return _fhepP; } + typename T::EdgePointer const FHEp() const { return _fhepP; } + typename T::EdgePointer const cFHEp() const { return _fhepP; } + + template + void ImportLocal(const LeftF & leftF){T::ImportLocal(leftF);} + inline void Alloc(const int & ns) {T::Alloc(ns);} + inline void Dealloc() { T::Dealloc();} + + static bool HasFHEAdjacency() { return true; } + static bool HasFHEAdjacencyOcc() { return false; } + static void Name(std::vector & name){name.push_back(std::string("PFHEAdj"));T::Name(name);} + +//private: + typename T::EdgePointer _fhepP ; +}; + + + } // end namespace face +}// end namespace vcg +#endif diff --git a/vcg/simplex/face/with/readme.txt b/vcg/simplex/face/component_rt.h similarity index 50% rename from vcg/simplex/face/with/readme.txt rename to vcg/simplex/face/component_rt.h index b984d019..39f68788 100644 --- a/vcg/simplex/face/with/readme.txt +++ b/vcg/simplex/face/component_rt.h @@ -1,14 +1,14 @@ -/**************************************************************************** +/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * -* Copyright(C) 2004 \/)\/ * +* Copyright(C) 2006 \/)\/ * * Visual Computing Lab /\/| * * ISTI - Italian National Research Council | * * \ * * 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 * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * @@ -20,33 +20,60 @@ * for more details. * * * ****************************************************************************/ +/**************************************************************************** + History -This folders contains most common FACE configuration files. +$Log: not supported by cvs2svn $ +Revision 1.2 2007/05/04 16:16:40 ganovelli +standardized to component style -The name of the file specifies the members that are added to the vertex -class. The name is a sequence of letter pairs, in strict alphabetical order. The -possible admitted letters pairs are: +Revision 1.1 2006/10/13 14:11:49 cignoni +first version -AF - Face-Face adjacency -AS - Shared Vertex-Face and Face-Face Adjacency -AV - Vertex-face adjacency +****************************************************************************/ -FC - Per-Face Color -FM - Per-Face Incremental Mark -FN - Per-Face Normal -FQ - Per-Face Quality -RT - Data for Optimized Point-Face Distance and Ray-Tracing Stuff -WC - Per-Wedge Color -WN - Per-Wedge Normal -WQ - Per-Wedge Quality -WT - Per-Wedge Texture Coords +#ifndef __VCG_FACE_PLUS_COMPONENT_RT +#define __VCG_FACE_PLUS_COMPONENT_RT -E.g. +#include -#include +namespace vcg { + namespace face { -generate a type +template +struct EdgePlaneInfo{ + CoordType edge[3]; + ::vcg::Plane3 plane; + typename CoordType::ScalarType edgescale; +}; -VertexAFFNWT +template class EdgePlane: public T { +public: + typedef EdgePlaneInfo EdgePlaneType; -that can store F-F adjacency, Per-face normal and color and per-wedge texture coords. + typename T::VertexType::CoordType &Edge(const int j) { + return _ep.edge[j]; + } + typename T::VertexType::CoordType cEdge(const int j)const { + return _ep.edge[j]; + } + + typename vcg::Plane3 &Plane() { + return _ep.plane; + } + typename vcg::Plane3 cPlane()const { + return _ep.plane; + } + + static bool HasEdgePlane() { return true; } + + static void Name(std::vector & name){name.push_back(std::string("EdgePlane"));T::Name(name);} + +private: + +EdgePlaneType _ep; +}; + + } // end namespace face +}// end namespace vcg +#endif diff --git a/vcg/simplex/face/face.h b/vcg/simplex/face/face_old.h similarity index 100% rename from vcg/simplex/face/face.h rename to vcg/simplex/face/face_old.h diff --git a/vcg/simplex/face/pos.h b/vcg/simplex/face/pos.h index b1b4f0de..4e1f3b50 100644 --- a/vcg/simplex/face/pos.h +++ b/vcg/simplex/face/pos.h @@ -268,7 +268,7 @@ public: /// Changes edge maintaining the same face and the same vertex void FlipE() { - assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z+0)%3)==v)); + assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z+0)%f->VN())==v)); if(f->V(f->Next(z))==v) z=f->Next(z); else z= f->Prev(z); assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z))==v)); @@ -326,7 +326,7 @@ public: const FaceType *FFlip() const { assert( f->FFp(z)->FFp(f->FFi(z))==f ); - assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z+0)%3)==v)); + assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z+0)%f->VN())==v)); FaceType *nf=f->FFp(z); return nf; } diff --git a/vcg/simplex/face/with/af.h b/vcg/simplex/face/with/af.h deleted file mode 100644 index e2eedf2b..00000000 --- a/vcg/simplex/face/with/af.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __VCGLIB_FACE_AF_TYPE -#define __VCGLIB_FACE_AF_TYPE - -#define FACE_TYPE FaceAF - -#define __VCGLIB_FACE_AF - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_AF - -#endif diff --git a/vcg/simplex/face/with/afav.h b/vcg/simplex/face/with/afav.h deleted file mode 100644 index 048e9fa3..00000000 --- a/vcg/simplex/face/with/afav.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __VCGLIB_FACE_AFAV_TYPE -#define __VCGLIB_FACE_AFAV_TYPE - -#define FACE_TYPE FaceAFAV - -#define __VCGLIB_FACE_AV -#define __VCGLIB_FACE_AF - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_AF -#undef __VCGLIB_FACE_AV - -#endif diff --git a/vcg/simplex/face/with/afavfcfnfmrt.h b/vcg/simplex/face/with/afavfcfnfmrt.h deleted file mode 100644 index 69d8cb87..00000000 --- a/vcg/simplex/face/with/afavfcfnfmrt.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __VCGLIB_FACE_AFAVFCFNFMRT_TYPE -#define __VCGLIB_FACE_AFAVFCFNFMRT_TYPE - -#define FACE_TYPE FaceAFAVFCFNFMRT - -#define __VCGLIB_FACE_AF -#define __VCGLIB_FACE_AV -#define __VCGLIB_FACE_FC -#define __VCGLIB_FACE_FN -#define __VCGLIB_FACE_FM -#define __VCGLIB_FACE_RT - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_AF -#undef __VCGLIB_FACE_AV -#undef __VCGLIB_FACE_FC -#undef __VCGLIB_FACE_FN -#undef __VCGLIB_FACE_FM -#undef __VCGLIB_FACE_RT -#endif \ No newline at end of file diff --git a/vcg/simplex/face/with/afavfn.h b/vcg/simplex/face/with/afavfn.h deleted file mode 100644 index a6b4c3c5..00000000 --- a/vcg/simplex/face/with/afavfn.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __VCGLIB_FACE_AFAVFN_TYPE -#define __VCGLIB_FACE_AFAVFN_TYPE - -#define FACE_TYPE FaceAFAVFN - -#define __VCGLIB_FACE_AF -#define __VCGLIB_FACE_FN -#define __VCGLIB_FACE_AV - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_AF -#undef __VCGLIB_FACE_FN -#undef __VCGLIB_FACE_AV - -#endif \ No newline at end of file diff --git a/vcg/simplex/face/with/afavfnfmrt.h b/vcg/simplex/face/with/afavfnfmrt.h deleted file mode 100644 index 1d698149..00000000 --- a/vcg/simplex/face/with/afavfnfmrt.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __VCGLIB_FACE_AFAVFNFMRT_TYPE -#define __VCGLIB_FACE_AFAVFNFMRT_TYPE - -#define FACE_TYPE FaceAFAVFNFMRT - -#define __VCGLIB_FACE_AF -#define __VCGLIB_FACE_FN -#define __VCGLIB_FACE_AV -#define __VCGLIB_FACE_FM -#define __VCGLIB_FACE_RT - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_AF -#undef __VCGLIB_FACE_FN -#undef __VCGLIB_FACE_AV -#undef __VCGLIB_FACE_FM -#undef __VCGLIB_FACE_RT -#endif \ No newline at end of file diff --git a/vcg/simplex/face/with/afavfnfmrtfq.h b/vcg/simplex/face/with/afavfnfmrtfq.h deleted file mode 100644 index 33905a5e..00000000 --- a/vcg/simplex/face/with/afavfnfmrtfq.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __VCGLIB_FACE_AFAVFNFMRTFQ_TYPE -#define __VCGLIB_FACE_AFAVFNFMRTFQ_TYPE - -#define FACE_TYPE FaceAFAVFNFMRTFQ - -#define __VCGLIB_FACE_AF -#define __VCGLIB_FACE_FN -#define __VCGLIB_FACE_AV -#define __VCGLIB_FACE_FM -#define __VCGLIB_FACE_RT -#define __VCGLIB_FACE_FQ - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_AF -#undef __VCGLIB_FACE_FN -#undef __VCGLIB_FACE_AV -#undef __VCGLIB_FACE_FM -#undef __VCGLIB_FACE_RT -#undef __VCGLIB_FACE_FQ -#endif diff --git a/vcg/simplex/face/with/afavfnfq.h b/vcg/simplex/face/with/afavfnfq.h deleted file mode 100644 index 1ab69916..00000000 --- a/vcg/simplex/face/with/afavfnfq.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __VCGLIB_FACE_AFAVFNFQ_TYPE -#define __VCGLIB_FACE_AFAVFNFQ_TYPE - -#define FACE_TYPE FaceAFAVFNFQ - -#define __VCGLIB_FACE_AF -#define __VCGLIB_FACE_FN -#define __VCGLIB_FACE_AV -#define __VCGLIB_FACE_FQ - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_AF -#undef __VCGLIB_FACE_FN -#undef __VCGLIB_FACE_AV -#undef __VCGLIB_FACE_FQ -#endif \ No newline at end of file diff --git a/vcg/simplex/face/with/afavfnfqrt.h b/vcg/simplex/face/with/afavfnfqrt.h deleted file mode 100644 index 4c7d6de7..00000000 --- a/vcg/simplex/face/with/afavfnfqrt.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __VCGLIB_FACE_AFAVFNFQRT_TYPE -#define __VCGLIB_FACE_AFAVFNFQRT_TYPE - -#define FACE_TYPE FaceAFAVFNFQRT - -#define __VCGLIB_FACE_AF -#define __VCGLIB_FACE_FN -#define __VCGLIB_FACE_AV -#define __VCGLIB_FACE_FQ -#define __VCGLIB_FACE_RT - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_AF -#undef __VCGLIB_FACE_FN -#undef __VCGLIB_FACE_AV -#undef __VCGLIB_FACE_FQ -#undef __VCGLIB_FACE_RT -#endif \ No newline at end of file diff --git a/vcg/simplex/face/with/affc.h b/vcg/simplex/face/with/affc.h deleted file mode 100644 index 66044a98..00000000 --- a/vcg/simplex/face/with/affc.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __VCGLIB_FACE_AFFC_TYPE -#define __VCGLIB_FACE_AFFC_TYPE - -#define FACE_TYPE FaceAFFC - -#define __VCGLIB_FACE_AF -#define __VCGLIB_FACE_FC - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_AF -#undef __VCGLIB_FACE_FC - -#endif diff --git a/vcg/simplex/face/with/affm.h b/vcg/simplex/face/with/affm.h deleted file mode 100644 index 5322657f..00000000 --- a/vcg/simplex/face/with/affm.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __VCGLIB_FACE_AFFM_TYPE -#define __VCGLIB_FACE_AFFM_TYPE - -#define FACE_TYPE FaceAFFM - -#define __VCGLIB_FACE_AF -#define __VCGLIB_FACE_FM - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_AF -#undef __VCGLIB_FACE_FM - -#endif diff --git a/vcg/simplex/face/with/affn.h b/vcg/simplex/face/with/affn.h deleted file mode 100644 index e26d7b44..00000000 --- a/vcg/simplex/face/with/affn.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __VCGLIB_FACE_AFFN_TYPE -#define __VCGLIB_FACE_AFFN_TYPE - -#define FACE_TYPE FaceAFFN - -#define __VCGLIB_FACE_AF -#define __VCGLIB_FACE_FN - - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_AF -#undef __VCGLIB_FACE_FN - -#endif \ No newline at end of file diff --git a/vcg/simplex/face/with/affnfmrt.h b/vcg/simplex/face/with/affnfmrt.h deleted file mode 100644 index f55f0ccd..00000000 --- a/vcg/simplex/face/with/affnfmrt.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __VCGLIB_FACE_AFAVFNFMRT_TYPE -#define __VCGLIB_FACE_AFAVFNFMRT_TYPE - -#define FACE_TYPE FaceAFFNFMRT - -#define __VCGLIB_FACE_AF -#define __VCGLIB_FACE_FN -#define __VCGLIB_FACE_FM -#define __VCGLIB_FACE_RT - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_AF -#undef __VCGLIB_FACE_FN -#undef __VCGLIB_FACE_FM -#undef __VCGLIB_FACE_RT -#endif \ No newline at end of file diff --git a/vcg/simplex/face/with/av.h b/vcg/simplex/face/with/av.h deleted file mode 100644 index 6a52308c..00000000 --- a/vcg/simplex/face/with/av.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __VCGLIB_FACE_AV_TYPE -#define __VCGLIB_FACE_AV_TYPE - -#define FACE_TYPE FaceAV - -#define __VCGLIB_FACE_AV - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_AV - -#endif diff --git a/vcg/simplex/face/with/avfn.h b/vcg/simplex/face/with/avfn.h deleted file mode 100644 index 747a4345..00000000 --- a/vcg/simplex/face/with/avfn.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __VCGLIB_FACE_AVFN_TYPE -#define __VCGLIB_FACE_AVFN_TYPE - -#define FACE_TYPE FaceAVFN - -#define __VCGLIB_FACE_FN -#define __VCGLIB_FACE_AV - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_FN -#undef __VCGLIB_FACE_AV - -#endif diff --git a/vcg/simplex/face/with/avfnfq.h b/vcg/simplex/face/with/avfnfq.h deleted file mode 100644 index 70e00be9..00000000 --- a/vcg/simplex/face/with/avfnfq.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __VCGLIB_FACE_AVFNFQ_TYPE -#define __VCGLIB_FACE_AVFNFQ_TYPE - -#define FACE_TYPE FaceAVFNFQ - -#define __VCGLIB_FACE_FN -#define __VCGLIB_FACE_AV -#define __VCGLIB_FACE_FQ - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_FN -#undef __VCGLIB_FACE_AV -#undef __VCGLIB_FACE_FQ - -#endif diff --git a/vcg/simplex/face/with/fc.h b/vcg/simplex/face/with/fc.h deleted file mode 100644 index e467edba..00000000 --- a/vcg/simplex/face/with/fc.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __VCGLIB_FACE_FC_TYPE -#define __VCGLIB_FACE_FC_TYPE - -#define FACE_TYPE FaceFC - -#define __VCGLIB_FACE_FC - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_FC - -#endif diff --git a/vcg/simplex/face/with/fcfmfnwcwnwt.h b/vcg/simplex/face/with/fcfmfnwcwnwt.h deleted file mode 100644 index a60c5a00..00000000 --- a/vcg/simplex/face/with/fcfmfnwcwnwt.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __VCGLIB_FACE_FCFMFNWCWNWT_TYPE -#define __VCGLIB_FACE_FCFMFNWCWNWT_TYPE - -#define FACE_TYPE FaceFCFMFNWCWNWT - -#define __VCGLIB_FACE_FC -#define __VCGLIB_FACE_FM -#define __VCGLIB_FACE_FN -#define __VCGLIB_FACE_WC -#define __VCGLIB_FACE_WN -#define __VCGLIB_FACE_WT - -#include - -#undef __VCGLIB_FACE_FC -#undef __VCGLIB_FACE_FM -#undef __VCGLIB_FACE_FN -#undef __VCGLIB_FACE_WC -#undef __VCGLIB_FACE_WN -#undef __VCGLIB_FACE_WT - -#undef FACE_TYPE - -#endif /* __VCGLIB_FACE_FCFMFNWCWNWT_TYPE */ diff --git a/vcg/simplex/face/with/fcfn.h b/vcg/simplex/face/with/fcfn.h deleted file mode 100644 index 9c205365..00000000 --- a/vcg/simplex/face/with/fcfn.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __VCGLIB_FACE_FCFN_TYPE -#define __VCGLIB_FACE_FCFN_TYPE - -#define FACE_TYPE FaceFCFN - -#define __VCGLIB_FACE_FC -#define __VCGLIB_FACE_FN - -#include - -#undef FACE_TYPE - -#define __VCGLIB_FACE_FC -#define __VCGLIB_FACE_FN - -#endif diff --git a/vcg/simplex/face/with/fm.h b/vcg/simplex/face/with/fm.h deleted file mode 100644 index 0b430edd..00000000 --- a/vcg/simplex/face/with/fm.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __VCGLIB_FACE_FM_TYPE -#define __VCGLIB_FACE_FM_TYPE - -#define FACE_TYPE FaceFM - -#define __VCGLIB_FACE_FM - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_FM - -#endif /* __VCGLIB_FACE_FM_TYPE */ diff --git a/vcg/simplex/face/with/fmfn.h b/vcg/simplex/face/with/fmfn.h deleted file mode 100644 index 6fdc6595..00000000 --- a/vcg/simplex/face/with/fmfn.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __VCGLIB_FACE_FMFN_TYPE -#define __VCGLIB_FACE_FMFN_TYPE - -#define FACE_TYPE FaceFMFN - -#define __VCGLIB_FACE_FM -#define __VCGLIB_FACE_FN - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_FM -#undef __VCGLIB_FACE_FN - -#endif \ No newline at end of file diff --git a/vcg/simplex/face/with/fn.h b/vcg/simplex/face/with/fn.h deleted file mode 100644 index 00edc9af..00000000 --- a/vcg/simplex/face/with/fn.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __VCGLIB_FACE_FN_TYPE -#define __VCGLIB_FACE_FN_TYPE - -#define FACE_TYPE FaceFN - -#define __VCGLIB_FACE_FN - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_FN - -#endif diff --git a/vcg/simplex/face/with/rt.h b/vcg/simplex/face/with/rt.h deleted file mode 100644 index 1ddd21d8..00000000 --- a/vcg/simplex/face/with/rt.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __VCGLIB_FACE_RT_TYPE -#define __VCGLIB_FACE_RT_TYPE - -#define FACE_TYPE FaceRT - - -#define __VCGLIB_FACE_RT - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_RT -#endif \ No newline at end of file diff --git a/vcg/simplex/face/with/rtfcfmfn.h b/vcg/simplex/face/with/rtfcfmfn.h deleted file mode 100644 index be19bb34..00000000 --- a/vcg/simplex/face/with/rtfcfmfn.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __VCGLIB_FACE_RTFMFN_TYPE -#define __VCGLIB_FACE_RTFMFN_TYPE - -#define FACE_TYPE FaceRTFCFMFN - -#define __VCGLIB_FACE_RT -#define __VCGLIB_FACE_FC -#define __VCGLIB_FACE_FM -#define __VCGLIB_FACE_FN - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_RT -#undef __VCGLIB_FACE_FC -#undef __VCGLIB_FACE_FM -#undef __VCGLIB_FACE_FN - -#endif diff --git a/vcg/simplex/face/with/rtfmfn.h b/vcg/simplex/face/with/rtfmfn.h deleted file mode 100644 index e52cdfa8..00000000 --- a/vcg/simplex/face/with/rtfmfn.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __VCGLIB_FACE_RTFMFN_TYPE -#define __VCGLIB_FACE_RTFMFN_TYPE - -#define FACE_TYPE FaceRTFMFN - -#define __VCGLIB_FACE_RT -#define __VCGLIB_FACE_FM -#define __VCGLIB_FACE_FN - -#include - -#undef FACE_TYPE - -#undef __VCGLIB_FACE_RT -#undef __VCGLIB_FACE_FM -#undef __VCGLIB_FACE_FN - -#endif diff --git a/vcg/simplex/face/with/wt.h b/vcg/simplex/face/with/wt.h deleted file mode 100644 index fb58961f..00000000 --- a/vcg/simplex/face/with/wt.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __VCGLIB_FACE_WT_TYPE - -#define __VCGLIB_FACE_WT_TYPE - - -#define FACE_TYPE FaceWT - - -#define __VCGLIB_FACE_WT - - - -#include - - - -#undef FACE_TYPE - - -#undef __VCGLIB_FACE_WT - - -#endif