From 71749144a21dcfd03682e7204b6e0b56a07c883b Mon Sep 17 00:00:00 2001 From: cignoni Date: Wed, 3 Mar 2004 16:08:38 +0000 Subject: [PATCH] First working version --- vcg/simplex/face/base.h | 2042 ++++++++++++++------------------------- 1 file changed, 744 insertions(+), 1298 deletions(-) diff --git a/vcg/simplex/face/base.h b/vcg/simplex/face/base.h index 498fa033..6a83161d 100644 --- a/vcg/simplex/face/base.h +++ b/vcg/simplex/face/base.h @@ -24,323 +24,675 @@ History $Log: not supported by cvs2svn $ -Revision 1.1 2004/02/10 01:11:28 cignoni -Edited Comments and GPL license +Revision 1.1 2004/02/13 00:44:45 cignoni +First commit... ****************************************************************************/ - - - #ifndef FACE_TYPE -#pragma message("\nYou should never directly include this file\n") +#pragma error message("\nYou should never directly include this file\_n") #else -/* People should subclass his vertex class from this one... */ -#include -#include -#include -#include -#include -#include -#include -#include +#include namespace vcg { -/** @name Face +/** +\ingroup face + @name Face Class Face. This is the base class for definition of a face of the mesh. @param FVTYPE (Templete Parameter) Specifies the vertex class type. */ -template > class FACE_TYPE +template > class FACE_TYPE { public: - typedef typename FVTYPE::face_type face_from_vert_type; - typedef typename FVTYPE::scalar_type FCTYPE; - /// The type of the scalar field of the vertex coordinate - typedef FCTYPE scalar_type; - /// The type of the the vertex coordinate - typedef Point3< FCTYPE > vectorial_type; /// The base type of the face - typedef FACE_TYPE face_base; + typedef FACE_TYPE BaseFaceType; /// The vertex type - typedef FVTYPE vertex_type; + typedef FVTYPE VertexType; + /// 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 typename FVTYPE::FaceType FaceFromVertType; /// The bounding box type - typedef Box3 bbox_type; - /// The texture coordiante type - typedef TCTYPE texcoord_type; + typedef Box3 BoxType; + + /// This are the _flags of face, the default value is 0 + int _flags; +/***********************************************/ +/** @name Vertex Pointer + blah + blah +**/ + //@{ protected: /// Vector of vertex pointer incident in the face - FVTYPE *v[3]; - /// This are the flags of face, the default value is 0 - int flags; + VertexType *v[3]; +public: + /** Return the pointer to the j-th vertex of the face. + @param j Index of the face vertex. + */ + inline FVTYPE * & 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 const FVTYPE * const & V( const int j ) const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert(j>=0); + assert(j<3); + return v[j]; + } + inline const FVTYPE * 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 FVTYPE * & V0( const int j ) { return V(j);} + inline FVTYPE * & V1( const int j ) { return V((j+1)%3);} + inline FVTYPE * & V2( const int j ) { return V((j+2)%3);} + inline const FVTYPE * const & V0( const int j ) const { return V(j);} + inline const FVTYPE * const & V1( const int j ) const { return V((j+1)%3);} + inline const FVTYPE * const & V2( const int j ) const { return V((j+2)%3);} + inline const FVTYPE * const & cV0( const int j ) const { return cV(j);} + inline const FVTYPE * const & cV1( const int j ) const { return cV((j+1)%3);} + inline const FVTYPE * 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 FVTYPE * & UberV( const int j ) + { + assert(j>=0); + assert(j<3); + return v[j]; + } + + inline const FVTYPE * const & UberV( const int j ) const + { + assert(j>=0); + assert(j<3); + return v[j]; + } -/*#******************* -* Quality * -**********************/ + //@} -#ifdef __VCGLIB_FACE_Q +/***********************************************/ +/** @name Normal + blah + blah +**/ + //@{ + +#ifdef __VCGLIB_FACE_FN + /// This vector indicates the normal of the face (defines if FACE_N is defined) protected: - float quality; + CoordType _n; +public: +#endif + + /// Return the reference of the normal to the face (if __VCGLIB_FACE_N is defined). + inline CoordType & N() + { +#ifdef __VCGLIB_FACE_N + return _n; +#else + assert(0); + return *(CoordType *)0; +#endif + } + /// Return the reference of the normal to the face (if __VCGLIB_FACE_N is defined). + inline const CoordType & N() const + { +#ifdef __VCGLIB_FACE_N + return _n; +#else + return vcg::Normal(V(0)->P(), V(1)->P(), V(2)->P()); +#endif + } + /// Return the reference of the normal to the face (if __VCGLIB_FACE_N is defined). + inline const CoordType cN() const + { + return Normal(); + } + + /// Calculate the normal to the face, the value is store in the field _n of the face +void ComputeNormal() +{ +#ifdef __VCGLIB_FACE_N + _n = vcg::Normal(V(0)->cP(), V(1)->cP(), V(2)->cP()); +#else + assert(0); +#endif +} +void ComputeNormalizedNormal() +{ +#ifdef __VCGLIB_FACE_N + _n = vcg::NormalizedNormal(V(0)->cP(), V(1)->cP(), V(2)->cP()); +#else + assert(0); +#endif +} + +/// Return the value of the face normal; warning: if __VCGLIB_FACE_N is not defined the value is computed each time +CoordType Normal() const +{ +#ifdef __VCGLIB_FACE_N + return _n; +#else + return vcg::Normal(V(0)->P(), V(1)->P(), V(2)->P()); +#endif +} +#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_Q - return quality; +#ifdef __VCGLIB_FACE_FQ + return _q; #else assert(0); - return *(float*)(&flags); + return *(float*)(&_flags); #endif } const float & Q() const { -#ifdef __VCGLIB_FACE_Q - return quality; +#ifdef __VCGLIB_FACE_FQ + return _q; #else assert(0); - return *(float*)(&flags); + return *(float*)(&_flags); #endif } -/*#******************* -* Texture * -**********************/ + //@} -#ifdef __VCGLIB_FACE_T - TCTYPE t; -#endif -public: - TCTYPE & T() - { -#ifdef __VCGLIB_FACE_T - return t; -#else - assert(0); - return *(TCTYPE*)(&flags); -#endif - } - -const TCTYPE & T() const - { -#ifdef __VCGLIB_FACE_T - return t; -#else - assert(0); - return *(TCTYPE*)(&flags); -#endif - } +/***********************************************/ +/** @name Texture + blah + blah +**/ + //@{ // Per Wedge Texture Coords protected: #ifdef __VCGLIB_FACE_WT - TCTYPE wt[3]; + TCTYPE _wt[3]; #endif public: TCTYPE & WT(const int i) { #ifdef __VCGLIB_FACE_WT - return wt[i]; + return _wt[i]; #else assert(0); - return *(TCTYPE*)(&flags); + return *(TCTYPE*)(&_flags); #endif } const TCTYPE & WT(const int i) const { #ifdef __VCGLIB_FACE_WT - return wt[i]; + return _wt[i]; #else assert(0); - return *(TCTYPE*)(&flags); + return *(TCTYPE*)(&_flags); #endif } -/*#******************* -* Colori * -**********************/ + //@} + +/***********************************************/ +/** @name Colors + blah + blah +**/ + //@{ protected: -#ifdef __VCGLIB_FACE_C - ColorUB c; +#ifdef __VCGLIB_FACE_FC + Color4b _c; #endif public: - ColorUB & C() + Color4b & C() { -#ifdef __VCGLIB_FACE_C - return c; +#ifdef __VCGLIB_FACE_FC + return _c; #else assert(0); - return *(ColorUB*)(&flags); + return *(Color4b*)(&_flags); #endif } - const ColorUB C() const + const Color4b C() const { -#ifdef __VCGLIB_FACE_C - return c; +#ifdef __VCGLIB_FACE_FC + return _c; #else - return ColorUB(ColorUB::White); + return Color4b(Color4b::White); #endif } protected: #ifdef __VCGLIB_FACE_WC - ColorUB wc[3]; + Color4b _wc[3]; #endif public: - ColorUB & WC(const int i) + Color4b & WC(const int i) { #ifdef __VCGLIB_FACE_WC - return wc[i]; + return _wc[i]; #else assert(0); - return *(ColorUB*)(&flags); + return *(Color4b*)(&_flags); #endif } -const ColorUB WC(const int i) const +const Color4b WC(const int i) const { #ifdef __VCGLIB_FACE_WC - return wc[i]; + return _wc[i]; #else assert(0); - return ColorUB(ColorUB::White); + return Color4b(Color4b::White); #endif } -/*#******************* -* Normals * -**********************/ -protected: -#ifdef __VCGLIB_FACE_N - /// This vector indicates the normal of the face (defines if FACE_N is defined) - vectorial_type n; -#endif -#ifdef __VCGLIB_FACE_WN - /// This vector indicates per wedge normal - vectorial_type wn[3]; -#endif -public: - vectorial_type & WN(const int i) - { -#ifdef __VCGLIB_FACE_WN - return wn[i]; -#else - assert(0); - return *(vectorial_type *)(&flags); -#endif - } + //@} -const vectorial_type & WN(const int i) const - { -#ifdef __VCGLIB_FACE_WN - return wn[i]; -#else - return vectorial_type(); -#endif - } -protected: +/***********************************************/ +/** @name Adjacency + blah + blah +**/ + //@{ -/*#******************* -* Adjacency data * -**********************/ -#if (defined(__VCGLIB_FACE_A) && defined(__VCGLIB_FACE_S)) +#if (defined(__VCGLIB_FACE_FA) && defined(__VCGLIB_FACE_SA)) #error Error: You cannot specify face-to-face and shared topology together #endif -#if (defined(__VCGLIB_FACE_V) && defined(__VCGLIB_FACE_S)) +#if (defined(__VCGLIB_FACE_VA) && defined(__VCGLIB_FACE_SA)) #error Error: You cannot specify vertex-face and shared topology together #endif - -#if defined(__VCGLIB_FACE_A) - /// Vector of face pointer, it's used to indicate the adjacency relations (defines if FACE_A is defined) +protected: +#if defined(__VCGLIB_FACE_FA) + /// Vector of face pointer, it's used to indicate the adjacency relations (defines if FACE_A is defined) FACE_TYPE *ff[3]; // Facce adiacenti /// Index of the face in the arrival face char zf[4]; #endif -#ifdef __VCGLIB_FACE_V +#ifdef __VCGLIB_FACE_VA ///Vettore di puntatori a faccia, utilizzato per indicare le adiacenze vertice faccia FACE_TYPE *fv[3]; char zv[3]; #endif -#ifdef __VCGLIB_FACE_S +#ifdef __VCGLIB_FACE_SA ///Vettore di puntatori a faccia, utilizzato per indicare le adiacenze vertice faccia FACE_TYPE *fs[3]; char zs[3]; #endif +public: -#ifdef __VCGLIB_FACE_M + + + + /** Return the pointer to the j-th adjacent face. + @param j Index of the edge. + */ + inline FACE_TYPE * & F( 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_FA) + return ff[j]; +#elif defined(__VCGLIB_FACE_SA) + return fs[j]; +#else + assert(0); + static FACE_TYPE *dum=0; + return dum; +#endif + } + + inline const FACE_TYPE * const & F( const int j ) const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert(j>=0); + assert(j<3); +#if defined(__VCGLIB_FACE_FA) + return ff[j]; +#elif defined(__VCGLIB_FACE_SA) + return fs[j]; +#else + assert(0); + return (FACE_TYPE *)this; +#endif + } + inline FACE_TYPE * & F1( const int j ) { return F((j+1)%3);} + inline FACE_TYPE * & F2( const int j ) { return F((j+2)%3);} + inline const FACE_TYPE * const& F1( const int j ) const { return F((j+1)%3);} + inline const FACE_TYPE * const& F2( const int j ) const { return F((j+2)%3);} + + +/** Return the pointer to the j-th adjacent face. + @param j Index of the edge. + */ + inline FACE_TYPE * & UberF( const int j ) + { + assert(j>=0); + assert(j<3); +#if defined(__VCGLIB_FACE_FA) + return ff[j]; +#elif defined(__VCGLIB_FACE_SA) + return fs[j]; +#else + assert(0); // if you stop here you are probably trying to use FF topology in a face without it + return *((FACE_TYPE **)(_flags)); +#endif + } + + inline const FACE_TYPE * const & UberF( const int j ) const + { + assert(j>=0); + assert(j<3); +#if defined(__VCGLIB_FACE_FA) + return ff[j]; +#elif defined(__VCGLIB_FACE_SA) + return fs[j]; +#else + assert(0); // if you stop here you are probably trying to use FF topology in a face without it + return *((FACE_TYPE **)(_flags)); +#endif + } + + + inline FACE_TYPE * & Fv( const int j ) + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert( (_flags & NOTWRITE) == 0 ); + assert(j>=0); + assert(j<3); +#ifdef __VCGLIB_FACE_VA + return fv[j]; +#elif defined(__VCGLIB_FACE_SA) + return fs[j]; +#else + assert(0); // you are probably trying to use VF topology in a vertex without it + return *((FACE_TYPE **)(_flags)); +#endif + } + + inline const FACE_TYPE * const & Fv( const int j ) const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert(j>=0); + assert(j<3); +#ifdef __VCGLIB_FACE_VA + return fv[j]; +#elif defined(__VCGLIB_FACE_SA) + return fs[j]; +#else + assert(0); + return (FACE_TYPE *)this; +#endif + } + + + /** Return the index that the face have in the j-th adjacent face. + @param j Index of the edge. + */ + inline char & Z( 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_FA) + return zf[j]; +#elif defined(__VCGLIB_FACE_SA) + return zs[j]; +#else + assert(0); + return *(char *)&_flags; // tanto per farlo compilare... +#endif + } + + inline const char & Z( const int j ) const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert(j>=0); + assert(j<3); +#if defined(__VCGLIB_FACE_FA) + return zf[j]; +#elif defined(__VCGLIB_FACE_SA) + return zs[j]; +#else + assert(0); + return *(char *)&_flags; +#endif + } + + /** 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_FA) + return zf[j]; +#elif defined(__VCGLIB_FACE_SA) + 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_FA) + return zf[j]; +#elif defined(__VCGLIB_FACE_SA) + return zs[j]; +#else + assert(0); + return *(char *)&_flags; +#endif + } + + + inline char & Zv( const int j ) + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert( (_flags & NOTWRITE) == 0 ); + assert(j>=0); + assert(j<3); +#ifdef __VCGLIB_FACE_VA + return zv[j]; +#elif defined(__VCGLIB_FACE_SA) + return zs[j]; +#else + assert(0); + return *(char *)&_flags; +#endif + } + + inline const char & Zv( const int j ) const + { + assert( (_flags & DELETED) == 0 ); + assert( (_flags & NOTREAD) == 0 ); + assert(j>=0); + assert(j<3); +#ifdef __VCGLIB_FACE_VA + return zv[j]; +#elif defined(__VCGLIB_FACE_SA) + 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; #endif // Mark - - -public: - enum { - OBJ_TYPE_A = 0x0001, - OBJ_TYPE_N = 0x0002, - OBJ_TYPE_M = 0x0004, - OBJ_TYPE_V = 0x0008, - OBJ_TYPE_S = 0x0010, - OBJ_TYPE_E = 0x0020, - OBJ_TYPE_C = 0x0040, - OBJ_TYPE_WN = 0x0080, - OBJ_TYPE_WC = 0x0100, - OBJ_TYPE_WT = 0x0200, - OBJ_TYPE_Q = 0x0400, - }; - - enum { - OBJ_TYPE = -#ifdef __VCGLIB_FACE_A - OBJ_TYPE_A | -#endif -#ifdef __VCGLIB_FACE_N - OBJ_TYPE_N | -#endif #ifdef __VCGLIB_FACE_M - OBJ_TYPE_M | + 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_M + imark = 0; #endif -#ifdef __VCGLIB_FACE_V - OBJ_TYPE_V | -#endif -#ifdef __VCGLIB_FACE_S - OBJ_TYPE_S | -#endif -#ifdef __VCGLIB_FACE_E - OBJ_TYPE_E | -#endif -#ifdef __VCGLIB_FACE_C - OBJ_TYPE_C | -#endif -#ifdef __VCGLIB_FACE_WN - OBJ_TYPE_WN | -#endif -#ifdef __VCGLIB_FACE_WC - OBJ_TYPE_WC | -#endif -#ifdef __VCGLIB_FACE_WT - OBJ_TYPE_WT | -#endif -#ifdef __VCGLIB_FACE_Q - OBJ_TYPE_Q | -#endif - 0 - }; + } + + + //@} +/***********************************************/ +/** @name Flags + blah + blah +**/ + //@{ + enum { // This bit indicate that the face is deleted from the mesh @@ -350,12 +702,8 @@ public: // This bit indicate that the face is not modifiable NOTWRITE = 0x00000004, // non modificabile (ma forse leggibile) // This bit indicate that the face is modified - MODIFIED = 0x00000008, // modificato - // This bit can be used to mark the visited face - VISITED = 0x00000010, // Visited - // This bit can be used to select - SELECTED = 0x00000020, // Selection flags - // Border flags, it is assumed that BORDERi = BORDER0<P() ); bb.Add( v[1]->P() ); bb.Add( v[2]->P() ); } - /// Return the number of vertices of the face - int size() const {return 3;} + /***********************************************/ + /** @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. + **/ + //@{ - /** Return the pointer to the j-th vertex of the face. - @param j Index of the face vertex. - */ - inline FVTYPE * & V( const int j ) - { - assert( (flags & DELETED) == 0 ); - assert( (flags & NOTREAD) == 0 ); - assert( (flags & NOTWRITE) == 0 ); - assert(j>=0); - assert(j=0); - assert(j=0); - assert(j=0); - assert(jP(); - } - - inline const vectorial_type & P( const int j ) const - { - assert( (flags & DELETED) == 0 ); - assert( (flags & NOTREAD) == 0 ); - assert(j>=0); - assert(jcP(); - } - inline const vectorial_type & cP( const int j ) const - { - assert( (flags & DELETED) == 0 ); - assert( (flags & NOTREAD) == 0 ); - assert(j>=0); - assert(jcP(); - } - - /** Return the pointer to the ((j+1)%3)-th vertex of the face. - @param j Index of the face vertex. - */ - inline FVTYPE * & V0( const int j ) { return V(j);} - inline FVTYPE * & V1( const int j ) { return V((j+1)%3);} - inline FVTYPE * & V2( const int j ) { return V((j+2)%3);} - inline const FVTYPE * const & V0( const int j ) const { return V(j);} - inline const FVTYPE * const & V1( const int j ) const { return V((j+1)%3);} - inline const FVTYPE * const & V2( const int j ) const { return V((j+2)%3);} - inline const FVTYPE * const & cV0( const int j ) const { return cV(j);} - inline const FVTYPE * const & cV1( const int j ) const { return cV((j+1)%3);} - inline const FVTYPE * const & cV2( const int j ) const { return cV((j+2)%3);} - - // Shortcut per accedere ai punti delle facce - inline vectorial_type & P0( const int j ) { return V(j)->P();} - inline vectorial_type & P1( const int j ) { return V((j+1)%3)->P();} - inline vectorial_type & P2( const int j ) { return V((j+2)%3)->P();} - inline const vectorial_type & P0( const int j ) const { return V(j)->P();} - inline const vectorial_type & P1( const int j ) const { return V((j+1)%3)->P();} - inline const vectorial_type & P2( const int j ) const { return V((j+2)%3)->P();} - inline const vectorial_type & cP0( const int j ) const { return cV(j)->P();} - inline const vectorial_type & cP1( const int j ) const { return cV((j+1)%3)->P();} - inline const vectorial_type & cP2( const int j ) const { return cV((j+2)%3)->P();} - - inline FVTYPE * & Supervisor_V( const int j ) - { - assert(j>=0); - assert(j=0); - assert(jP(), V(1)->P(), V(2)->P()); + return false; #endif - } - /// Return the reference of the normal to the face (if __VCGLIB_FACE_N is defined). - inline const vectorial_type cN() const - { - return Normal(); - } - - /** Return the pointer to the j-th adjacent face. - @param j Index of the edge. - */ - inline FACE_TYPE * & F( const int j ) - { - assert( (flags & DELETED) == 0 ); - assert( (flags & NOTREAD) == 0 ); - assert( (flags & NOTWRITE) == 0 ); - assert(j>=0); - assert(j=0); - assert(j=0); - assert(j=0); - assert(j=0); - assert(j=0); - assert(j=0); - assert(j=0); - assert(j=0); - assert(j=0); - assert(j=0); - assert(j=0); - assert(j=0 && i<3); - return v[i]; - } - inline const FVTYPE * & operator [] ( const int i ) const { - assert(i>=0 && i<3); - return v[i]; - } - */ - - /// operator to compare two faces + /// operator to compare two faces inline bool operator == ( const FACE_TYPE & f ) const { - for(int i=0; icP(), V(1)->cP(), V(2)->cP()); -#else - assert(0); -#endif -} -void ComputeNormalizedNormal() -{ -#ifdef __VCGLIB_FACE_N - n = vcg::NormalizedNormal(V(0)->cP(), V(1)->cP(), V(2)->cP()); -#else - assert(0); -#endif -} - -/// Return the value of the face normal; warning: if __VCGLIB_FACE_N is not defined the value is computed each time -vectorial_type Normal() const -{ -#ifdef __VCGLIB_FACE_N - return n; -#else - return vcg::Normal(V(0)->P(), V(1)->P(), V(2)->P()); -#endif -} - /** 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) + @param _c Valore di ritorno per il vertice V(2) @return true se bq appartiene alla faccia, false altrimenti */ -bool InterpolationParameters(const vectorial_type & bq, scalar_type &a, scalar_type &b, scalar_type &c ) const -{ - /********** VECCHIA VERSIONE ********************* - //Calcolo degli assi dominanti - int axis; // asse piu' perpendicolare alla faccia - scalar_type max; - vectorial_type fnorm = Normal(); - max = Abs(fnorm[0]); - axis = 0; - if( max < Abs(fnorm[1]) ) - { - max = Abs(fnorm[1]); - axis = 1; - } - if( max < Abs(fnorm[2]) ) - { - max = Abs(fnorm[2]); - axis = 2; - } - - scalar_type x[3]; - scalar_type C[3][3+1]; - - C[0][0] = cV(0)->P()[(axis+1)%3]; - C[0][1] = cV(1)->P()[(axis+1)%3]; - C[0][2] = cV(2)->P()[(axis+1)%3]; - C[0][3] = bq [(axis+1)%3]; - - C[1][0] = cV(0)->P()[(axis+2)%3]; - C[1][1] = cV(1)->P()[(axis+2)%3]; - C[1][2] = cV(2)->P()[(axis+2)%3]; - C[1][3] = bq [(axis+2)%3]; - - C[2][0] = 1; - C[2][1] = 1; - C[2][2] = 1; - C[2][3] = 1; - - if(Gauss33(x,C)) - { - a=x[0]; - b=x[1]; - c=x[2]; - return true; - } - else - { - a=b=c=1.0/3.0; - return false; - } -********** FINE VECCHIA VERSIONE ***************/ - - const scalar_type EPSILON = scalar_type(0.000001); +bool InterpolationParameters(const CoordType & bq, ScalarType &a, ScalarType &b, ScalarType &_c ) const +{ +const ScalarType EPSILON = ScalarType(0.000001); #define x1 (cV(0)->P().x()) @@ -999,24 +950,24 @@ bool InterpolationParameters(const vectorial_type & bq, scalar_type &a, scalar_t #define py (bq.y()) #define pz (bq.z()) - scalar_type t1 = px*y2; - scalar_type t2 = px*y3; - scalar_type t3 = py*x2; - scalar_type t4 = py*x3; - scalar_type t5 = x2*y3; - scalar_type t6 = x3*y2; - scalar_type t8 = x1*y2; - scalar_type t9 = x1*y3; - scalar_type t10 = y1*x2; - scalar_type t11 = y1*x3; - scalar_type t13 = t8-t9-t10+t11+t5-t6; + 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) { - scalar_type t15 = px*y1; - scalar_type t16 = py*x1; + 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; + _c = (t15-t1-t16+t3+t8-t10)/t13; return true; } @@ -1033,11 +984,11 @@ bool InterpolationParameters(const vectorial_type & bq, scalar_type &a, scalar_t t13 = t8-t9-t10+t11+t5-t6; if(fabs(t13)>=EPSILON) { - scalar_type t15 = px*z1; - scalar_type t16 = pz*x1; + 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; + _c = (t15-t1-t16+t3+t8-t10)/t13; return true; } @@ -1049,11 +1000,11 @@ bool InterpolationParameters(const vectorial_type & bq, scalar_type &a, scalar_t t13 = t8-t9-t10+t11+t5-t6; if(fabs(t13)>=EPSILON) { - scalar_type t15 = pz*y1; - scalar_type t16 = py*z1; + 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; + _c = (t15-t1-t16+t3+t8-t10)/t13; return true; } @@ -1074,237 +1025,42 @@ bool InterpolationParameters(const vectorial_type & bq, scalar_type &a, scalar_t } -/*#******************* -* Adjacency Members * -**********************/ - - -/** Return a boolean that indicate if the face is complex. - @param j Index of the edge - @return true se la faccia e' manifold, false altrimenti -*/ -inline bool IsManifold( const int j ) const -{ -#if (defined(__VCGLIB_FACE_A) || defined(__VCGLIB_FACE_S)) - return ( F(j)==this || this == F(j)->F(Z(j)) ); -#endif - return true; - assert(0); -} - -/** Return a boolean that indicate if the j-th edge of the face is a border. - @param j Index of the edge - @return true if j is an edge of border, false otherwise -*/ -inline bool IsBorder( const int j ) const -{ -#if (defined(__VCGLIB_FACE_A) || defined(__VCGLIB_FACE_S)) - return F(j)==this; -#endif - return true; - assert(0); -} - - -/// This function counts the boreders of the face -inline int BorderCount() const -{ -#if (defined(__VCGLIB_FACE_A) || defined(__VCGLIB_FACE_S)) - int t = 0; - if( IsBorder(0) ) ++t; - if( IsBorder(1) ) ++t; - if( IsBorder(2) ) ++t; - return t; -#endif - assert(0); - return 3; -} - - -/// This function counts the number of incident faces in a complex edge -inline int ComplexSize(const int e) const -{ -#if (defined(__VCGLIB_FACE_A) || defined(__VCGLIB_FACE_S)) - int cnt=0; - FACE_TYPE *fi=(FACE_TYPE *)this; - int nzi,zi=e; - do - { - nzi=fi->Z(zi); - fi=fi->F(zi); - zi=nzi; - ++cnt; - } - while(fi!=this); - return cnt; -#endif - assert(0); - return 2; -} - -/*Funzione di detach che scollega una faccia da un ciclo -(eventualmente costituito da due soli elementi) incidente su un edge*/ -/** This function detach the face from the adjacent face via the edge e. It's possible to use it also in non-two manifold situation. - The function cannot be applicated if the adjacencies among faces aren't define. - @param e Index of the edge -*/ -void Detach(const int e) -{ - typedef FEdgePosB< FACE_TYPE > ETYPE; - - assert(!IsBorder(e)); - ETYPE EPB(this,e); // la faccia dall'altra parte - EPB.NextF(); - int cnt=0; - while ( EPB.f->F(EPB.z) != this) - { - assert(!IsManifold(e)); // Si entra in questo loop solo se siamo in una situazione non manifold. - assert(!EPB.f->IsBorder(EPB.z)); - EPB.NextF(); - cnt++; - } - assert(EPB.f->F(EPB.z)==this); - - EPB.f->F(EPB.z) = F(e); - EPB.f->Z(EPB.z) = Z(e); - - F(e) = this; - Z(e) = e; - - EPB.f->SetM(); - this->SetM(); -} - -void OldDetach(const int e) -{ - typedef EdgePosB< FACE_TYPE > ETYPE; - - assert(!IsBorder(e)); - ETYPE EPB(this,e); - ETYPE TEPB(0,-1); - EPB.NextF(); - while ( EPB.f != this) - { - TEPB = EPB; - assert(!EPB.f->IsBorder(EPB.z)); - EPB.NextF(); - } - assert(TEPB.f->F(TEPB.z)==this); - TEPB.f->F(TEPB.z) = F(e); - TEPB.f->Z(TEPB.z) = Z(e); - F(e) = this; - Z(e) = e; - TEPB.f->SetM(); - this->SetM(); -} - - -/** This function attach the face (via the edge z1) to another face (via the edge z2). It's possible to use it also in non-two manifold situation. - The function cannot be applicated if the adjacencies among faces aren't define. - @param z1 Index of the edge - @param f2 Pointer to the face - @param z2 The edge of the face f2 -*/ -void Attach(int z1, face_base *&f2, int z2) -{ - typedef FEdgePosB< FACE_TYPE > ETYPE; - ETYPE EPB(f2,z2); - ETYPE TEPB; - TEPB = EPB; - EPB.NextF(); - while( EPB.f != f2) //Alla fine del ciclo TEPB contiene la faccia che precede f2 - { - TEPB = EPB; - EPB.NextF(); - } - //Salvo i dati di f1 prima di sovrascrivere - face_base *f1prec = this->F(z1); - int z1prec = this->Z(z1); - //Aggiorno f1 - this->F(z1) = TEPB.f->F(TEPB.z); - this->Z(z1) = TEPB.f->Z(TEPB.z); - //Aggiorno la faccia che precede f2 - TEPB.f->F(TEPB.z) = f1prec; - TEPB.f->Z(TEPB.z) = z1prec; -} - - -void AssertAdj() -{ - assert(F(0)->F(Z(0))==this); - assert(F(1)->F(Z(1))==this); - assert(F(2)->F(Z(2))==this); - - assert(F(0)->Z(Z(0))==0); - assert(F(1)->Z(Z(1))==1); - assert(F(2)->Z(Z(2))==2); -} -//#endif // Adjacency - -/*#************** -* Mark Members * -*****************/ -/// Return the incremental mark of the face -#ifdef __VCGLIB_FACE_M - 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_M - imark = 0; -#endif - } /// Return the DOUBLE of the area of the face -FCTYPE Area() const +ScalarType Area() const { return Norm( (V(1)->P() - V(0)->P()) ^ (V(2)->P() - V(0)->P()) ); } -vectorial_type Barycenter() const +CoordType Barycenter() const { - return (V(0)->P()+V(1)->P()+V(2)->P())/FCTYPE(3.0); + return (V(0)->P()+V(1)->P()+V(2)->P())/ScalarType(3.0); } -FCTYPE Perimeter() const +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 quality of the face, the return value is in [0,sqrt(3)/2] = [0 - 0.866.. ] -FCTYPE QualityFace( ) const +/// 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)->P(), V(1)->P(), V(2)->P()); /* - vectorial_type d10 = V(1)->P() - V(0)->P(); - vectorial_type d20 = V(2)->P() - V(0)->P(); - vectorial_type d12 = V(1)->P() - V(2)->P(); + CoordType d10 = V(1)->P() - V(0)->P(); + CoordType d20 = V(2)->P() - V(0)->P(); + CoordType d12 = V(1)->P() - V(2)->P(); - vectorial_type x = d10^d20; + CoordType x = d10^d20; - FCTYPE a = Norm( x ); // doppio dell' Area - FCTYPE b; + ScalarType a = Norm( x ); // doppio dell' Area + ScalarType b; b = Norm2( d10 ); - FCTYPE t = b; + ScalarType t = b; t = Norm2( d20 ); if( bZ(Z((e+1)%3)) = (e+1)%3; - F((e+2)%3)->Z(Z((e+2)%3)) = (e+2)%3; -#endif -}*/ - -// Stacca la faccia corrente dalla catena di facce incidenti sul vertice z, -// NOTA funziona SOLO per la topologia VF!!! -// usata nelle classi di collapse -void VFDetach(int z) -{ - - if(V(z)->Fp()==this ) - { - int fz = V(z)->Zp(); - V(z)->Fp() = (face_from_vert_type *) F(fz); - V(z)->Zp() = Z(fz); - } - else - { - VEdgePosB x,y; - - x.f = V(z)->Fp(); - x.z = V(z)->Zp(); - - for(;;) - { - y = x; - x.NextF(); - assert(x.f!=0); - if(x.f==this) - { - y.f->F(y.z) = F(z); - y.f->Z(y.z) = Z(z); - break; - } - } - } -} - // Sezione dist e ray -#ifdef __VCGLIB_FACE_E - vectorial_type edge[3]; - Plane3 plane; +#ifdef __VCGLIB_FACE_RT + CoordType edge[3]; + Plane3 plane; +#endif - void ComputeE() - { + void ComputeRT() + { + #ifdef __VCGLIB_FACE_RT // Primo calcolo degli edges edge[0] = V(1)->P(); edge[0] -= V(0)->P(); edge[1] = V(2)->P(); edge[1] -= V(1)->P(); edge[2] = V(0)->P(); edge[2] -= V(2)->P(); // Calcolo di plane - plane.n = edge[0]^edge[1]; - plane.d = plane.n * V(0)->P(); + plane._n = edge[0]^edge[1]; + plane.d = plane._n * V(0)->P(); plane.Normalize(); // Calcolo migliore proiezione - scalar_type nx = Abs(plane.n[0]); - scalar_type ny = Abs(plane.n[1]); - scalar_type nz = Abs(plane.n[2]); - scalar_type d; - if(nx>ny && nx>nz) { flags |= NORMX; d = 1/plane.n[0]; } - else if(ny>nz) { flags |= NORMY; d = 1/plane.n[1]; } - else { flags |= NORMZ; d = 1/plane.n[2]; } + ScalarType nx = Abs(plane._n[0]); + ScalarType ny = Abs(plane._n[1]); + ScalarType nz = Abs(plane._n[2]); + ScalarType d; + if(nx>ny && nx>nz) { _flags |= NORMX; d = 1/plane._n[0]; } + else if(ny>nz) { _flags |= NORMY; d = 1/plane._n[1]; } + else { _flags |= NORMZ; d = 1/plane._n[2]; } // Scalatura spigoli edge[0] *= d; edge[1] *= d; edge[2] *= d; - } - -/* - Point face distance - trova il punto

sulla faccia piu' vicino a , con possibilità di - rejection veloce su se la distanza trovata è maggiore di - - Commenti del 12/11/02 - Funziona solo se la faccia e di quelle di tipo E (con edge e piano per faccia gia' calcolati) - algoritmo: - 1) si calcola la proiezione

di q sul piano della faccia - 2) se la distanza punto piano e' > rejdist ritorna - 3) si lavora sul piano migliore e si cerca di capire se il punto sta dentro il triangolo: - a) prodotto vettore tra edge triangolo (v[i+1]-v[i]) e (p-v[i]) - b) se il risultato e' negativo (gira in senso orario) allora il punto - sta fuori da quella parte e si fa la distanza punto segmento. - c) se il risultato sempre positivo allora sta dentro il triangolo - 4) e si restituisce la distanza punto /piano gia` calcolata - - Note sulla robustezza: - il calcolo del prodotto vettore e` la cosa piu` delicata: - possibili fallimenti quando a^b ~= 0 - 1) doveva essere <= 0 e viene positivo (q era fuori o sulla linea dell'edge) - allora capita che si faccia la distanza punto piano anziche` la distanza punto seg - 2) doveva essere > 0 e viene <=0 (q era dentro il triangolo) - -*/ - bool Dist( const vectorial_type & q, scalar_type & dist, vectorial_type & p ) - { - //const scalar_type EPSILON = scalar_type( 0.000001); - const scalar_type EPSILON = 0.00000001; - scalar_type b,b0,b1,b2; - // Calcolo distanza punto piano - scalar_type d = Distance( plane, q ); - if( d>dist || d<-dist ) // Risultato peggiore: niente di fatto - return false; - - // Calcolo del punto sul piano - // NOTA: aggiunto un '-d' in fondo Paolo C. - vectorial_type t = plane.n; - t[0] *= -d; - t[1] *= -d; - t[2] *= -d; - p = q; p += t; - - #define PP(i) (v[i]->P()) - #define E(i) (edge[i]) - - switch( flags & (NORMX|NORMY|NORMZ) ) - { - case NORMX: - b0 = E(1)[1]*(p[2] - PP(1)[2]) - E(1)[2]*(p[1] - PP(1)[1]); - if(b0<=0) - { - b0 = PSDist(q,V(1)->P(),V(2)->P(),p); - if(dist>b0) { dist = b0; return true; } - else return false; - } - b1 = E(2)[1]*(p[2] - PP(2)[2]) - E(2)[2]*(p[1] - PP(2)[1]); - if(b1<=0) - { - b1 = PSDist(q,V(2)->P(),V(0)->P(),p); - if(dist>b1) { dist = b1; return true; } - else return false; - } - b2 = E(0)[1]*(p[2] - PP(0)[2]) - E(0)[2]*(p[1] - PP(0)[1]); - if(b2<=0) - { - b2 = PSDist(q,V(0)->P(),V(1)->P(),p); - if(dist>b2) { dist = b2; return true; } - else return false; - } - // sono tutti e tre > 0 quindi dovrebbe essere dentro; - // per sicurezza se il piu' piccolo dei tre e' < epsilon (scalato rispetto all'area della faccia - // per renderlo dimension independent.) allora si usa ancora la distanza punto - // segmento che e' piu robusta della punto piano, e si fa dalla parte a cui siamo piu' - // vicini (come prodotto vettore) - // Nota: si potrebbe rendere un pochino piu' veloce sostituendo Area() - // con il prodotto vettore dei due edge in 2d lungo il piano migliore. - if( (b=min(b0,min(b1,b2))) < EPSILON*Area()) - { - scalar_type bt; - if(b==b0) bt = PSDist(q,V(1)->P(),V(2)->P(),p); - else if(b==b1) bt = PSDist(q,V(2)->P(),V(0)->P(),p); - else if(b==b2) bt = PSDist(q,V(0)->P(),V(1)->P(),p); - //printf("Warning area:%g %g %g %g thr:%g bt:%g\n",Area(), b0,b1,b2,EPSILON*Area(),bt); - if(dist>bt) { dist = bt; return true; } - else return false; - } - break; - - case NORMY: - b0 = E(1)[2]*(p[0] - PP(1)[0]) - E(1)[0]*(p[2] - PP(1)[2]); - if(b0<=0) - { - b0 = PSDist(q,V(1)->P(),V(2)->P(),p); - if(dist>b0) { dist = b0; return true; } - else return false; - } - b1 = E(2)[2]*(p[0] - PP(2)[0]) - E(2)[0]*(p[2] - PP(2)[2]); - if(b1<=0) - { - b1 = PSDist(q,V(2)->P(),V(0)->P(),p); - if(dist>b1) { dist = b1; return true; } - else return false; - } - b2 = E(0)[2]*(p[0] - PP(0)[0]) - E(0)[0]*(p[2] - PP(0)[2]); - if(b2<=0) - { - b2 = PSDist(q,V(0)->P(),V(1)->P(),p); - if(dist>b2) { dist = b2; return true; } - else return false; - } - if( (b=min(b0,min(b1,b2))) < EPSILON*Area()) - { - scalar_type bt; - if(b==b0) bt = PSDist(q,V(1)->P(),V(2)->P(),p); - else if(b==b1) bt = PSDist(q,V(2)->P(),V(0)->P(),p); - else if(b==b2) bt = PSDist(q,V(0)->P(),V(1)->P(),p); - //printf("Warning area:%g %g %g %g thr:%g bt:%g\n",Area(), b0,b1,b2,EPSILON*Area(),bt); - if(dist>bt) { dist = bt; return true; } - else return false; - } - break; - - case NORMZ: - b0 = E(1)[0]*(p[1] - PP(1)[1]) - E(1)[1]*(p[0] - PP(1)[0]); - if(b0<=0) - { - b0 = PSDist(q,V(1)->P(),V(2)->P(),p); - if(dist>b0) { dist = b0; return true; } - else return false; - } - b1 = E(2)[0]*(p[1] - PP(2)[1]) - E(2)[1]*(p[0] - PP(2)[0]); - if(b1<=0) - { - b1 = PSDist(q,V(2)->P(),V(0)->P(),p); - if(dist>b1) { dist = b1; return true; } - else return false; - } - b2 = E(0)[0]*(p[1] - PP(0)[1]) - E(0)[1]*(p[0] - PP(0)[0]); - if(b2<=0) - { - b2 = PSDist(q,V(0)->P(),V(1)->P(),p); - if(dist>b2) { dist = b2; return true; } - else return false; - } - if( (b=min(b0,min(b1,b2))) < EPSILON*Area()) - { - scalar_type bt; - if(b==b0) bt = PSDist(q,V(1)->P(),V(2)->P(),p); - else if(b==b1) bt = PSDist(q,V(2)->P(),V(0)->P(),p); - else if(b==b2) bt = PSDist(q,V(0)->P(),V(1)->P(),p); - //printf("Warning area:%g %g %g %g thr:%g bt:%g\n",Area(), b0,b1,b2,EPSILON*Area(),bt); - - if(dist>bt) { dist = bt; return true; } - else return false; - } - break; - } - - #undef E - #undef PP - - dist = scalar_type(fabs(d)); - //dist = Distance(p,q); - return true; - } - - - //Intersect ray with triangle. This is an optimized version of the - //intersection routine from Snyder and Barr's '87 SIGGRAPH paper. - //Si distingue fra distanza negativa e positiva (N e P) - //Returns 1 or 0 - static inline bool CheckVal( const scalar_type b ){ - return b<-1e-20 || b>1.0+1e-20 ; - } - - bool Intersect( Line3 const & r, scalar_type &d ) - { - const scalar_type EPSILON = 1e-20; - - vectorial_type p; - - scalar_type k = plane.n * r.dire; // Plane intersection. - if (k< EPSILON && k>-EPSILON) - return false; - - d = (plane.d - plane.n * r.orig) / k; - p = r.orig + r.dire*d; - - scalar_type b; - - vectorial_type p0 = v[0]->P(); - vectorial_type p1 = v[1]->P(); - vectorial_type p2 = v[2]->P(); - - switch(flags & (NORMX|NORMY|NORMZ)){ - case NORMX: - b= edge[1][1]*(p[2]-p1[2]) - edge[1][2]*(p[1]-p1[1]); if(CheckVal(b)) return false; - b= edge[2][1]*(p[2]-p2[2]) - edge[2][2]*(p[1]-p2[1]); if(CheckVal(b)) return false; - b= edge[0][1]*(p[2]-p0[2]) - edge[0][2]*(p[1]-p0[1]); if(CheckVal(b)) return false; - break; - case NORMY: - b= edge[1][2]*(p[0]-p1[0]) - edge[1][0]*(p[2]-p1[2]); if(CheckVal(b)) return false; - b= edge[2][2]*(p[0]-p2[0]) - edge[2][0]*(p[2]-p2[2]); if(CheckVal(b)) return false; - b= edge[0][2]*(p[0]-p0[0]) - edge[0][0]*(p[2]-p0[2]); if(CheckVal(b)) return false; - break; - case NORMZ: - b= edge[1][0]*(p[1]-p1[1]) - edge[1][1]*(p[0]-p1[0]); if(CheckVal(b)) return false; - b= edge[2][0]*(p[1]-p2[1]) - edge[2][1]*(p[0]-p2[0]); if(CheckVal(b)) return false; - b= edge[0][0]*(p[1]-p0[1]) - edge[0][1]*(p[0]-p0[0]); if(CheckVal(b)) return false; - break; - } - - return true; - } - #endif + } + - // Intersect ray with triangle. - // returns barycientric coordinate and dist - bool Intersect( Line3 const & ray, scalar_type & dist, scalar_type &a, scalar_type &b) { - //static double a,b; - return Intersection( ray, v[0]->P(), v[1]->P(), v[2]->P(), a,b, dist ); - }; /// return the index [0..2] of a vertex in a face inline int VertexIndex( const FVTYPE * w ) const @@ -1669,48 +1157,6 @@ void VFDetach(int z) else return -1; } - /// Return the texture distorsion - scalar_type texture_distorsion( int nt=0 ) const - { -#ifndef __VCGLIB_FACE_WT - assert(0); -#endif - scalar_type e = 0; - for(int nz=0;nz<3;++nz) - { - scalar_type l0 = Distance( V1(nz)->P(),V(nz)->P() ); - scalar_type l1 = Distance( WT((nz+1)%3).t(nt), WT(nz).t(nt) ); - scalar_type dl = l1-l0; - e += dl*dl; - } - e = (e/3)/ Area(); - return e; - } - - /// Return the texture distorsion - scalar_type hoppe_distorsion( int nt=0 ) const - { -#ifndef __VCGLIB_FACE_WT - assert(0); -#endif - scalar_type A = Area(); - - scalar_type s1 = WT(0).u(nt); - scalar_type t1 = WT(0).v(nt); - scalar_type s2 = WT(1).u(nt); - scalar_type t2 = WT(1).v(nt); - scalar_type s3 = WT(2).u(nt); - scalar_type t3 = WT(2).v(nt); - - vectorial_type Ss = (V(0)->P()*(t2-t3)+V(1)->P()*(t3-t1)+V(2)->P()*(t1-t2))/(2*A); - vectorial_type St = (V(0)->P()*(s3-s2)+V(1)->P()*(s1-s3)+V(2)->P()*(s2-s1))/(2*A); - - scalar_type a = Ss*Ss; - scalar_type b = Ss*St; - scalar_type c = St*St; - - return sqrt((a+c)/2+sqrt((a-c)*(a-c)+4*b*b)); - } }; //end Class