GCC Code Coverage Report


Directory: ./
File: openvdb/openvdb/unittest/TestPointMove.cc
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 376 387 97.2%
Functions: 17 17 100.0%
Branches: 472 1640 28.8%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 #include <openvdb/points/PointAttribute.h>
5 #include <openvdb/points/PointDataGrid.h>
6 #include <openvdb/points/PointConversion.h>
7 #include <openvdb/points/PointMove.h>
8 #include <openvdb/points/PointScatter.h>
9 #include <openvdb/openvdb.h>
10 #include <openvdb/Types.h>
11 #include "util.h"
12
13 #include <gtest/gtest.h>
14
15 #include <algorithm>
16 #include <atomic>
17 #include <map>
18 #include <sstream>
19 #include <string>
20 #include <vector>
21
22 using namespace openvdb;
23 using namespace openvdb::points;
24
25 6 class TestPointMove: public ::testing::Test
26 {
27 public:
28 6 void SetUp() override { openvdb::initialize(); }
29 6 void TearDown() override { openvdb::uninitialize(); }
30
31 void testCachedDeformer();
32 }; // class TestPointMove
33
34
35 ////////////////////////////////////////
36
37
38 namespace {
39
40 struct OffsetDeformer
41 {
42 OffsetDeformer(const Vec3d& _offset)
43
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 : offset(_offset){ }
44
45 template <typename LeafT>
46 void reset(const LeafT&, size_t /*idx*/) { }
47
48 template <typename IndexIterT>
49 void apply(Vec3d& position, const IndexIterT&) const
50 {
51 position += offset;
52 }
53
54 Vec3d offset;
55 }; // struct OffsetDeformer
56
57 template <typename FilterT>
58 39 struct OffsetFilteredDeformer
59 {
60 3 OffsetFilteredDeformer(const Vec3d& _offset,
61 const FilterT& _filter)
62 : offset(_offset)
63
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
3 , filter(_filter) { }
64
65 template <typename LeafT>
66 void reset(const LeafT& leaf, size_t /*idx*/)
67 {
68
4/8
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 5 times.
✗ Branch 11 not taken.
18 filter.template reset<LeafT>(leaf);
69 18 }
70
71 template <typename IndexIterT>
72 36 void apply(Vec3d& position, const IndexIterT& iter) const
73 {
74
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 14 times.
36 if (!filter.template valid<IndexIterT>(iter)) return;
75 position += offset;
76 }
77
78 //void finalize() const { }
79
80 Vec3d offset;
81 FilterT filter;
82 }; // struct OffsetFilteredDeformer
83
84
85 PointDataGrid::Ptr
86 16 positionsToGrid(const std::vector<Vec3s>& positions, const float voxelSize = 1.0)
87 {
88 const PointAttributeVector<Vec3s> pointList(positions);
89
90 openvdb::math::Transform::Ptr transform(
91 16 openvdb::math::Transform::createLinearTransform(voxelSize));
92
93 tools::PointIndexGrid::Ptr pointIndexGrid =
94
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 tools::createPointIndexGrid<tools::PointIndexGrid>(pointList, *transform);
95
96 PointDataGrid::Ptr points =
97 createPointDataGrid<NullCodec, PointDataGrid>(*pointIndexGrid,
98
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 pointList, *transform);
99
100 // assign point 3 to new group "test" if more than 3 points
101
102
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
16 if (positions.size() > 3) {
103
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
13 appendGroup(points->tree(), "test");
104
105
2/6
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
13 std::vector<short> groups(positions.size(), 0);
106 13 groups[2] = 1;
107
108
3/6
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
26 setGroup(points->tree(), pointIndexGrid->tree(), groups, "test");
109 }
110
111 16 return points;
112 }
113
114
115 std::vector<Vec3s>
116
1/2
✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
18 gridToPositions(const PointDataGrid::Ptr& points, bool sort = true)
117 {
118 std::vector<Vec3s> positions;
119
120
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 18 times.
55 for (auto leaf = points->tree().beginLeaf(); leaf; ++leaf) {
121
122 const openvdb::points::AttributeArray& positionArray =
123
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 leaf->constAttributeArray("P");
124
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
74 openvdb::points::AttributeHandle<openvdb::Vec3f> positionHandle(positionArray);
125
126
4/6
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 53 times.
✓ Branch 4 taken 37 times.
✓ Branch 6 taken 53 times.
✗ Branch 7 not taken.
180 for (auto iter = leaf->beginIndexOn(); iter; ++iter) {
127
1/2
✓ Branch 2 taken 53 times.
✗ Branch 3 not taken.
53 openvdb::Vec3f voxelPosition = positionHandle.get(*iter);
128
2/4
✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 53 times.
✗ Branch 5 not taken.
53 openvdb::Vec3d xyz = iter.getCoord().asVec3d();
129 openvdb::Vec3f worldPosition = points->transform().indexToWorld(voxelPosition + xyz);
130
131
1/2
✓ Branch 1 taken 53 times.
✗ Branch 2 not taken.
53 positions.push_back(worldPosition);
132 }
133 }
134
135
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 3 times.
33 if (sort) std::sort(positions.begin(), positions.end());
136 18 return positions;
137 }
138
139
140 std::vector<Vec3s>
141 6 applyOffset(const std::vector<Vec3s>& positions, const Vec3s& offset)
142 {
143 std::vector<Vec3s> newPositions;
144
145
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 6 times.
25 for (const auto& it : positions) {
146
1/4
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
19 newPositions.emplace_back(it + offset);
147 }
148
149 6 std::sort(newPositions.begin(), newPositions.end());
150 6 return newPositions;
151 }
152
153
154 template<typename T>
155 inline void
156 ASSERT_APPROX_EQUAL(const std::vector<T>& a, const std::vector<T>& b,
157 const Index lineNumber, const double /*tolerance*/ = 1e-6)
158 {
159 std::stringstream ss;
160 ss << "Assertion Line Number: " << lineNumber;
161
162 if (a.size() != b.size()) FAIL() << ss.str();
163
164 for (int i = 0; i < a.size(); i++) {
165 if (!math::isApproxEqual(a[i], b[i])) FAIL() << ss.str();
166 }
167 }
168
169
170 template<typename T>
171 inline void
172 19 ASSERT_APPROX_EQUAL(const std::vector<math::Vec3<T>>& a, const std::vector<math::Vec3<T>>& b,
173 const Index lineNumber, const double /*tolerance*/ = 1e-6)
174 {
175 38 std::stringstream ss;
176 ss << "Assertion Line Number: " << lineNumber;
177
178
1/12
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
19 if (a.size() != b.size()) FAIL() << ss.str();
179
180
2/2
✓ Branch 0 taken 1102785 times.
✓ Branch 1 taken 19 times.
1102804 for (size_t i = 0; i < a.size(); i++) {
181
1/12
✗ Branch 0 not taken.
✓ Branch 1 taken 1102785 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
1102785 if (!math::isApproxEqual(a[i], b[i])) FAIL() << ss.str();
182 }
183 }
184
185 struct NullObject { };
186
187 // A dummy iterator that can be used to match LeafIter and IndexIter interfaces
188 struct DummyIter
189 {
190 1 DummyIter(Index _index): index(_index) { }
191 //Index pos() const { return index; }
192
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 Index operator*() const { return index; }
193 Index index;
194 };
195
196 struct OddIndexFilter
197 {
198 static bool initialized() { return true; }
199 static index::State state() { return index::PARTIAL; }
200 template <typename LeafT>
201 static index::State state(const LeafT&) { return index::PARTIAL; }
202
203 template <typename LeafT>
204 void reset(const LeafT&) { }
205 template <typename IterT>
206 bool valid(const IterT& iter) const {
207
2/4
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 return ((*iter) % 2) == 1;
208 }
209 };
210
211 } // namespace
212
213
214 1 void TestPointMove::testCachedDeformer()
215 {
216 NullObject nullObject;
217
218 // create an empty cache and CachedDeformer
219 CachedDeformer<double>::Cache cache;
220 EXPECT_TRUE(cache.leafs.empty());
221
222 1 CachedDeformer<double> cachedDeformer(cache);
223
224 // check initialization is as expected
225
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(cachedDeformer.mLeafVec == nullptr);
226
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(cachedDeformer.mLeafMap == nullptr);
227
228 // throw when resetting cachedDeformer with an empty cache
229
4/20
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
2 EXPECT_THROW(cachedDeformer.reset(nullObject, size_t(0)), openvdb::IndexError);
230
231 // manually create one leaf in the cache
232
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 cache.leafs.resize(1);
233 auto& leaf = cache.leafs[0];
234
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(leaf.vecData.empty());
235
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(leaf.mapData.empty());
236
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(Index(0), leaf.totalSize);
237
238 // reset should no longer throw and leaf vec pointer should now be non-null
239
5/22
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
1 EXPECT_NO_THROW(cachedDeformer.reset(nullObject, size_t(0)));
240
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(cachedDeformer.mLeafMap == nullptr);
241
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(cachedDeformer.mLeafVec != nullptr);
242
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(cachedDeformer.mLeafVec->empty());
243
244 // nothing stored in the cache so position is unchanged
245 DummyIter indexIter(0);
246 Vec3d position(0,0,0);
247 1 Vec3d newPosition(position);
248 1 cachedDeformer.apply(newPosition, indexIter);
249
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(math::isApproxEqual(position, newPosition));
250
251 // insert a new value into the leaf vector and verify tbe position is deformed
252 Vec3d deformedPosition(5,10,15);
253
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 leaf.vecData.push_back(deformedPosition);
254 1 cachedDeformer.apply(newPosition, indexIter);
255
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(math::isApproxEqual(deformedPosition, newPosition));
256
257 // insert a new value into the leaf map and verify the position is deformed as before
258 Vec3d newDeformedPosition(2,3,4);
259 1 leaf.mapData.insert({0, newDeformedPosition});
260 newPosition.setZero();
261 1 cachedDeformer.apply(newPosition, indexIter);
262
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(math::isApproxEqual(deformedPosition, newPosition));
263
264 // now reset the cached deformer and verify the value is updated
265 // (map has precedence over vector)
266
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 cachedDeformer.reset(nullObject, size_t(0));
267
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(cachedDeformer.mLeafMap != nullptr);
268
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(cachedDeformer.mLeafVec == nullptr);
269 newPosition.setZero();
270 1 cachedDeformer.apply(newPosition, indexIter);
271
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(math::isApproxEqual(newDeformedPosition, newPosition));
272
273 // four points, some same leaf, some different
274 const float voxelSize = 1.0f;
275 std::vector<Vec3s> positions = {
276 {5, 2, 3},
277 {2, 4, 1},
278 {50, 5, 1},
279 {3, 20, 1},
280
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 };
281
282
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
283
284 // evaluate with null deformer and no filter
285
286 NullDeformer nullDeformer;
287 NullFilter nullFilter;
288
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 cachedDeformer.evaluate(*points, nullDeformer, nullFilter);
289
290
3/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
1 EXPECT_EQ(size_t(points->tree().leafCount()), cache.leafs.size());
291
292 int leafIndex = 0;
293
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 for (auto leafIter = points->tree().cbeginLeaf(); leafIter; ++leafIter) {
294
4/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 3 times.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
14 for (auto iter = leafIter->beginIndexOn(); iter; ++iter) {
295
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
12 AttributeHandle<Vec3f> handle(leafIter->constAttributeArray("P"));
296
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 Vec3f pos(handle.get(*iter) + iter.getCoord().asVec3s());
297
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 Vec3f cachePosition = cache.leafs[leafIndex].vecData[*iter];
298
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
4 EXPECT_TRUE(math::isApproxEqual(pos, cachePosition));
299 }
300
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 leafIndex++;
301 }
302
303 // evaluate with Offset deformer and no filter
304
305 Vec3d yOffset(1,2,3);
306 OffsetDeformer yOffsetDeformer(yOffset);
307
308
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 cachedDeformer.evaluate(*points, yOffsetDeformer, nullFilter);
309
310
3/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
1 EXPECT_EQ(size_t(points->tree().leafCount()), cache.leafs.size());
311
312 leafIndex = 0;
313
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 for (auto leafIter = points->tree().cbeginLeaf(); leafIter; ++leafIter) {
314
4/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 3 times.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
14 for (auto iter = leafIter->beginIndexOn(); iter; ++iter) {
315
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
12 AttributeHandle<Vec3f> handle(leafIter->constAttributeArray("P"));
316
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 Vec3f pos(handle.get(*iter) + iter.getCoord().asVec3s() + yOffset);
317
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 Vec3f cachePosition = cache.leafs[leafIndex].vecData[*iter];
318
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
4 EXPECT_TRUE(math::isApproxEqual(pos, cachePosition));
319 }
320
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 leafIndex++;
321 }
322
323 // evaluate with Offset deformer and OddIndex filter
324
325 OddIndexFilter oddFilter;
326
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 cachedDeformer.evaluate(*points, yOffsetDeformer, oddFilter);
327
328
3/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
1 EXPECT_EQ(size_t(points->tree().leafCount()), cache.leafs.size());
329
330 leafIndex = 0;
331
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 for (auto leafIter = points->tree().cbeginLeaf(); leafIter; ++leafIter) {
332 // odd filter writes to mapData, not vecData
333
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
3 EXPECT_TRUE(cache.leafs[leafIndex].vecData.empty());
334 const auto& data = cache.leafs[leafIndex].mapData;
335
336
4/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 3 times.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
14 for (auto iter = leafIter->beginIndexOn(); iter; ++iter) {
337
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
12 AttributeHandle<Vec3f> handle(leafIter->constAttributeArray("P"));
338
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 Vec3f pos(handle.get(*iter) + iter.getCoord().asVec3s() + yOffset);
339
340 4 const auto miter = data.find(*iter);
341
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if (!oddFilter.valid(iter)) {
342
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
3 EXPECT_TRUE(miter == data.cend());
343 }
344 else {
345
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(miter != data.cend());
346 const Vec3f& cachePosition = miter->second;
347
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(math::isApproxEqual(pos, cachePosition));
348 }
349 }
350
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 leafIndex++;
351 }
352 1 }
353
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 TEST_F(TestPointMove, testCachedDeformer) { testCachedDeformer(); }
354
355
356
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 TEST_F(TestPointMove, testMoveLocal)
357 {
358 // This test is for points that only move locally, meaning that
359 // they remain in the leaf from which they originated
360
361 { // single point, y offset, same voxel
362 const float voxelSize = 1.0f;
363 Vec3d offset(0, 0.1, 0);
364 OffsetDeformer deformer(offset);
365
366 std::vector<Vec3s> positions = {
367 {10, 10, 10},
368
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 };
369
370
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 std::vector<Vec3s> desiredPositions = applyOffset(positions, offset);
371
372
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
373
374 movePoints(*points, deformer);
375
376
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> actualPositions = gridToPositions(points);
377
378
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, actualPositions, __LINE__);
379 }
380
381 { // two points, y offset, same voxel
382 const float voxelSize = 1.0f;
383 Vec3d offset(0, 0.1, 0);
384 OffsetDeformer deformer(offset);
385
386 std::vector<Vec3s> positions = {
387 {10, 10, 10},
388 {10, 10.1f, 10},
389
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 };
390
391
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 std::vector<Vec3s> desiredPositions = applyOffset(positions, offset);
392
393
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
394
395 movePoints(*points, deformer);
396
397
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> actualPositions = gridToPositions(points);
398
399
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, actualPositions, __LINE__);
400 }
401
402 { // two points, y offset, different voxels
403 const float voxelSize = 1.0f;
404 Vec3d offset(0, 0.1, 0);
405 OffsetDeformer deformer(offset);
406
407 std::vector<Vec3s> positions = {
408 {10, 10, 10},
409 {10, 11, 10},
410
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 };
411
412
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 std::vector<Vec3s> desiredPositions = applyOffset(positions, offset);
413
414
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
415
416 movePoints(*points, deformer);
417
418
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> actualPositions = gridToPositions(points);
419
420
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, actualPositions, __LINE__);
421 }
422
423 { // four points, y offset, same voxel, only third point is kept
424 const float voxelSize = 1.0f;
425 Vec3d offset(0, 0.1, 0);
426 OffsetDeformer deformer(offset);
427
428 std::vector<Vec3s> positions = {
429 {10, 10, 10},
430 {10, 10.1f, 10},
431 {10, 10.2f, 10},
432 {10, 10.3f, 10},
433
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 };
434
435 std::vector<Vec3s> desiredPositions;
436
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 desiredPositions.emplace_back(positions[2]+offset);
437
438
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
439
440
3/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
3 std::vector<std::string> includeGroups{"test"};
441 1 std::vector<std::string> excludeGroups;
442
443 auto leaf = points->tree().cbeginLeaf();
444
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
445 movePoints(*points, deformer, filter);
446
447
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> actualPositions = gridToPositions(points);
448
449
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, actualPositions, __LINE__);
450 }
451
452 { // four points, y offset, different voxels, only third point is kept
453 const float voxelSize = 1.0f;
454 Vec3d offset(0, 0.1, 0);
455 OffsetDeformer deformer(offset);
456
457 std::vector<Vec3s> positions = {
458 {10, 10, 10},
459 {10, 11, 10},
460 {10, 12, 10},
461 {10, 13, 10},
462
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 };
463
464 std::vector<Vec3s> desiredPositions;
465
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 desiredPositions.emplace_back(positions[2]+offset);
466
467
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
468
469
3/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
3 std::vector<std::string> includeGroups{"test"};
470 1 std::vector<std::string> excludeGroups;
471
472 auto leaf = points->tree().cbeginLeaf();
473
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
474 movePoints(*points, deformer, filter);
475
476
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> actualPositions = gridToPositions(points);
477
478
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, actualPositions, __LINE__);
479 }
480
481 { // four points, y offset, different voxels, only third point is moved
482 const float voxelSize = 1.0f;
483 Vec3d offset(0, 0.1, 0);
484
485 std::vector<Vec3s> positions = {
486 {10, 10, 10},
487 {10, 11, 10},
488 {10, 12, 10},
489 {10, 13, 10},
490 1 };
491
492
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> desiredPositions(positions);
493 1 desiredPositions[2] = Vec3s(positions[2] + offset);
494
495 1 std::sort(desiredPositions.begin(), desiredPositions.end());
496
497
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
498
499
3/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
3 std::vector<std::string> includeGroups{"test"};
500 1 std::vector<std::string> excludeGroups;
501
502 auto leaf = points->tree().cbeginLeaf();
503
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
504 OffsetFilteredDeformer<MultiGroupFilter> deformer(offset, filter);
505 movePoints(*points, deformer);
506
507
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> actualPositions = gridToPositions(points);
508
509
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, actualPositions, __LINE__);
510 }
511 1 }
512
513
514
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 TEST_F(TestPointMove, testMoveGlobal)
515 {
516 { // four points, all different leafs
517 const float voxelSize = 0.1f;
518 Vec3d offset(0, 10.1, 0);
519 OffsetDeformer deformer(offset);
520
521 std::vector<Vec3s> positions = {
522 {1, 1, 1},
523 {1, 5.05f, 1},
524 {2, 1, 1},
525 {2, 2, 1},
526
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 };
527
528
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 std::vector<Vec3s> desiredPositions = applyOffset(positions, offset);
529
530
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
531
532 movePoints(*points, deformer);
533
534
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> actualPositions = gridToPositions(points);
535
536
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, actualPositions, __LINE__);
537 }
538
539 { // four points, all different leafs, only third point is kept
540 const float voxelSize = 0.1f;
541 Vec3d offset(0, 10.1, 0);
542 OffsetDeformer deformer(offset);
543
544 std::vector<Vec3s> positions = {
545 {1, 1, 1},
546 {1, 5.05f, 1},
547 {2, 1, 1},
548 {2, 2, 1},
549
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 };
550
551 std::vector<Vec3s> desiredPositions;
552
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 desiredPositions.emplace_back(positions[2]+offset);
553
554
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
555
556
3/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
3 std::vector<std::string> includeGroups{"test"};
557 1 std::vector<std::string> excludeGroups;
558
559 auto leaf = points->tree().cbeginLeaf();
560
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
561 movePoints(*points, deformer, filter);
562
563
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> actualPositions = gridToPositions(points);
564
565
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, actualPositions, __LINE__);
566 }
567
568 { // four points, all different leafs, third point is deleted
569 const float voxelSize = 0.1f;
570 Vec3d offset(0, 10.1, 0);
571 OffsetDeformer deformer(offset);
572
573 std::vector<Vec3s> positions = {
574 {1, 1, 1},
575 {1, 5.05f, 1},
576 {2, 1, 1},
577 {2, 2, 1},
578 1 };
579
580
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
581
582 std::vector<Vec3s> desiredPositions;
583
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 desiredPositions.emplace_back(positions[0]+offset);
584
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 desiredPositions.emplace_back(positions[1]+offset);
585
2/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 desiredPositions.emplace_back(positions[3]+offset);
586
587 1 std::vector<std::string> includeGroups;
588
3/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
3 std::vector<std::string> excludeGroups{"test"};
589
590 auto leaf = points->tree().cbeginLeaf();
591
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
592 movePoints(*points, deformer, filter);
593
594
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> actualPositions = gridToPositions(points);
595
596
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, actualPositions, __LINE__);
597 }
598
599 { // six points, some same leaf, some different
600 const float voxelSize = 1.0f;
601 Vec3d offset(0, 0.1, 0);
602 OffsetDeformer deformer(offset);
603
604 std::vector<Vec3s> positions = {
605 {1, 1, 1},
606 {1.01f, 1.01f, 1.01f},
607 {1, 5.05f, 1},
608 {2, 1, 1},
609 {2.01f, 1.01f, 1.01f},
610 {2, 2, 1},
611
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 };
612
613
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 std::vector<Vec3s> desiredPositions = applyOffset(positions, offset);
614
615
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
616
617 movePoints(*points, deformer);
618
619
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> actualPositions = gridToPositions(points);
620
621
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, actualPositions, __LINE__);
622 }
623
624 { // four points, all different leafs, only third point is moved
625 const float voxelSize = 0.1f;
626 Vec3d offset(0, 10.1, 0);
627
628 std::vector<Vec3s> positions = {
629 {1, 1, 1},
630 {1, 5.05f, 1},
631 {2, 1, 1},
632 {2, 2, 1},
633 1 };
634
635
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> desiredPositions(positions);
636 1 desiredPositions[2] = Vec3s(positions[2] + offset);
637
638 1 std::sort(desiredPositions.begin(), desiredPositions.end());
639
640
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
641
642
3/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
3 std::vector<std::string> includeGroups{"test"};
643 1 std::vector<std::string> excludeGroups;
644
645 auto leaf = points->tree().cbeginLeaf();
646
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
647 OffsetFilteredDeformer<MultiGroupFilter> deformer(offset, filter);
648 movePoints(*points, deformer);
649
650
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> actualPositions = gridToPositions(points);
651
652
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, actualPositions, __LINE__);
653 }
654
655 { // four points, all different leafs, only third point is kept but not moved
656 const float voxelSize = 0.1f;
657 Vec3d offset(0, 10.1, 0);
658
659 std::vector<Vec3s> positions = {
660 {1, 1, 1},
661 {1, 5.05f, 1},
662 {2, 1, 1},
663 {2, 2, 1},
664
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 };
665
666 std::vector<Vec3s> desiredPositions;
667
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 desiredPositions.emplace_back(positions[2]);
668
669 1 std::sort(desiredPositions.begin(), desiredPositions.end());
670
671
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
672
673 // these groups mark which points are kept
674
675
3/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
3 std::vector<std::string> includeGroups{"test"};
676 1 std::vector<std::string> excludeGroups;
677
678 // these groups mark which points are moved
679
680 1 std::vector<std::string> moveIncludeGroups;
681
3/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
3 std::vector<std::string> moveExcludeGroups{"test"};
682
683 auto leaf = points->tree().cbeginLeaf();
684
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 MultiGroupFilter moveFilter(moveIncludeGroups, moveExcludeGroups, leaf->attributeSet());
685
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
686 OffsetFilteredDeformer<MultiGroupFilter> deformer(offset, moveFilter);
687 movePoints(*points, deformer, filter);
688
689
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> actualPositions = gridToPositions(points);
690
691
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, actualPositions, __LINE__);
692 }
693 1 }
694
695
696 namespace {
697
698 // Custom Deformer with reset and apply counters
699 struct CustomDeformer
700 {
701 using LeafT = PointDataGrid::TreeType::LeafNodeType;
702
703 CustomDeformer(const openvdb::Vec3d& offset,
704 std::atomic<int>& resetCalls,
705 std::atomic<int>& applyCalls)
706 1 : mOffset(offset)
707 , mResetCalls(resetCalls)
708
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 , mApplyCalls(applyCalls) { }
709
710 template <typename LeafT>
711 void reset(const LeafT& /*leaf*/, size_t /*idx*/)
712 {
713
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
9 mResetCalls++;
714 }
715
716 template <typename IndexIterT>
717 12 void apply(Vec3d& position, const IndexIterT&) const
718 {
719 // ensure reset has been called at least once
720
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (mResetCalls > 0) {
721 position += mOffset;
722 }
723 12 mApplyCalls++;
724 12 }
725
726 const openvdb::Vec3d mOffset;
727 std::atomic<int>& mResetCalls;
728 std::atomic<int>& mApplyCalls;
729 }; // struct CustomDeformer
730
731 // Custom Deformer that always returns the position supplied in the constructor
732 struct StaticDeformer
733 {
734 StaticDeformer(const openvdb::Vec3d& position)
735
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 : mPosition(position) { }
736
737 template <typename LeafT>
738 void reset(const LeafT& /*leaf*/, size_t /*idx*/) { }
739
740 template <typename IndexIterT>
741 void apply(Vec3d& position, const IndexIterT&) const
742 {
743
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
8 position = mPosition;
744 }
745
746 const openvdb::Vec3d mPosition;
747 }; // struct StaticDeformer
748
749 } // namespace
750
751
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 TEST_F(TestPointMove, testCustomDeformer)
752 {
753 { // four points, some same leaf, some different, custom deformer
754 const float voxelSize = 1.0f;
755 Vec3d offset(4.5,3.2,1.85);
756
757 std::vector<Vec3s> positions = {
758 {5, 2, 3},
759 {2, 4, 1},
760 {50, 5, 1},
761 {3, 20, 1},
762
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 };
763
764
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 std::vector<Vec3s> desiredPositions = applyOffset(positions, offset);
765
766
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
767
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr cachedPoints = points->deepCopy();
768
769
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 const int leafCount = points->tree().leafCount();
770
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 const int pointCount = int(positions.size());
771
772 std::atomic<int> resetCalls, applyCalls;
773 resetCalls = 0;
774 applyCalls = 0;
775
776 // this deformer applies an offset and tracks the number of calls
777
778 CustomDeformer deformer(offset, resetCalls, applyCalls);
779
780 movePoints(*points, deformer);
781
782
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(2*leafCount == resetCalls);
783
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(2*pointCount == applyCalls);
784
785
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> actualPositions = gridToPositions(points);
786
787
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, actualPositions, __LINE__);
788
789 // use CachedDeformer
790
791 resetCalls = 0;
792 applyCalls = 0;
793
794 CachedDeformer<double>::Cache cache;
795 1 CachedDeformer<double> cachedDeformer(cache);
796 NullFilter filter;
797
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 cachedDeformer.evaluate(*cachedPoints, deformer, filter);
798
799
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 movePoints(*cachedPoints, cachedDeformer);
800
801
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(leafCount == resetCalls);
802
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(pointCount == applyCalls);
803
804
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> cachedPositions = gridToPositions(cachedPoints);
805
806
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, cachedPositions, __LINE__);
807 }
808
809 {
810 { // four points, some same leaf, some different, static deformer
811 const float voxelSize = 1.0f;
812 Vec3d newPosition(15.2,18.3,-100.9);
813
814 std::vector<Vec3s> positions = {
815 {5, 2, 3},
816 {2, 4, 1},
817 {50, 5, 1},
818 {3, 20, 1},
819
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 };
820
821
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 std::vector<Vec3s> desiredPositions(positions.size(), newPosition);
822
823
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
824
825 StaticDeformer deformer(newPosition);
826
827 movePoints(*points, deformer);
828
829
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> actualPositions = gridToPositions(points);
830
831
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, actualPositions, __LINE__);
832 }
833 }
834 1 }
835
836
837 namespace {
838
839 // Custom deformer that stores a map of current positions to new positions
840 1 struct AssignDeformer
841 {
842 AssignDeformer(const std::map<Vec3d, Vec3d>& _values)
843 1 : values(_values) { }
844
845 template <typename LeafT>
846 void reset(const LeafT&, size_t /*idx*/) { }
847
848 template <typename IndexIterT>
849 void apply(Vec3d& position, const IndexIterT&) const
850 {
851
8/16
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 8 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 8 times.
✗ Branch 23 not taken.
22 position = values.at(position);
852 }
853
854 std::map<Vec3d, Vec3d> values;
855 }; // struct AssignDeformer
856
857 }
858
859
860
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 TEST_F(TestPointMove, testPointData)
861 {
862 // four points, some same leaf, some different
863 // spatial order is (1, 0, 3, 2)
864
865 const float voxelSize = 1.0f;
866 std::vector<Vec3s> positions = {
867 {5, 2, 3},
868 {2, 4, 1},
869 {50, 5, 1},
870 {3, 20, 1},
871
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 };
872
873 // simple reversing deformer
874
875 std::map<Vec3d, Vec3d> remap;
876
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 remap.insert({positions[0], positions[3]});
877
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 remap.insert({positions[1], positions[2]});
878
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 remap.insert({positions[2], positions[1]});
879
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 remap.insert({positions[3], positions[0]});
880
881 AssignDeformer deformer(remap);
882
883 { // reversing point positions results in the same iteration order due to spatial organisation
884
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PointDataGrid::Ptr points = positionsToGrid(positions, voxelSize);
885
886
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> initialPositions = gridToPositions(points, /*sort=*/false);
887
888 1 std::vector<std::string> includeGroups;
889 1 std::vector<std::string> excludeGroups;
890
891 movePoints(*points, deformer);
892
893
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> finalPositions1 = gridToPositions(points, /*sort=*/false);
894
895
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(initialPositions, finalPositions1, __LINE__);
896
897 // now we delete the third point while sorting, using the test group
898
899
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 excludeGroups.push_back("test");
900
901 auto leaf = points->tree().cbeginLeaf();
902
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
903 movePoints(*points, deformer, filter);
904
905 std::vector<Vec3s> desiredPositions;
906
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 desiredPositions.emplace_back(positions[0]);
907
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 desiredPositions.emplace_back(positions[1]);
908
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 desiredPositions.emplace_back(positions[3]);
909
910
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::vector<Vec3s> finalPositions2 = gridToPositions(points, /*sort=*/false);
911
912 1 std::sort(desiredPositions.begin(), desiredPositions.end());
913 1 std::sort(finalPositions2.begin(), finalPositions2.end());
914
915
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(desiredPositions, finalPositions2, __LINE__);
916 }
917
918 { // additional point data - integer "id", float "pscale", "odd" and "even" groups
919
920 std::vector<int> id;
921
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 id.push_back(0);
922
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 id.push_back(1);
923
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 id.push_back(2);
924
2/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 id.push_back(3);
925
926 std::vector<float> radius;
927
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 radius.push_back(0.1f);
928
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 radius.push_back(0.15f);
929
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 radius.push_back(0.2f);
930
2/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 radius.push_back(0.5f);
931
932 // manually construct point data grid instead of using positionsToGrid()
933
934 const PointAttributeVector<Vec3s> pointList(positions);
935
936 openvdb::math::Transform::Ptr transform(
937
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 openvdb::math::Transform::createLinearTransform(voxelSize));
938
939 tools::PointIndexGrid::Ptr pointIndexGrid =
940
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 tools::createPointIndexGrid<tools::PointIndexGrid>(pointList, *transform);
941
942 PointDataGrid::Ptr points =
943 createPointDataGrid<NullCodec, PointDataGrid>(*pointIndexGrid,
944
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pointList, *transform);
945 auto idAttributeType =
946
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 openvdb::points::TypedAttributeArray<int>::attributeType();
947
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 openvdb::points::appendAttribute(points->tree(), "id", idAttributeType);
948
949 // create a wrapper around the id vector
950 openvdb::points::PointAttributeVector<int> idWrapper(id);
951
952 openvdb::points::populateAttribute<openvdb::points::PointDataTree,
953
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 openvdb::tools::PointIndexTree, openvdb::points::PointAttributeVector<int>>(
954 points->tree(), pointIndexGrid->tree(), "id", idWrapper);
955
956 // use fixed-point codec for radius
957 // note that this attribute type is not registered by default so needs to be
958 // explicitly registered.
959 using Codec = openvdb::points::FixedPointCodec</*1-byte=*/false,
960 openvdb::points::UnitRange>;
961
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 openvdb::points::TypedAttributeArray<float, Codec>::registerType();
962 auto radiusAttributeType =
963
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 openvdb::points::TypedAttributeArray<float, Codec>::attributeType();
964
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 openvdb::points::appendAttribute(points->tree(), "pscale", radiusAttributeType);
965
966 // create a wrapper around the radius vector
967 openvdb::points::PointAttributeVector<float> radiusWrapper(radius);
968
969 openvdb::points::populateAttribute<openvdb::points::PointDataTree,
970
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 openvdb::tools::PointIndexTree, openvdb::points::PointAttributeVector<float>>(
971 points->tree(), pointIndexGrid->tree(), "pscale", radiusWrapper);
972
973
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 appendGroup(points->tree(), "odd");
974
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 appendGroup(points->tree(), "even");
975
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 appendGroup(points->tree(), "nonzero");
976
977
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 std::vector<short> oddGroups(positions.size(), 0);
978 1 oddGroups[1] = 1;
979 1 oddGroups[3] = 1;
980
2/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 std::vector<short> evenGroups(positions.size(), 0);
981 1 evenGroups[0] = 1;
982 1 evenGroups[2] = 1;
983
2/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 std::vector<short> nonZeroGroups(positions.size(), 1);
984 1 nonZeroGroups[0] = 0;
985
986
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 setGroup(points->tree(), pointIndexGrid->tree(), evenGroups, "even");
987
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 setGroup(points->tree(), pointIndexGrid->tree(), oddGroups, "odd");
988
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
2 setGroup(points->tree(), pointIndexGrid->tree(), nonZeroGroups, "nonzero");
989
990
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 movePoints(*points, deformer);
991
992 // extract data
993
994 std::vector<int> id2;
995 std::vector<float> radius2;
996 std::vector<short> oddGroups2;
997 std::vector<short> evenGroups2;
998 std::vector<short> nonZeroGroups2;
999
1000
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 for (auto leaf = points->tree().cbeginLeaf(); leaf; ++leaf) {
1001
1002
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
12 AttributeHandle<int> idHandle(leaf->constAttributeArray("id"));
1003
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
12 AttributeHandle<float> pscaleHandle(leaf->constAttributeArray("pscale"));
1004
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
6 GroupHandle oddHandle(leaf->groupHandle("odd"));
1005
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
6 GroupHandle evenHandle(leaf->groupHandle("even"));
1006
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
6 GroupHandle nonZeroHandle(leaf->groupHandle("nonzero"));
1007
1008
3/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 3 times.
10 for (auto iter = leaf->beginIndexOn(); iter; ++iter) {
1009
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 id2.push_back(idHandle.get(*iter));
1010
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 radius2.push_back(pscaleHandle.get(*iter));
1011
4/6
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
6 oddGroups2.push_back(oddHandle.get(*iter) ? 1 : 0);
1012
4/6
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
6 evenGroups2.push_back(evenHandle.get(*iter) ? 1 : 0);
1013
5/8
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 3 times.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
5 nonZeroGroups2.push_back(nonZeroHandle.get(*iter) ? 1 : 0);
1014 }
1015 }
1016
1017 // new reversed order is (2, 3, 0, 1)
1018
1019
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(2, id2[0]);
1020
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(3, id2[1]);
1021
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(0, id2[2]);
1022
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(1, id2[3]);
1023
1024
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(math::isApproxEqual(radius[0], radius2[2], 1e-3f));
1025
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(math::isApproxEqual(radius[1], radius2[3], 1e-3f));
1026
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(math::isApproxEqual(radius[2], radius2[0], 1e-3f));
1027
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_TRUE(math::isApproxEqual(radius[3], radius2[1], 1e-3f));
1028
1029
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(short(0), oddGroups2[0]);
1030
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(short(1), oddGroups2[1]);
1031
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(short(0), oddGroups2[2]);
1032
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(short(1), oddGroups2[3]);
1033
1034
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(short(1), evenGroups2[0]);
1035
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(short(0), evenGroups2[1]);
1036
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(short(1), evenGroups2[2]);
1037
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(short(0), evenGroups2[3]);
1038
1039
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(short(1), nonZeroGroups2[0]);
1040
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(short(1), nonZeroGroups2[1]);
1041
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_EQ(short(0), nonZeroGroups2[2]);
1042
2/18
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1 EXPECT_EQ(short(1), nonZeroGroups2[3]);
1043 }
1044
1045 { // larger data set with a cached deformer and group filtering
1046 std::vector<openvdb::Vec3R> newPositions;
1047 const int count = 10000;
1048
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 unittest_util::genPoints(count, newPositions);
1049
1050 // manually construct point data grid instead of using positionsToGrid()
1051
1052 const PointAttributeVector<openvdb::Vec3R> pointList(newPositions);
1053
1054 openvdb::math::Transform::Ptr transform(
1055
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 openvdb::math::Transform::createLinearTransform(/*voxelSize=*/0.1));
1056
1057 tools::PointIndexGrid::Ptr pointIndexGrid =
1058
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 tools::createPointIndexGrid<tools::PointIndexGrid>(pointList, *transform);
1059
1060 PointDataGrid::Ptr points =
1061 createPointDataGrid<NullCodec, PointDataGrid>(*pointIndexGrid,
1062
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pointList, *transform);
1063
1064
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 appendGroup(points->tree(), "odd");
1065
1066
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 std::vector<short> oddGroups(newPositions.size(), 0);
1067
2/2
✓ Branch 0 taken 5000 times.
✓ Branch 1 taken 1 times.
5001 for (size_t i = 1; i < newPositions.size(); i += 2) {
1068 5000 oddGroups[i] = 1;
1069 }
1070
1071
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 setGroup(points->tree(), pointIndexGrid->tree(), oddGroups, "odd");
1072
1073
3/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
3 std::vector<std::string> includeGroups{"odd"};
1074 1 std::vector<std::string> excludeGroups;
1075
1076 auto leaf = points->tree().cbeginLeaf();
1077
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 MultiGroupFilter advectFilter(includeGroups, excludeGroups, leaf->attributeSet());
1078 1 OffsetDeformer offsetDeformer(Vec3d(0, 1, 0));
1079
1080 CachedDeformer<double>::Cache cache;
1081 1 CachedDeformer<double> cachedDeformer(cache);
1082
1083
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 cachedDeformer.evaluate(*points, offsetDeformer, advectFilter);
1084
1085 double ySumBefore = 0.0;
1086 double ySumAfter = 0.0;
1087
1088
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 1 times.
33 for (auto leaf = points->tree().cbeginLeaf(); leaf; ++leaf) {
1089
3/6
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 32 times.
✗ Branch 8 not taken.
128 AttributeHandle<Vec3f> handle(leaf->constAttributeArray("P"));
1090
3/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10000 times.
✓ Branch 4 taken 32 times.
10064 for (auto iter = leaf->beginIndexOn(); iter; ++iter) {
1091
3/6
✓ Branch 1 taken 10000 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 10000 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 10000 times.
✗ Branch 9 not taken.
10000 Vec3d position = handle.get(*iter) + iter.getCoord().asVec3s();
1092 10000 position = transform->indexToWorld(position);
1093
1/2
✓ Branch 1 taken 10000 times.
✗ Branch 2 not taken.
10000 ySumBefore += position.y();
1094 }
1095 }
1096
1097
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 movePoints(*points, cachedDeformer);
1098
1099
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 1 times.
49 for (auto leaf = points->tree().cbeginLeaf(); leaf; ++leaf) {
1100
3/6
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 48 times.
✗ Branch 8 not taken.
192 AttributeHandle<Vec3f> handle(leaf->constAttributeArray("P"));
1101
3/4
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10000 times.
✓ Branch 4 taken 48 times.
10096 for (auto iter = leaf->beginIndexOn(); iter; ++iter) {
1102
3/6
✓ Branch 1 taken 10000 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 10000 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 10000 times.
✗ Branch 9 not taken.
10000 Vec3d position = handle.get(*iter) + iter.getCoord().asVec3s();
1103 10000 position = transform->indexToWorld(position);
1104
1/2
✓ Branch 1 taken 10000 times.
✗ Branch 2 not taken.
10000 ySumAfter += position.y();
1105 }
1106 }
1107
1108 // total increase in Y should be approximately count / 2
1109 // (only odd points are being moved 1.0 in Y)
1110 1 double increaseInY = ySumAfter - ySumBefore;
1111
1112
2/16
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1 EXPECT_NEAR(increaseInY, static_cast<double>(count) / 2.0,
1113 /*tolerance=*/double(0.01));
1114 }
1115 1 }
1116
1117
1118
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 TEST_F(TestPointMove, testPointOrder)
1119 {
1120 struct Local
1121 {
1122 using GridT = points::PointDataGrid;
1123
1124 3 static void populate(std::vector<Vec3s>& positions, const GridT& points,
1125 const math::Transform& transform, bool /*threaded*/)
1126 {
1127 3 auto newPoints1 = points.deepCopy();
1128
1129 points::NullDeformer nullDeformer;
1130 points::NullFilter nullFilter;
1131
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 points::movePoints(*newPoints1, transform, nullDeformer, nullFilter);
1132
1133
1/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
3 size_t totalPoints = points::pointCount(newPoints1->tree());
1134
1135
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 positions.reserve(totalPoints);
1136
1137
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 3 times.
27 for (auto leaf = newPoints1->tree().cbeginLeaf(); leaf; ++leaf) {
1138
3/6
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 24 times.
✗ Branch 8 not taken.
96 AttributeHandle<Vec3f> handle(leaf->constAttributeArray("P"));
1139
3/4
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1654104 times.
✓ Branch 4 taken 24 times.
1654152 for (auto iter = leaf->beginIndexOn(); iter; ++iter) {
1140
2/4
✓ Branch 2 taken 1654104 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1654104 times.
✗ Branch 6 not taken.
3308208 positions.push_back(handle.get(*iter));
1141 }
1142 }
1143 3 }
1144 };
1145
1146 1 auto sourceTransform = math::Transform::createLinearTransform(/*voxelSize=*/0.1);
1147
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 auto targetTransform = math::Transform::createLinearTransform(/*voxelSize=*/1.0);
1148
1149 auto mask = MaskGrid::create();
1150
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
2 mask->setTransform(sourceTransform);
1151
2/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2 mask->denseFill(CoordBBox(Coord(-20,-20,-20), Coord(20,20,20)), true);
1152
1153
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 auto points = points::denseUniformPointScatter(*mask, /*pointsPerVoxel=*/8);
1154
1155 // three copies of the points, two multi-threaded and one single-threaded
1156 std::vector<Vec3s> positions1;
1157 std::vector<Vec3s> positions2;
1158 std::vector<Vec3s> positions3;
1159
1160
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Local::populate(positions1, *points, *targetTransform, true);
1161
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Local::populate(positions2, *points, *targetTransform, true);
1162
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Local::populate(positions3, *points, *targetTransform, false);
1163
1164 // verify all sequences are identical to confirm that points are ordered deterministically
1165
1166
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(positions1, positions2, __LINE__);
1167
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ASSERT_APPROX_EQUAL(positions1, positions3, __LINE__);
1168 1 }
1169