1 // Copyright 2018 The Draco Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 #include "draco/compression/attributes/point_d_vector.h"
16
17 #include "draco/compression/point_cloud/algorithms/point_cloud_types.h"
18 #include "draco/core/draco_test_base.h"
19
20 namespace draco {
21
22 class PointDVectorTest : public ::testing::Test {
23 protected:
24 template <typename PT>
TestIntegrity()25 void TestIntegrity() {}
26 template <typename PT>
TestSize()27 void TestSize() {
28 for (uint32_t n_items = 0; n_items <= 10; ++n_items) {
29 for (uint32_t dimensionality = 1; dimensionality <= 10;
30 ++dimensionality) {
31 draco::PointDVector<PT> var(n_items, dimensionality);
32 ASSERT_EQ(n_items, var.size());
33 ASSERT_EQ(n_items * dimensionality, var.GetBufferSize());
34 }
35 }
36 }
37 template <typename PT>
TestContentsContiguous()38 void TestContentsContiguous() {
39 for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
40 for (uint32_t dimensionality = 1; dimensionality < 10;
41 dimensionality += 2) {
42 for (uint32_t att_dimensionality = 1;
43 att_dimensionality <= dimensionality; att_dimensionality += 2) {
44 for (uint32_t offset_dimensionality = 0;
45 offset_dimensionality < dimensionality - att_dimensionality;
46 ++offset_dimensionality) {
47 PointDVector<PT> var(n_items, dimensionality);
48
49 std::vector<PT> att(n_items * att_dimensionality);
50 for (PT val = 0; val < n_items; val += 1) {
51 for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
52 att[val * att_dimensionality + att_dim] = val;
53 }
54 }
55 const PT *const attribute_data = att.data();
56
57 var.CopyAttribute(att_dimensionality, offset_dimensionality,
58 attribute_data);
59
60 for (PT val = 0; val < n_items; val += 1) {
61 for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
62 ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
63 }
64 }
65 }
66 }
67 }
68 }
69 }
70 template <typename PT>
TestContentsDiscrete()71 void TestContentsDiscrete() {
72 for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
73 for (uint32_t dimensionality = 1; dimensionality < 10;
74 dimensionality += 2) {
75 for (uint32_t att_dimensionality = 1;
76 att_dimensionality <= dimensionality; att_dimensionality += 2) {
77 for (uint32_t offset_dimensionality = 0;
78 offset_dimensionality < dimensionality - att_dimensionality;
79 ++offset_dimensionality) {
80 PointDVector<PT> var(n_items, dimensionality);
81
82 std::vector<PT> att(n_items * att_dimensionality);
83 for (PT val = 0; val < n_items; val += 1) {
84 for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
85 att[val * att_dimensionality + att_dim] = val;
86 }
87 }
88 const PT *const attribute_data = att.data();
89
90 for (PT item = 0; item < n_items; item += 1) {
91 var.CopyAttribute(att_dimensionality, offset_dimensionality, item,
92 attribute_data + item * att_dimensionality);
93 }
94
95 for (PT val = 0; val < n_items; val += 1) {
96 for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
97 ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
98 }
99 }
100 }
101 }
102 }
103 }
104 }
105
106 template <typename PT>
TestContentsCopy()107 void TestContentsCopy() {
108 for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
109 for (uint32_t dimensionality = 1; dimensionality < 10;
110 dimensionality += 2) {
111 for (uint32_t att_dimensionality = 1;
112 att_dimensionality <= dimensionality; att_dimensionality += 2) {
113 for (uint32_t offset_dimensionality = 0;
114 offset_dimensionality < dimensionality - att_dimensionality;
115 ++offset_dimensionality) {
116 PointDVector<PT> var(n_items, dimensionality);
117 PointDVector<PT> dest(n_items, dimensionality);
118
119 std::vector<PT> att(n_items * att_dimensionality);
120 for (PT val = 0; val < n_items; val += 1) {
121 for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
122 att[val * att_dimensionality + att_dim] = val;
123 }
124 }
125 const PT *const attribute_data = att.data();
126
127 var.CopyAttribute(att_dimensionality, offset_dimensionality,
128 attribute_data);
129
130 for (PT item = 0; item < n_items; item += 1) {
131 dest.CopyItem(var, item, item);
132 }
133
134 for (PT val = 0; val < n_items; val += 1) {
135 for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
136 ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
137 ASSERT_EQ(dest[val][offset_dimensionality + att_dim], val);
138 }
139 }
140 }
141 }
142 }
143 }
144 }
145 template <typename PT>
TestIterator()146 void TestIterator() {
147 for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
148 for (uint32_t dimensionality = 1; dimensionality < 10;
149 dimensionality += 2) {
150 for (uint32_t att_dimensionality = 1;
151 att_dimensionality <= dimensionality; att_dimensionality += 2) {
152 for (uint32_t offset_dimensionality = 0;
153 offset_dimensionality < dimensionality - att_dimensionality;
154 ++offset_dimensionality) {
155 PointDVector<PT> var(n_items, dimensionality);
156 PointDVector<PT> dest(n_items, dimensionality);
157
158 std::vector<PT> att(n_items * att_dimensionality);
159 for (PT val = 0; val < n_items; val += 1) {
160 for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
161 att[val * att_dimensionality + att_dim] = val;
162 }
163 }
164 const PT *const attribute_data = att.data();
165
166 var.CopyAttribute(att_dimensionality, offset_dimensionality,
167 attribute_data);
168
169 for (PT item = 0; item < n_items; item += 1) {
170 dest.CopyItem(var, item, item);
171 }
172
173 auto V0 = var.begin();
174 auto VE = var.end();
175 auto D0 = dest.begin();
176 auto DE = dest.end();
177
178 while (V0 != VE && D0 != DE) {
179 ASSERT_EQ(*D0, *V0); // compare PseudoPointD
180 // verify elemental values
181 for (auto index = 0; index < dimensionality; index += 1) {
182 ASSERT_EQ((*D0)[index], (*V0)[index]);
183 }
184 ++V0;
185 ++D0;
186 }
187
188 for (PT val = 0; val < n_items; val += 1) {
189 for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
190 ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
191 ASSERT_EQ(dest[val][offset_dimensionality + att_dim], val);
192 }
193 }
194 }
195 }
196 }
197 }
198 }
199 template <typename PT>
TestPoint3Iterator()200 void TestPoint3Iterator() {
201 for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
202 const uint32_t dimensionality = 3;
203 // for (uint32_t dimensionality = 1; dimensionality < 10;
204 // dimensionality += 2) {
205 const uint32_t att_dimensionality = 3;
206 // for (uint32_t att_dimensionality = 1;
207 // att_dimensionality <= dimensionality; att_dimensionality += 2) {
208 for (uint32_t offset_dimensionality = 0;
209 offset_dimensionality < dimensionality - att_dimensionality;
210 ++offset_dimensionality) {
211 PointDVector<PT> var(n_items, dimensionality);
212 PointDVector<PT> dest(n_items, dimensionality);
213
214 std::vector<PT> att(n_items * att_dimensionality);
215 std::vector<draco::Point3ui> att3(n_items);
216 for (PT val = 0; val < n_items; val += 1) {
217 att3[val][0] = val;
218 att3[val][1] = val;
219 att3[val][2] = val;
220 for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
221 att[val * att_dimensionality + att_dim] = val;
222 }
223 }
224 const PT *const attribute_data = att.data();
225
226 var.CopyAttribute(att_dimensionality, offset_dimensionality,
227 attribute_data);
228
229 for (PT item = 0; item < n_items; item += 1) {
230 dest.CopyItem(var, item, item);
231 }
232
233 auto aV0 = att3.begin();
234 auto aVE = att3.end();
235 auto V0 = var.begin();
236 auto VE = var.end();
237 auto D0 = dest.begin();
238 auto DE = dest.end();
239
240 while (aV0 != aVE && V0 != VE && D0 != DE) {
241 ASSERT_EQ(*D0, *V0); // compare PseudoPointD
242 // verify elemental values
243 for (auto index = 0; index < dimensionality; index += 1) {
244 ASSERT_EQ((*D0)[index], (*V0)[index]);
245 ASSERT_EQ((*D0)[index], (*aV0)[index]);
246 ASSERT_EQ((*aV0)[index], (*V0)[index]);
247 }
248 ++aV0;
249 ++V0;
250 ++D0;
251 }
252
253 for (PT val = 0; val < n_items; val += 1) {
254 for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
255 ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
256 ASSERT_EQ(dest[val][offset_dimensionality + att_dim], val);
257 }
258 }
259 }
260 }
261 }
262
TestPseudoPointDSwap()263 void TestPseudoPointDSwap() {
264 draco::Point3ui val = {0, 1, 2};
265 draco::Point3ui dest = {10, 11, 12};
266 draco::PseudoPointD<uint32_t> val_src1(&val[0], 3);
267 draco::PseudoPointD<uint32_t> dest_src1(&dest[0], 3);
268
269 ASSERT_EQ(val_src1[0], 0);
270 ASSERT_EQ(val_src1[1], 1);
271 ASSERT_EQ(val_src1[2], 2);
272 ASSERT_EQ(dest_src1[0], 10);
273 ASSERT_EQ(dest_src1[1], 11);
274 ASSERT_EQ(dest_src1[2], 12);
275
276 ASSERT_NE(val_src1, dest_src1);
277
278 swap(val_src1, dest_src1);
279
280 ASSERT_EQ(dest_src1[0], 0);
281 ASSERT_EQ(dest_src1[1], 1);
282 ASSERT_EQ(dest_src1[2], 2);
283 ASSERT_EQ(val_src1[0], 10);
284 ASSERT_EQ(val_src1[1], 11);
285 ASSERT_EQ(val_src1[2], 12);
286
287 ASSERT_NE(val_src1, dest_src1);
288 }
TestPseudoPointDEquality()289 void TestPseudoPointDEquality() {
290 draco::Point3ui val = {0, 1, 2};
291 draco::Point3ui dest = {0, 1, 2};
292 draco::PseudoPointD<uint32_t> val_src1(&val[0], 3);
293 draco::PseudoPointD<uint32_t> val_src2(&val[0], 3);
294 draco::PseudoPointD<uint32_t> dest_src1(&dest[0], 3);
295 draco::PseudoPointD<uint32_t> dest_src2(&dest[0], 3);
296
297 ASSERT_EQ(val_src1, val_src1);
298 ASSERT_EQ(val_src1, val_src2);
299 ASSERT_EQ(dest_src1, val_src1);
300 ASSERT_EQ(dest_src1, val_src2);
301 ASSERT_EQ(val_src2, val_src1);
302 ASSERT_EQ(val_src2, val_src2);
303 ASSERT_EQ(dest_src2, val_src1);
304 ASSERT_EQ(dest_src2, val_src2);
305
306 for (auto i = 0; i < 3; i++) {
307 ASSERT_EQ(val_src1[i], val_src1[i]);
308 ASSERT_EQ(val_src1[i], val_src2[i]);
309 ASSERT_EQ(dest_src1[i], val_src1[i]);
310 ASSERT_EQ(dest_src1[i], val_src2[i]);
311 ASSERT_EQ(val_src2[i], val_src1[i]);
312 ASSERT_EQ(val_src2[i], val_src2[i]);
313 ASSERT_EQ(dest_src2[i], val_src1[i]);
314 ASSERT_EQ(dest_src2[i], val_src2[i]);
315 }
316 }
TestPseudoPointDInequality()317 void TestPseudoPointDInequality() {
318 draco::Point3ui val = {0, 1, 2};
319 draco::Point3ui dest = {1, 2, 3};
320 draco::PseudoPointD<uint32_t> val_src1(&val[0], 3);
321 draco::PseudoPointD<uint32_t> val_src2(&val[0], 3);
322 draco::PseudoPointD<uint32_t> dest_src1(&dest[0], 3);
323 draco::PseudoPointD<uint32_t> dest_src2(&dest[0], 3);
324
325 ASSERT_EQ(val_src1, val_src1);
326 ASSERT_EQ(val_src1, val_src2);
327 ASSERT_NE(dest_src1, val_src1);
328 ASSERT_NE(dest_src1, val_src2);
329 ASSERT_EQ(val_src2, val_src1);
330 ASSERT_EQ(val_src2, val_src2);
331 ASSERT_NE(dest_src2, val_src1);
332 ASSERT_NE(dest_src2, val_src2);
333
334 for (auto i = 0; i < 3; i++) {
335 ASSERT_EQ(val_src1[i], val_src1[i]);
336 ASSERT_EQ(val_src1[i], val_src2[i]);
337 ASSERT_NE(dest_src1[i], val_src1[i]);
338 ASSERT_NE(dest_src1[i], val_src2[i]);
339 ASSERT_EQ(val_src2[i], val_src1[i]);
340 ASSERT_EQ(val_src2[i], val_src2[i]);
341 ASSERT_NE(dest_src2[i], val_src1[i]);
342 ASSERT_NE(dest_src2[i], val_src2[i]);
343 }
344 }
345 };
346
TEST_F(PointDVectorTest,VectorTest)347 TEST_F(PointDVectorTest, VectorTest) {
348 TestSize<uint32_t>();
349 TestContentsDiscrete<uint32_t>();
350 TestContentsContiguous<uint32_t>();
351 TestContentsCopy<uint32_t>();
352 TestIterator<uint32_t>();
353 TestPoint3Iterator<uint32_t>();
354 }
TEST_F(PointDVectorTest,PseudoPointDTest)355 TEST_F(PointDVectorTest, PseudoPointDTest) {
356 TestPseudoPointDSwap();
357 TestPseudoPointDEquality();
358 TestPseudoPointDInequality();
359 }
360 } // namespace draco
361