From ba19b93aa3bf3f65e3c85271ee33d4391422cf3f Mon Sep 17 00:00:00 2001 From: Martin Heistermann Date: Tue, 21 May 2019 16:27:39 +0200 Subject: [PATCH] implement/improve mesh assignment --- src/OpenVolumeMesh/Core/BaseProperty.hh | 5 +++ src/OpenVolumeMesh/Core/GeometryKernel.hh | 5 +++ src/OpenVolumeMesh/Core/PropertyPtr.hh | 2 ++ src/OpenVolumeMesh/Core/PropertyPtrT_impl.hh | 7 ++++ src/OpenVolumeMesh/Core/ResourceManager.cc | 34 +++++++++++++++++--- src/OpenVolumeMesh/Core/TopologyKernel.hh | 3 ++ 6 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/OpenVolumeMesh/Core/BaseProperty.hh b/src/OpenVolumeMesh/Core/BaseProperty.hh index 71e99ee..4c39c97 100644 --- a/src/OpenVolumeMesh/Core/BaseProperty.hh +++ b/src/OpenVolumeMesh/Core/BaseProperty.hh @@ -62,6 +62,7 @@ public: BaseProperty& operator=(const BaseProperty& _cpy) = delete; + virtual ~BaseProperty() {} virtual const std::string& name() const = 0; @@ -92,6 +93,10 @@ public: protected: + /// Copy data from other property. `other` MUST point to an object with the same type as `this`! + /// Currently no type check is performed. + virtual void assign_values_from(const BaseProperty *other) = 0; + virtual void delete_multiple_entries(const std::vector& _tags) = 0; virtual void resize(size_t /*_size*/) = 0; diff --git a/src/OpenVolumeMesh/Core/GeometryKernel.hh b/src/OpenVolumeMesh/Core/GeometryKernel.hh index 8541a00..ab8f85d 100644 --- a/src/OpenVolumeMesh/Core/GeometryKernel.hh +++ b/src/OpenVolumeMesh/Core/GeometryKernel.hh @@ -64,6 +64,11 @@ public: /// Destructor ~GeometryKernel() = default; + template + void assign(const GeometryKernel *other) { + TopologyKernelT::assign(other); + other->clone_vertices(vertices_); + } /// Override of empty add_vertex function virtual VertexHandle add_vertex() { return add_vertex(VecT()); } diff --git a/src/OpenVolumeMesh/Core/PropertyPtr.hh b/src/OpenVolumeMesh/Core/PropertyPtr.hh index 1c5d408..6c8840c 100644 --- a/src/OpenVolumeMesh/Core/PropertyPtr.hh +++ b/src/OpenVolumeMesh/Core/PropertyPtr.hh @@ -115,6 +115,8 @@ public: protected: + void assign_values_from(const BaseProperty *other) override; + virtual void delete_multiple_entries(const std::vector& _tags); virtual void resize(size_t _size); diff --git a/src/OpenVolumeMesh/Core/PropertyPtrT_impl.hh b/src/OpenVolumeMesh/Core/PropertyPtrT_impl.hh index e240e15..6bcfb70 100644 --- a/src/OpenVolumeMesh/Core/PropertyPtrT_impl.hh +++ b/src/OpenVolumeMesh/Core/PropertyPtrT_impl.hh @@ -59,6 +59,13 @@ PropertyPtr::~PropertyPtr() { } } +template +void PropertyPtr::assign_values_from(const BaseProperty *other) { + auto _other = static_cast*>(other); + // FIXME: would be nice to perform a type check here + ptr::shared_ptr::get()->data_vector() = _other->get()->data_vector(); +} + template void PropertyPtr::resize(size_t _size) { ptr::shared_ptr::get()->resize(_size); diff --git a/src/OpenVolumeMesh/Core/ResourceManager.cc b/src/OpenVolumeMesh/Core/ResourceManager.cc index fa8a90e..0772678 100644 --- a/src/OpenVolumeMesh/Core/ResourceManager.cc +++ b/src/OpenVolumeMesh/Core/ResourceManager.cc @@ -51,11 +51,34 @@ ResourceManager& ResourceManager::operator=(const ResourceManager &other) if (this == &other) return *this; - auto cloneProps = [this](const Properties &src, Properties &dest) { - dest.reserve(src.size()); - for (BaseProperty *bp: src) { - dest.push_back(bp->clone(*this, bp->handle())); + auto cloneProps = [this](const Properties &src, Properties &dest) + { + // If possible, re-use existing properties instead of copying + // everything blindly. + // This way, references to properties of `this` do not expire + // if a corresponding property exists in `other`, e.g. attributes. + Properties out; + out.reserve(src.size()); + for (BaseProperty *srcprop: src) { + bool found = false; + for (auto it = dest.begin(); it != dest.end(); ++it) { + auto dstprop = *it; + if (dstprop->name() == srcprop->name()) + { + // TODO: type check + out.push_back(dstprop); + dest.erase(it); + dstprop->assign_values_from(srcprop); + found = true; + break; + } + } + if (!found) { + out.push_back(srcprop->clone(*this, OpenVolumeMeshHandle(-1))); + } } + updatePropHandles(out); + dest = std::move(out); }; cloneProps(other.vertex_props_, vertex_props_); cloneProps(other.edge_props_, edge_props_); @@ -72,7 +95,8 @@ ResourceManager& ResourceManager::operator=(ResourceManager &&other) if (this == &other) return *this; - auto moveProps = [this](Properties &&src, Properties &dest) { + auto moveProps = [this](Properties &&src, Properties &dest){ + // TODO: check for existing properties and move data contents instead of Property classes dest = std::move(src); for (auto prop: dest) { prop->setResMan(this); diff --git a/src/OpenVolumeMesh/Core/TopologyKernel.hh b/src/OpenVolumeMesh/Core/TopologyKernel.hh index 8fde79a..f638ce5 100644 --- a/src/OpenVolumeMesh/Core/TopologyKernel.hh +++ b/src/OpenVolumeMesh/Core/TopologyKernel.hh @@ -62,6 +62,9 @@ public: TopologyKernel& operator=(const TopologyKernel&) = default; + void assign(const TopologyKernel *other) { + *this = *other; + } /* * Defines and constants -- GitLab