From a78a51e6501580f73594b0f7f645cea02dc9f61b Mon Sep 17 00:00:00 2001 From: "T.Alderighi" Date: Thu, 20 Feb 2020 20:31:47 +0100 Subject: [PATCH] handling non trivially copyable types in the attribute copy when appending meshes. https://en.cppreference.com/w/cpp/types/is_trivially_copyable --- vcg/complex/append.h | 96 +++++++------ vcg/container/simple_temporary_data.h | 191 +++++++++++++++++--------- 2 files changed, 169 insertions(+), 118 deletions(-) diff --git a/vcg/complex/append.h b/vcg/complex/append.h index a3c47245..047214f9 100644 --- a/vcg/complex/append.h +++ b/vcg/complex/append.h @@ -415,60 +415,56 @@ static void Mesh(MeshLeft& ml, ConstMeshRight& mr, const bool selected = false, // 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(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi,++id_r) - if( !(*vi).IsD() && (!selected || (*vi).IsS())) - memcpy((*al)._handle->At(remap.vert[Index(mr,*vi)]),(*ar)._handle->At(id_r), - (*al)._handle->SizeOf()); - } - } + // 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())) - memcpy((*al)._handle->At(remap.edge[Index(mr,*ei)]),(*ar)._handle->At(id_r), - (*al)._handle->SizeOf()); - } - } + // 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())) - memcpy((*al)._handle->At(remap.face[Index(mr,*fi)]),(*ar)._handle->At(id_r), - (*al)._handle->SizeOf()); - } - } + // 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())) - memcpy((*al)._handle->At(remap.tetra[Index(mr, *ti)]),(*ar)._handle->At(id_r), - (*al)._handle->SizeOf()); - } - } + // 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 diff --git a/vcg/container/simple_temporary_data.h b/vcg/container/simple_temporary_data.h index cd5c8605..979e4357 100644 --- a/vcg/container/simple_temporary_data.h +++ b/vcg/container/simple_temporary_data.h @@ -24,62 +24,82 @@ #ifndef __VCGLIB_SIMPLE__ #define __VCGLIB_SIMPLE__ -namespace vcg { +namespace vcg +{ -class SimpleTempDataBase{ +class SimpleTempDataBase +{ public: - virtual ~SimpleTempDataBase() {} - SimpleTempDataBase() {} + virtual ~SimpleTempDataBase() {} + SimpleTempDataBase() {} virtual void Resize(size_t sz) = 0; - virtual void Reorder(std::vector & newVertIndex)=0; - virtual size_t SizeOf() const = 0; - virtual void * DataBegin() = 0; - virtual void * At(size_t i ) = 0; + virtual void Reorder(std::vector &newVertIndex) = 0; + virtual size_t SizeOf() const = 0; + virtual void *DataBegin() = 0; + + virtual void *At(size_t i) = 0; + virtual const void *At(size_t i) const = 0; + virtual void CopyValue(const size_t to, const size_t from, const SimpleTempDataBase *other) = 0; }; template -class VectorNBW: public std::vector {}; +class VectorNBW : public std::vector +{ +}; template <> -class VectorNBW{ +class VectorNBW +{ public: - VectorNBW():data(0),datasize(0),datareserve(0){} + VectorNBW() : data(0), datasize(0), datareserve(0) {} - ~VectorNBW() { + ~VectorNBW() + { if (data) delete[] data; } - bool * data ; + bool *data; - void reserve (const int & sz) { - if(sz<=datareserve) return; - bool * newdataLoc = new bool[ sz ]; - if(datasize!=0) memcpy(newdataLoc,data,sizeof(datasize)); - std::swap(data,newdataLoc); - if(newdataLoc != 0) delete[] newdataLoc; + void reserve(const int &sz) + { + if (sz <= datareserve) + return; + bool *newdataLoc = new bool[sz]; + if (datasize != 0) + memcpy(newdataLoc, data, sizeof(datasize)); + std::swap(data, newdataLoc); + if (newdataLoc != 0) + delete[] newdataLoc; datareserve = sz; } - void resize (const int & sz) { + void resize(const int &sz) + { int oldDatasize = datasize; - if(sz <= oldDatasize) return; - if(sz > datareserve) + if (sz <= oldDatasize) + return; + if (sz > datareserve) reserve(sz); datasize = sz; - memset(&data[oldDatasize],0,datasize-oldDatasize); - } - void push_back(const bool & v) { resize(datasize+1); data[datasize] = v;} + memset(&data[oldDatasize], 0, datasize - oldDatasize); + } + void push_back(const bool &v) + { + resize(datasize + 1); + data[datasize] = v; + } - void clear(){ datasize = 0;} + void clear() { datasize = 0; } - unsigned int size() const { return datasize;} + unsigned int size() const { return datasize; } - bool empty() const {return datasize==0;} + bool empty() const { return datasize == 0; } - bool * begin() const {return data;} + bool *begin() const { return data; } - bool & operator [](const int & i){return data[i];} + bool &operator[](const int &i) { return data[i]; } + const bool &operator[](const int &i) const { return data[i]; } private: int datasize; @@ -87,77 +107,112 @@ private: }; template -class SimpleTempData:public SimpleTempDataBase{ +class SimpleTempData : public SimpleTempDataBase +{ - public: - typedef SimpleTempData SimpTempDataType; +public: + typedef SimpleTempData SimpTempDataType; typedef ATTR_TYPE AttrType; - STL_CONT& c; + STL_CONT &c; VectorNBW data; int padding; - SimpleTempData(STL_CONT &_c):c(_c),padding(0){data.reserve(c.capacity());data.resize(c.size());}; - SimpleTempData(STL_CONT &_c, const ATTR_TYPE &val):c(_c){ - data.reserve(c.capacity());data.resize(c.size()); + SimpleTempData(STL_CONT &_c) : c(_c), padding(0) + { + data.reserve(c.capacity()); + data.resize(c.size()); + }; + SimpleTempData(STL_CONT &_c, const ATTR_TYPE &val) : c(_c) + { + data.reserve(c.capacity()); + data.resize(c.size()); Init(val); }; ~SimpleTempData() - { - data.clear(); - } + { + data.clear(); + } void Init(const ATTR_TYPE &val) { - std::fill(data.begin(),data.end(),val); + std::fill(data.begin(), data.end(), val); } // access to data - ATTR_TYPE & operator[](const typename STL_CONT::value_type & v){return data[&v-&*c.begin()];} - ATTR_TYPE & operator[](const typename STL_CONT::value_type * v){return data[v-&*c.begin()];} - ATTR_TYPE & operator[](const typename STL_CONT::iterator & cont){return data[&(*cont)-&*c.begin()];} - ATTR_TYPE & operator[](size_t i){return data[i];} + ATTR_TYPE &operator[](const typename STL_CONT::value_type &v) { return data[&v - &*c.begin()]; } + ATTR_TYPE &operator[](const typename STL_CONT::value_type *v) { return data[v - &*c.begin()]; } + ATTR_TYPE &operator[](const typename STL_CONT::iterator &cont) { return data[&(*cont) - &*c.begin()]; } + ATTR_TYPE &operator[](size_t i) { return data[i]; } - void * At(size_t i ) {return &(*this)[i];}; + const ATTR_TYPE &operator[](const typename STL_CONT::value_type &v) const { return data[&v - &*c.begin()]; } + const ATTR_TYPE &operator[](const typename STL_CONT::value_type *v) const { return data[v - &*c.begin()]; } + const ATTR_TYPE &operator[](const typename STL_CONT::iterator &cont) const { return data[&(*cont) - &*c.begin()]; } + const ATTR_TYPE &operator[](size_t i) const { return data[i]; } + + void *At(size_t i) { return &(*this)[i]; } + const void *At(size_t i) const { return &(*this)[i]; } + + void CopyValue(const size_t to, const size_t from, const SimpleTempDataBase *other) + { + assert(other != nullptr); + data[to] = *(static_cast(other->At(from))); + } // update temporary data size - bool UpdateSize(){ - if(data.size() != c.size()) - { - data.resize(c.size()); - return false; - } - return true; + bool UpdateSize() + { + if (data.size() != c.size()) + { + data.resize(c.size()); + return false; } + return true; + } - void Resize(size_t sz){ + void Resize(size_t sz) + { data.resize(sz); } - void Reorder(std::vector & newVertIndex){ - for(unsigned int i = 0 ; i < data.size(); ++i){ - if( newVertIndex[i] != (std::numeric_limits::max)()) + void Reorder(std::vector &newVertIndex) + { + for (unsigned int i = 0; i < data.size(); ++i) + { + if (newVertIndex[i] != (std::numeric_limits::max)()) data[newVertIndex[i]] = data[i]; } } - size_t SizeOf() const {return sizeof(ATTR_TYPE);} - void * DataBegin() {return data.empty()?NULL:&(*data.begin());} + size_t SizeOf() const { return sizeof(ATTR_TYPE); } + void *DataBegin() { return data.empty() ? NULL : &(*data.begin()); } }; template -class Attribute: public SimpleTempDataBase { +class Attribute : public SimpleTempDataBase +{ public: typedef ATTR_TYPE AttrType; - AttrType * attribute; - Attribute(){attribute = new ATTR_TYPE();} - ~Attribute(){delete attribute;} - size_t SizeOf()const {return sizeof(ATTR_TYPE);} - void * DataBegin(){return attribute;} + AttrType *attribute; + Attribute() { attribute = new ATTR_TYPE(); } + ~Attribute() { delete attribute; } + size_t SizeOf() const { return sizeof(ATTR_TYPE); } + void *DataBegin() { return attribute; } - void Resize(size_t ) {assert(0);} - void Reorder(std::vector & ){assert(0);} - void * At(size_t ) {assert(0);return (void*)0;} + void Resize(size_t) { assert(0); } + void Reorder(std::vector &) { assert(0); } + + void *At(size_t) + { + assert(0); + return (void *)0; + } + const void *At(size_t) const + { + assert(0); + return (void *)0; + } + void CopyValue(const size_t, const size_t, const SimpleTempDataBase *) { assert(0); } }; } // end namespace vcg