From fc108322b5ee4021bc83b189dbb50b4b096bea53 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 10 Sep 2020 14:06:10 +0200 Subject: [PATCH 01/10] 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; From 1144dfbae47f615bddd76b4397192da8ff1d8b78 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 10 Sep 2020 14:35:48 +0200 Subject: [PATCH 02/10] using range for in MeshAppendConst --- vcg/complex/append.h | 146 +++++++++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 62 deletions(-) diff --git a/vcg/complex/append.h b/vcg/complex/append.h index 4ea8fd03..cd52a483 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::ConstTetraIterator TetraIteratorRight; + typedef typename ConstMeshRight::TetraIterator TetraIteratorRight; typedef typename ConstMeshRight::VertexPointer VertexPointerRight; - typedef typename ConstMeshRight::ConstVertexIterator VertexIteratorRight; - typedef typename ConstMeshRight::ConstEdgeIterator EdgeIteratorRight; - typedef typename ConstMeshRight::ConstHEdgeIterator HEdgeIteratorRight; - typedef typename ConstMeshRight::ConstFaceIterator FaceIteratorRight; + typedef typename ConstMeshRight::VertexIterator VertexIteratorRight; + typedef typename ConstMeshRight::EdgeIterator EdgeIteratorRight; + typedef typename ConstMeshRight::HEdgeIterator HEdgeIteratorRight; + typedef typename ConstMeshRight::FaceIterator FaceIteratorRight; typedef typename ConstMeshRight::FacePointer FacePointerRight; struct Remap{ @@ -514,11 +514,12 @@ static void MeshAppendConst( else vp=Allocator::AddVertices(ml,mr.vn); - for(VertexIteratorRight vi=mr.vert.begin(); vi!=mr.vert.end(); ++vi) + for (auto v : mr.vert) + //for(VertexIteratorRight vi=mr.vert.begin(); vi!=mr.vert.end(); ++vi) { - if(!(*vi).IsD() && (!selected || (*vi).IsS())) + if(!v.IsD() && (!selected || v.IsS())) { - size_t ind=Index(mr,*vi); + size_t ind=Index(mr,v); remap.vert[ind]=int(Index(ml,*vp)); ++vp; } @@ -530,9 +531,10 @@ static void MeshAppendConst( 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); + for (auto e : mr.edge) + //for(EdgeIteratorRight ei=mr.edge.begin(); ei!=mr.edge.end(); ++ei) + if(!e.IsD() && (!selected || e.IsS())){ + size_t ind=Index(mr,e); remap.edge[ind]=int(Index(ml,*ep)); ++ep; } @@ -544,31 +546,34 @@ static void MeshAppendConst( 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); + for (auto f : mr.face) + //for(FaceIteratorRight fi=mr.face.begin(); fi!=mr.face.end(); ++fi) + if(!f.IsD() && (!selected || f.IsS())){ + size_t ind=Index(mr,f); 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); + for (auto he : mr.hedge) + //for(HEdgeIteratorRight hi=mr.hedge.begin(); hi!=mr.hedge.end(); ++hi) + if(!he.IsD() && (!selected || he.IsS())){ + size_t ind=Index(mr,he); assert(remap.hedge[ind]==Remap::InvalidIndex()); HEdgeIteratorLeft hp = Allocator::AddHEdges(ml,1); - (*hp).ImportData(*(hi)); + (*hp).ImportData(he); 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); + for (auto t : mr.tetra) + //for (TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti) + if (!t.IsD() && (!selected || t.IsS())) { + size_t idx = Index(mr, t); assert (remap.tetra[idx] == Remap::InvalidIndex()); TetraIteratorLeft tp = Allocator::AddTetras(ml, 1); - (*tp).ImportData(*ti); + (*tp).ImportData(t); remap.tetra[idx] = Index(ml, *tp); } @@ -576,64 +581,69 @@ static void MeshAppendConst( // 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); + for (auto v: mr.vert) + //for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi) + if( !v.IsD() && (!selected || v.IsS())){ + ml.vert[remap.vert[Index(mr,v)]].ImportData(v); + if(adjFlag) ImportVertexAdj(ml,mr,ml.vert[remap.vert[Index(mr,v)]],v,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); + for (auto e: mr.edge) + //for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei) + if(!e.IsD() && (!selected || e.IsS())){ + ml.edge[remap.edge[Index(mr,e)]].ImportData(e); // Edge to Vertex Adj - EdgeLeft &el = ml.edge[remap.edge[Index(mr,*ei)]]; + EdgeLeft &el = ml.edge[remap.edge[Index(mr,e)]]; 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))]]; + el.V(0) = &ml.vert[remap.vert[Index(mr,e.cV(0))]]; + el.V(1) = &ml.vert[remap.vert[Index(mr,e.cV(1))]]; } - if(adjFlag) ImportEdgeAdj(ml,mr,el,*ei,remap); + if(adjFlag) ImportEdgeAdj(ml,mr,el,e,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())) + for (auto f: mr.face) + //for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi) + if(!f.IsD() && (!selected || f.IsS())) { - FaceLeft &fl = ml.face[remap.face[Index(mr,*fi)]]; - fl.Alloc(fi->VN()); + FaceLeft &fl = ml.face[remap.face[Index(mr,f)]]; + fl.Alloc(f.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.V(i) = &ml.vert[remap.vert[Index(mr,f.cV(i))]]; } - fl.ImportData(*fi); + fl.ImportData(f); 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); + if(adjFlag) ImportFaceAdj(ml,mr,ml.face[remap.face[Index(mr,f)]],f,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); + for (auto he : mr.hedge) + //for(HEdgeIteratorRight hi=mr.hedge.begin();hi!=mr.hedge.end();++hi) + if(!he.IsD() && (!selected || he.IsS())){ + ml.hedge[remap.hedge[Index(mr,he)]].ImportData(he); + ImportHEdgeAdj(ml,mr,ml.hedge[remap.hedge[Index(mr,he)]],he,remap,selected); } //tetra - for(TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti) - if(!(*ti).IsD() && (!selected || (*ti).IsS())) + for (auto t: mr.tetra) + //for(TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti) + if(!t.IsD() && (!selected || t.IsS())) { - TetraLeft &tl = ml.tetra[remap.tetra[Index(mr,*ti)]]; + TetraLeft &tl = ml.tetra[remap.tetra[Index(mr,t)]]; 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.V(i) = &ml.vert[remap.vert[Index(mr,t.cV(i))]]; } - tl.ImportData(*ti); - if(adjFlag) ImportTetraAdj(ml, mr, ml.tetra[remap.tetra[Index(mr,*ti)]], *ti, remap); + tl.ImportData(t); + if(adjFlag) ImportTetraAdj(ml, mr, ml.tetra[remap.tetra[Index(mr,t)]], t, remap); } @@ -659,9 +669,12 @@ static void MeshAppendConst( 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); + for (auto v: mr.vert){ + //for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi,++id_r) + if( !v.IsD() && (!selected || v.IsS())) + (*al)._handle->CopyValue(remap.vert[Index(mr,v)], id_r, (*ar)._handle); + ++id_r; + } } } @@ -671,9 +684,12 @@ static void MeshAppendConst( 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); + for (auto e: mr.edge){ + //for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei,++id_r) + if( !e.IsD() && (!selected || e.IsS())) + (*al)._handle->CopyValue(remap.edge[Index(mr,e)], id_r, (*ar)._handle); + ++id_r; + } } } @@ -683,9 +699,12 @@ static void MeshAppendConst( 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); + for (auto f: mr.face) { + //for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi,++id_r) + if( !f.IsD() && (!selected || f.IsS())) + (*al)._handle->CopyValue(remap.face[Index(mr,f)], id_r, (*ar)._handle); + ++id_r; + } } } @@ -695,9 +714,12 @@ static void MeshAppendConst( 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); + for (auto t: mr.tetra) { + //for(TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti, ++id_r) + if( !t.IsD() && (!selected || t.IsS())) + (*al)._handle->CopyValue(remap.tetra[Index(mr, t)], id_r, (*ar)._handle); + ++id_r; + } } } // per mesh attributes From 6014f75b60815657dc6ac014dd6aca8d4e6ff6fc Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 10 Sep 2020 15:44:27 +0200 Subject: [PATCH 03/10] using ForEach. add const ForEach and ForEachHEdge --- vcg/complex/append.h | 223 ++++++++++++++++++++++-------------------- vcg/complex/foreach.h | 102 +++++++++++++++++++ 2 files changed, 217 insertions(+), 108 deletions(-) diff --git a/vcg/complex/append.h b/vcg/complex/append.h index cd52a483..02580a4b 100644 --- a/vcg/complex/append.h +++ b/vcg/complex/append.h @@ -514,16 +514,15 @@ static void MeshAppendConst( else vp=Allocator::AddVertices(ml,mr.vn); - for (auto v : mr.vert) - //for(VertexIteratorRight vi=mr.vert.begin(); vi!=mr.vert.end(); ++vi) + ForEachVertex(mr, [&](const VertexRight& v) { - if(!v.IsD() && (!selected || v.IsS())) + if(!selected || v.IsS()) { size_t ind=Index(mr,v); remap.vert[ind]=int(Index(ml,*vp)); ++vp; } - } + }); // edge remap.edge.resize(mr.edge.size(), Remap::InvalidIndex()); EdgeIteratorLeft ep; @@ -531,13 +530,14 @@ static void MeshAppendConst( if(selected) ep=Allocator::AddEdges(ml,sen); else ep=Allocator::AddEdges(ml,mr.en); - for (auto e : mr.edge) - //for(EdgeIteratorRight ei=mr.edge.begin(); ei!=mr.edge.end(); ++ei) - if(!e.IsD() && (!selected || e.IsS())){ + ForEachEdge(mr, [&](const EdgeRight& e) + { + if(!selected || e.IsS()){ size_t ind=Index(mr,e); remap.edge[ind]=int(Index(ml,*ep)); ++ep; } + }); // face remap.face.resize(mr.face.size(), Remap::InvalidIndex()); @@ -546,52 +546,58 @@ static void MeshAppendConst( if(selected) fp=Allocator::AddFaces(ml,sfn); else fp=Allocator::AddFaces(ml,mr.fn); - for (auto f : mr.face) - //for(FaceIteratorRight fi=mr.face.begin(); fi!=mr.face.end(); ++fi) - if(!f.IsD() && (!selected || f.IsS())){ + ForEachFace(mr, [&](const FaceRight& f) + { + if(!selected || f.IsS()){ size_t ind=Index(mr,f); remap.face[ind]=int(Index(ml,*fp)); ++fp; } + }); // hedge remap.hedge.resize(mr.hedge.size(),Remap::InvalidIndex()); - for (auto he : mr.hedge) - //for(HEdgeIteratorRight hi=mr.hedge.begin(); hi!=mr.hedge.end(); ++hi) - if(!he.IsD() && (!selected || he.IsS())){ + + ForEachHEdge(mr, [&](const HEdgeRight& he) + { + if(!selected || he.IsS()){ size_t ind=Index(mr,he); assert(remap.hedge[ind]==Remap::InvalidIndex()); HEdgeIteratorLeft hp = Allocator::AddHEdges(ml,1); (*hp).ImportData(he); remap.hedge[ind]=Index(ml,*hp); } + }); remap.tetra.resize(mr.tetra.size(), Remap::InvalidIndex()); - for (auto t : mr.tetra) - //for (TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti) - if (!t.IsD() && (!selected || t.IsS())) { + + ForEachTetra(mr, [&](const TetraRight& t) + { + if (!selected || t.IsS()) { size_t idx = Index(mr, t); assert (remap.tetra[idx] == Remap::InvalidIndex()); TetraIteratorLeft tp = Allocator::AddTetras(ml, 1); (*tp).ImportData(t); remap.tetra[idx] = Index(ml, *tp); } + }); // phase 2. // copy data from mr to its corresponding elements in ml and adjacencies // vertex - for (auto v: mr.vert) - //for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi) - if( !v.IsD() && (!selected || v.IsS())){ + ForEachVertex(mr, [&](const VertexRight& v) + { + if(!selected || v.IsS()){ ml.vert[remap.vert[Index(mr,v)]].ImportData(v); if(adjFlag) ImportVertexAdj(ml,mr,ml.vert[remap.vert[Index(mr,v)]],v,remap); } + }); // edge - for (auto e: mr.edge) - //for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei) - if(!e.IsD() && (!selected || e.IsS())){ + ForEachEdge(mr, [&](const EdgeRight& e) + { + if(!selected || e.IsS()){ ml.edge[remap.edge[Index(mr,e)]].ImportData(e); // Edge to Vertex Adj EdgeLeft &el = ml.edge[remap.edge[Index(mr,e)]]; @@ -601,13 +607,14 @@ static void MeshAppendConst( } if(adjFlag) ImportEdgeAdj(ml,mr,el,e,remap); } + }); // face const size_t textureOffset = ml.textures.size(); bool WTFlag = HasPerWedgeTexCoord(mr) && (textureOffset>0); - for (auto f: mr.face) - //for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi) - if(!f.IsD() && (!selected || f.IsS())) + ForEachFace(mr, [&](const FaceRight& f) + { + if(!selected || f.IsS()) { FaceLeft &fl = ml.face[remap.face[Index(mr,f)]]; fl.Alloc(f.VN()); @@ -622,19 +629,21 @@ static void MeshAppendConst( if(adjFlag) ImportFaceAdj(ml,mr,ml.face[remap.face[Index(mr,f)]],f,remap); } + }); // hedge - for (auto he : mr.hedge) - //for(HEdgeIteratorRight hi=mr.hedge.begin();hi!=mr.hedge.end();++hi) - if(!he.IsD() && (!selected || he.IsS())){ + ForEachHEdge(mr, [&](const HEdgeRight& he) + { + if(!selected || he.IsS()){ ml.hedge[remap.hedge[Index(mr,he)]].ImportData(he); ImportHEdgeAdj(ml,mr,ml.hedge[remap.hedge[Index(mr,he)]],he,remap,selected); } + }); //tetra - for (auto t: mr.tetra) - //for(TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti) - if(!t.IsD() && (!selected || t.IsS())) + ForEachTetra(mr, [&](const TetraRight& t) + { + if(!selected || t.IsS()) { TetraLeft &tl = ml.tetra[remap.tetra[Index(mr,t)]]; @@ -646,91 +655,89 @@ static void MeshAppendConst( if(adjFlag) ImportTetraAdj(ml, mr, ml.tetra[remap.tetra[Index(mr,t)]], t, remap); } + }); - // phase 3. - // take care of other per mesh data: textures, attributes + // 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()); + // 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 + // 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; + 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 (auto v: mr.vert){ - //for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi,++id_r) - if( !v.IsD() && (!selected || v.IsS())) - (*al)._handle->CopyValue(remap.vert[Index(mr,v)], id_r, (*ar)._handle); - ++id_r; - } - } - } + // 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 (auto v: mr.vert){ + if( !v.IsD() && (!selected || v.IsS())) + (*al)._handle->CopyValue(remap.vert[Index(mr,v)], id_r, (*ar)._handle); + ++id_r; + } + } + } - // 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 (auto e: mr.edge){ - //for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei,++id_r) - if( !e.IsD() && (!selected || e.IsS())) - (*al)._handle->CopyValue(remap.edge[Index(mr,e)], id_r, (*ar)._handle); - ++id_r; - } - } - } + // 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 (auto e: mr.edge){ + if( !e.IsD() && (!selected || e.IsS())) + (*al)._handle->CopyValue(remap.edge[Index(mr,e)], id_r, (*ar)._handle); + ++id_r; + } + } + } - // 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 (auto f: mr.face) { - //for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi,++id_r) - if( !f.IsD() && (!selected || f.IsS())) - (*al)._handle->CopyValue(remap.face[Index(mr,f)], id_r, (*ar)._handle); - ++id_r; - } - } - } + // 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 (auto f: mr.face) { + if( !f.IsD() && (!selected || f.IsS())) + (*al)._handle->CopyValue(remap.face[Index(mr,f)], id_r, (*ar)._handle); + ++id_r; + } + } + } - // 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 (auto t: mr.tetra) { - //for(TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti, ++id_r) - if( !t.IsD() && (!selected || t.IsS())) - (*al)._handle->CopyValue(remap.tetra[Index(mr, t)], id_r, (*ar)._handle); - ++id_r; - } - } - } - // 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()) - // //... - // } + // 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 (auto t: mr.tetra) { + if( !t.IsD() && (!selected || t.IsS())) + (*al)._handle->CopyValue(remap.tetra[Index(mr, t)], id_r, (*ar)._handle); + ++id_r; + } + } + } + + // 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. diff --git a/vcg/complex/foreach.h b/vcg/complex/foreach.h index 156d3489..4f7710fd 100644 --- a/vcg/complex/foreach.h +++ b/vcg/complex/foreach.h @@ -34,6 +34,22 @@ namespace tri { @{ */ +template +inline void ForEachFacePos(const MeshType &m, std::function &)> action) +{ + typedef typename face::Pos PosType; + + for(auto fi=m.face.begin();fi!=m.face.end();++fi) + if(!(*fi).IsD()) + { + for(int i=0;i<3;++i) + { + PosType pi(&*fi,i); + action(pi); + } + } +} + template inline void ForEachFacePos(MeshType &m, std::function &)> action) { @@ -108,6 +124,25 @@ inline void ForEachFace(MeshType &m, std::function +inline void ForEachVertex(const MeshType &m, std::function action) +{ + if(m.vn == (int) m.vert.size()) + { + for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) { + action(*vi); + } + } + else + { + for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) + if(!(*vi).IsD()) + { + action(*vi); + } + } +} + template inline void ForEachVertex(MeshType &m, std::function action) { @@ -127,6 +162,54 @@ inline void ForEachVertex(MeshType &m, std::function +inline void ForEachHEdge(const MeshType &m, std::function action) +{ + if(m.hn == (int) m.hedge.size()) + { + for(auto hei=m.hedge.begin();hei!=m.hedge.end();++hei) { + action(*hei); + } + } + else + { + for(auto hei=m.hedge.begin();hei!=m.hedge.end();++hei) + if(!(*hei).IsD()) + { + action(*hei); + } + } +} + +template +inline void ForEachHEdge(MeshType &m, std::function action) +{ + if(m.hn == (int) m.hedge.size()) + { + for(auto hei=m.hedge.begin();hei!=m.hedge.end();++hei) { + action(*hei); + } + } + else + { + for(auto hei=m.hedge.begin();hei!=m.hedge.end();++hei) + if(!(*hei).IsD()) + { + action(*hei); + } + } +} + /** * ForEachEdge Helper * to traverse all the vertexes of a mesh you can simply write something like: @@ -137,6 +220,25 @@ inline void ForEachVertex(MeshType &m, std::function +inline void ForEachEdge(const MeshType &m, std::function action) +{ + if(m.en == (int) m.edge.size()) + { + for(auto ei=m.edge.begin();ei!=m.edge.end();++ei) { + action(*ei); + } + } + else + { + for(auto ei=m.edge.begin();ei!=m.edge.end();++ei) + if(!(*ei).IsD()) + { + action(*ei); + } + } +} + template inline void ForEachEdge(MeshType &m, std::function action) { From 27856fce257cabe19f720d341a8b490b627abbd5 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 10 Sep 2020 16:38:22 +0200 Subject: [PATCH 04/10] clean selection.h --- vcg/complex/algorithms/update/selection.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/vcg/complex/algorithms/update/selection.h b/vcg/complex/algorithms/update/selection.h index b6cd1c5f..30cc5a8f 100644 --- a/vcg/complex/algorithms/update/selection.h +++ b/vcg/complex/algorithms/update/selection.h @@ -272,8 +272,6 @@ static void Clear(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 (auto f: m.face) if(!f.IsD() && f.IsS()) ++selCnt; return selCnt; @@ -283,8 +281,6 @@ static size_t FaceCount(const 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 (auto e: m.edge) if(!e.IsD() && e.IsS()) ++selCnt; return selCnt; @@ -294,8 +290,6 @@ static size_t EdgeCount(const 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 (auto v: m.vert) if(!v.IsD() && v.IsS()) ++selCnt; return selCnt; @@ -305,7 +299,7 @@ static size_t VertexCount(const MeshType &m) static size_t TetraCount (const MeshType & m) { size_t selCnt = 0; - ForEachTetra(m, [&selCnt] (TetraType & t) { + ForEachTetra(m, [&selCnt] (const TetraType & t) { if (t.IsS()) ++selCnt; }); From 98ff47110d81c78fef0a3fa810ddfa4f44940549 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 10 Sep 2020 14:06:10 +0200 Subject: [PATCH 05/10] 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; From dc5b0649eeb08e924b0654deeba92be019096ba5 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 10 Sep 2020 14:35:48 +0200 Subject: [PATCH 06/10] using range for in MeshAppendConst --- vcg/complex/append.h | 146 +++++++++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 62 deletions(-) diff --git a/vcg/complex/append.h b/vcg/complex/append.h index 4ea8fd03..cd52a483 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::ConstTetraIterator TetraIteratorRight; + typedef typename ConstMeshRight::TetraIterator TetraIteratorRight; typedef typename ConstMeshRight::VertexPointer VertexPointerRight; - typedef typename ConstMeshRight::ConstVertexIterator VertexIteratorRight; - typedef typename ConstMeshRight::ConstEdgeIterator EdgeIteratorRight; - typedef typename ConstMeshRight::ConstHEdgeIterator HEdgeIteratorRight; - typedef typename ConstMeshRight::ConstFaceIterator FaceIteratorRight; + typedef typename ConstMeshRight::VertexIterator VertexIteratorRight; + typedef typename ConstMeshRight::EdgeIterator EdgeIteratorRight; + typedef typename ConstMeshRight::HEdgeIterator HEdgeIteratorRight; + typedef typename ConstMeshRight::FaceIterator FaceIteratorRight; typedef typename ConstMeshRight::FacePointer FacePointerRight; struct Remap{ @@ -514,11 +514,12 @@ static void MeshAppendConst( else vp=Allocator::AddVertices(ml,mr.vn); - for(VertexIteratorRight vi=mr.vert.begin(); vi!=mr.vert.end(); ++vi) + for (auto v : mr.vert) + //for(VertexIteratorRight vi=mr.vert.begin(); vi!=mr.vert.end(); ++vi) { - if(!(*vi).IsD() && (!selected || (*vi).IsS())) + if(!v.IsD() && (!selected || v.IsS())) { - size_t ind=Index(mr,*vi); + size_t ind=Index(mr,v); remap.vert[ind]=int(Index(ml,*vp)); ++vp; } @@ -530,9 +531,10 @@ static void MeshAppendConst( 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); + for (auto e : mr.edge) + //for(EdgeIteratorRight ei=mr.edge.begin(); ei!=mr.edge.end(); ++ei) + if(!e.IsD() && (!selected || e.IsS())){ + size_t ind=Index(mr,e); remap.edge[ind]=int(Index(ml,*ep)); ++ep; } @@ -544,31 +546,34 @@ static void MeshAppendConst( 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); + for (auto f : mr.face) + //for(FaceIteratorRight fi=mr.face.begin(); fi!=mr.face.end(); ++fi) + if(!f.IsD() && (!selected || f.IsS())){ + size_t ind=Index(mr,f); 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); + for (auto he : mr.hedge) + //for(HEdgeIteratorRight hi=mr.hedge.begin(); hi!=mr.hedge.end(); ++hi) + if(!he.IsD() && (!selected || he.IsS())){ + size_t ind=Index(mr,he); assert(remap.hedge[ind]==Remap::InvalidIndex()); HEdgeIteratorLeft hp = Allocator::AddHEdges(ml,1); - (*hp).ImportData(*(hi)); + (*hp).ImportData(he); 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); + for (auto t : mr.tetra) + //for (TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti) + if (!t.IsD() && (!selected || t.IsS())) { + size_t idx = Index(mr, t); assert (remap.tetra[idx] == Remap::InvalidIndex()); TetraIteratorLeft tp = Allocator::AddTetras(ml, 1); - (*tp).ImportData(*ti); + (*tp).ImportData(t); remap.tetra[idx] = Index(ml, *tp); } @@ -576,64 +581,69 @@ static void MeshAppendConst( // 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); + for (auto v: mr.vert) + //for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi) + if( !v.IsD() && (!selected || v.IsS())){ + ml.vert[remap.vert[Index(mr,v)]].ImportData(v); + if(adjFlag) ImportVertexAdj(ml,mr,ml.vert[remap.vert[Index(mr,v)]],v,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); + for (auto e: mr.edge) + //for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei) + if(!e.IsD() && (!selected || e.IsS())){ + ml.edge[remap.edge[Index(mr,e)]].ImportData(e); // Edge to Vertex Adj - EdgeLeft &el = ml.edge[remap.edge[Index(mr,*ei)]]; + EdgeLeft &el = ml.edge[remap.edge[Index(mr,e)]]; 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))]]; + el.V(0) = &ml.vert[remap.vert[Index(mr,e.cV(0))]]; + el.V(1) = &ml.vert[remap.vert[Index(mr,e.cV(1))]]; } - if(adjFlag) ImportEdgeAdj(ml,mr,el,*ei,remap); + if(adjFlag) ImportEdgeAdj(ml,mr,el,e,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())) + for (auto f: mr.face) + //for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi) + if(!f.IsD() && (!selected || f.IsS())) { - FaceLeft &fl = ml.face[remap.face[Index(mr,*fi)]]; - fl.Alloc(fi->VN()); + FaceLeft &fl = ml.face[remap.face[Index(mr,f)]]; + fl.Alloc(f.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.V(i) = &ml.vert[remap.vert[Index(mr,f.cV(i))]]; } - fl.ImportData(*fi); + fl.ImportData(f); 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); + if(adjFlag) ImportFaceAdj(ml,mr,ml.face[remap.face[Index(mr,f)]],f,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); + for (auto he : mr.hedge) + //for(HEdgeIteratorRight hi=mr.hedge.begin();hi!=mr.hedge.end();++hi) + if(!he.IsD() && (!selected || he.IsS())){ + ml.hedge[remap.hedge[Index(mr,he)]].ImportData(he); + ImportHEdgeAdj(ml,mr,ml.hedge[remap.hedge[Index(mr,he)]],he,remap,selected); } //tetra - for(TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti) - if(!(*ti).IsD() && (!selected || (*ti).IsS())) + for (auto t: mr.tetra) + //for(TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti) + if(!t.IsD() && (!selected || t.IsS())) { - TetraLeft &tl = ml.tetra[remap.tetra[Index(mr,*ti)]]; + TetraLeft &tl = ml.tetra[remap.tetra[Index(mr,t)]]; 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.V(i) = &ml.vert[remap.vert[Index(mr,t.cV(i))]]; } - tl.ImportData(*ti); - if(adjFlag) ImportTetraAdj(ml, mr, ml.tetra[remap.tetra[Index(mr,*ti)]], *ti, remap); + tl.ImportData(t); + if(adjFlag) ImportTetraAdj(ml, mr, ml.tetra[remap.tetra[Index(mr,t)]], t, remap); } @@ -659,9 +669,12 @@ static void MeshAppendConst( 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); + for (auto v: mr.vert){ + //for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi,++id_r) + if( !v.IsD() && (!selected || v.IsS())) + (*al)._handle->CopyValue(remap.vert[Index(mr,v)], id_r, (*ar)._handle); + ++id_r; + } } } @@ -671,9 +684,12 @@ static void MeshAppendConst( 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); + for (auto e: mr.edge){ + //for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei,++id_r) + if( !e.IsD() && (!selected || e.IsS())) + (*al)._handle->CopyValue(remap.edge[Index(mr,e)], id_r, (*ar)._handle); + ++id_r; + } } } @@ -683,9 +699,12 @@ static void MeshAppendConst( 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); + for (auto f: mr.face) { + //for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi,++id_r) + if( !f.IsD() && (!selected || f.IsS())) + (*al)._handle->CopyValue(remap.face[Index(mr,f)], id_r, (*ar)._handle); + ++id_r; + } } } @@ -695,9 +714,12 @@ static void MeshAppendConst( 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); + for (auto t: mr.tetra) { + //for(TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti, ++id_r) + if( !t.IsD() && (!selected || t.IsS())) + (*al)._handle->CopyValue(remap.tetra[Index(mr, t)], id_r, (*ar)._handle); + ++id_r; + } } } // per mesh attributes From 09b12339c04efce4f80fcf24024c325ae4b5aa25 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 10 Sep 2020 15:44:27 +0200 Subject: [PATCH 07/10] using ForEach. add const ForEach and ForEachHEdge --- vcg/complex/append.h | 223 ++++++++++++++++++++++-------------------- vcg/complex/foreach.h | 102 +++++++++++++++++++ 2 files changed, 217 insertions(+), 108 deletions(-) diff --git a/vcg/complex/append.h b/vcg/complex/append.h index cd52a483..02580a4b 100644 --- a/vcg/complex/append.h +++ b/vcg/complex/append.h @@ -514,16 +514,15 @@ static void MeshAppendConst( else vp=Allocator::AddVertices(ml,mr.vn); - for (auto v : mr.vert) - //for(VertexIteratorRight vi=mr.vert.begin(); vi!=mr.vert.end(); ++vi) + ForEachVertex(mr, [&](const VertexRight& v) { - if(!v.IsD() && (!selected || v.IsS())) + if(!selected || v.IsS()) { size_t ind=Index(mr,v); remap.vert[ind]=int(Index(ml,*vp)); ++vp; } - } + }); // edge remap.edge.resize(mr.edge.size(), Remap::InvalidIndex()); EdgeIteratorLeft ep; @@ -531,13 +530,14 @@ static void MeshAppendConst( if(selected) ep=Allocator::AddEdges(ml,sen); else ep=Allocator::AddEdges(ml,mr.en); - for (auto e : mr.edge) - //for(EdgeIteratorRight ei=mr.edge.begin(); ei!=mr.edge.end(); ++ei) - if(!e.IsD() && (!selected || e.IsS())){ + ForEachEdge(mr, [&](const EdgeRight& e) + { + if(!selected || e.IsS()){ size_t ind=Index(mr,e); remap.edge[ind]=int(Index(ml,*ep)); ++ep; } + }); // face remap.face.resize(mr.face.size(), Remap::InvalidIndex()); @@ -546,52 +546,58 @@ static void MeshAppendConst( if(selected) fp=Allocator::AddFaces(ml,sfn); else fp=Allocator::AddFaces(ml,mr.fn); - for (auto f : mr.face) - //for(FaceIteratorRight fi=mr.face.begin(); fi!=mr.face.end(); ++fi) - if(!f.IsD() && (!selected || f.IsS())){ + ForEachFace(mr, [&](const FaceRight& f) + { + if(!selected || f.IsS()){ size_t ind=Index(mr,f); remap.face[ind]=int(Index(ml,*fp)); ++fp; } + }); // hedge remap.hedge.resize(mr.hedge.size(),Remap::InvalidIndex()); - for (auto he : mr.hedge) - //for(HEdgeIteratorRight hi=mr.hedge.begin(); hi!=mr.hedge.end(); ++hi) - if(!he.IsD() && (!selected || he.IsS())){ + + ForEachHEdge(mr, [&](const HEdgeRight& he) + { + if(!selected || he.IsS()){ size_t ind=Index(mr,he); assert(remap.hedge[ind]==Remap::InvalidIndex()); HEdgeIteratorLeft hp = Allocator::AddHEdges(ml,1); (*hp).ImportData(he); remap.hedge[ind]=Index(ml,*hp); } + }); remap.tetra.resize(mr.tetra.size(), Remap::InvalidIndex()); - for (auto t : mr.tetra) - //for (TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti) - if (!t.IsD() && (!selected || t.IsS())) { + + ForEachTetra(mr, [&](const TetraRight& t) + { + if (!selected || t.IsS()) { size_t idx = Index(mr, t); assert (remap.tetra[idx] == Remap::InvalidIndex()); TetraIteratorLeft tp = Allocator::AddTetras(ml, 1); (*tp).ImportData(t); remap.tetra[idx] = Index(ml, *tp); } + }); // phase 2. // copy data from mr to its corresponding elements in ml and adjacencies // vertex - for (auto v: mr.vert) - //for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi) - if( !v.IsD() && (!selected || v.IsS())){ + ForEachVertex(mr, [&](const VertexRight& v) + { + if(!selected || v.IsS()){ ml.vert[remap.vert[Index(mr,v)]].ImportData(v); if(adjFlag) ImportVertexAdj(ml,mr,ml.vert[remap.vert[Index(mr,v)]],v,remap); } + }); // edge - for (auto e: mr.edge) - //for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei) - if(!e.IsD() && (!selected || e.IsS())){ + ForEachEdge(mr, [&](const EdgeRight& e) + { + if(!selected || e.IsS()){ ml.edge[remap.edge[Index(mr,e)]].ImportData(e); // Edge to Vertex Adj EdgeLeft &el = ml.edge[remap.edge[Index(mr,e)]]; @@ -601,13 +607,14 @@ static void MeshAppendConst( } if(adjFlag) ImportEdgeAdj(ml,mr,el,e,remap); } + }); // face const size_t textureOffset = ml.textures.size(); bool WTFlag = HasPerWedgeTexCoord(mr) && (textureOffset>0); - for (auto f: mr.face) - //for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi) - if(!f.IsD() && (!selected || f.IsS())) + ForEachFace(mr, [&](const FaceRight& f) + { + if(!selected || f.IsS()) { FaceLeft &fl = ml.face[remap.face[Index(mr,f)]]; fl.Alloc(f.VN()); @@ -622,19 +629,21 @@ static void MeshAppendConst( if(adjFlag) ImportFaceAdj(ml,mr,ml.face[remap.face[Index(mr,f)]],f,remap); } + }); // hedge - for (auto he : mr.hedge) - //for(HEdgeIteratorRight hi=mr.hedge.begin();hi!=mr.hedge.end();++hi) - if(!he.IsD() && (!selected || he.IsS())){ + ForEachHEdge(mr, [&](const HEdgeRight& he) + { + if(!selected || he.IsS()){ ml.hedge[remap.hedge[Index(mr,he)]].ImportData(he); ImportHEdgeAdj(ml,mr,ml.hedge[remap.hedge[Index(mr,he)]],he,remap,selected); } + }); //tetra - for (auto t: mr.tetra) - //for(TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti) - if(!t.IsD() && (!selected || t.IsS())) + ForEachTetra(mr, [&](const TetraRight& t) + { + if(!selected || t.IsS()) { TetraLeft &tl = ml.tetra[remap.tetra[Index(mr,t)]]; @@ -646,91 +655,89 @@ static void MeshAppendConst( if(adjFlag) ImportTetraAdj(ml, mr, ml.tetra[remap.tetra[Index(mr,t)]], t, remap); } + }); - // phase 3. - // take care of other per mesh data: textures, attributes + // 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()); + // 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 + // 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; + 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 (auto v: mr.vert){ - //for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi,++id_r) - if( !v.IsD() && (!selected || v.IsS())) - (*al)._handle->CopyValue(remap.vert[Index(mr,v)], id_r, (*ar)._handle); - ++id_r; - } - } - } + // 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 (auto v: mr.vert){ + if( !v.IsD() && (!selected || v.IsS())) + (*al)._handle->CopyValue(remap.vert[Index(mr,v)], id_r, (*ar)._handle); + ++id_r; + } + } + } - // 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 (auto e: mr.edge){ - //for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei,++id_r) - if( !e.IsD() && (!selected || e.IsS())) - (*al)._handle->CopyValue(remap.edge[Index(mr,e)], id_r, (*ar)._handle); - ++id_r; - } - } - } + // 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 (auto e: mr.edge){ + if( !e.IsD() && (!selected || e.IsS())) + (*al)._handle->CopyValue(remap.edge[Index(mr,e)], id_r, (*ar)._handle); + ++id_r; + } + } + } - // 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 (auto f: mr.face) { - //for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi,++id_r) - if( !f.IsD() && (!selected || f.IsS())) - (*al)._handle->CopyValue(remap.face[Index(mr,f)], id_r, (*ar)._handle); - ++id_r; - } - } - } + // 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 (auto f: mr.face) { + if( !f.IsD() && (!selected || f.IsS())) + (*al)._handle->CopyValue(remap.face[Index(mr,f)], id_r, (*ar)._handle); + ++id_r; + } + } + } - // 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 (auto t: mr.tetra) { - //for(TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti, ++id_r) - if( !t.IsD() && (!selected || t.IsS())) - (*al)._handle->CopyValue(remap.tetra[Index(mr, t)], id_r, (*ar)._handle); - ++id_r; - } - } - } - // 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()) - // //... - // } + // 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 (auto t: mr.tetra) { + if( !t.IsD() && (!selected || t.IsS())) + (*al)._handle->CopyValue(remap.tetra[Index(mr, t)], id_r, (*ar)._handle); + ++id_r; + } + } + } + + // 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. diff --git a/vcg/complex/foreach.h b/vcg/complex/foreach.h index 156d3489..4f7710fd 100644 --- a/vcg/complex/foreach.h +++ b/vcg/complex/foreach.h @@ -34,6 +34,22 @@ namespace tri { @{ */ +template +inline void ForEachFacePos(const MeshType &m, std::function &)> action) +{ + typedef typename face::Pos PosType; + + for(auto fi=m.face.begin();fi!=m.face.end();++fi) + if(!(*fi).IsD()) + { + for(int i=0;i<3;++i) + { + PosType pi(&*fi,i); + action(pi); + } + } +} + template inline void ForEachFacePos(MeshType &m, std::function &)> action) { @@ -108,6 +124,25 @@ inline void ForEachFace(MeshType &m, std::function +inline void ForEachVertex(const MeshType &m, std::function action) +{ + if(m.vn == (int) m.vert.size()) + { + for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) { + action(*vi); + } + } + else + { + for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) + if(!(*vi).IsD()) + { + action(*vi); + } + } +} + template inline void ForEachVertex(MeshType &m, std::function action) { @@ -127,6 +162,54 @@ inline void ForEachVertex(MeshType &m, std::function +inline void ForEachHEdge(const MeshType &m, std::function action) +{ + if(m.hn == (int) m.hedge.size()) + { + for(auto hei=m.hedge.begin();hei!=m.hedge.end();++hei) { + action(*hei); + } + } + else + { + for(auto hei=m.hedge.begin();hei!=m.hedge.end();++hei) + if(!(*hei).IsD()) + { + action(*hei); + } + } +} + +template +inline void ForEachHEdge(MeshType &m, std::function action) +{ + if(m.hn == (int) m.hedge.size()) + { + for(auto hei=m.hedge.begin();hei!=m.hedge.end();++hei) { + action(*hei); + } + } + else + { + for(auto hei=m.hedge.begin();hei!=m.hedge.end();++hei) + if(!(*hei).IsD()) + { + action(*hei); + } + } +} + /** * ForEachEdge Helper * to traverse all the vertexes of a mesh you can simply write something like: @@ -137,6 +220,25 @@ inline void ForEachVertex(MeshType &m, std::function +inline void ForEachEdge(const MeshType &m, std::function action) +{ + if(m.en == (int) m.edge.size()) + { + for(auto ei=m.edge.begin();ei!=m.edge.end();++ei) { + action(*ei); + } + } + else + { + for(auto ei=m.edge.begin();ei!=m.edge.end();++ei) + if(!(*ei).IsD()) + { + action(*ei); + } + } +} + template inline void ForEachEdge(MeshType &m, std::function action) { From 8874b3785823c027744fd9d2441069e9f45c2119 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 10 Sep 2020 16:38:22 +0200 Subject: [PATCH 08/10] clean selection.h --- vcg/complex/algorithms/update/selection.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/vcg/complex/algorithms/update/selection.h b/vcg/complex/algorithms/update/selection.h index b6cd1c5f..30cc5a8f 100644 --- a/vcg/complex/algorithms/update/selection.h +++ b/vcg/complex/algorithms/update/selection.h @@ -272,8 +272,6 @@ static void Clear(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 (auto f: m.face) if(!f.IsD() && f.IsS()) ++selCnt; return selCnt; @@ -283,8 +281,6 @@ static size_t FaceCount(const 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 (auto e: m.edge) if(!e.IsD() && e.IsS()) ++selCnt; return selCnt; @@ -294,8 +290,6 @@ static size_t EdgeCount(const 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 (auto v: m.vert) if(!v.IsD() && v.IsS()) ++selCnt; return selCnt; @@ -305,7 +299,7 @@ static size_t VertexCount(const MeshType &m) static size_t TetraCount (const MeshType & m) { size_t selCnt = 0; - ForEachTetra(m, [&selCnt] (TetraType & t) { + ForEachTetra(m, [&selCnt] (const TetraType & t) { if (t.IsS()) ++selCnt; }); From 6f4e196236f3b5c36de921e16a3d4c1bf79e7f1e Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 11 Sep 2020 15:09:02 +0200 Subject: [PATCH 09/10] templating callable function in foreachs to allow usage of lambdas --- vcg/complex/foreach.h | 48 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/vcg/complex/foreach.h b/vcg/complex/foreach.h index 4f7710fd..a062e41c 100644 --- a/vcg/complex/foreach.h +++ b/vcg/complex/foreach.h @@ -34,8 +34,8 @@ namespace tri { @{ */ -template -inline void ForEachFacePos(const MeshType &m, std::function &)> action) +template +inline void ForEachFacePos(const MeshType &m, Callable action) { typedef typename face::Pos PosType; @@ -50,8 +50,8 @@ inline void ForEachFacePos(const MeshType &m, std::function -inline void ForEachFacePos(MeshType &m, std::function &)> action) +template +inline void ForEachFacePos(MeshType &m, Callable action) { typedef typename face::Pos PosType; @@ -76,8 +76,8 @@ inline void ForEachFacePos(MeshType &m, std::function -inline void ForEachFace(const MeshType &m, std::function action) +template +inline void ForEachFace(const MeshType &m, Callable action) { if(m.fn == (int) m.face.size()) { @@ -95,8 +95,8 @@ inline void ForEachFace(const MeshType &m, std::function -inline void ForEachFace(MeshType &m, std::function action) +template +inline void ForEachFace(MeshType &m, Callable action) { if(m.fn == (int) m.face.size()) { @@ -124,8 +124,8 @@ inline void ForEachFace(MeshType &m, std::function -inline void ForEachVertex(const MeshType &m, std::function action) +template +inline void ForEachVertex(const MeshType &m, Callable action) { if(m.vn == (int) m.vert.size()) { @@ -143,8 +143,8 @@ inline void ForEachVertex(const MeshType &m, std::function -inline void ForEachVertex(MeshType &m, std::function action) +template +inline void ForEachVertex(MeshType &m, Callable action) { if(m.vn == (int) m.vert.size()) { @@ -172,8 +172,8 @@ inline void ForEachVertex(MeshType &m, std::function -inline void ForEachHEdge(const MeshType &m, std::function action) +template +inline void ForEachHEdge(const MeshType &m, Callable action) { if(m.hn == (int) m.hedge.size()) { @@ -191,8 +191,8 @@ inline void ForEachHEdge(const MeshType &m, std::function -inline void ForEachHEdge(MeshType &m, std::function action) +template +inline void ForEachHEdge(MeshType &m, Callable action) { if(m.hn == (int) m.hedge.size()) { @@ -220,8 +220,8 @@ inline void ForEachHEdge(MeshType &m, std::function -inline void ForEachEdge(const MeshType &m, std::function action) +template +inline void ForEachEdge(const MeshType &m, Callable action) { if(m.en == (int) m.edge.size()) { @@ -239,8 +239,8 @@ inline void ForEachEdge(const MeshType &m, std::function -inline void ForEachEdge(MeshType &m, std::function action) +template +inline void ForEachEdge(MeshType &m, Callable action) { if(m.en == (int) m.edge.size()) { @@ -268,8 +268,8 @@ inline void ForEachEdge(MeshType &m, std::function -inline void ForEachTetra(const MeshType &m, std::function action) +template +inline void ForEachTetra(const MeshType &m, Callable action) { if(m.tn == (int) m.tetra.size()) { @@ -287,8 +287,8 @@ inline void ForEachTetra(const MeshType &m, std::function -inline void ForEachTetra(MeshType &m, std::function action) +template +inline void ForEachTetra(MeshType &m, Callable action) { if(m.tn == (int) m.tetra.size()) { From 55b55abdeddf947136b4e3682829953e95032b7f Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 11 Sep 2020 15:30:57 +0200 Subject: [PATCH 10/10] foreach used in selection.h --- vcg/complex/algorithms/update/selection.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/vcg/complex/algorithms/update/selection.h b/vcg/complex/algorithms/update/selection.h index 30cc5a8f..221db704 100644 --- a/vcg/complex/algorithms/update/selection.h +++ b/vcg/complex/algorithms/update/selection.h @@ -183,6 +183,7 @@ typedef typename MeshType::VertexType VertexType; typedef typename MeshType::VertexPointer VertexPointer; typedef typename MeshType::VertexIterator VertexIterator; typedef typename MeshType::EdgeIterator EdgeIterator; +typedef typename MeshType::EdgeType EdgeType; typedef typename MeshType::FaceType FaceType; typedef typename MeshType::FacePointer FacePointer; typedef typename MeshType::FaceIterator FaceIterator; @@ -272,8 +273,9 @@ static void Clear(MeshType &m) static size_t FaceCount(const MeshType &m) { size_t selCnt=0; - for (auto f: m.face) - if(!f.IsD() && f.IsS()) ++selCnt; + ForEachFace(m, [&](const FaceType& f){ + if(f.IsS()) ++selCnt; + }); return selCnt; } @@ -281,8 +283,9 @@ static size_t FaceCount(const MeshType &m) static size_t EdgeCount(const MeshType &m) { size_t selCnt=0; - for (auto e: m.edge) - if(!e.IsD() && e.IsS()) ++selCnt; + ForEachEdge(m, [&](const EdgeType& e){ + if(e.IsS()) ++selCnt; + }); return selCnt; } @@ -290,8 +293,9 @@ static size_t EdgeCount(const MeshType &m) static size_t VertexCount(const MeshType &m) { size_t selCnt=0; - for (auto v: m.vert) - if(!v.IsD() && v.IsS()) ++selCnt; + ForEachVertex(m, [&](const VertexType& v){ + if(v.IsS()) ++selCnt; + }); return selCnt; } @@ -299,9 +303,8 @@ static size_t VertexCount(const MeshType &m) static size_t TetraCount (const MeshType & m) { size_t selCnt = 0; - ForEachTetra(m, [&selCnt] (const TetraType & t) { - if (t.IsS()) - ++selCnt; + ForEachTetra(m, [&] (const TetraType & t) { + if (t.IsS()) ++selCnt; }); return selCnt;