/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004-2012 \/)\/ * * 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_MESH #define __VCG_MESH #include #include #include #include #include #include #include #include #include #include namespace vcg { namespace tri { /** \addtogroup trimesh */ /*@{*/ /* MeshTypeHolder is a class which is used to define the types in the mesh */ template struct BaseMeshTypeHolder{ typedef bool ScalarType; typedef std::vector< typename TYPESPOOL::VertexType > CONTV; typedef std::vector< typename TYPESPOOL::EdgeType > CONTE; typedef std::vector< typename TYPESPOOL::FaceType > CONTF; typedef std::vector< typename TYPESPOOL::HEdgeType > CONTH; typedef CONTV VertContainer; typedef _Vertex VertexType; typedef typename TYPESPOOL::VertexPointer VertexPointer; typedef const typename TYPESPOOL::VertexPointer ConstVertexPointer; typedef bool CoordType; typedef typename CONTV::iterator VertexIterator; typedef typename CONTV::const_iterator ConstVertexIterator; typedef CONTE EdgeContainer; typedef typename CONTE::value_type EdgeType; typedef typename TYPESPOOL::EdgePointer EdgePointer; typedef typename CONTE::iterator EdgeIterator; typedef typename CONTE::const_iterator ConstEdgeIterator; typedef CONTF FaceContainer; typedef typename CONTF::value_type FaceType; typedef typename CONTF::const_iterator ConstFaceIterator; typedef typename CONTF::iterator FaceIterator; typedef typename TYPESPOOL::FacePointer FacePointer; typedef const typename TYPESPOOL::FacePointer ConstFacePointer; typedef CONTH HEdgeContainer; typedef typename CONTH::value_type HEdgeType; typedef typename TYPESPOOL::HEdgePointer HEdgePointer; typedef typename CONTH::iterator HEdgeIterator; typedef typename CONTH::const_iterator ConstHEdgeIterator; }; template struct MeshTypeHolder: public T {}; template struct MeshTypeHolder: public T { typedef CONT VertContainer; typedef typename VertContainer::value_type VertexType; typedef VertexType * VertexPointer; typedef const VertexType * ConstVertexPointer; typedef typename VertexType::ScalarType ScalarType; typedef typename VertexType::CoordType CoordType; typedef typename VertContainer::iterator VertexIterator; typedef typename VertContainer::const_iterator ConstVertexIterator; }; template struct MeshTypeHolder< T, CONT, AllTypes::AEdgeType>: public T{ typedef CONT EdgeContainer; typedef typename EdgeContainer::value_type EdgeType; typedef typename EdgeContainer::value_type * EdgePointer; typedef typename EdgeContainer::iterator EdgeIterator; typedef typename EdgeContainer::const_iterator ConstEdgeIterator; }; template struct MeshTypeHolder< T, CONT, AllTypes::AFaceType>:public T { typedef CONT FaceContainer; typedef typename FaceContainer::value_type FaceType; typedef typename FaceContainer::const_iterator ConstFaceIterator; typedef typename FaceContainer::iterator FaceIterator; typedef FaceType * FacePointer; typedef const FaceType * ConstFacePointer; }; template struct MeshTypeHolder< T, CONT, AllTypes::AHEdgeType>: public T{ typedef CONT HEdgeContainer; typedef typename HEdgeContainer::value_type HEdgeType; typedef typename HEdgeContainer::value_type * HEdgePointer; typedef typename HEdgeContainer::iterator HEdgeIterator; typedef typename HEdgeContainer::const_iterator ConstHEdgeIterator; }; template struct Der: public MeshTypeHolder{}; struct DummyContainer{struct value_type{ typedef int IAm;}; }; /** \brief The official \b mesh class As explained in \ref basic_concepts, this class is templated over a list of container of simplexes (like vertex, face, edges) */ template < class Container0 = DummyContainer, class Container1 = DummyContainer, class Container2 = DummyContainer, class Container3 = DummyContainer > class TriMesh : public MArity4< BaseMeshTypeHolder, Container0, Der ,Container1, Der, Container2, Der, Container3, Der>{ public: typedef typename TriMesh::ScalarType ScalarType; typedef typename TriMesh::VertContainer VertContainer; typedef typename TriMesh::EdgeContainer EdgeContainer; typedef typename TriMesh::FaceContainer FaceContainer; // types for vertex typedef typename TriMesh::VertexType VertexType; typedef typename TriMesh::VertexPointer VertexPointer; typedef typename TriMesh::ConstVertexPointer ConstVertexPointer; typedef typename TriMesh::CoordType CoordType; typedef typename TriMesh::VertexIterator VertexIterator; typedef typename TriMesh::ConstVertexIterator ConstVertexIterator; // types for edge typedef typename TriMesh::EdgeType EdgeType; typedef typename TriMesh::EdgePointer EdgePointer; typedef typename TriMesh::EdgeIterator EdgeIterator; typedef typename TriMesh::ConstEdgeIterator ConstEdgeIterator; //types for face typedef typename TriMesh::FaceType FaceType; typedef typename TriMesh::ConstFaceIterator ConstFaceIterator; typedef typename TriMesh::FaceIterator FaceIterator; typedef typename TriMesh::FacePointer FacePointer; typedef typename TriMesh::ConstFacePointer ConstFacePointer; // types for hedge typedef typename TriMesh::HEdgeType HEdgeType; typedef typename TriMesh::HEdgePointer HEdgePointer; typedef typename TriMesh::HEdgeIterator HEdgeIterator; typedef typename TriMesh::HEdgeContainer HEdgeContainer; typedef typename TriMesh::ConstHEdgeIterator ConstHEdgeIterator; typedef vcg::PointerToAttribute PointerToAttribute; typedef TriMesh MeshType; typedef Box3 BoxType; /// Container of vertices, usually a vector. VertContainer vert; /// Current number of vertices; this member is for internal use only. You should always use the VN() member int vn; /// Current number of vertices inline int VN() const { return vn; } /// Container of edges, usually a vector. EdgeContainer edge; /// Current number of edges; this member is for internal use only. You should always use the EN() member int en; /// Current number of edges inline int EN() const { return en; } /// Container of faces, usually a vector. FaceContainer face; /// Current number of faces; this member is for internal use only. You should always use the FN() member int fn; /// Current number of faces inline int FN() const { return fn; } /// Container of half edges, usually a vector. HEdgeContainer hedge; /// Current number of halfedges; this member is for internal use only. You should always use the HN() member int hn; /// Current number of halfedges; inline int HN() const { return hn; } /// Bounding box of the mesh Box3 bbox; /// Nomi di textures // std::vector textures; // std::vector normalmaps; int attrn; // total numer of attribute created std::set< PointerToAttribute > vert_attr; std::set< PointerToAttribute > edge_attr; std::set< PointerToAttribute > face_attr; std::set< PointerToAttribute > mesh_attr; template class AttributeHandle{ public: AttributeHandle(){_handle=(SimpleTempData *)NULL;} AttributeHandle( void *ah,const int & n):_handle ( (SimpleTempData *)ah ),n_attr(n){} AttributeHandle operator = ( const PointerToAttribute & pva){ _handle = (SimpleTempData *)pva._handle; n_attr = pva.n_attr; return (*this); } //pointer to the SimpleTempData that stores the attribute SimpleTempData * _handle; // its attribute number int n_attr; // access function template ATTR_TYPE & operator [](const RefType & i){return (*_handle)[i];} }; template class PerVertexAttributeHandle: public AttributeHandle{ public: PerVertexAttributeHandle():AttributeHandle(){} PerVertexAttributeHandle( void *ah,const int & n):AttributeHandle(ah,n){} }; template class PerFaceAttributeHandle: public AttributeHandle{ public: PerFaceAttributeHandle():AttributeHandle(){} PerFaceAttributeHandle( void *ah,const int & n):AttributeHandle(ah,n){} }; template class PerEdgeAttributeHandle: public AttributeHandle{ public: PerEdgeAttributeHandle():AttributeHandle(){} PerEdgeAttributeHandle( void *ah,const int & n):AttributeHandle(ah,n){} }; template class PerMeshAttributeHandle{ public: PerMeshAttributeHandle(){_handle=NULL;} PerMeshAttributeHandle(void *ah,const int & n):_handle ( (Attribute *)ah ),n_attr(n){} PerMeshAttributeHandle operator = ( const PerMeshAttributeHandle & pva){ _handle = (Attribute *)pva._handle; n_attr = pva.n_attr; return (*this); } Attribute * _handle; int n_attr; ATTR_TYPE & operator ()(){ return *((Attribute *)_handle)->attribute;} }; // the camera member (that should keep the intrinsics) is no more needed since 2006, when intrisncs moved into the Shot structure //Camera camera; // intrinsic Shot shot; // intrinsic && extrinsic private: /// The per-mesh color. Not very useful and meaningful... Color4b c; public: inline Color4b C() const { return c; } inline Color4b & C() { return c; } /// Default constructor TriMesh() { Clear(); } /// destructor ~TriMesh() { typename std::set< PointerToAttribute>::iterator i; for( i = vert_attr.begin(); i != vert_attr.end(); ++i) delete ((SimpleTempDataBase*)(*i)._handle); for( i = edge_attr.begin(); i != edge_attr.end(); ++i) delete ((SimpleTempDataBase*)(*i)._handle); for( i = face_attr.begin(); i != face_attr.end(); ++i) delete ((SimpleTempDataBase*)(*i)._handle); for( i = mesh_attr.begin(); i != mesh_attr.end(); ++i) delete ((SimpleTempDataBase*)(*i)._handle); FaceIterator fi; for(fi = face.begin(); fi != face.end(); ++fi) (*fi).Dealloc(); } int Mem(const int & nv, const int & nf) const { typename std::set< PointerToAttribute>::const_iterator i; int size = 0; size += sizeof(TriMesh)+sizeof(VertexType)*nv+sizeof(FaceType)*nf; for( i = vert_attr.begin(); i != vert_attr.end(); ++i) size += ((SimpleTempDataBase*)(*i)._handle)->SizeOf()*nv; for( i = edge_attr.begin(); i != edge_attr.end(); ++i) size += ((SimpleTempDataBase*)(*i)._handle)->SizeOf()*en; for( i = face_attr.begin(); i != face_attr.end(); ++i) size += ((SimpleTempDataBase*)(*i)._handle)->SizeOf()*nf; for( i = mesh_attr.begin(); i != mesh_attr.end(); ++i) size += ((SimpleTempDataBase*)(*i)._handle)->SizeOf(); return size; } int MemUsed() const {return Mem(vert.size(),face.size());} inline int MemNeeded() const {return Mem(vn,fn);} /// Function to destroy the mesh void Clear() { vert.clear(); face.clear(); edge.clear(); // textures.clear(); // normalmaps.clear(); vn = 0; en = 0; fn = 0; hn = 0; imark = 0; attrn = 0; C()=Color4b::Gray; } int & SimplexNumber(){ return fn;} int & VertexNumber(){ return vn;} /// The incremental mark int imark; private: // TriMesh cannot be copied. Use Append (see vcg/complex/append.h) TriMesh operator =(const TriMesh & /*m*/){assert(0);return TriMesh();} TriMesh(const TriMesh & ){} }; // end class Mesh /// Initialize the imark-system of the faces template inline void InitFaceIMark(MeshType & m) { typename MeshType::FaceIterator f; for(f=m.face.begin();f!=m.face.end();++f) if( !(*f).IsD() && (*f).IsR() && (*f).IsW() ) (*f).InitIMark(); } /// Initialize the imark-system of the vertices template inline void InitVertexIMark(MeshType & m) { typename MeshType::VertexIterator vi; for(vi=m.vert.begin();vi!=m.vert.end();++vi) if( !(*vi).IsD() && (*vi).IsRW() ) (*vi).InitIMark(); } /** \brief Access function to the incremental mark. You should not use this member directly. In most of the case just use IsMarked() and Mark() */ template inline int & IMark(MeshType & m){return m.imark;} /** \brief Check if the vertex incremental mark matches the one of the mesh. @param m the mesh containing the element @param v Vertex pointer */ template inline bool IsMarked(MeshType & m, typename MeshType::ConstVertexPointer v ) { return v->IMark() == m.imark; } /** \brief Check if the face incremental mark matches the one of the mesh. @param m the mesh containing the element @param f Face pointer */ template inline bool IsMarked( MeshType & m,typename MeshType::ConstFacePointer f ) { return f->IMark() == m.imark; } /** \brief Set the vertex incremental mark of the vertex to the one of the mesh. @param m the mesh containing the element @param v Vertex pointer */ template inline void Mark(MeshType & m, typename MeshType::VertexPointer v ) { v->IMark() = m.imark; } /** \brief Set the face incremental mark of the vertex to the one of the mesh. @param m the mesh containing the element @param f Vertex pointer */ template inline void Mark(MeshType & m, typename MeshType::FacePointer f ) { f->IMark() = m.imark; } /** \brief Unmark, in constant time, all the elements (face and vertices) of a mesh. @param m the mesh containing the element In practice this function just increment the internal counter that stores the value for which an element is considered marked; therefore all the mesh elements become immediately un-mmarked. */ template inline void UnMarkAll(MeshType & m) { ++m.imark; } template < class CType0, class CType1 , class CType2, class CType3> bool HasPerVertexVEAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::VertContainer::value_type::HasVEAdjacency();} template < class CType0, class CType1, class CType2 , class CType3> bool HasPerEdgeVEAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::EdgeContainer::value_type::HasVEAdjacency();} template < class VertexType> bool VertexVectorHasPerFaceVFAdjacency (const std::vector &) { return VertexType::HasVFAdjacency(); } template < class FaceType > bool FaceVectorHasPerFaceVFAdjacency (const std::vector &) { return FaceType::HasVFAdjacency(); } template < class TriMeshType> bool HasPerFaceVFAdjacency (const TriMeshType &m) { return tri::FaceVectorHasPerFaceVFAdjacency (m.vert); } template < class TriMeshType> bool HasPerVertexVFAdjacency (const TriMeshType &m) { return tri::VertexVectorHasPerFaceVFAdjacency(m.vert); } template < class VertexType> bool VertexVectorHasPerVertexQuality (const std::vector &) { return VertexType::HasQuality (); } template < class VertexType> bool VertexVectorHasPerVertexNormal (const std::vector &) { return VertexType::HasNormal (); } template < class VertexType> bool VertexVectorHasPerVertexColor (const std::vector &) { return VertexType::HasColor (); } template < class VertexType> bool VertexVectorHasPerVertexMark (const std::vector &) { return VertexType::HasMark (); } template < class VertexType> bool VertexVectorHasPerVertexFlags (const std::vector &) { return VertexType::HasFlags (); } template < class VertexType> bool VertexVectorHasPerVertexRadius (const std::vector &) { return VertexType::HasRadius (); } template < class VertexType> bool VertexVectorHasPerVertexCurvature (const std::vector &) { return VertexType::HasCurvature (); } template < class VertexType> bool VertexVectorHasPerVertexCurvatureDir(const std::vector &) { return VertexType::HasCurvatureDir(); } template < class VertexType> bool VertexVectorHasPerVertexTexCoord (const std::vector &) { return VertexType::HasTexCoord (); } template < class TriMeshType> bool HasPerVertexQuality (const TriMeshType &m) { return tri::VertexVectorHasPerVertexQuality (m.vert); } template < class TriMeshType> bool HasPerVertexNormal (const TriMeshType &m) { return tri::VertexVectorHasPerVertexNormal (m.vert); } template < class TriMeshType> bool HasPerVertexColor (const TriMeshType &m) { return tri::VertexVectorHasPerVertexColor (m.vert); } template < class TriMeshType> bool HasPerVertexMark (const TriMeshType &m) { return tri::VertexVectorHasPerVertexMark (m.vert); } template < class TriMeshType> bool HasPerVertexFlags (const TriMeshType &m) { return tri::VertexVectorHasPerVertexFlags (m.vert); } template < class TriMeshType> bool HasPerVertexRadius (const TriMeshType &m) { return tri::VertexVectorHasPerVertexRadius (m.vert); } template < class TriMeshType> bool HasPerVertexCurvature (const TriMeshType &m) { return tri::VertexVectorHasPerVertexCurvature (m.vert); } template < class TriMeshType> bool HasPerVertexCurvatureDir(const TriMeshType &m) { return tri::VertexVectorHasPerVertexCurvatureDir(m.vert); } template < class TriMeshType> bool HasPerVertexTexCoord (const TriMeshType &m) { return tri::VertexVectorHasPerVertexTexCoord (m.vert); } template < class FaceType> bool FaceVectorHasPerWedgeColor (const std::vector &) { return FaceType::HasWedgeColor (); } template < class FaceType> bool FaceVectorHasPerWedgeNormal (const std::vector &) { return FaceType::HasWedgeNormal (); } template < class FaceType> bool FaceVectorHasPerWedgeTexCoord(const std::vector &) { return FaceType::HasWedgeTexCoord(); } template < class TriMeshType> bool HasPerWedgeColor (const TriMeshType &m) { return tri::FaceVectorHasPerWedgeColor (m.face); } template < class TriMeshType> bool HasPerWedgeNormal (const TriMeshType &m) { return tri::FaceVectorHasPerWedgeNormal (m.face); } template < class TriMeshType> bool HasPerWedgeTexCoord(const TriMeshType &m) { return tri::FaceVectorHasPerWedgeTexCoord(m.face); } template < class CType0, class CType1, class CType2 , class CType3> bool HasPolyInfo (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::FaceContainer::value_type::HasPolyInfo();} template < class FaceType> bool FaceVectorHasPerFaceFlags (const std::vector &) { return FaceType::HasFlags (); } template < class FaceType> bool FaceVectorHasPerFaceNormal (const std::vector &) { return FaceType::HasFaceNormal (); } template < class FaceType> bool FaceVectorHasPerFaceColor (const std::vector &) { return FaceType::HasFaceColor (); } template < class FaceType> bool FaceVectorHasPerFaceMark (const std::vector &) { return FaceType::HasFaceMark (); } template < class FaceType> bool FaceVectorHasPerFaceQuality(const std::vector &) { return FaceType::HasFaceQuality(); } template < class FaceType> bool FaceVectorHasFFAdjacency (const std::vector &) { return FaceType::HasFFAdjacency(); } template < class FaceType> bool FaceVectorHasFEAdjacency (const std::vector &) { return FaceType::HasFEAdjacency(); } template < class FaceType> bool FaceVectorHasFVAdjacency (const std::vector &) { return FaceType::HasFVAdjacency(); } template < class FaceType> bool FaceVectorHasPerFaceCurvatureDir (const std::vector &) { return FaceType::HasCurvatureDir(); } template < class TriMeshType> bool HasPerFaceFlags (const TriMeshType &m) { return tri::FaceVectorHasPerFaceFlags (m.face); } template < class TriMeshType> bool HasPerFaceNormal (const TriMeshType &m) { return tri::FaceVectorHasPerFaceNormal (m.face); } template < class TriMeshType> bool HasPerFaceColor (const TriMeshType &m) { return tri::FaceVectorHasPerFaceColor (m.face); } template < class TriMeshType> bool HasPerFaceMark (const TriMeshType &m) { return tri::FaceVectorHasPerFaceMark (m.face); } template < class TriMeshType> bool HasPerFaceQuality (const TriMeshType &m) { return tri::FaceVectorHasPerFaceQuality (m.face); } template < class TriMeshType> bool HasPerFaceCurvatureDir(const TriMeshType &m) { return tri::FaceVectorHasPerFaceCurvatureDir(m.face); } template < class TriMeshType> bool HasFFAdjacency (const TriMeshType &m) { return tri::FaceVectorHasFFAdjacency (m.face); } template < class TriMeshType> bool HasFEAdjacency (const TriMeshType &m) { return tri::FaceVectorHasFEAdjacency (m.face); } template < class TriMeshType> bool HasFVAdjacency (const TriMeshType &m) { return tri::FaceVectorHasFVAdjacency (m.face); } template < class CType0, class CType1, class CType2 , class CType3> bool HasVEAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::VertContainer::value_type::HasVEAdjacency();} template < class CType0, class CType1, class CType2 , class CType3> bool HasVHAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::VertContainer::value_type::HasVHAdjacency();} template < class CType0, class CType1, class CType2 , class CType3> bool HasEVAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::EdgeType::HasEVAdjacency();} template < class CType0, class CType1, class CType2 , class CType3> bool HasEEAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::EdgeType::HasEEAdjacency();} template < class CType0, class CType1, class CType2 , class CType3> bool HasEFAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::EdgeType::HasEFAdjacency();} template < class CType0, class CType1, class CType2 , class CType3> bool HasEHAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::EdgeType::HasEHAdjacency();} template < class CType0, class CType1, class CType2 , class CType3> bool HasFHAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::FaceType::HasFHAdjacency();} template < class CType0, class CType1, class CType2 , class CType3> bool HasHVAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::HEdgeType::HasHVAdjacency();} template < class CType0, class CType1, class CType2 , class CType3> bool HasHEAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::HEdgeType::HasHEAdjacency();} template < class CType0, class CType1, class CType2 , class CType3> bool HasHFAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::HEdgeType::HasHFAdjacency();} template < class CType0, class CType1, class CType2 , class CType3> bool HasHNextAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh< CType0, CType1, CType2 , CType3>::HEdgeType::HasHNextAdjacency();} template < class CType0, class CType1, class CType2 , class CType3> bool HasHPrevAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh< CType0, CType1, CType2 , CType3>::HEdgeType::HasHPrevAdjacency();} template < class CType0, class CType1, class CType2 , class CType3> bool HasHOppAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh< CType0, CType1, CType2 , CType3>::HEdgeType::HasHOppAdjacency();} //template < class CType0, class CType1 , class CType2, class CType3> //bool HasVFAdjacency (const TriMesh < CType0 , CType1, CType2, CType3> & m ) { // // gcc 4.4: if the expressions assigned to a1 and a2 are replaced in the assert we get a compilation error // // for the macro assert // bool a1 = TriMesh < CType0 , CType1, CType2, CType3>::FaceContainer::value_type::HasVFAdjacency(); // bool a2 = TriMesh < CType0 , CType1, CType2, CType3>::VertContainer::value_type::HasVFAdjacency(); // // a1 and a2 are still evaluated but not referenced, this causes a warning // (void)a1; // (void)a2; // assert(a1==a2); // // return vcg::tri::HasPerVertexVFAdjacency< CType0, CType1 , CType2, CType3>(m) && // vcg::tri::HasPerFaceVFAdjacency< CType0, CType1 , CType2, CType3>(m) ; //} template bool HasPerVertexAttribute(const MESH_TYPE &m, std::string name){ typename std::set< typename MESH_TYPE::PointerToAttribute>::const_iterator ai; typename MESH_TYPE::PointerToAttribute h; h._name = name; ai = m.vert_attr.find(h); return (ai!= m.vert_attr.end() ) ; } template bool HasPerFaceAttribute(const MESH_TYPE &m, std::string name){ typename std::set< typename MESH_TYPE::PointerToAttribute>::const_iterator ai; typename MESH_TYPE::PointerToAttribute h; h._name = name; ai = m.face_attr.find(h); return (ai!= m.face_attr.end() ) ; } template bool HasPerMeshAttribute(const MESH_TYPE &m, std::string name){ typename std::set< typename MESH_TYPE::PointerToAttribute>::const_iterator ai; typename MESH_TYPE::PointerToAttribute h; h._name = name; ai = m.mesh_attr.find(h); return (ai!= m.mesh_attr.end() ) ; } /*@}*/ /*@}*/ } // end namespace } // end namespace #endif