1 //=============================================================================
2 //
3 // Copyright (c) Kitware, Inc.
4 // All rights reserved.
5 // See LICENSE.txt for details.
6 //
7 // This software is distributed WITHOUT ANY WARRANTY; without even
8 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
9 // PURPOSE. See the above copyright notice for more information.
10 //
11 // Copyright 2016 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
12 // Copyright 2016 UT-Battelle, LLC.
13 // Copyright 2016 Los Alamos National Security.
14 //
15 // Under the terms of Contract DE-NA0003525 with NTESS,
16 // the U.S. Government retains certain rights in this software.
17 // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
18 // Laboratory (LANL), the U.S. Government retains certain rights in
19 // this software.
20 //
21 //=============================================================================
22
23 #include <vtkm/Transform3D.h>
24
25 #include <vtkm/testing/Testing.h>
26
27 #include <ctime>
28 #include <random>
29
30 namespace
31 {
32
33 std::mt19937 g_RandomGenerator;
34
35 template <typename T>
36 struct TransformTests
37 {
38 std::uniform_real_distribution<T> RandomDistribution;
TransformTests__anon27c7b8210111::TransformTests39 TransformTests()
40 : RandomDistribution(0.0f, 1.0f)
41 {
42 }
43
RandomNum__anon27c7b8210111::TransformTests44 T RandomNum() { return this->RandomDistribution(g_RandomGenerator); }
45
46 using Vec = vtkm::Vec<T, 3>;
47 using Transform = vtkm::Matrix<T, 4, 4>;
48
RandomVector__anon27c7b8210111::TransformTests49 Vec RandomVector()
50 {
51 Vec vec(this->RandomNum(), this->RandomNum(), this->RandomNum());
52 return T(2) * vec - Vec(1);
53 }
54
CheckTranslate__anon27c7b8210111::TransformTests55 void CheckTranslate()
56 {
57 std::cout << "--- Checking translate" << std::endl;
58
59 Vec startPoint = this->RandomVector();
60 std::cout << " Starting point: " << startPoint << std::endl;
61
62 Vec translateAmount = this->RandomVector();
63 std::cout << " Translation amount: " << translateAmount << std::endl;
64
65 Transform translate = vtkm::Transform3DTranslate(translateAmount);
66
67 Vec translated1 = vtkm::Transform3DPoint(translate, startPoint);
68 std::cout << " First translation: " << translated1 << std::endl;
69 VTKM_TEST_ASSERT(test_equal(translated1, startPoint + translateAmount), "Bad translation.");
70
71 Vec translated2 = vtkm::Transform3DPoint(translate, translated1);
72 std::cout << " Second translation: " << translated2 << std::endl;
73 VTKM_TEST_ASSERT(test_equal(translated2, startPoint + T(2) * translateAmount),
74 "Bad translation.");
75
76 // Vectors should be invariant to translation.
77 translated1 = vtkm::Transform3DVector(translate, startPoint);
78 std::cout << " Translated vector: " << translated1 << std::endl;
79 VTKM_TEST_ASSERT(test_equal(translated1, startPoint), "Bad translation.");
80 }
81
CheckScale__anon27c7b8210111::TransformTests82 void CheckScale()
83 {
84 std::cout << "--- Checking scale" << std::endl;
85
86 Vec startPoint = this->RandomVector();
87 std::cout << " Starting point: " << startPoint << std::endl;
88
89 Vec scaleAmount = this->RandomVector();
90 std::cout << " Scale amount: " << scaleAmount << std::endl;
91
92 Transform scale = vtkm::Transform3DScale(scaleAmount);
93
94 Vec scaled1 = vtkm::Transform3DPoint(scale, startPoint);
95 std::cout << " First scale: " << scaled1 << std::endl;
96 VTKM_TEST_ASSERT(test_equal(scaled1, startPoint * scaleAmount), "Bad scale.");
97
98 Vec scaled2 = vtkm::Transform3DPoint(scale, scaled1);
99 std::cout << " Second scale: " << scaled2 << std::endl;
100 VTKM_TEST_ASSERT(test_equal(scaled2, startPoint * scaleAmount * scaleAmount), "Bad scale.");
101
102 // Vectors should scale the same as points.
103 scaled1 = vtkm::Transform3DVector(scale, startPoint);
104 std::cout << " Scaled vector: " << scaled1 << std::endl;
105 VTKM_TEST_ASSERT(test_equal(scaled1, startPoint * scaleAmount), "Bad scale.");
106 }
107
CheckRotate__anon27c7b8210111::TransformTests108 void CheckRotate()
109 {
110 std::cout << "--- Checking rotate" << std::endl;
111
112 Vec startPoint = this->RandomVector();
113 std::cout << " Starting point: " << startPoint << std::endl;
114
115 const T ninetyDegrees = T(90);
116
117 std::cout << "--Rotate 90 degrees around X" << std::endl;
118 Transform rotateX = vtkm::Transform3DRotateX(ninetyDegrees);
119
120 Vec rotated1 = vtkm::Transform3DPoint(rotateX, startPoint);
121 std::cout << " First rotate: " << rotated1 << std::endl;
122 VTKM_TEST_ASSERT(test_equal(rotated1, Vec(startPoint[0], -startPoint[2], startPoint[1])),
123 "Bad rotate.");
124
125 Vec rotated2 = vtkm::Transform3DPoint(rotateX, rotated1);
126 std::cout << " Second rotate: " << rotated2 << std::endl;
127 VTKM_TEST_ASSERT(test_equal(rotated2, Vec(startPoint[0], -startPoint[1], -startPoint[2])),
128 "Bad rotate.");
129
130 // Vectors should rotate the same as points.
131 rotated1 = vtkm::Transform3DVector(rotateX, startPoint);
132 std::cout << " Vector rotate: " << rotated1 << std::endl;
133 VTKM_TEST_ASSERT(test_equal(rotated1, Vec(startPoint[0], -startPoint[2], startPoint[1])),
134 "Bad rotate.");
135
136 std::cout << "--Rotate 90 degrees around Y" << std::endl;
137 Transform rotateY = vtkm::Transform3DRotateY(ninetyDegrees);
138
139 rotated1 = vtkm::Transform3DPoint(rotateY, startPoint);
140 std::cout << " First rotate: " << rotated1 << std::endl;
141 VTKM_TEST_ASSERT(test_equal(rotated1, Vec(startPoint[2], startPoint[1], -startPoint[0])),
142 "Bad rotate.");
143
144 rotated2 = vtkm::Transform3DPoint(rotateY, rotated1);
145 std::cout << " Second rotate: " << rotated2 << std::endl;
146 VTKM_TEST_ASSERT(test_equal(rotated2, Vec(-startPoint[0], startPoint[1], -startPoint[2])),
147 "Bad rotate.");
148
149 // Vectors should rotate the same as points.
150 rotated1 = vtkm::Transform3DVector(rotateY, startPoint);
151 std::cout << " Vector rotate: " << rotated1 << std::endl;
152 VTKM_TEST_ASSERT(test_equal(rotated1, Vec(startPoint[2], startPoint[1], -startPoint[0])),
153 "Bad rotate.");
154
155 std::cout << "--Rotate 90 degrees around Z" << std::endl;
156 Transform rotateZ = vtkm::Transform3DRotateZ(ninetyDegrees);
157
158 rotated1 = vtkm::Transform3DPoint(rotateZ, startPoint);
159 std::cout << " First rotate: " << rotated1 << std::endl;
160 VTKM_TEST_ASSERT(test_equal(rotated1, Vec(-startPoint[1], startPoint[0], startPoint[2])),
161 "Bad rotate.");
162
163 rotated2 = vtkm::Transform3DPoint(rotateZ, rotated1);
164 std::cout << " Second rotate: " << rotated2 << std::endl;
165 VTKM_TEST_ASSERT(test_equal(rotated2, Vec(-startPoint[0], -startPoint[1], startPoint[2])),
166 "Bad rotate.");
167
168 // Vectors should rotate the same as points.
169 rotated1 = vtkm::Transform3DVector(rotateZ, startPoint);
170 std::cout << " Vector rotate: " << rotated1 << std::endl;
171 VTKM_TEST_ASSERT(test_equal(rotated1, Vec(-startPoint[1], startPoint[0], startPoint[2])),
172 "Bad rotate.");
173 }
174
CheckPerspective__anon27c7b8210111::TransformTests175 void CheckPerspective()
176 {
177 std::cout << "--- Checking Perspective" << std::endl;
178
179 Vec startPoint = this->RandomVector();
180 std::cout << " Starting point: " << startPoint << std::endl;
181
182 Transform perspective(0);
183 perspective(0, 0) = 1;
184 perspective(1, 1) = 1;
185 perspective(2, 2) = 1;
186 perspective(3, 2) = 1;
187
188 Vec projected = vtkm::Transform3DPointPerspective(perspective, startPoint);
189 std::cout << " Projected: " << projected << std::endl;
190 VTKM_TEST_ASSERT(test_equal(projected, startPoint / startPoint[2]), "Bad perspective.");
191 }
192 };
193
194 struct TryTransformsFunctor
195 {
196 template <typename T>
operator ()__anon27c7b8210111::TryTransformsFunctor197 void operator()(T) const
198 {
199 TransformTests<T> tests;
200 tests.CheckTranslate();
201 tests.CheckScale();
202 tests.CheckRotate();
203 }
204 };
205
TestTransforms()206 void TestTransforms()
207 {
208 vtkm::UInt32 seed = static_cast<vtkm::UInt32>(std::time(nullptr));
209 std::cout << "Seed: " << seed << std::endl;
210 g_RandomGenerator.seed(seed);
211
212 vtkm::testing::Testing::TryTypes(TryTransformsFunctor(), vtkm::TypeListTagFieldScalar());
213 }
214
215 } // anonymous namespace
216
UnitTestTransform3D(int,char * [])217 int UnitTestTransform3D(int, char* [])
218 {
219 return vtkm::testing::Testing::Run(TestTransforms);
220 }
221