Commit 3a072607 authored by Jan Möbius's avatar Jan Möbius

Merge branch 'propmgr' into 'master'

Propmgr

Added some more convenience to the PropertyManager class.

See merge request !85
parents ffba4767 f08f96eb
Pipeline #2759 passed with stage
in 21 minutes and 29 seconds
......@@ -208,6 +208,42 @@ class PropertyManager {
return std::move(pm);
}
/**
* Like createIfNotExists() with two parameters except, if the property
* doesn't exist, it is initialized with the supplied value over
* the supplied range after creation. If the property already exists,
* this method has the exact same effect as the two parameter version.
* Lifecycle management is disabled in any case.
*
* @see makePropertyManagerFromExistingOrNew
*/
template<typename PROP_VALUE, typename ITERATOR_TYPE>
static PropertyManager createIfNotExists(MeshT &mesh, const char *propname,
const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end,
const PROP_VALUE &init_value) {
const bool exists = propertyExists(mesh, propname);
PropertyManager pm(mesh, propname, exists);
pm.retain();
if (!exists)
pm.set_range(begin, end, init_value);
return std::move(pm);
}
/**
* Like createIfNotExists() with two parameters except, if the property
* doesn't exist, it is initialized with the supplied value over
* the supplied range after creation. If the property already exists,
* this method has the exact same effect as the two parameter version.
* Lifecycle management is disabled in any case.
*
* @see makePropertyManagerFromExistingOrNew
*/
template<typename PROP_VALUE, typename ITERATOR_RANGE>
static PropertyManager createIfNotExists(MeshT &mesh, const char *propname,
const ITERATOR_RANGE &range, const PROP_VALUE &init_value) {
return createIfNotExists(
mesh, propname, range.begin(), range.end(), init_value);
}
PropertyManager duplicate(const char *clone_name) {
PropertyManager pm(*mesh_, clone_name, false);
......@@ -267,6 +303,27 @@ class PropertyManager {
return (Proxy)pm;
}
/**
* Like createIfNotExists() with two parameters except, if the property
* doesn't exist, it is initialized with the supplied value over
* the supplied range after creation. If the property already exists,
* this method has the exact same effect as the two parameter version.
* Lifecycle management is disabled in any case.
*
* @see makePropertyManagerFromExistingOrNew
*/
template<typename PROP_VALUE, typename ITERATOR_TYPE>
static Proxy createIfNotExists(MeshT &mesh, const char *propname,
const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end,
const PROP_VALUE &init_value) {
const bool exists = propertyExists(mesh, propname);
PropertyManager pm(mesh, propname, exists);
pm.retain();
if (!exists)
pm.set_range(begin, end, init_value);
return (Proxy)pm;
}
Proxy duplicate(const char *clone_name) {
PropertyManager pm(*mesh_, clone_name, false);
pm.mesh_->property(pm.prop_) = mesh_->property(prop_);
......@@ -353,6 +410,14 @@ class PropertyManager {
(*this)[*begin] = value;
}
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
template<typename HandleTypeIteratorRange, typename PROP_VALUE>
void set_range(const HandleTypeIteratorRange &range,
const PROP_VALUE &value) {
set_range(range.begin(), range.end(), value);
}
#endif
/**
* Conveniently transfer the values managed by one property manager
* onto the values managed by a different property manager.
......@@ -466,5 +531,47 @@ PropertyManager<PROPTYPE, MeshT> makePropertyManagerFromExistingOrNew(MeshT &mes
return PropertyManager<PROPTYPE, MeshT>::createIfNotExists(mesh, propname);
}
/** \relates PropertyManager
* Like the two parameter version of makePropertyManagerFromExistingOrNew()
* except it initializes the property with the specified value over the
* specified range if it needs to be created. If the property already exists,
* this function has the exact same effect as the two parameter version.
*
* Creates a non-owning wrapper for a mesh property (no lifecycle management).
* If the given property does not exist, it is created.
*
* Intended for creating or accessing persistent properties.
*/
template<typename PROPTYPE, typename MeshT,
typename ITERATOR_TYPE, typename PROP_VALUE>
PropertyManager<PROPTYPE, MeshT> makePropertyManagerFromExistingOrNew(
MeshT &mesh, const char *propname,
const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end,
const PROP_VALUE &init_value) {
return PropertyManager<PROPTYPE, MeshT>::createIfNotExists(
mesh, propname, begin, end, init_value);
}
/** \relates PropertyManager
* Like the two parameter version of makePropertyManagerFromExistingOrNew()
* except it initializes the property with the specified value over the
* specified range if it needs to be created. If the property already exists,
* this function has the exact same effect as the two parameter version.
*
* Creates a non-owning wrapper for a mesh property (no lifecycle management).
* If the given property does not exist, it is created.
*
* Intended for creating or accessing persistent properties.
*/
template<typename PROPTYPE, typename MeshT,
typename ITERATOR_RANGE, typename PROP_VALUE>
PropertyManager<PROPTYPE, MeshT> makePropertyManagerFromExistingOrNew(
MeshT &mesh, const char *propname,
const ITERATOR_RANGE &range,
const PROP_VALUE &init_value) {
return makePropertyManagerFromExistingOrNew<PROPTYPE, MeshT>(
mesh, propname, range.begin(), range.end(), init_value);
}
} /* namespace OpenMesh */
#endif /* PROPERTYMANAGER_HH_ */
......@@ -60,36 +60,76 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) {
face_vhandles.push_back(vhandle[3]);
mesh_.add_face(face_vhandles);
OpenMesh::PropertyManager<
OpenMesh::VPropHandleT<bool>, Mesh> pm_v_bool(mesh_, "pm_v_bool");
pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), false);
for (int i = 0; i < 4; ++i)
ASSERT_FALSE(pm_v_bool[vhandle[i]]);
pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), true);
for (int i = 0; i < 4; ++i)
ASSERT_TRUE(pm_v_bool[vhandle[i]]);
OpenMesh::PropertyManager<
OpenMesh::EPropHandleT<bool>, Mesh> pm_e_bool(mesh_, "pm_e_bool");
pm_e_bool.set_range(mesh_.edges_begin(), mesh_.edges_end(), false);
for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
e_it != f_end; ++e_it)
ASSERT_FALSE(pm_e_bool[*e_it]);
pm_e_bool.set_range(mesh_.edges_begin(), mesh_.edges_end(), true);
for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
e_it != f_end; ++e_it)
ASSERT_TRUE(pm_e_bool[*e_it]);
OpenMesh::PropertyManager<
OpenMesh::FPropHandleT<bool>, Mesh> pm_f_bool(mesh_, "pm_f_bool");
pm_f_bool.set_range(mesh_.faces_begin(), mesh_.faces_end(), false);
for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
f_it != f_end; ++f_it)
ASSERT_FALSE(pm_f_bool[*f_it]);
pm_f_bool.set_range(mesh_.faces_begin(), mesh_.faces_end(), true);
for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
f_it != f_end; ++f_it)
ASSERT_TRUE(pm_f_bool[*f_it]);
{
OpenMesh::PropertyManager<
OpenMesh::VPropHandleT<bool>, Mesh> pm_v_bool(mesh_, "pm_v_bool");
pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), false);
for (int i = 0; i < 4; ++i)
ASSERT_FALSE(pm_v_bool[vhandle[i]]);
pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), true);
for (int i = 0; i < 4; ++i)
ASSERT_TRUE(pm_v_bool[vhandle[i]]);
OpenMesh::PropertyManager<
OpenMesh::EPropHandleT<bool>, Mesh> pm_e_bool(mesh_, "pm_e_bool");
pm_e_bool.set_range(mesh_.edges_begin(), mesh_.edges_end(), false);
for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
e_it != f_end; ++e_it)
ASSERT_FALSE(pm_e_bool[*e_it]);
pm_e_bool.set_range(mesh_.edges_begin(), mesh_.edges_end(), true);
for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
e_it != f_end; ++e_it)
ASSERT_TRUE(pm_e_bool[*e_it]);
OpenMesh::PropertyManager<
OpenMesh::FPropHandleT<bool>, Mesh> pm_f_bool(mesh_, "pm_f_bool");
pm_f_bool.set_range(mesh_.faces_begin(), mesh_.faces_end(), false);
for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
f_it != f_end; ++f_it)
ASSERT_FALSE(pm_f_bool[*f_it]);
pm_f_bool.set_range(mesh_.faces_begin(), mesh_.faces_end(), true);
for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
f_it != f_end; ++f_it)
ASSERT_TRUE(pm_f_bool[*f_it]);
}
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
/*
* Same thing again, this time with C++11 ranges.
*/
{
OpenMesh::PropertyManager<
OpenMesh::VPropHandleT<bool>, Mesh> pm_v_bool(mesh_, "pm_v_bool2");
pm_v_bool.set_range(mesh_.vertices(), false);
for (int i = 0; i < 4; ++i)
ASSERT_FALSE(pm_v_bool[vhandle[i]]);
pm_v_bool.set_range(mesh_.vertices(), true);
for (int i = 0; i < 4; ++i)
ASSERT_TRUE(pm_v_bool[vhandle[i]]);
OpenMesh::PropertyManager<
OpenMesh::EPropHandleT<bool>, Mesh> pm_e_bool(mesh_, "pm_e_bool2");
pm_e_bool.set_range(mesh_.edges(), false);
for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
e_it != f_end; ++e_it)
ASSERT_FALSE(pm_e_bool[*e_it]);
pm_e_bool.set_range(mesh_.edges(), true);
for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end();
e_it != f_end; ++e_it)
ASSERT_TRUE(pm_e_bool[*e_it]);
OpenMesh::PropertyManager<
OpenMesh::FPropHandleT<bool>, Mesh> pm_f_bool(mesh_, "pm_f_bool2");
pm_f_bool.set_range(mesh_.faces(), false);
for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
f_it != f_end; ++f_it)
ASSERT_FALSE(pm_f_bool[*f_it]);
pm_f_bool.set_range(mesh_.faces(), true);
for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end();
f_it != f_end; ++f_it)
ASSERT_TRUE(pm_f_bool[*f_it]);
}
#endif
}
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment