From a39a42d2ca15285f992126e87c6faf71b44c177d Mon Sep 17 00:00:00 2001 From: ganovelli Date: Mon, 4 Feb 2008 21:26:49 +0000 Subject: [PATCH] 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 --- vcg/simplex/faceplus/base.h | 5 +++ vcg/simplex/faceplus/component.h | 48 +++++++++++++++++++++++++- vcg/simplex/faceplus/component_ocf.h | 27 ++++++++++++++- vcg/simplex/vertexplus/base.h | 5 +++ vcg/simplex/vertexplus/component.h | 43 +++++++++++++++++++++-- vcg/simplex/vertexplus/component_ocf.h | 18 ++++++++++ 6 files changed, 142 insertions(+), 4 deletions(-) diff --git a/vcg/simplex/faceplus/base.h b/vcg/simplex/faceplus/base.h index ded822e4..f90c1f30 100644 --- a/vcg/simplex/faceplus/base.h +++ b/vcg/simplex/faceplus/base.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +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 @@ -97,6 +100,8 @@ class FaceTypeHolder{ typedef BET *EdgePointer; typedef BFT *FacePointer; typedef BTT *TetraPointer; + template + void ImportLocal(const LeftF & l){} static void Name(std::vector & name){} diff --git a/vcg/simplex/faceplus/component.h b/vcg/simplex/faceplus/component.h index 8b86b019..4d09fbca 100644 --- a/vcg/simplex/faceplus/component.h +++ b/vcg/simplex/faceplus/component.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +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 @@ -112,6 +115,8 @@ public: 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(T::ImportLocal(leftF);} static bool HasVertexRef() { return false; } static void Name(std::vector & name){T::Name(name);} @@ -159,6 +164,10 @@ public: 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);} + static bool HasVertexRef() { return true; } static void Name(std::vector & name){name.push_back(std::string("VertexRef"));T::Name(name);} @@ -180,6 +189,8 @@ public: 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; } @@ -194,6 +205,8 @@ 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);} static bool HasFaceNormal() { return true; } // void ComputeNormal() { _norm = vcg::Normal(*(static_cast(this))); } // void ComputeNormalizedNormal() { _norm = vcg::NormalizedNormal(*this);} @@ -215,6 +228,8 @@ 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);} static bool HasFaceNormal() { return true; } static void Name(std::vector & name){name.push_back(std::string("NormalAbs"));T::Name(name);} @@ -227,6 +242,8 @@ 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);} static bool HasWedgeNormal() { return true; } static void Name(std::vector & name){name.push_back(std::string("WedgeNormal"));T::Name(name);} @@ -254,6 +271,8 @@ public: 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){ TT::ImportLocal(leftF);} static bool HasWedgeTexCoord() { return false; } static bool HasWedgeTexCoordOcc() { return false; } static void Name(std::vector & name){TT::Name(name);} @@ -265,6 +284,8 @@ public: 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();TT::ImportLocal(leftF);} static bool HasWedgeTexCoord() { return true; } static void Name(std::vector & name){name.push_back(std::string("WedgeTexCoord"));TT::Name(name);} @@ -288,6 +309,8 @@ 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);} static bool HasFlags() { return false; } static bool HasFlagsOcc() { return false; } static void Name(std::vector & name){T::Name(name);} @@ -298,7 +321,10 @@ template class BitFlags: public T { public: BitFlags(){_flags=0;} int &Flags() {return _flags; } - const int Flags() const {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);} static bool HasFlags() { return true; } static void Name(std::vector & name){name.push_back(std::string("BitFlags"));T::Name(name);} @@ -328,6 +354,9 @@ public: typedef A ColorType; Color():_color(vcg::Color4b::White) {} ColorType &C() { return _color; } + const ColorType &cC() { return _color; } + template + void ImportLocal(const LeftF & leftF){ C() = leftF.cC();T::ImportLocal(leftF);} static bool HasFaceColor() { return true; } static void Name(std::vector & name){name.push_back(std::string("Color"));T::Name(name);} @@ -339,6 +368,10 @@ 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);} @@ -361,6 +394,9 @@ 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);} 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);} @@ -387,6 +423,8 @@ public: inline void InitIMark() { } inline int & IMark() { assert(0); static int tmp=-1; return tmp;} inline const int IMark() const {return 0;} + template + void ImportLocal(const LeftF & leftF){T::ImportLocal(leftF);} static void Name(std::vector & name){T::Name(name);} }; @@ -397,6 +435,8 @@ public: 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: @@ -418,6 +458,8 @@ public: 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);} static bool HasVFAdjacency() { return false; } static bool HasFFAdjacency() { return false; } static bool HasFFAdjacencyOcc() { return false; } @@ -437,6 +479,8 @@ public: 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);} 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);} @@ -466,6 +510,8 @@ public: 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);} 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);} diff --git a/vcg/simplex/faceplus/component_ocf.h b/vcg/simplex/faceplus/component_ocf.h index e92161fa..ef8d5a6c 100644 --- a/vcg/simplex/faceplus/component_ocf.h +++ b/vcg/simplex/faceplus/component_ocf.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +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. @@ -335,6 +338,11 @@ public: assert((*this).Base().VFAdjacencyEnabled); return (*this).Base().AV[(*this).Index()]._zp[j]; } + + template + void ImportLocal(const LeftF & leftF){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; } @@ -364,6 +372,11 @@ public: assert((*this).Base().FFAdjacencyEnabled); return (*this).Base().AF[(*this).Index()]._zp[j]; } + + template + void ImportLocal(const LeftF & leftF){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; } @@ -387,6 +400,8 @@ public: assert((*this).Base().NormalEnabled); return (*this).Base().NV[(*this).Index()]; } + template + void ImportLocal(const LeftF & leftF){N() = leftF.cN(); T::ImportLocal(leftF);} }; @@ -403,6 +418,9 @@ public: assert((*this).Base().ColorEnabled); return (*this).Base().CV[(*this).Index()]; } + + template + void ImportLocal(const LeftF & leftF){C() = leftF.cC(); T::ImportLocal(leftF);} static bool HasFaceColor() { return true; } static bool HasFaceColorOcf() { return true; } }; @@ -422,7 +440,9 @@ public: assert((*this).Base().MarkEnabled); return (*this).Base().MV[(*this).Index()]; } ; - + + template + void ImportLocal(const LeftF & leftF){IMark() = leftF.cIMark(); T::ImportLocal(leftF);} static bool HasFaceMark() { return true; } static bool HasFaceMarkOcf() { return true; } inline void InitIMark() { IMark() = 0; } @@ -436,6 +456,8 @@ public: 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){WT() = leftF.cWT(); T::ImportLocal(leftF);} static bool HasWedgeTexCoord() { return true; } static bool HasWedgeTexCoordOcf() { return true; } }; @@ -448,6 +470,9 @@ 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; } diff --git a/vcg/simplex/vertexplus/base.h b/vcg/simplex/vertexplus/base.h index 8fc2d1f5..a07e6132 100644 --- a/vcg/simplex/vertexplus/base.h +++ b/vcg/simplex/vertexplus/base.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.10 2007/03/12 15:37:21 tarini +Texture coord name change! "TCoord" and "Texture" are BAD. "TexCoord" is GOOD. + Revision 1.9 2007/02/12 19:00:56 ganovelli added Name(std:vector& n) that fills n with the names of the attribute of the vertex type @@ -84,6 +87,8 @@ class VertexTypeHolder{ typedef BET *EdgePointer; typedef BFT *FacePointer; typedef BTT *TetraPointer; + template < class LeftV> + void ImportLocal(const LeftV & left ) { } static void Name(std::vector & name){} }; diff --git a/vcg/simplex/vertexplus/component.h b/vcg/simplex/vertexplus/component.h index 2ca5a82a..afa1b422 100644 --- a/vcg/simplex/vertexplus/component.h +++ b/vcg/simplex/vertexplus/component.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.23 2007/06/04 15:40:22 turini +Add vertex-tetrahedron adjacency component VTAdj. + Revision 1.22 2007/03/12 15:37:21 tarini Texture coord name change! "TCoord" and "Texture" are BAD. "TexCoord" is GOOD. @@ -120,6 +123,8 @@ public: const CoordType &P() const { static CoordType coord(0, 0, 0); assert(0); return coord; } const CoordType &cP() const { static CoordType coord(0, 0, 0); assert(0); return coord; } CoordType &UberP() { static CoordType coord(0, 0, 0); return coord; } + template < class LeftV> + void ImportLocal(const LeftV & left ) { T::ImportLocal( left); } static bool HasCoord() { return false; } static void Name(std::vector & name){T::Name(name);} @@ -133,7 +138,9 @@ public: const CoordType &P() const { return _coord; } const CoordType &cP() const { return _coord; } CoordType &UberP() { return _coord; } - + + template < class LeftV> + void ImportLocal(const LeftV & left ) { P() = left.cP(); T::ImportLocal( left); } static bool HasCoord() { return true; } static void Name(std::vector & name){name.push_back(std::string("Coord"));T::Name(name);} @@ -154,7 +161,9 @@ public: typedef vcg::Point3s 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); assert(0); return dummy_normal; } - static bool HasNormal() { return false; } + template < class LeftV> + void ImportLocal(const LeftV & left ) { T::ImportLocal( left); } + static bool HasNormal() { return false; } static bool HasNormalOcc() { return false; } static void Name(std::vector & name){T::Name(name);} @@ -164,6 +173,8 @@ public: typedef A NormalType; NormalType &N() { return _norm; } const NormalType &cN() const { return _norm; } + template < class LeftV> + void ImportLocal(const LeftV & left ) { N() = left.cN(); T::ImportLocal( left); } static bool HasNormal() { return true; } static void Name(std::vector & name){name.push_back(std::string("Normal"));T::Name(name);} @@ -191,6 +202,8 @@ public: inline void InitIMark() { } inline int & IMark() { assert(0); static int tmp=-1; return tmp;} inline const int & IMark() const {return 0;} + template < class LeftV> + void ImportLocal(const LeftV & left ) { T::ImportLocal( left); } static void Name(std::vector & name){T::Name(name);} }; @@ -201,6 +214,8 @@ public: inline void InitIMark() { _imark = 0; } inline int & IMark() { return _imark;} inline const int & IMark() const {return _imark;} + template < class LeftV> + void ImportLocal(const LeftV & left ) { IMark() = left.IMark(); T::ImportLocal( left); } static void Name(std::vector & name){name.push_back(std::string("Mark"));T::Name(name);} private: @@ -213,6 +228,8 @@ template class EmptyTexCoord: public TT { public: typedef vcg::TexCoord2 TexCoordType; TexCoordType &T() { static TexCoordType dummy_texcoord; assert(0); return dummy_texcoord; } + template < class LeftV> + void ImportLocal(const LeftV & left ) { TT::ImportLocal( left); } static bool HasTexCoord() { return false; } static void Name(std::vector & name){TT::Name(name);} @@ -221,6 +238,9 @@ template class TexCoord: public TT { public: typedef A TexCoordType; TexCoordType &T() { return _t; } + const TexCoordType &cT() const { return _t; } + template < class LeftV> + void ImportLocal(const LeftV & left ) { T() = left.cT(); T::ImportLocal( left); } static bool HasTexCoord() { return true; } static void Name(std::vector & name){name.push_back(std::string("TexCoord"));TT::Name(name);} @@ -246,6 +266,8 @@ 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 < class LeftV> + void ImportLocal(const LeftV & left ) { T::ImportLocal( left); } static bool HasFlags() { return false; } static void Name(std::vector & name){T::Name(name);} @@ -257,6 +279,8 @@ public: typedef int FlagType; int &Flags() {return _flags; } const int Flags() const {return _flags; } + template < class LeftV> + void ImportLocal(const LeftV & left ) { Flags() = left.cFlags(); T::ImportLocal( left); } static bool HasFlags() { return true; } static void Name(std::vector & name){name.push_back(std::string("BitFlags"));T::Name(name);} @@ -270,6 +294,8 @@ template class EmptyColor: public T { public: typedef vcg::Color4b ColorType; ColorType &C() { static ColorType dumcolor(vcg::Color4b::White); assert(0); return dumcolor; } + template < class LeftV> + void ImportLocal(const LeftV & left ) { T::ImportLocal( left); } static bool HasColor() { return false; } static void Name(std::vector & name){T::Name(name);} @@ -279,6 +305,10 @@ public: Color():_color(vcg::Color4b::White) {} typedef A ColorType; ColorType &C() { return _color; } + const ColorType &C() const { return _color; } + const ColorType &cC() const { return _color; } + template < class LeftV> + void ImportLocal(const LeftV & left ) { C() = left.cC(); T::ImportLocal( left); } static bool HasColor() { return true; } static void Name(std::vector & name){name.push_back(std::string("Color"));T::Name(name);} @@ -296,6 +326,8 @@ template class EmptyQuality: public T { public: typedef float QualityType; QualityType &Q() { static QualityType dummyQuality(0); assert(0); return dummyQuality; } + template < class LeftV> + void ImportLocal(const LeftV & left ) { T::ImportLocal( left); } static bool HasQuality() { return false; } static void Name(std::vector & name){T::Name(name);} @@ -304,6 +336,9 @@ template class Quality: public TT { public: typedef A QualityType; QualityType &Q() { return _quality; } + const QualityType & cQ() const {return _quality; } + template < class LeftV> + void ImportLocal(const LeftV & left ) { Q() = left.cQ(); TT::ImportLocal( left); } static bool HasQuality() { return true; } static void Name(std::vector & name){name.push_back(std::string("Quality"));TT::Name(name);} @@ -329,6 +364,8 @@ public: typename T::FacePointer &VFp() { static typename T::FacePointer fp=0; assert(0); return fp; } typename T::FacePointer cVFp() { static typename T::FacePointer fp=0; assert(0); return fp; } int &VFi(){static int z=0; return z;}; + template < class LeftV> + void ImportLocal(const LeftV & left ) { T::ImportLocal( left); } static bool HasVFAdjacency() { return false; } static bool HasVFAdjacencyOcc() { return false; } static void Name(std::vector & name){ T::Name(name);} @@ -340,6 +377,8 @@ public: typename T::FacePointer &VFp() {return _fp; } typename T::FacePointer cVFp() {return _fp; } int &VFi() {return _zp; } + template < class LeftV> + void ImportLocal(const LeftV & left ) { VFp() = NULL; T::ImportLocal( left); } static bool HasVFAdjacency() { return true; } static bool HasVFAdjacencyOcc() { return true; } static void Name(std::vector & name){name.push_back(std::string("VFAdj"));T::Name(name);} diff --git a/vcg/simplex/vertexplus/component_ocf.h b/vcg/simplex/vertexplus/component_ocf.h index 6b14c643..0e0d1bf2 100644 --- a/vcg/simplex/vertexplus/component_ocf.h +++ b/vcg/simplex/vertexplus/component_ocf.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.11 2007/12/11 18:25:31 cignoni +added missing include limits + Revision 1.10 2007/12/11 11:36:03 cignoni Added the CompactVertexVector garbage collecting function. @@ -246,6 +249,9 @@ public: assert((*this).Base().VFAdjacencyEnabled); return (*this).Base().AV[(*this).Index()()]._zp; } + template + void ImportLocal(const LeftV & leftv){VFp() = NULL; VFi() = -1; T::ImporLocal(leftV);} + static bool HasVFAdjacency() { return true; } static bool HasVFAdjacencyOcf() { return true; } @@ -264,6 +270,13 @@ public: // you cannot use Normals before enabling them with: yourmesh.vert.EnableNormal() assert((*this).Base().NormalEnabled); return (*this).Base().NV[(*this).Index()]; } + const NormalType &N() const { + // you cannot use Normals before enabling them with: yourmesh.vert.EnableNormal() + assert((*this).Base().NormalEnabled); + return (*this).Base().NV[(*this).Index()]; } + + template + void ImportLocal(const LeftV & leftv){ N() = leftV.cN(); T::ImporLocal(leftV);} }; template class Normal3sOcf: public NormalOcf {}; @@ -276,6 +289,9 @@ template class ColorOcf: public T { public: typedef A ColorType; ColorType &C() { assert((*this).Base().NormalEnabled); return (*this).Base().CV[(*this).Index()()]; } + const ColorType &cC() const { assert((*this).Base().NormalEnabled); return (*this).Base().CV[(*this).Index()()]; } + template + void ImportLocal(const LeftV & leftv){ C() = leftV.cC(); T::ImporLocal(leftV);} static bool HasColor() { return true; } static bool HasColorOcf() { return true; } }; @@ -288,6 +304,8 @@ template class QualityOcf: public T { public: typedef A QualityType; QualityType &Q() { assert((*this).Base().QualityEnabled); return (*this).Base().QV[(*this).Index()()]; } + template + void ImportLocal(const LeftV & leftv){ Q() = leftV.cQ(); T::ImporLocal(leftV);} static bool HasQuality() { return true; } static bool HasQualityOcf() { return true; } };