#include #include #include #include namespace { class OpenMeshVectorTest : public testing::Test { protected: // This function is called before each test is run virtual void SetUp() { // Do some initial stuff with the member data here... } // This function is called after all tests are through virtual void TearDown() { // Do some final stuff with the member data here... } }; /* * ==================================================================== * Define tests below * ==================================================================== */ /* Compute surface area via cross product */ TEST_F(OpenMeshVectorTest, ComputeTriangleSurfaceWithCrossProduct) { // // vec1 // x // | // | // | // x------>x vec2 // OpenMesh::Vec3d vec1(0.0,1.0,0.0); OpenMesh::Vec3d vec2(1.0,0.0,0.0); double area = 0.5 * cross(vec1,vec2).norm(); EXPECT_EQ(0.5f , area ) << "Wrong area in cross product function"; area = 0.5 * ( vec1 % vec2 ).norm(); EXPECT_EQ(0.5f , area ) << "Wrong area in cross product operator"; } /* Check OpenMesh Vector type abs function */ TEST_F(OpenMeshVectorTest, AbsTest) { OpenMesh::Vec3d vec1(0.5,0.5,-0.5); EXPECT_EQ( vec1.l8_norm() , 0.5f ) << "Wrong l8norm computation"; } /* Compute surface area via cross product */ TEST_F(OpenMeshVectorTest, VectorCasting) { OpenMesh::Vec3d vecd(1.0,2.0,3.0); OpenMesh::Vec3f vecf = OpenMesh::vector_cast(vecd); EXPECT_EQ(1.f, vecf[0]) << "vector type cast failed on component 0"; EXPECT_EQ(2.f, vecf[1]) << "vector type cast failed on component 1"; EXPECT_EQ(3.f, vecf[2]) << "vector type cast failed on component 2"; OpenMesh::Vec4d vecd4(40.0,30.0,20.0,10.0); vecd = OpenMesh::vector_cast(vecd4); EXPECT_EQ(40.0, vecd[0]) << "vector dimension cast failed on component 0"; EXPECT_EQ(30.0, vecd[1]) << "vector dimension cast failed on component 1"; EXPECT_EQ(20.0, vecd[2]) << "vector dimension cast failed on component 2"; } #if __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__) TEST_F(OpenMeshVectorTest, cpp11_constructors) { OpenMesh::Vec3d vec1 { 1.2, 2.0, 3.0 }; EXPECT_EQ(1.2, vec1[0]); EXPECT_EQ(2.0, vec1[1]); EXPECT_EQ(3.0, vec1[2]); OpenMesh::Vec4f vec2 { 1.2f, 3.5f, 1.0f, 0.0f }; EXPECT_EQ(1.2f, vec2[0]); EXPECT_EQ(3.5f, vec2[1]); EXPECT_EQ(1.0f, vec2[2]); EXPECT_EQ(0.0f, vec2[3]); OpenMesh::Vec4f vec2b { vec2 }; EXPECT_EQ(1.2f, vec2b[0]); EXPECT_EQ(3.5f, vec2b[1]); EXPECT_EQ(1.0f, vec2b[2]); EXPECT_EQ(0.0f, vec2b[3]); OpenMesh::Vec4d vec4d { 1.23 }; EXPECT_EQ(1.23, vec4d[0]); EXPECT_EQ(1.23, vec4d[1]); EXPECT_EQ(1.23, vec4d[2]); EXPECT_EQ(1.23, vec4d[3]); } TEST_F(OpenMeshVectorTest, cpp11_htmlColorLiteral) { static constexpr OpenMesh::Vec4f rose = 0xFFC7F1FF_htmlColor; EXPECT_EQ(0xFFC7F1FF_htmlColor, rose); const OpenMesh::Vec4f light_blue = 0x1FCFFFFF_htmlColor; EXPECT_LE((OpenMesh::Vec4f(0.1215686274f, 0.8117647058f, 1.0f, 1.0f) - light_blue).sqrnorm(), 1e-10); const auto light_blue_2 = 0x1FCFFFFF_htmlColor; // Check whether auto type deduction works as expected. static_assert(std::is_same ::value, "Bad type deduced from _htmlColor literal."); EXPECT_EQ(light_blue, light_blue_2); } namespace { class C { public: C() {} C(const C &rhs) { ADD_FAILURE() << "Copy constructor used."; } C(C &&rhs) { ++copy_con; } C &operator= (const C &rhs) { ADD_FAILURE() << "Copy assignemnt used."; return *this; } C &operator= (C &&rhs) { ++copy_ass; return *this; } static int copy_con; static int copy_ass; }; int C::copy_con = 0; int C::copy_ass = 0; } /** * Checks two things: * 1) Whether VectorT works with a non-arithmetic type. * 2) Whether move construction and assignment works. */ TEST_F(OpenMeshVectorTest, move_constructor_assignment) { C::copy_con = 0; C::copy_ass = 0; // Test move assigning. OpenMesh::VectorT x, y; x = std::move(y); EXPECT_EQ(3, C::copy_ass); EXPECT_EQ(0, C::copy_con); // Test move constructing. OpenMesh::VectorT z(std::move(x)); EXPECT_EQ(3, C::copy_ass); EXPECT_EQ(3, C::copy_con); } TEST_F(OpenMeshVectorTest, iterator_init) { std::list a; a.push_back(1.0); a.push_back(2.0); a.push_back(3.0); OpenMesh::Vec3f v(a.begin()); EXPECT_EQ(OpenMesh::Vec3f(1.0, 2.0, 3.0), v); } #endif // C++11 TEST_F(OpenMeshVectorTest, BasicLinearAlgebra) { OpenMesh::Vec3d v(1, 2, 3); EXPECT_EQ(v[0], 1.0); EXPECT_EQ(v[1], 2.0); EXPECT_EQ(v[2], 3.0); EXPECT_EQ(OpenMesh::Vec3d(-1, -2, -3), -v); EXPECT_EQ(3, OpenMesh::Vec3d(1, 3, 2).max()); EXPECT_EQ(3, OpenMesh::Vec3d(1, 2, 3).max()); EXPECT_EQ(3, OpenMesh::Vec3d(1, 3, -4).max()); EXPECT_EQ(3, OpenMesh::Vec3d(-4, 2, 3).max()); EXPECT_EQ(4, OpenMesh::Vec3d(1, 3, -4).max_abs()); EXPECT_EQ(4, OpenMesh::Vec3d(-4, 2, 3).max_abs()); EXPECT_EQ(1, OpenMesh::Vec3d(1, 3, 2).min()); EXPECT_EQ(1, OpenMesh::Vec3d(1, 2, 3).min()); EXPECT_EQ(-4, OpenMesh::Vec3d(1, 3, -4).min()); EXPECT_EQ(-4, OpenMesh::Vec3d(-4, 2, 3).min()); EXPECT_EQ(1, OpenMesh::Vec3d(1, 3, -4).min_abs()); EXPECT_EQ(2, OpenMesh::Vec3d(-4, 2, 3).min_abs()); EXPECT_NEAR(14, OpenMesh::Vec3d(1, 2, 3) | OpenMesh::Vec3d(1, 2, 3), 1e-6); EXPECT_NEAR(-14, OpenMesh::Vec3d(1, 2, 3) | OpenMesh::Vec3d(-1, -2, -3), 1e-6); EXPECT_NEAR(14, OpenMesh::Vec3d(-1, -2, -3) | OpenMesh::Vec3d(-1, -2, -3), 1e-6); } TEST_F(OpenMeshVectorTest, array_init) { float a[3]; a[0] = 1.0; a[1] = 2.0; a[2] = 3.0; OpenMesh::Vec3f v(a); EXPECT_EQ(OpenMesh::Vec3f(1.0, 2.0, 3.0), v); } TEST_F(OpenMeshVectorTest, normalized_cond) { OpenMesh::Vec3d v1(1, -2, 3), v2(0, 0, 0); EXPECT_EQ(OpenMesh::Vec3d(0, 0, 0), v2.normalize_cond()); const OpenMesh::Vec3d r1 = OpenMesh::Vec3d( 0.2672612419124244, -0.5345224838248488, 0.8017837257372732) - v1.normalize_cond(); EXPECT_NEAR(r1[0], 0.0, 1e-12); EXPECT_NEAR(r1[1], 0.0, 1e-12); EXPECT_NEAR(r1[2], 0.0, 1e-12); } TEST_F(OpenMeshVectorTest, size_dim) { OpenMesh::Vec3d v3d(1, 2, 3); OpenMesh::Vec3f v3f(1, 2, 3); OpenMesh::Vec2i v2i(1, 2); EXPECT_EQ(3u, v3d.size()); EXPECT_EQ(3, v3d.dim()); EXPECT_EQ(3u, v3f.size()); EXPECT_EQ(3, v3f.dim()); EXPECT_EQ(2u, v2i.size()); EXPECT_EQ(2, v2i.dim()); } }