From 98ff47110d81c78fef0a3fa810ddfa4f44940549 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 10 Sep 2020 14:06:10 +0200 Subject: [PATCH] const correctness for make a copy from a const right Mesh --- vcg/complex/algorithms/update/selection.h | 26 ++- vcg/complex/append.h | 262 +++++++++++++++++++++- vcg/simplex/edge/component.h | 2 + vcg/simplex/face/component.h | 1 + vcg/simplex/face/component_ocf.h | 5 + vcg/simplex/face/component_polygon.h | 1 + vcg/simplex/tetrahedron/component.h | 3 +- vcg/simplex/vertex/component.h | 6 + vcg/simplex/vertex/component_ocf.h | 4 + 9 files changed, 289 insertions(+), 21 deletions(-) diff --git a/vcg/complex/algorithms/update/selection.h b/vcg/complex/algorithms/update/selection.h index ae9d4d04..b6cd1c5f 100644 --- a/vcg/complex/algorithms/update/selection.h +++ b/vcg/complex/algorithms/update/selection.h @@ -269,34 +269,40 @@ static void Clear(MeshType &m) } /// \brief This function returns the number of selected faces. -static size_t FaceCount(MeshType &m) +static size_t FaceCount(const MeshType &m) { size_t selCnt=0; - for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) - if(!(*fi).IsD() && (*fi).IsS()) ++selCnt; + //for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) + // if(!(*fi).IsD() && (*fi).IsS()) ++selCnt; + for (auto f: m.face) + if(!f.IsD() && f.IsS()) ++selCnt; return selCnt; } /// \brief This function returns the number of selected edges. -static size_t EdgeCount(MeshType &m) +static size_t EdgeCount(const MeshType &m) { size_t selCnt=0; - for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei) - if(!(*ei).IsD() && (*ei).IsS()) ++selCnt; + //for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei) + // if(!(*ei).IsD() && (*ei).IsS()) ++selCnt; + for (auto e: m.edge) + if(!e.IsD() && e.IsS()) ++selCnt; return selCnt; } /// \brief This function returns the number of selected vertices. -static size_t VertexCount(MeshType &m) +static size_t VertexCount(const MeshType &m) { size_t selCnt=0; - for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) - if(!(*vi).IsD() && (*vi).IsS()) ++selCnt; + //for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) + // if(!(*vi).IsD() && (*vi).IsS()) ++selCnt; + for (auto v: m.vert) + if(!v.IsD() && v.IsS()) ++selCnt; return selCnt; } /// \brief This function returns the number of selected tetras. -static size_t TetraCount (MeshType & m) +static size_t TetraCount (const MeshType & m) { size_t selCnt = 0; ForEachTetra(m, [&selCnt] (TetraType & t) { diff --git a/vcg/complex/append.h b/vcg/complex/append.h index 047214f9..4ea8fd03 100644 --- a/vcg/complex/append.h +++ b/vcg/complex/append.h @@ -63,12 +63,12 @@ public: typedef typename ConstMeshRight::FaceType FaceRight; typedef typename ConstMeshRight::TetraType TetraRight; typedef typename ConstMeshRight::TetraPointer TetraPointerRight; - typedef typename ConstMeshRight::TetraIterator TetraIteratorRight; + typedef typename ConstMeshRight::ConstTetraIterator TetraIteratorRight; typedef typename ConstMeshRight::VertexPointer VertexPointerRight; - typedef typename ConstMeshRight::VertexIterator VertexIteratorRight; - typedef typename ConstMeshRight::EdgeIterator EdgeIteratorRight; - typedef typename ConstMeshRight::HEdgeIterator HEdgeIteratorRight; - typedef typename ConstMeshRight::FaceIterator FaceIteratorRight; + typedef typename ConstMeshRight::ConstVertexIterator VertexIteratorRight; + typedef typename ConstMeshRight::ConstEdgeIterator EdgeIteratorRight; + typedef typename ConstMeshRight::ConstHEdgeIterator HEdgeIteratorRight; + typedef typename ConstMeshRight::ConstFaceIterator FaceIteratorRight; typedef typename ConstMeshRight::FacePointer FacePointerRight; struct Remap{ @@ -76,7 +76,7 @@ public: std::vector vert, face, edge, hedge, tetra; }; - static void ImportVertexAdj(MeshLeft &ml, ConstMeshRight &mr, VertexLeft &vl, VertexRight &vr, Remap &remap ){ + static void ImportVertexAdj(MeshLeft &ml, const ConstMeshRight &mr, VertexLeft &vl, const VertexRight &vr, Remap &remap ){ // Vertex to Edge Adj if(HasVEAdjacency(ml) && HasVEAdjacency(mr) && vr.cVEp() != 0){ size_t i = Index(mr,vr.cVEp()); @@ -105,7 +105,7 @@ public: } } - static void ImportEdgeAdj(MeshLeft &ml, ConstMeshRight &mr, EdgeLeft &el, const EdgeRight &er, Remap &remap) + static void ImportEdgeAdj(MeshLeft &ml, const ConstMeshRight &mr, EdgeLeft &el, const EdgeRight &er, Remap &remap) { // Edge to Edge Adj if(HasEEAdjacency(ml) && HasEEAdjacency(mr)) @@ -129,7 +129,7 @@ public: } - static void ImportFaceAdj(MeshLeft &ml, ConstMeshRight &mr, FaceLeft &fl, const FaceRight &fr, Remap &remap ) + static void ImportFaceAdj(MeshLeft &ml, const ConstMeshRight &mr, FaceLeft &fl, const FaceRight &fr, Remap &remap ) { // Face to Edge Adj if(HasFEAdjacency(ml) && HasFEAdjacency(mr)){ @@ -183,7 +183,7 @@ public: fl.FHp() = &ml.hedge[remap.hedge[Index(mr,fr.cFHp())]]; } - static void ImportHEdgeAdj(MeshLeft &ml, ConstMeshRight &mr, HEdgeLeft &hl, const HEdgeRight &hr, Remap &remap, bool /*sel*/ ){ + static void ImportHEdgeAdj(MeshLeft &ml, const ConstMeshRight &mr, HEdgeLeft &hl, const HEdgeRight &hr, Remap &remap, bool /*sel*/ ){ // HEdge to Vertex Adj if(HasHVAdjacency(ml) && HasHVAdjacency(mr)) hl.HVp() = &ml.vert[remap.vert[Index(mr,hr.cHVp())]]; @@ -214,7 +214,7 @@ public: hl.HPp() = &ml.hedge[remap.hedge[Index(mr,hr.cHPp())]]; } - static void ImportTetraAdj(MeshLeft &ml, ConstMeshRight &mr, TetraLeft &tl, const TetraRight &tr, Remap &remap ) + static void ImportTetraAdj(MeshLeft &ml, const ConstMeshRight &mr, TetraLeft &tl, const TetraRight &tr, Remap &remap ) { // Tetra to Tetra Adj if(HasTTAdjacency(ml) && HasTTAdjacency(mr)){ @@ -476,6 +476,241 @@ static void Mesh(MeshLeft& ml, ConstMeshRight& mr, const bool selected = false, // } } +/** + * @brief MeshAppendConst + * @param ml + * @param mr + * + * This is function is similar with the Mesh function, but does not + * never update selections. In some cases, after the append, + * selection of vertices may be inconsistent with face selection, + * as explained above. + * To avoid this, before using this function, call the following functions: + * + * \code{.cpp} + * vcg::tri::UpdateSelection::VertexFromEdgeLoose(mr,true); + * vcg::tri::UpdateSelection::VertexFromFaceLoose(mr,true); + * \endcode + * + * or, use the Mesh function that takes a non-const Right Mesh argument. + */ +static void MeshAppendConst( + MeshLeft& ml, + const ConstMeshRight& mr, + const bool selected = false, + const bool adjFlag = false) +{ + // phase 1. allocate on ml vert,edge,face, hedge to accomodat those of mr + // and build the remapping for all + + Remap remap; + + // vertex + remap.vert.resize(mr.vert.size(), Remap::InvalidIndex()); + VertexIteratorLeft vp; + size_t svn = UpdateSelection::VertexCount(mr); + if(selected) + vp=Allocator::AddVertices(ml,int(svn)); + else + vp=Allocator::AddVertices(ml,mr.vn); + + for(VertexIteratorRight vi=mr.vert.begin(); vi!=mr.vert.end(); ++vi) + { + if(!(*vi).IsD() && (!selected || (*vi).IsS())) + { + size_t ind=Index(mr,*vi); + remap.vert[ind]=int(Index(ml,*vp)); + ++vp; + } + } + // edge + remap.edge.resize(mr.edge.size(), Remap::InvalidIndex()); + EdgeIteratorLeft ep; + size_t sen = UpdateSelection::EdgeCount(mr); + if(selected) ep=Allocator::AddEdges(ml,sen); + else ep=Allocator::AddEdges(ml,mr.en); + + for(EdgeIteratorRight ei=mr.edge.begin(); ei!=mr.edge.end(); ++ei) + if(!(*ei).IsD() && (!selected || (*ei).IsS())){ + size_t ind=Index(mr,*ei); + remap.edge[ind]=int(Index(ml,*ep)); + ++ep; + } + + // face + remap.face.resize(mr.face.size(), Remap::InvalidIndex()); + FaceIteratorLeft fp; + size_t sfn = UpdateSelection::FaceCount(mr); + if(selected) fp=Allocator::AddFaces(ml,sfn); + else fp=Allocator::AddFaces(ml,mr.fn); + + for(FaceIteratorRight fi=mr.face.begin(); fi!=mr.face.end(); ++fi) + if(!(*fi).IsD() && (!selected || (*fi).IsS())){ + size_t ind=Index(mr,*fi); + remap.face[ind]=int(Index(ml,*fp)); + ++fp; + } + + // hedge + remap.hedge.resize(mr.hedge.size(),Remap::InvalidIndex()); + for(HEdgeIteratorRight hi=mr.hedge.begin(); hi!=mr.hedge.end(); ++hi) + if(!(*hi).IsD() && (!selected || (*hi).IsS())){ + size_t ind=Index(mr,*hi); + assert(remap.hedge[ind]==Remap::InvalidIndex()); + HEdgeIteratorLeft hp = Allocator::AddHEdges(ml,1); + (*hp).ImportData(*(hi)); + remap.hedge[ind]=Index(ml,*hp); + } + + remap.tetra.resize(mr.tetra.size(), Remap::InvalidIndex()); + for (TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti) + if (!(*ti).IsD() && (!selected || (*ti).IsS())) { + size_t idx = Index(mr, *ti); + assert (remap.tetra[idx] == Remap::InvalidIndex()); + TetraIteratorLeft tp = Allocator::AddTetras(ml, 1); + (*tp).ImportData(*ti); + remap.tetra[idx] = Index(ml, *tp); + } + + // phase 2. + // copy data from mr to its corresponding elements in ml and adjacencies + + // vertex + for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi) + if( !(*vi).IsD() && (!selected || (*vi).IsS())){ + ml.vert[remap.vert[Index(mr,*vi)]].ImportData(*vi); + if(adjFlag) ImportVertexAdj(ml,mr,ml.vert[remap.vert[Index(mr,*vi)]],*vi,remap); + } + + // edge + for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei) + if(!(*ei).IsD() && (!selected || (*ei).IsS())){ + ml.edge[remap.edge[Index(mr,*ei)]].ImportData(*ei); + // Edge to Vertex Adj + EdgeLeft &el = ml.edge[remap.edge[Index(mr,*ei)]]; + if(HasEVAdjacency(ml) && HasEVAdjacency(mr)){ + el.V(0) = &ml.vert[remap.vert[Index(mr,ei->cV(0))]]; + el.V(1) = &ml.vert[remap.vert[Index(mr,ei->cV(1))]]; + } + if(adjFlag) ImportEdgeAdj(ml,mr,el,*ei,remap); + } + + // face + const size_t textureOffset = ml.textures.size(); + bool WTFlag = HasPerWedgeTexCoord(mr) && (textureOffset>0); + for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi) + if(!(*fi).IsD() && (!selected || (*fi).IsS())) + { + FaceLeft &fl = ml.face[remap.face[Index(mr,*fi)]]; + fl.Alloc(fi->VN()); + if(HasFVAdjacency(ml) && HasFVAdjacency(mr)){ + for(int i = 0; i < fl.VN(); ++i) + fl.V(i) = &ml.vert[remap.vert[Index(mr,fi->cV(i))]]; + } + fl.ImportData(*fi); + if(WTFlag) + for(int i = 0; i < fl.VN(); ++i) + fl.WT(i).n() += short(textureOffset); + if(adjFlag) ImportFaceAdj(ml,mr,ml.face[remap.face[Index(mr,*fi)]],*fi,remap); + + } + + // hedge + for(HEdgeIteratorRight hi=mr.hedge.begin();hi!=mr.hedge.end();++hi) + if(!(*hi).IsD() && (!selected || (*hi).IsS())){ + ml.hedge[remap.hedge[Index(mr,*hi)]].ImportData(*hi); + ImportHEdgeAdj(ml,mr,ml.hedge[remap.hedge[Index(mr,*hi)]],*hi,remap,selected); + } + + //tetra + for(TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti) + if(!(*ti).IsD() && (!selected || (*ti).IsS())) + { + TetraLeft &tl = ml.tetra[remap.tetra[Index(mr,*ti)]]; + + if(HasFVAdjacency(ml) && HasFVAdjacency(mr)){ + for(int i = 0; i < 4; ++i) + tl.V(i) = &ml.vert[remap.vert[Index(mr,ti->cV(i))]]; + } + tl.ImportData(*ti); + if(adjFlag) ImportTetraAdj(ml, mr, ml.tetra[remap.tetra[Index(mr,*ti)]], *ti, remap); + + } + + // phase 3. + // take care of other per mesh data: textures, attributes + + // At the end concatenate the vector with texture names. + ml.textures.insert(ml.textures.end(),mr.textures.begin(),mr.textures.end()); + + // Attributes. Copy only those attributes that are present in both meshes + // Two attributes in different meshes are considered the same if they have the same + // name and the same type. This may be deceiving because they could in fact have + // different semantic, but this is up to the developer. + // If the left mesh has attributes that are not in the right mesh, their values for the elements + // of the right mesh will be uninitialized + + unsigned int id_r; + typename std::set< PointerToAttribute >::iterator al, ar; + + // per vertex attributes + for(al = ml.vert_attr.begin(); al != ml.vert_attr.end(); ++al) + if(!(*al)._name.empty()){ + ar = mr.vert_attr.find(*al); + if(ar!= mr.vert_attr.end()){ + id_r = 0; + for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi,++id_r) + if( !(*vi).IsD() && (!selected || (*vi).IsS())) + (*al)._handle->CopyValue(remap.vert[Index(mr,*vi)], id_r, (*ar)._handle); + } + } + + // per edge attributes + for(al = ml.edge_attr.begin(); al != ml.edge_attr.end(); ++al) + if(!(*al)._name.empty()){ + ar = mr.edge_attr.find(*al); + if(ar!= mr.edge_attr.end()){ + id_r = 0; + for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei,++id_r) + if( !(*ei).IsD() && (!selected || (*ei).IsS())) + (*al)._handle->CopyValue(remap.edge[Index(mr,*ei)], id_r, (*ar)._handle); + } + } + + // per face attributes + for(al = ml.face_attr.begin(); al != ml.face_attr.end(); ++al) + if(!(*al)._name.empty()){ + ar = mr.face_attr.find(*al); + if(ar!= mr.face_attr.end()){ + id_r = 0; + for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi,++id_r) + if( !(*fi).IsD() && (!selected || (*fi).IsS())) + (*al)._handle->CopyValue(remap.face[Index(mr,*fi)], id_r, (*ar)._handle); + } + } + + // per tetra attributes + for(al = ml.tetra_attr.begin(); al != ml.tetra_attr.end(); ++al) + if(!(*al)._name.empty()){ + ar = mr.tetra_attr.find(*al); + if(ar!= mr.tetra_attr.end()){ + id_r = 0; + for(TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti, ++id_r) + if( !(*ti).IsD() && (!selected || (*ti).IsS())) + (*al)._handle->CopyValue(remap.tetra[Index(mr, *ti)], id_r, (*ar)._handle); + } + } + // per mesh attributes + // if both ml and mr have an attribute with the same name, no action is done + // if mr has an attribute that is NOT present in ml, the attribute is added to ml + //for(ar = mr.mesh_attr.begin(); ar != mr.mesh_attr.end(); ++ar) + // if(!(*ar)._name.empty()){ + // al = ml.mesh_attr.find(*ar); + // if(al== ml.mesh_attr.end()) + // //... + // } +} + /*! \brief Copy the second mesh over the first one. The first mesh is destroyed. If requested only the selected elements are copied. */ @@ -485,6 +720,13 @@ static void MeshCopy(MeshLeft& ml, ConstMeshRight& mr, bool selected=false, cons Mesh(ml,mr,selected,adjFlag); ml.bbox.Import(mr.bbox); } + +static void MeshCopyConst(MeshLeft& ml, const ConstMeshRight& mr, bool selected=false, const bool adjFlag = false) +{ + ml.Clear(); + MeshAppendConst(ml,mr,selected,adjFlag); + ml.bbox.Import(mr.bbox); +} /*! \brief %Append only the selected elements of second mesh to the first one. It is just a wrap of the main Append::Mesh() diff --git a/vcg/simplex/edge/component.h b/vcg/simplex/edge/component.h index a78ca4c6..69d32765 100644 --- a/vcg/simplex/edge/component.h +++ b/vcg/simplex/edge/component.h @@ -78,6 +78,7 @@ public: typename T::EdgePointer &VEp(const int & ) { static typename T::EdgePointer ep=0; assert(0); return ep; } typename T::EdgePointer cVEp(const int & ) const { static typename T::EdgePointer ep=0; assert(0); return ep; } int &VEi(const int &){static int z=0; assert(0); return z;} + int VEi(const int &) const {static int z=0; assert(0); return z;} int cVEi(const int &) const {static int z=0; assert(0); return z;} static bool HasVEAdjacency() { return false; } @@ -278,6 +279,7 @@ public: typename T::EdgePointer &VEp(const int & i) {return _ep[i]; } typename T::EdgePointer cVEp(const int & i) const {return _ep[i]; } int &VEi(const int & i){ return _zp[i];} + int VEi(const int & i)const {return _zp[i];} int cVEi(const int &i )const {return _zp[i];} template < class LeftV> diff --git a/vcg/simplex/face/component.h b/vcg/simplex/face/component.h index ebdc3739..da731066 100644 --- a/vcg/simplex/face/component.h +++ b/vcg/simplex/face/component.h @@ -114,6 +114,7 @@ public: typename T::HEdgePointer &FHp() { static typename T::HEdgePointer fp=0; assert(0); return fp; } typename T::HEdgePointer cFHp() const { static typename T::HEdgePointer fp=0; assert(0); return fp; } char &VFi(int) { static char z=0; assert(0); return z;} + char VFi(int) const { static char z=0; assert(0); return z;} char &FFi(int) { static char z=0; assert(0); return z;} char cVFi(int) const { static char z=0; assert(0); return z;} char cFFi(int) const { static char z=0; assert(0); return z;} diff --git a/vcg/simplex/face/component_ocf.h b/vcg/simplex/face/component_ocf.h index bf4c3fb1..a09e84f7 100644 --- a/vcg/simplex/face/component_ocf.h +++ b/vcg/simplex/face/component_ocf.h @@ -408,6 +408,11 @@ public: return (*this).Base().AV[(*this).Index()]._zp[j]; } + char VFi(const int j) const { + assert((*this).Base().VFAdjacencyEnabled); + return (*this).Base().AV[(*this).Index()]._zp[j]; + } + char cVFi(const int j) const { assert((*this).Base().VFAdjacencyEnabled); return (*this).Base().AV[(*this).Index()]._zp[j]; diff --git a/vcg/simplex/face/component_polygon.h b/vcg/simplex/face/component_polygon.h index dde27016..8ac67f47 100644 --- a/vcg/simplex/face/component_polygon.h +++ b/vcg/simplex/face/component_polygon.h @@ -136,6 +136,7 @@ public: 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]; } + char VFi(const int j) const {return _vfiP[j]; } template void ImportData(const LeftF & leftF){T::ImportData(leftF);} inline void Alloc(const int & ns) { diff --git a/vcg/simplex/tetrahedron/component.h b/vcg/simplex/tetrahedron/component.h index d2d8c878..7cd9781d 100644 --- a/vcg/simplex/tetrahedron/component.h +++ b/vcg/simplex/tetrahedron/component.h @@ -47,7 +47,7 @@ public: //Empty vertexref inline typename T::VertexType * & V( const int ) { assert(0); static typename T::VertexType *vp=0; return vp; } inline typename T::VertexType * const & V( const int ) const { assert(0); static typename T::VertexType *vp=0; return vp; } - inline const typename T::VertexType * cV( const int ) { assert(0); static typename T::VertexType *vp=0; return vp; } + inline const typename T::VertexType * cV( const int ) const { assert(0); static typename T::VertexType *vp=0; return vp; } inline typename T::CoordType & P( const int ) { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; } inline const typename T::CoordType & P( const int ) const { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; } inline const typename T::CoordType &cP( const int ) const { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; } @@ -112,6 +112,7 @@ public: typename T::TetraPointer const cTTp( const int ) const { static typename T::TetraPointer const tp=0; assert(0); return tp; } char & VTi( const int ) { static char z=0; assert(0); return z; } + char VTi( const int ) const { static char z=0; assert(0); return z; } char cVTi( const int ) const { static char z=0; assert(0); return z; } char & TTi( const int ) { static char z=0; assert(0); return z; } char cTTi( const int ) const { static char z=0; assert(0); return z; } diff --git a/vcg/simplex/vertex/component.h b/vcg/simplex/vertex/component.h index 1a95aca9..1914dbbd 100644 --- a/vcg/simplex/vertex/component.h +++ b/vcg/simplex/vertex/component.h @@ -99,6 +99,7 @@ public: typename TT::TetraPointer &VTp() { static typename TT::TetraPointer tp = 0; assert(0); return tp; } typename TT::TetraPointer cVTp() const { static typename TT::TetraPointer tp = 0; assert(0); return tp; } int &VTi() { static int z = 0; assert(0); return z; } + int VTi() const { static int z = 0; assert(0); return z; } int cVTi() const { static int z = 0; assert(0); return z; } static bool HasVTAdjacency() { return false; } bool IsVTInitialized() const {return static_cast(this)->cVTi()!=-1;} @@ -112,6 +113,7 @@ public: typename TT::FacePointer &VFp() { static typename TT::FacePointer fp=0; assert(0); return fp; } typename TT::FacePointer cVFp() const { static typename TT::FacePointer fp=0; assert(0); return fp; } int &VFi() { static int z=-1; assert(0); return z;} + int VFi() const { static int z=-1; assert(0); return z;} int cVFi() const { static int z=-1; assert(0); return z;} bool IsNull() const { return true; } static bool HasVFAdjacency() { return false; } @@ -126,6 +128,7 @@ public: typename TT::EdgePointer &VEp() { static typename TT::EdgePointer ep=0; assert(0); return ep; } typename TT::EdgePointer cVEp() const { static typename TT::EdgePointer ep=0; assert(0); return ep; } int &VEi() { static int z=-1; return z;} + int VEi() const { static int z=-1; return z;} int cVEi() const { static int z=-1; return z;} static bool HasVEAdjacency() { return false; } bool IsVEInitialized() const {return static_cast(this)->cVEi()!=-1;} @@ -138,6 +141,7 @@ public: typename TT::HEdgePointer &VHp() { static typename TT::HEdgePointer ep=0; assert(0); return ep; } typename TT::HEdgePointer cVHp() const { static typename TT::HEdgePointer ep=0; assert(0); return ep; } int &VHi() { static int z=0; return z;} + int VHi() const { static int z=0; return z;} int cVHi() const { static int z=0; return z;} static bool HasVHAdjacency() { return false; } @@ -531,6 +535,7 @@ public: typename T::EdgePointer &VEp() {return _ep; } typename T::EdgePointer cVEp() const {return _ep; } int &VEi() {return _zp; } + int VEi() const {return _zp; } int cVEi() const {return _zp; } template < class RightValueType> void ImportData(const RightValueType & rVert ) { T::ImportData( rVert); } @@ -559,6 +564,7 @@ Note that if you use this component it is expected that on the Face you use also typename T::FacePointer &VFp() { return _fp; } typename T::FacePointer cVFp() const { return _fp; } int &VFi() { return _zp; } + int VFi() const { return _zp; } int cVFi() const { return _zp; } bool IsNull() const { return _zp==-1;} template < class RightValueType> diff --git a/vcg/simplex/vertex/component_ocf.h b/vcg/simplex/vertex/component_ocf.h index 72b42fbd..35572cbc 100644 --- a/vcg/simplex/vertex/component_ocf.h +++ b/vcg/simplex/vertex/component_ocf.h @@ -285,6 +285,10 @@ public: assert((*this).Base().VFAdjacencyEnabled); return (*this).Base().AV[(*this).Index()]._zp; } + int VFi() const { + assert((*this).Base().VFAdjacencyEnabled); + return (*this).Base().AV[(*this).Index()]._zp; + } int cVFi() const { if(! (*this).Base().VFAdjacencyEnabled ) return -1; return (*this).Base().AV[(*this).Index()]._zp;