Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
unittests_vector_type.cc
1 #include <gtest/gtest.h>
2 #include <Unittests/unittests_common.hh>
3 #include <iostream>
4 #include <list>
5 
6 namespace {
7 
8 class OpenMeshVectorTest : public testing::Test {
9 
10  protected:
11 
12  // This function is called before each test is run
13  virtual void SetUp() {
14 
15  // Do some initial stuff with the member data here...
16  }
17 
18  // This function is called after all tests are through
19  virtual void TearDown() {
20 
21  // Do some final stuff with the member data here...
22  }
23 
24 };
25 
26 
27 
28 /*
29  * ====================================================================
30  * Define tests below
31  * ====================================================================
32  */
33 
34 /* Compute surface area via cross product
35  */
36 TEST_F(OpenMeshVectorTest, ComputeTriangleSurfaceWithCrossProduct) {
37 
38 
39  //
40  // vec1
41  // x
42  // |
43  // |
44  // |
45  // x------>x vec2
46  //
47 
48  OpenMesh::Vec3d vec1(0.0,1.0,0.0);
49  OpenMesh::Vec3d vec2(1.0,0.0,0.0);
50 
51  double area = 0.5 * cross(vec1,vec2).norm();
52  EXPECT_EQ(0.5f , area ) << "Wrong area in cross product function";
53 
54  area = 0.5 * ( vec1 % vec2 ).norm();
55  EXPECT_EQ(0.5f , area ) << "Wrong area in cross product operator";
56 
57 }
58 
59 /* Check OpenMesh Vector type abs function
60  */
61 TEST_F(OpenMeshVectorTest, AbsTest) {
62 
63  OpenMesh::Vec3d vec1(0.5,0.5,-0.5);
64 
65  EXPECT_EQ( vec1.l8_norm() , 0.5f ) << "Wrong l8norm computation";
66 
67 }
68 
69 /* Compute surface area via cross product
70  */
71 TEST_F(OpenMeshVectorTest, VectorCasting) {
72 
73  OpenMesh::Vec3d vecd(1.0,2.0,3.0);
75  EXPECT_EQ(1.f, vecf[0]) << "vector type cast failed on component 0";
76  EXPECT_EQ(2.f, vecf[1]) << "vector type cast failed on component 1";
77  EXPECT_EQ(3.f, vecf[2]) << "vector type cast failed on component 2";
78 
79  OpenMesh::Vec4d vecd4(40.0,30.0,20.0,10.0);
81  EXPECT_EQ(40.0, vecd[0]) << "vector dimension cast failed on component 0";
82  EXPECT_EQ(30.0, vecd[1]) << "vector dimension cast failed on component 1";
83  EXPECT_EQ(20.0, vecd[2]) << "vector dimension cast failed on component 2";
84 
85 }
86 
87 #if _MSC_VER >= 1900 || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__)
88 TEST_F(OpenMeshVectorTest, cpp11_constructors) {
89  OpenMesh::Vec3d vec1 { 1.2, 2.0, 3.0 };
90 
91  EXPECT_EQ(1.2, vec1[0]);
92  EXPECT_EQ(2.0, vec1[1]);
93  EXPECT_EQ(3.0, vec1[2]);
94 
95  OpenMesh::Vec4f vec2 { 1.2f, 3.5f, 1.0f, 0.0f };
96 
97  EXPECT_EQ(1.2f, vec2[0]);
98  EXPECT_EQ(3.5f, vec2[1]);
99  EXPECT_EQ(1.0f, vec2[2]);
100  EXPECT_EQ(0.0f, vec2[3]);
101 
102  OpenMesh::Vec4f vec2b { vec2 };
103 
104  EXPECT_EQ(1.2f, vec2b[0]);
105  EXPECT_EQ(3.5f, vec2b[1]);
106  EXPECT_EQ(1.0f, vec2b[2]);
107  EXPECT_EQ(0.0f, vec2b[3]);
108 
109  OpenMesh::Vec4d vec4d { 1.23 };
110  EXPECT_EQ(1.23, vec4d[0]);
111  EXPECT_EQ(1.23, vec4d[1]);
112  EXPECT_EQ(1.23, vec4d[2]);
113  EXPECT_EQ(1.23, vec4d[3]);
114 }
115 
116 TEST_F(OpenMeshVectorTest, cpp11_htmlColorLiteral) {
117  static constexpr OpenMesh::Vec4f rose = 0xFFC7F1FF_htmlColor;
118 
119  EXPECT_EQ(0xFFC7F1FF_htmlColor, rose);
120 
121  const OpenMesh::Vec4f light_blue = 0x1FCFFFFF_htmlColor;
122  EXPECT_LE((OpenMesh::Vec4f(0.1215686274f, 0.8117647058f, 1.0f, 1.0f)
123  - light_blue).sqrnorm(), 1e-10);
124 
125  const auto light_blue_2 = 0x1FCFFFFF_htmlColor;
126  // Check whether auto type deduction works as expected.
127  static_assert(std::is_same<decltype(light_blue_2), decltype(light_blue)>
128  ::value, "Bad type deduced from _htmlColor literal.");
129  EXPECT_EQ(light_blue, light_blue_2);
130 }
131 
132 
133 namespace {
134 class C {
135  public:
136  C() {}
137  C(const C &rhs) { ADD_FAILURE() << "Copy constructor used."; }
138  C(C &&rhs) { ++copy_con; }
139  C &operator= (const C &rhs) {
140  ADD_FAILURE() << "Copy assignemnt used.";
141  return *this;
142  }
143  C &operator= (C &&rhs) { ++copy_ass; return *this; }
144 
145  static int copy_con;
146  static int copy_ass;
147 };
148 
149 int C::copy_con = 0;
150 int C::copy_ass = 0;
151 }
152 
158 TEST_F(OpenMeshVectorTest, move_constructor_assignment) {
159 
160  C::copy_con = 0;
161  C::copy_ass = 0;
162 
163  // Test move assigning.
165  x = std::move(y);
166  EXPECT_EQ(3, C::copy_ass);
167  EXPECT_EQ(0, C::copy_con);
168 
169  // Test move constructing.
170  OpenMesh::VectorT<C, 3> z(std::move(x));
171  EXPECT_EQ(3, C::copy_ass);
172  EXPECT_EQ(3, C::copy_con);
173 }
174 
175 TEST_F(OpenMeshVectorTest, iterator_init) {
176  std::list<float> a;
177  a.push_back(1.0);
178  a.push_back(2.0);
179  a.push_back(3.0);
180  OpenMesh::Vec3f v(a.begin());
181  EXPECT_EQ(OpenMesh::Vec3f(1.0, 2.0, 3.0), v);
182 }
183 
184 #endif // C++11
185 
186 
187 TEST_F(OpenMeshVectorTest, BasicArithmeticInPlace) {
188  OpenMesh::Vec3d v1(1, 2, 3);
189  double s1 = 2;
190  const double epsilon = 1e-6;
191 
192  OpenMesh::Vec3d v2add (3, 4, 6); v2add += v1;
193  OpenMesh::Vec3d v2sub (3, 4, 6); v2sub -= v1;
194  OpenMesh::Vec3d v2cmul(3, 4, 6); v2cmul *= v1;
195  OpenMesh::Vec3d v2cdiv(3, 4, 6); v2cdiv /= v1;
196  OpenMesh::Vec3d v2smul(3, 4, 6); v2smul *= s1;
197  OpenMesh::Vec3d v2sdiv(3, 4, 6); v2sdiv /= s1;
198 
199  EXPECT_NEAR(4, v2add[0], epsilon);
200  EXPECT_NEAR(6, v2add[1], epsilon);
201  EXPECT_NEAR(9, v2add[2], epsilon);
202 
203  EXPECT_NEAR(2, v2sub[0], epsilon);
204  EXPECT_NEAR(2, v2sub[1], epsilon);
205  EXPECT_NEAR(3, v2sub[2], epsilon);
206 
207  EXPECT_NEAR( 3, v2cmul[0], epsilon);
208  EXPECT_NEAR( 8, v2cmul[1], epsilon);
209  EXPECT_NEAR(18, v2cmul[2], epsilon);
210 
211  EXPECT_NEAR(3, v2cdiv[0], epsilon);
212  EXPECT_NEAR(2, v2cdiv[1], epsilon);
213  EXPECT_NEAR(2, v2cdiv[2], epsilon);
214 
215  EXPECT_NEAR( 6, v2smul[0], epsilon);
216  EXPECT_NEAR( 8, v2smul[1], epsilon);
217  EXPECT_NEAR(12, v2smul[2], epsilon);
218 
219  EXPECT_NEAR(1.5, v2sdiv[0], epsilon);
220  EXPECT_NEAR(2.0, v2sdiv[1], epsilon);
221  EXPECT_NEAR(3.0, v2sdiv[2], epsilon);
222 }
223 
224 TEST_F(OpenMeshVectorTest, BasicArithmeticImmutable) {
225  OpenMesh::Vec3d v1(1, 2, 3);
226  const double epsilon = 1e-6;
227 
228  OpenMesh::Vec3d v2add = v1 + OpenMesh::Vec3d(2, 4, 6);
229  OpenMesh::Vec3d v2sub = v1 - OpenMesh::Vec3d(2, 4, 6);
230  OpenMesh::Vec3d v2cmul = v1 * OpenMesh::Vec3d(2, 4, 6);
231  OpenMesh::Vec3d v2cdiv = v1 / OpenMesh::Vec3d(2, 4, 6);
232  OpenMesh::Vec3d v2smul = v1 * 2.0;
233  OpenMesh::Vec3d v2sdiv = v1 / 2.0;
234  OpenMesh::Vec3d v2neg = -v1;
235 
236  EXPECT_NEAR(3, v2add[0], epsilon);
237  EXPECT_NEAR(6, v2add[1], epsilon);
238  EXPECT_NEAR(9, v2add[2], epsilon);
239 
240  EXPECT_NEAR(-1, v2sub[0], epsilon);
241  EXPECT_NEAR(-2, v2sub[1], epsilon);
242  EXPECT_NEAR(-3, v2sub[2], epsilon);
243 
244  EXPECT_NEAR( 2, v2cmul[0], epsilon);
245  EXPECT_NEAR( 8, v2cmul[1], epsilon);
246  EXPECT_NEAR(18, v2cmul[2], epsilon);
247 
248  EXPECT_NEAR(0.5, v2cdiv[0], epsilon);
249  EXPECT_NEAR(0.5, v2cdiv[1], epsilon);
250  EXPECT_NEAR(0.5, v2cdiv[2], epsilon);
251 
252  EXPECT_NEAR(2, v2smul[0], epsilon);
253  EXPECT_NEAR(4, v2smul[1], epsilon);
254  EXPECT_NEAR(6, v2smul[2], epsilon);
255 
256  EXPECT_NEAR(0.5, v2sdiv[0], epsilon);
257  EXPECT_NEAR(1.0, v2sdiv[1], epsilon);
258  EXPECT_NEAR(1.5, v2sdiv[2], epsilon);
259 
260  EXPECT_NEAR(-1, v2neg[0], epsilon);
261  EXPECT_NEAR(-2, v2neg[1], epsilon);
262  EXPECT_NEAR(-3, v2neg[2], epsilon);
263 }
264 
265 TEST_F(OpenMeshVectorTest, BasicLinearAlgebra) {
266  OpenMesh::Vec3d v(1, 2, 3);
267  EXPECT_EQ(v[0], 1.0);
268  EXPECT_EQ(v[1], 2.0);
269  EXPECT_EQ(v[2], 3.0);
270 
271  EXPECT_EQ(OpenMesh::Vec3d(-1, -2, -3), -v);
272  EXPECT_EQ(3, OpenMesh::Vec3d(1, 3, 2).max());
273  EXPECT_EQ(3, OpenMesh::Vec3d(1, 2, 3).max());
274  EXPECT_EQ(3, OpenMesh::Vec3d(1, 3, -4).max());
275  EXPECT_EQ(3, OpenMesh::Vec3d(-4, 2, 3).max());
276  EXPECT_EQ(4, OpenMesh::Vec3d(1, 3, -4).max_abs());
277  EXPECT_EQ(4, OpenMesh::Vec3d(-4, 2, 3).max_abs());
278 
279  EXPECT_EQ(1, OpenMesh::Vec3d(1, 3, 2).min());
280  EXPECT_EQ(1, OpenMesh::Vec3d(1, 2, 3).min());
281  EXPECT_EQ(-4, OpenMesh::Vec3d(1, 3, -4).min());
282  EXPECT_EQ(-4, OpenMesh::Vec3d(-4, 2, 3).min());
283  EXPECT_EQ(1, OpenMesh::Vec3d(1, 3, -4).min_abs());
284  EXPECT_EQ(2, OpenMesh::Vec3d(-4, 2, 3).min_abs());
285 
286  EXPECT_NEAR(14, OpenMesh::Vec3d(1, 2, 3) | OpenMesh::Vec3d(1, 2, 3), 1e-6);
287  EXPECT_NEAR(-14, OpenMesh::Vec3d(1, 2, 3) | OpenMesh::Vec3d(-1, -2, -3), 1e-6);
288  EXPECT_NEAR(14, OpenMesh::Vec3d(-1, -2, -3) | OpenMesh::Vec3d(-1, -2, -3), 1e-6);
289 }
290 
291 TEST_F(OpenMeshVectorTest, array_init) {
292  float a[3]; a[0] = 1.0; a[1] = 2.0; a[2] = 3.0;
293  OpenMesh::Vec3f v(a);
294  EXPECT_EQ(OpenMesh::Vec3f(1.0, 2.0, 3.0), v);
295 
296  // This should not invoke the array constructor.
297  OpenMesh::Vec3d v2(3.0f);
298 }
299 
300 TEST_F(OpenMeshVectorTest, normalized_cond) {
301  OpenMesh::Vec3d v1(1, -2, 3), v2(0, 0, 0);
302  EXPECT_EQ(OpenMesh::Vec3d(0, 0, 0), v2.normalize_cond());
303  const OpenMesh::Vec3d r1 =
305  0.2672612419124244,
306  -0.5345224838248488,
307  0.8017837257372732) - v1.normalize_cond();
308  EXPECT_NEAR(r1[0], 0.0, 1e-12);
309  EXPECT_NEAR(r1[1], 0.0, 1e-12);
310  EXPECT_NEAR(r1[2], 0.0, 1e-12);
311 }
312 
313 TEST_F(OpenMeshVectorTest, size_dim) {
314  OpenMesh::Vec3d v3d(1, 2, 3);
315  OpenMesh::Vec3f v3f(1, 2, 3);
316  OpenMesh::Vec2i v2i(1, 2);
317 
318  EXPECT_EQ(3u, v3d.size());
319  EXPECT_EQ(3, v3d.dim());
320  EXPECT_EQ(3u, v3f.size());
321  EXPECT_EQ(3, v3f.dim());
322  EXPECT_EQ(2u, v2i.size());
323  EXPECT_EQ(2, v2i.dim());
324 }
325 
326 }
VectorT< double, 3 > Vec3d
Definition: Vector11T.hh:771
void vector_cast(const src_t &_src, dst_t &_dst, GenProg::Int2Type< n >)
Cast vector type to another vector type by copying the vector elements.
Definition: vector_cast.hh:86
VectorT< Scalar, N > cross(const VectorT< Scalar, N > &_v1, const VectorT< Scalar, N > &_v2)
Definition: MeshNode2T.cc:272