2015-05-11 16:28:10 +00:00
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
#include <Unittests/unittests_common.hh>
|
|
|
|
|
#include <OpenMesh/Core/Utils/PropertyManager.hh>
|
|
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
class OpenMeshPropertyManager : public OpenMeshBase {
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
|
|
// This function is called before each test is run
|
|
|
|
|
virtual void SetUp() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This function is called after all tests are through
|
|
|
|
|
virtual void TearDown() {
|
|
|
|
|
|
|
|
|
|
// Do some final stuff with the member data here...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Member already defined in OpenMeshBase
|
|
|
|
|
//Mesh mesh_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ====================================================================
|
2016-04-14 13:34:23 +02:00
|
|
|
* General Tests
|
2015-05-11 16:28:10 +00:00
|
|
|
* ====================================================================
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Collapsing a tetrahedron
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(OpenMeshPropertyManager, set_range_bool) {
|
|
|
|
|
|
|
|
|
|
mesh_.clear();
|
|
|
|
|
|
|
|
|
|
// Add some vertices
|
|
|
|
|
Mesh::VertexHandle vhandle[4];
|
|
|
|
|
|
|
|
|
|
vhandle[0] = mesh_.add_vertex(Mesh::Point(0, 0, 0));
|
|
|
|
|
vhandle[1] = mesh_.add_vertex(Mesh::Point(0, 1, 0));
|
|
|
|
|
vhandle[2] = mesh_.add_vertex(Mesh::Point(1, 1, 0));
|
|
|
|
|
vhandle[3] = mesh_.add_vertex(Mesh::Point(0, 0, 1));
|
|
|
|
|
|
|
|
|
|
// Add two faces
|
|
|
|
|
std::vector<Mesh::VertexHandle> face_vhandles;
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[0]);
|
|
|
|
|
face_vhandles.push_back(vhandle[1]);
|
|
|
|
|
face_vhandles.push_back(vhandle[2]);
|
|
|
|
|
mesh_.add_face(face_vhandles);
|
|
|
|
|
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[0]);
|
|
|
|
|
face_vhandles.push_back(vhandle[2]);
|
|
|
|
|
face_vhandles.push_back(vhandle[3]);
|
|
|
|
|
mesh_.add_face(face_vhandles);
|
|
|
|
|
|
2016-09-12 16:57:33 +02:00
|
|
|
{
|
|
|
|
|
OpenMesh::PropertyManager<
|
2019-10-31 14:31:00 +01:00
|
|
|
OpenMesh::VPropHandleT<bool>> pm_v_bool(mesh_, "pm_v_bool");
|
2016-09-12 16:57:33 +02:00
|
|
|
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<
|
2019-10-31 14:31:00 +01:00
|
|
|
OpenMesh::EPropHandleT<bool>> pm_e_bool(mesh_, "pm_e_bool");
|
2016-09-12 16:57:33 +02:00
|
|
|
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<
|
2019-10-31 14:31:00 +01:00
|
|
|
OpenMesh::FPropHandleT<bool>> pm_f_bool(mesh_, "pm_f_bool");
|
2016-09-12 16:57:33 +02:00
|
|
|
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]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Same thing again, this time with C++11 ranges.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
OpenMesh::PropertyManager<
|
2019-10-31 14:31:00 +01:00
|
|
|
OpenMesh::VPropHandleT<bool>> pm_v_bool(mesh_, "pm_v_bool2");
|
2016-09-12 16:57:33 +02:00
|
|
|
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<
|
2019-10-31 14:31:00 +01:00
|
|
|
OpenMesh::EPropHandleT<bool>> pm_e_bool(mesh_, "pm_e_bool2");
|
2016-09-12 16:57:33 +02:00
|
|
|
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<
|
2019-10-31 14:31:00 +01:00
|
|
|
OpenMesh::FPropHandleT<bool>> pm_f_bool(mesh_, "pm_f_bool2");
|
2016-09-12 16:57:33 +02:00
|
|
|
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]);
|
|
|
|
|
}
|
2015-05-11 16:28:10 +00:00
|
|
|
}
|
|
|
|
|
|
2016-04-14 13:34:23 +02:00
|
|
|
/*
|
|
|
|
|
* ====================================================================
|
2018-11-30 20:14:17 +01:00
|
|
|
* Factory Functions
|
2016-04-14 13:34:23 +02:00
|
|
|
* ====================================================================
|
|
|
|
|
*/
|
2015-05-11 16:28:10 +00:00
|
|
|
|
2016-04-14 13:34:23 +02:00
|
|
|
/*
|
|
|
|
|
* Temporary property
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(OpenMeshPropertyManager, cpp11_temp_property) {
|
|
|
|
|
using handle_type = OpenMesh::VPropHandleT<int>;
|
|
|
|
|
const auto prop_name = "pm_v_test_property";
|
2019-10-31 14:31:55 +01:00
|
|
|
ASSERT_FALSE((OpenMesh::hasProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name)));
|
2016-04-14 13:34:23 +02:00
|
|
|
|
|
|
|
|
{
|
2018-11-30 20:14:17 +01:00
|
|
|
auto vprop = OpenMesh::makeTemporaryProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name);
|
2016-04-14 13:34:23 +02:00
|
|
|
static_cast<void>(vprop); // Unused variable
|
2019-10-31 14:31:55 +01:00
|
|
|
ASSERT_TRUE((OpenMesh::hasProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name)));
|
2016-04-14 13:34:23 +02:00
|
|
|
}
|
|
|
|
|
|
2019-10-31 14:31:55 +01:00
|
|
|
ASSERT_FALSE((OpenMesh::hasProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name)));
|
2016-04-14 13:34:23 +02:00
|
|
|
}
|
2015-05-11 16:28:10 +00:00
|
|
|
|
2016-04-14 13:34:23 +02:00
|
|
|
/*
|
|
|
|
|
* Two temporary properties on a mesh using the same name and type. The second
|
|
|
|
|
* (inner) one shadows the first (outer) one instead of aliasing.
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(OpenMeshPropertyManager, cpp11_temp_property_shadowing) {
|
|
|
|
|
auto vh = mesh_.add_vertex({0,0,0}); // Dummy vertex to attach properties to
|
|
|
|
|
|
|
|
|
|
const auto prop_name = "pm_v_test_property";
|
|
|
|
|
|
2018-11-30 20:14:17 +01:00
|
|
|
auto outer_prop = OpenMesh::makeTemporaryProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name);
|
2016-04-14 13:34:23 +02:00
|
|
|
outer_prop[vh] = 100;
|
|
|
|
|
ASSERT_EQ(100, outer_prop[vh]);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
// inner_prop uses same type and name as outer_prop
|
2018-11-30 20:14:17 +01:00
|
|
|
auto inner_prop = OpenMesh::makeTemporaryProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name);
|
2016-04-14 13:34:23 +02:00
|
|
|
inner_prop[vh] = 200;
|
|
|
|
|
ASSERT_EQ(200, inner_prop[vh]);
|
|
|
|
|
// End of scope: inner_prop is removed from mesh_
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ensure outer_prop still exists and its data has not been overwritten by inner_prop
|
2019-10-31 14:31:55 +01:00
|
|
|
ASSERT_TRUE((OpenMesh::hasProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name)));
|
2016-04-14 13:34:23 +02:00
|
|
|
ASSERT_EQ(100, outer_prop[vh]);
|
|
|
|
|
}
|
2015-05-11 16:28:10 +00:00
|
|
|
|
2016-04-14 13:34:23 +02:00
|
|
|
/*
|
|
|
|
|
* In sequence:
|
|
|
|
|
* - add a persistent property to a mesh
|
|
|
|
|
* - retrieve an existing property of a mesh and modify it
|
|
|
|
|
* - obtain a non-owning property handle
|
|
|
|
|
* - attempt to obtain a non-owning handle to a non-existing property (throws)
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(OpenMeshPropertyManager, cpp11_persistent_and_non_owning_properties) {
|
|
|
|
|
auto vh = mesh_.add_vertex({0,0,0}); // Dummy vertex to attach properties to
|
|
|
|
|
|
|
|
|
|
const auto prop_name = "pm_v_test_property";
|
|
|
|
|
|
2019-10-31 14:31:55 +01:00
|
|
|
ASSERT_FALSE((OpenMesh::hasProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name)));
|
2016-04-14 13:34:23 +02:00
|
|
|
|
|
|
|
|
{
|
2018-11-30 20:14:17 +01:00
|
|
|
auto prop = OpenMesh::getOrMakeProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name);
|
2016-04-14 13:34:23 +02:00
|
|
|
prop[vh] = 100;
|
|
|
|
|
// End of scope, property persists
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-31 14:31:55 +01:00
|
|
|
ASSERT_TRUE((OpenMesh::hasProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name)));
|
2016-04-14 13:34:23 +02:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
// Since a property of the same name and type already exists, this refers to the existing property.
|
2018-11-30 20:14:17 +01:00
|
|
|
auto prop = OpenMesh::getOrMakeProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name);
|
2016-04-14 13:34:23 +02:00
|
|
|
ASSERT_EQ(100, prop[vh]);
|
|
|
|
|
prop[vh] = 200;
|
|
|
|
|
// End of scope, property persists
|
|
|
|
|
}
|
2015-05-11 16:28:10 +00:00
|
|
|
|
2019-10-31 14:31:55 +01:00
|
|
|
ASSERT_TRUE((OpenMesh::hasProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name)));
|
2016-04-14 13:34:23 +02:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
// Acquire non-owning handle to the property, knowing it exists
|
2018-11-30 20:14:17 +01:00
|
|
|
auto prop = OpenMesh::getProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name);
|
2016-04-14 13:34:23 +02:00
|
|
|
ASSERT_EQ(200, prop[vh]);
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-31 14:31:55 +01:00
|
|
|
ASSERT_TRUE((OpenMesh::hasProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name)));
|
2016-04-14 13:34:23 +02:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
// Attempt to acquire non-owning handle for a non-existing property
|
2018-11-30 20:14:17 +01:00
|
|
|
auto code_that_throws = [&](){
|
|
|
|
|
OpenMesh::getProperty<OpenMesh::VertexHandle, int>(mesh_, "wrong_prop_name");
|
|
|
|
|
};
|
|
|
|
|
ASSERT_THROW(code_that_throws(), std::runtime_error);
|
2016-04-14 13:34:23 +02:00
|
|
|
}
|
|
|
|
|
|
2019-10-31 14:31:55 +01:00
|
|
|
ASSERT_TRUE((OpenMesh::hasProperty<OpenMesh::VertexHandle, int>(mesh_, prop_name)));
|
2016-04-14 13:34:23 +02:00
|
|
|
}
|
2015-05-11 16:28:10 +00:00
|
|
|
|
|
|
|
|
}
|