allow adding temporary properties on const meshes

This commit is contained in:
Max Lyon
2019-11-05 15:30:05 +01:00
parent ab353c8dd0
commit c4e7125c97
2 changed files with 173 additions and 66 deletions

View File

@@ -4,6 +4,13 @@
#include <iostream>
//#define ENABLE_PROPERTY_TIMING_OUTPUT
#ifdef ENABLE_PROPERTY_TIMING_OUTPUT
#define TIMING_OUTPUT(X) X
#else
#define TIMING_OUTPUT(X)
#endif
namespace {
class OpenMeshPropertyManager : public OpenMeshBase {
@@ -228,7 +235,7 @@ TEST_F(OpenMeshPropertyManager, property_move_construction) {
auto t_start = std::chrono::high_resolution_clock::now();
auto prop2 = std::move(prop1);
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "move constructing property from temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "move constructing property from temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_FALSE(prop1.isValid()) << "prop1 should have been invalidated";
@@ -244,7 +251,7 @@ TEST_F(OpenMeshPropertyManager, property_move_construction) {
auto t_start = std::chrono::high_resolution_clock::now();
auto prop2 = std::move(prop1); // prop1 and prop2 should refere to the same property
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "move constructing from named took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "move constructing from named took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_TRUE(prop1.isValid()) << "named properties cannot be invalidated";
@@ -279,7 +286,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = prop1;
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "copying property temporary to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "copying property temporary to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed";
@@ -303,7 +310,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = prop1;
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "copying property temporary to named took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "copying property temporary to named took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed";
@@ -328,7 +335,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = prop1;
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "copying property named to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "copying property named to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
prop1.set_range(mesh_.vertices(), 0);
@@ -351,7 +358,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = prop1;
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "copying property named to named with different name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "copying property named to named with different name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
prop1.set_range(mesh_.vertices(), 0);
@@ -372,7 +379,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = prop1; // this should be a no op
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "copying property named to named with same name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "copying property named to named with same name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly";
EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly";
@@ -417,7 +424,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_same_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = std::move(prop1); // this should be cheap
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "moving property temporary to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "moving property temporary to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving";
@@ -439,7 +446,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_same_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = std::move(prop1);
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "moving property temporary to named took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "moving property temporary to named took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving";
@@ -462,7 +469,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_same_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "moving property named to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "moving property named to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving";
@@ -487,7 +494,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_same_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "moving property named to named with different name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "moving property named to named with different name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving";
@@ -510,7 +517,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_same_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = std::move(prop1); // this should be a no op
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "moving property named to named with same name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "moving property named to named with same name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving";
@@ -553,7 +560,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = prop1;
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "copying property temporary to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "copying property temporary to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed";
@@ -578,7 +585,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = prop1;
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "copying property temporary to named took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "copying property temporary to named took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed";
@@ -603,7 +610,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = prop1;
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "copying property named to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "copying property named to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
prop1.set_range(mesh_.vertices(), 0);
@@ -626,7 +633,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = prop1;
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "copying property named to named with different name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "copying property named to named with different name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
prop1.set_range(mesh_.vertices(), 0);
@@ -646,7 +653,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = prop1; // this should be a no op
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "copying property named to named with same name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "copying property named to named with same name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly";
EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly";
@@ -687,7 +694,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = std::move(prop1); // this should be cheap
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "moving property temporary to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "moving property temporary to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving";
@@ -710,7 +717,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = std::move(prop1);
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "moving property temporary to named took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "moving property temporary to named took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving";
@@ -733,7 +740,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "moving property named to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "moving property named to temporary took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving";
@@ -758,7 +765,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "moving property named to named with different name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "moving property named to named with different name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving";
@@ -783,7 +790,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) {
auto t_start = std::chrono::high_resolution_clock::now();
prop2 = std::move(prop1); // should copy
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "moving property named to named with same name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;
TIMING_OUTPUT(std::cout << "moving property named to named with same name took " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving";
@@ -803,5 +810,63 @@ TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) {
}
TEST_F(OpenMeshPropertyManager, temporary_property_on_const_mesh) {
const auto& const_ref = mesh_;
auto cog = OpenMesh::FProp<Mesh::Point>(const_ref);
auto points = OpenMesh::getPointsProperty(const_ref);
for (auto fh : const_ref.faces())
cog(fh) = fh.vertices().avg(points);
auto cog_copy = cog;
for (auto fh : const_ref.faces())
{
EXPECT_NE(&cog(fh), &cog_copy(fh)) << "Both properties point to the same memory";
EXPECT_EQ(cog(fh), cog_copy(fh)) << "Property not copied correctly";
}
auto description = OpenMesh::MProp<std::string>(const_ref);
description() = "Cool Const Mesh";
std::cout << description(OpenMesh::MeshHandle(33)) << std::endl;
}
OpenMesh::VProp<int> get_id_prop(const OpenMesh::PolyConnectivity& mesh)
{
auto t_start = std::chrono::high_resolution_clock::now();
auto id_prop = OpenMesh::VProp<int>(mesh);
for (auto vh : mesh.vertices())
id_prop(vh) = vh.idx();
auto t_end = std::chrono::high_resolution_clock::now();
TIMING_OUTPUT(std::cout << "Time spend in function: " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
return id_prop;
}
TEST_F(OpenMeshPropertyManager, return_property_from_function) {
for (int i = 0; i < 1000000; ++i)
mesh_.add_vertex(Mesh::Point());
auto t_start = std::chrono::high_resolution_clock::now();
auto id_p = get_id_prop(mesh_);
auto t_end = std::chrono::high_resolution_clock::now();
TIMING_OUTPUT(std::cout << "Time spend around function " << std::chrono::duration_cast<std::chrono::milliseconds>(t_end-t_start).count() << "ms" << std::endl;)
for (auto vh : mesh_.vertices())
{
EXPECT_EQ(id_p(vh), vh.idx()) << "Property not returned correctly" << std::endl;
}
}
}