36#include <OpenVolumeMesh/Core/ResourceManager.hh>
37#include <OpenVolumeMesh/Core/Properties/PropertyPtr.hh>
38#include <OpenVolumeMesh/Core/detail/internal_type_name.hh>
40namespace OpenVolumeMesh {
43template<
typename EntityTag>
44detail::Tracker<PropertyStorageBase> &
45ResourceManager::storage_tracker()
const
47 return storage_trackers_.get<EntityTag>();
55template<
typename EntityTag>
58 for (
auto prop: persistent_props_.get<EntityTag>()) {
59 prop->set_persistent(
false);
61 persistent_props_.get<EntityTag>().clear();
63 for (
auto prop: storage_tracker<EntityTag>()) {
64 prop->set_shared(
false);
68template <
typename Handle>
69void ResourceManager::swap_property_elements(Handle _idx_a, Handle _idx_b)
71 static_assert(is_handle_v<Handle>);
72 for (
auto &prop: storage_tracker<typename Handle::EntityTag>()) {
73 prop->swap(_idx_a.uidx(), _idx_b.uidx());
77template <
typename Handle>
78void ResourceManager::copy_property_elements(Handle _idx_a, Handle _idx_b)
80 static_assert(is_handle_v<Handle>);
81 for (
auto &prop: storage_tracker<typename Handle::EntityTag>()) {
82 prop->copy(_idx_a.uidx(), _idx_b.uidx());
87VertexPropertyT<T> ResourceManager::request_vertex_property(
const std::string& _name,
const T _def) {
89 return request_property<T, Entity::Vertex>(_name, _def);
93EdgePropertyT<T> ResourceManager::request_edge_property(
const std::string& _name,
const T _def) {
95 return request_property<T, Entity::Edge>(_name, _def);
99HalfEdgePropertyT<T> ResourceManager::request_halfedge_property(
const std::string& _name,
const T _def) {
101 return request_property<T, Entity::HalfEdge>(_name, _def);
105FacePropertyT<T> ResourceManager::request_face_property(
const std::string& _name,
const T _def) {
107 return request_property<T, Entity::Face>(_name, _def);
111HalfFacePropertyT<T> ResourceManager::request_halfface_property(
const std::string& _name,
const T _def) {
112 return request_property<T, Entity::HalfFace>(_name, _def);
116CellPropertyT<T> ResourceManager::request_cell_property(
const std::string& _name,
const T _def) {
118 return request_property<T, Entity::Cell>(_name, _def);
122MeshPropertyT<T> ResourceManager::request_mesh_property(
const std::string& _name,
const T _def) {
124 return request_property<T, Entity::Mesh>(_name, _def);
127template<
typename T,
typename EntityTag>
128std::optional<PropertyPtr<T, EntityTag>>
129ResourceManager::internal_find_property(
const std::string& _name)
const
135 auto type_name = detail::internal_type_name<T>();
137 for(
auto &prop: storage_tracker<EntityTag>())
140 && prop->name() == _name
141 && prop->internal_type_name() == type_name)
143 return prop_ptr_from_storage<T, EntityTag>(prop);
149template<
class T,
class EntityTag>
150PropertyPtr<T, EntityTag> ResourceManager::internal_create_property(
151 std::string _name,
const T _def,
bool _shared)
const
153 auto storage = std::make_shared<PropertyStorageT<T>>(
154 &storage_tracker<EntityTag>(),
159 storage->resize(n<EntityTag>());
160 return PropertyPtr<T, EntityTag>(std::move(storage));
163template<
typename T,
typename EntityTag>
166 auto prop = internal_find_property<T, EntityTag>(_name);
169 bool shared = !_name.empty();
170 return internal_create_property<T, EntityTag>(_name, _def, shared);
173template<
typename T,
typename EntityTag>
174std::optional<PropertyPtr<T, EntityTag>>
177 auto prop = internal_find_property<T, EntityTag>(_name);
180 auto ptr = internal_create_property<T, EntityTag>(std::move(_name), _def,
true);
185template<
typename T,
typename EntityTag>
186std::optional<PropertyPtr<T, EntityTag>>
189 auto prop = internal_find_property<T, EntityTag>(_name);
192 return internal_create_property<T, EntityTag>(std::move(_name), _def,
true);
194template<
typename T,
typename EntityTag>
198 return internal_create_property<T, EntityTag>(std::move(_name), _def,
false);
201template<
typename T,
typename EntityTag>
202std::optional<PropertyPtr<T, EntityTag>>
205 return internal_find_property<T, EntityTag>(_name);
208template<
typename T,
typename EntityTag>
209std::optional<const PropertyPtr<T, EntityTag>>
212 return internal_find_property<T, EntityTag>(_name);
216template<
typename T,
class EntityTag>
219 if(_enable == _prop.shared())
return;
221 auto sptr = std::static_pointer_cast<PropertyStorageBase>(_prop.storage());
223 if (_prop.anonymous()) {
224 throw std::runtime_error(
"Shared properties must have a name!");
226 auto existing = internal_find_property<T, EntityTag>(_prop.name());
228 throw std::runtime_error(
"A shared property with this name, type and entity type already exists.");
231 set_persistent(_prop,
false);
233 sptr->set_shared(_enable);
236template<
typename T,
class EntityTag>
237void ResourceManager::set_persistent(PropertyPtr<T, EntityTag>& _prop,
bool _enable)
239 if(_enable == _prop.persistent())
return;
241 auto sptr = std::static_pointer_cast<PropertyStorageBase>(_prop.storage());
243 if (!_prop.shared()) {
244 throw std::runtime_error(
"Persistent properties must be shared (set_shared).");
246 persistent_props_.get<EntityTag>().insert(sptr);
248 persistent_props_.get<EntityTag>().erase(sptr);
250 sptr->set_persistent(_enable);
254template<
class EntityTag>
255void ResourceManager::resize_props(
size_t _n)
257 static_assert(is_entity_v<EntityTag>);
258 for (
auto &prop: storage_tracker<EntityTag>()) {
263template<
class EntityTag>
264void ResourceManager::reserve_props(
size_t _n)
266 static_assert(is_entity_v<EntityTag>);
267 for (
auto &prop: storage_tracker<EntityTag>()) {
273template<
typename Handle>
274void ResourceManager::entity_deleted(Handle _h)
276 static_assert(is_handle_v<Handle>);
277 for (
auto &prop: storage_tracker<typename Handle::EntityTag>()) {
278 prop->delete_element(_h.uidx());
283template<
typename EntityTag>
285 return storage_tracker<EntityTag>().size();
288template<
typename EntityTag>
290 return persistent_props_.get<EntityTag>().size();
295template<
typename EntityTag>
298 auto &src_all = _src.template storage_tracker<EntityTag>();
299 auto &dst_all = storage_tracker<EntityTag>();
304 auto &persistent = persistent_props_.get<EntityTag>();
308 for (
const auto &srcprop: src_all) {
310 if (!srcprop->shared()) {
316 for (
auto it = dst_all.begin(); it != dst_all.end(); ++it)
319 if (!dstprop->shared()) {
322 if (dstprop->name() == srcprop->name()
323 && dstprop->internal_type_name() == srcprop->internal_type_name())
326 dstprop->assign_values_from(srcprop);
327 if (srcprop->persistent() && !dstprop->persistent()) {
328 persistent.insert(dstprop->shared_from_this());
337 auto dstprop = srcprop->clone();
338 dstprop->set_tracker(&storage_tracker<EntityTag>());
339 if (srcprop->persistent()) {
340 persistent.insert(dstprop->shared_from_this());
351template <
class T,
typename Entity>
352PropertyPtr<T, Entity>::PropertyPtr(ResourceManager *mesh, std::string _name, T
const &_def)
354 *
this = mesh->request_property<T, Entity>(_name, _def);
358template <
class T,
typename EntityTag>
359PropertyPtr<T, EntityTag> ResourceManager::
360prop_ptr_from_storage(PropertyStorageBase *_prop)
362 auto ps = std::static_pointer_cast<PropertyStorageT<T>>(
363 _prop->shared_from_this());
364 return PropertyPtr<T, EntityTag>(std::move(ps));
std::optional< PropertyPtr< T, EntityTag > > create_shared_property(std::string _name, const T _def=T())
std::optional< PropertyPtr< T, EntityTag > > get_property(const std::string &_name)
void clear_props()
drop persistent properties.
size_t n_persistent_props() const
number of persistent properties
std::optional< PropertyPtr< T, EntityTag > > create_persistent_property(std::string _name, const T _def=T())
size_t n_props() const
number of tracked properties
PropertyPtr< T, EntityTag > create_private_property(std::string _name={}, const T _def=T()) const
PropertyPtr< T, EntityTag > request_property(const std::string &_name=std::string(), const T _def=T())