GCC Code Coverage Report


Directory: ./
File: openvdb/openvdb/unittest/TestPointRasterizeTrilinear.cc
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 168 173 97.1%
Functions: 24 24 100.0%
Branches: 154 530 29.1%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 #include <openvdb/openvdb.h>
5 #include <openvdb/points/PointAttribute.h>
6 #include <openvdb/points/PointCount.h>
7 #include <openvdb/points/PointConversion.h>
8 #include <openvdb/points/PointScatter.h>
9 #include <openvdb/points/PointRasterizeTrilinear.h>
10
11 #include <gtest/gtest.h>
12
13 using namespace openvdb;
14
15 9 class TestPointRasterize: public ::testing::Test
16 {
17 public:
18 9 void SetUp() override { openvdb::initialize(); }
19 9 void TearDown() override { openvdb::uninitialize(); }
20 }; // class TestPointRasterize
21
22 struct DefaultTransfer
23 {
24 inline bool startPointLeaf(const points::PointDataTree::LeafNodeType&) { return true; }
25 inline bool endPointLeaf(const points::PointDataTree::LeafNodeType&) { return true; }
26 inline bool finalize(const Coord&, size_t) { return true; }
27 };
28
29 template <typename T, bool Staggered>
30
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 inline void testTrilinear(const T& v)
31 {
32 static constexpr bool IsVec = ValueTraits<T>::IsVec;
33 using VecT = typename std::conditional<IsVec, T, math::Vec3<T>>::type;
34 using ResultValueT = typename std::conditional<Staggered && !IsVec, VecT, T>::type;
35 using ResultTreeT = typename points::PointDataTree::ValueConverter<ResultValueT>::Type;
36
37 std::vector<Vec3f> positions;
38
1/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
16 positions.emplace_back(Vec3f(0.0f));
39
40 const double voxelSize = 0.1;
41
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 math::Transform::Ptr transform =
42 math::Transform::createLinearTransform(voxelSize);
43
44
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 points::PointDataGrid::Ptr points =
45 points::createPointDataGrid<points::NullCodec,
46 points::PointDataGrid, Vec3f>(positions, *transform);
47
48
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
16 points::appendAttribute<T>(points->tree(), "test", v);
49
3/8
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
16 TreeBase::Ptr tree =
50 points::rasterizeTrilinear<Staggered, T>(points->tree(), "test");
51
52
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 8 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.
16 EXPECT_TRUE(tree);
53 typename ResultTreeT::Ptr typed = DynamicPtrCast<ResultTreeT>(tree);
54
1/16
✗ Branch 0 not taken.
✓ Branch 1 taken 8 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.
16 EXPECT_TRUE(typed);
55
56 const ResultValueT result = typed->getValue(Coord(0,0,0));
57
58 // convert both to vecs even if they are scalars to avoid having
59 // to specialise this method
60 16 const VecT expected(v);
61
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
12 const VecT vec(result);
62
2/16
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 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.
16 EXPECT_NEAR(expected[0], vec[0], 1e-6);
63
2/16
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 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.
16 EXPECT_NEAR(expected[1], vec[1], 1e-6);
64
2/16
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 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.
16 EXPECT_NEAR(expected[2], vec[2], 1e-6);
65 16 }
66
67
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 TEST_F(TestPointRasterize, testTrilinearRasterizeFloat)
68 {
69 1 testTrilinear<float, false>(111.0f);
70 1 testTrilinear<float, true>(111.0f);
71 1 }
72
73
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 TEST_F(TestPointRasterize, testTrilinearRasterizeDouble)
74 {
75 1 testTrilinear<double, false>(222.0);
76 1 testTrilinear<double, true>(222.0);
77 1 }
78
79
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 TEST_F(TestPointRasterize, testTrilinearRasterizeVec3f)
80 {
81 1 testTrilinear<Vec3f, false>(Vec3f(111.0f,222.0f,333.0f));
82 1 testTrilinear<Vec3f, true>(Vec3f(111.0f,222.0f,333.0f));
83 1 }
84
85
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 TEST_F(TestPointRasterize, testTrilinearRasterizeVec3d)
86 {
87 1 testTrilinear<Vec3d, false>(Vec3d(444.0,555.0,666.0));
88 1 testTrilinear<Vec3d, true>(Vec3d(444.0,555.0,666.0));
89 1 }
90
91
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 TEST_F(TestPointRasterize, testRasterizeWithFilter)
92 {
93 struct CountPointsTransferScheme
94 : public DefaultTransfer
95 , public points::VolumeTransfer<Int32Tree>
96 {
97 CountPointsTransferScheme(Int32Tree& tree)
98 : points::VolumeTransfer<Int32Tree>(&tree) {}
99
100 inline Int32 range(const Coord&, size_t) const { return 0; }
101 inline void rasterizePoint(const Coord& ijk,
102 const Index,
103 const CoordBBox&)
104 {
105 const Index offset = points::PointDataTree::LeafNodeType::coordToOffset(ijk);
106 auto* const data = this->template buffer<0>();
107 2 data[offset] += 1;
108 2 }
109 };
110
111 std::vector<Vec3f> positions;
112
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 positions.emplace_back(Vec3f(0.0f, 0.0f, 0.0f));
113
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 positions.emplace_back(Vec3f(0.0f, 0.0f, 0.0f));
114
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 positions.emplace_back(Vec3f(0.0f, 0.0f, 0.0f));
115
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 positions.emplace_back(Vec3f(0.0f, 0.0f, 0.0f));
116
117 const double voxelSize = 0.1;
118 math::Transform::Ptr transform =
119
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 math::Transform::createLinearTransform(voxelSize);
120
121 points::PointDataGrid::Ptr points =
122 points::createPointDataGrid<points::NullCodec,
123
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 points::PointDataGrid>(positions, *transform);
124
125 points::PointDataTree& tree = points->tree();
126
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 points::appendGroup(tree, "test");
127
128
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 auto groupHandle = tree.beginLeaf()->groupWriteHandle("test");
129
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 groupHandle.set(0, true);
130
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 groupHandle.set(1, false);
131
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 groupHandle.set(2, true);
132
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 groupHandle.set(3, false);
133
134
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Int32Tree::Ptr intTree(new Int32Tree);
135
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 intTree->setValueOn(Coord(0,0,0));
136
137 CountPointsTransferScheme transfer(*intTree);
138
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 points::GroupFilter filter("test", tree.cbeginLeaf()->attributeSet());
139
140
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 points::rasterize(*points, transfer, filter);
141 1 const int count = intTree->getValue(Coord(0,0,0));
142
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(2, count);
143 1 }
144
145
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 TEST_F(TestPointRasterize, testRasterizeWithInitializeAndFinalize)
146 {
147 struct LinearFunctionPointCountTransferScheme
148 : public DefaultTransfer
149 , public points::VolumeTransfer<Int32Tree>
150 {
151 LinearFunctionPointCountTransferScheme(Int32Tree& tree) :
152 points::VolumeTransfer<Int32Tree>(&tree) {}
153
154 inline Int32 range(const Coord&, size_t) const { return 0; }
155
156 1 inline void initialize(const Coord& c, size_t i, const CoordBBox& b)
157 {
158 1 this->points::VolumeTransfer<Int32Tree>::initialize(c,i,b);
159 auto* const data = this->template buffer<0>();
160 const auto& mask = *(this->template mask<0>());
161
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
3 for (auto iter = mask.beginOn(); iter; ++iter) {
162 1 data[iter.pos()] += 10;
163 }
164 1 }
165
166 1 inline bool finalize(const Coord&, size_t)
167 {
168 auto* const data = this->template buffer<0>();
169 const auto& mask = *(this->template mask<0>());
170
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
3 for (auto iter = mask.beginOn(); iter; ++iter) {
171 1 data[iter.pos()] *= 2;
172 }
173 1 return true;
174 }
175
176 inline void rasterizePoint(const Coord& ijk, const Index, const CoordBBox&)
177 {
178 const Index offset = points::PointDataTree::LeafNodeType::coordToOffset(ijk);
179 auto* const data = this->template buffer<0>();
180 4 data[offset] += 1;
181 }
182 };
183
184 std::vector<Vec3f> positions;
185
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 positions.emplace_back(Vec3f(0.0f, 0.0f, 0.0f));
186
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 positions.emplace_back(Vec3f(0.0f, 0.0f, 0.0f));
187
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 positions.emplace_back(Vec3f(0.0f, 0.0f, 0.0f));
188
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 positions.emplace_back(Vec3f(0.0f, 0.0f, 0.0f));
189
190 const double voxelSize = 0.1;
191 math::Transform::Ptr transform =
192
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 math::Transform::createLinearTransform(voxelSize);
193
194 points::PointDataGrid::Ptr points =
195 points::createPointDataGrid<points::NullCodec,
196
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 points::PointDataGrid>(positions, *transform);
197
198
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Int32Tree::Ptr intTree(new Int32Tree);
199
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 intTree->setValueOn(Coord(0,0,0));
200
201 LinearFunctionPointCountTransferScheme transfer(*intTree);
202
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 points::rasterize(*points, transfer);
203
204 1 const int value = intTree->getValue(Coord(0,0,0));
205
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(/*(10+4)*2*/28, value);
206 1 }
207
208
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 TEST_F(TestPointRasterize, tetsSingleTreeRasterize)
209 {
210 struct CountPoints27TransferScheme
211 : public DefaultTransfer
212 , public points::VolumeTransfer<Int32Tree>
213 {
214 CountPoints27TransferScheme(Int32Tree& tree)
215 : points::VolumeTransfer<Int32Tree>(&tree) {}
216
217 /// @brief The maximum lookup range of this transfer scheme in voxels.
218 inline Int32 range(const Coord&, size_t) const { return 1; }
219
220 /// @brief The point stamp function. Each point which contributes to the
221 /// current leaf that the thread has access to will call this function
222 /// exactly once.
223 /// @param ijk The current voxel containing the point being rasterized. May
224 /// not be inside the destination leaf nodes.
225 /// @param id The point index being rasterized
226 /// @param bounds The active bounds of the leaf node(s) being written to.
227 6 void rasterizePoint(const Coord& ijk, const Index, const CoordBBox& bounds)
228 {
229 static const Index DIM = Int32Tree::LeafNodeType::DIM;
230 static const Index LOG2DIM = Int32Tree::LeafNodeType::LOG2DIM;
231
232 6 CoordBBox intersectBox(ijk.offsetBy(-1), ijk.offsetBy(1));
233 6 intersectBox.intersect(bounds);
234 if (intersectBox.empty()) return;
235 auto* const data = this->template buffer<0>();
236 const auto& mask = *(this->template mask<0>());
237
238 // loop over voxels in this leaf which are affected by this point
239
240 const Coord& a(intersectBox.min());
241 const Coord& b(intersectBox.max());
242
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
14 for (Coord c = a; c.x() <= b.x(); ++c.x()) {
243 8 const Index i = ((c.x() & (DIM-1u)) << 2*LOG2DIM);
244
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8 times.
20 for (c.y() = a.y(); c.y() <= b.y(); ++c.y()) {
245 12 const Index j = ((c.y() & (DIM-1u)) << LOG2DIM);
246
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 12 times.
32 for (c.z() = a.z(); c.z() <= b.z(); ++c.z()) {
247 assert(bounds.isInside(c));
248 20 const Index offset = i + j + /*k*/(c.z() & (DIM-1u));
249
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 8 times.
20 if (!mask.isOn(offset)) continue;
250 8 data[offset] += 1;
251
252 }
253 }
254 }
255 }
256 };
257
258 std::vector<Vec3f> positions;
259
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 positions.emplace_back(Vec3f(0.0f, 0.0f, 0.0f));
260
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 positions.emplace_back(Vec3f(0.1f, 0.1f, 0.1f));
261
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 positions.emplace_back(Vec3f(0.2f, 0.2f, 0.2f));
262
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 positions.emplace_back(Vec3f(-0.1f,-0.1f,-0.1f));
263
264 const double voxelSize = 0.1;
265 math::Transform::Ptr transform =
266
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 math::Transform::createLinearTransform(voxelSize);
267
268 points::PointDataGrid::Ptr points =
269 points::createPointDataGrid<points::NullCodec,
270
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 points::PointDataGrid>(positions, *transform);
271
272
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Int32Tree::Ptr intTree(new Int32Tree);
273
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 intTree->setValueOn(Coord(0,0,0));
274
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 intTree->setValueOn(Coord(1,1,1));
275
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 intTree->setValueOn(Coord(-1,-1,-1));
276
277 CountPoints27TransferScheme transfer(*intTree);
278
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 points::rasterize(*points, transfer);
279
280 1 int count = intTree->getValue(Coord(0,0,0));
281
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, count);
282 1 count = intTree->getValue(Coord(1,1,1));
283
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, count);
284 1 count = intTree->getValue(Coord(-1,-1,-1));
285
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(2, count);
286 1 }
287
288
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 TEST_F(TestPointRasterize, testMultiTreeRasterize)
289 {
290 /// @brief An example multi tree transfer scheme which rasterizes a vector
291 /// attribute into an int grid using length, and an int attribute
292 /// into a vector grid. Based on a 27 lookup stencil.
293 ///
294 struct MultiTransferScheme
295 : public DefaultTransfer
296 , public points::VolumeTransfer<Int32Tree, Vec3DTree>
297 {
298 using BaseT = points::VolumeTransfer<Int32Tree, Vec3DTree>;
299
300 MultiTransferScheme(const size_t vIdx,const size_t iIdx,
301 Int32Tree& t1, Vec3DTree& t2)
302 1 : BaseT(t1, t2)
303 , mVIdx(vIdx), mIIdx(iIdx)
304
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 , mVHandle(), mIHandle() {}
305
306 MultiTransferScheme(const MultiTransferScheme& other)
307 2 : BaseT(other), mVIdx(other.mVIdx), mIIdx(other.mIIdx)
308 1 , mVHandle(), mIHandle() {}
309
310 inline Int32 range(const Coord&, size_t) const { return 1; }
311
312 1 inline bool startPointLeaf(const points::PointDataTree::LeafNodeType& leaf)
313 {
314 1 mVHandle = points::AttributeHandle<Vec3d>::create(leaf.constAttributeArray(mVIdx));
315 1 mIHandle = points::AttributeHandle<int>::create(leaf.constAttributeArray(mIIdx));
316 1 return true;
317 }
318
319 1 void rasterizePoint(const Coord& ijk, const Index id, const CoordBBox& bounds)
320 {
321 static const Index DIM = Int32Tree::LeafNodeType::DIM;
322 static const Index LOG2DIM = Int32Tree::LeafNodeType::LOG2DIM;
323
324 1 CoordBBox intersectBox(ijk.offsetBy(-1), ijk.offsetBy(1));
325 1 intersectBox.intersect(bounds);
326 if (intersectBox.empty()) return;
327
328 auto* const data1 = this->template buffer<0>();
329 auto* const data2 = this->template buffer<1>();
330 const auto& mask = *(this->template mask<0>());
331
332 // loop over voxels in this leaf which are affected by this point
333 1 const Vec3d& vec = mVHandle->get(id);
334 1 const int integer = mIHandle->get(id);
335
336 const Coord& a(intersectBox.min());
337 const Coord& b(intersectBox.max());
338
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for (Coord c = a; c.x() <= b.x(); ++c.x()) {
339 1 const Index i = ((c.x() & (DIM-1u)) << 2*LOG2DIM);
340
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for (c.y() = a.y(); c.y() <= b.y(); ++c.y()) {
341 1 const Index j = ((c.y() & (DIM-1u)) << LOG2DIM);
342
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for (c.z() = a.z(); c.z() <= b.z(); ++c.z()) {
343 assert(bounds.isInside(c));
344 1 const Index offset = i + j + /*k*/(c.z() & (DIM-1u));
345
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (!mask.isOn(offset)) continue;
346 1 data1[offset] += static_cast<int>(vec.length());
347 1 data2[offset] += Vec3d(integer);
348 }
349 }
350 }
351 }
352
353 private:
354 const size_t mVIdx;
355 const size_t mIIdx;
356 points::AttributeHandle<Vec3d>::Ptr mVHandle;
357 points::AttributeHandle<int>::Ptr mIHandle;
358 };
359
360 std::vector<Vec3f> positions;
361
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 positions.emplace_back(Vec3f(0.0f, 0.0f, 0.0f));
362
363 const double voxelSize = 0.1;
364 math::Transform::Ptr transform =
365
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 math::Transform::createLinearTransform(voxelSize);
366
367 points::PointDataGrid::Ptr points =
368 points::createPointDataGrid<points::NullCodec,
369
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 points::PointDataGrid>(positions, *transform);
370
371 points::PointDataTree& tree = points->tree();
372
373 const Vec3d vectorValue(444.0f,555.0f,666.0f);
374
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 points::appendAttribute<Vec3d>(tree, "testVec3d", vectorValue);
375
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 points::appendAttribute<int>(tree, "testInt", 7);
376
377
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Vec3DTree::Ptr vecTree(new Vec3DTree);
378
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Int32Tree::Ptr intTree(new Int32Tree);
379 vecTree->topologyUnion(tree);
380 intTree->topologyUnion(tree);
381
382
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 const points::PointDataTree::LeafNodeType& leaf = *(tree.cbeginLeaf());
383
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 const size_t vidx = leaf.attributeSet().descriptor().find("testVec3d");
384
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 const size_t iidx = leaf.attributeSet().descriptor().find("testInt");
385
386 1 MultiTransferScheme transfer(vidx, iidx, *intTree, *vecTree);
387
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 points::rasterize(*points, transfer);
388
389
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 const Vec3d vecResult = vecTree->getValue(Coord(0,0,0));
390
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 const int intResult = intTree->getValue(Coord(0,0,0));
391
392
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(7.0, vecResult[0]);
393
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(7.0, vecResult[1]);
394
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(7.0, vecResult[2]);
395
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 const int expected = static_cast<int>(vectorValue.length());
396
1/14
✗ 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 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
1 EXPECT_EQ(expected, intResult);
397 1 }
398
399
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 TEST_F(TestPointRasterize, testMultiTreeRasterizeWithMask)
400 {
401 1 struct CountPointsMaskTransferScheme
402 : public DefaultTransfer
403 , public points::VolumeTransfer<BoolTree, Int32Tree>
404 {
405 using BaseT = points::VolumeTransfer<BoolTree, Int32Tree>;
406 CountPointsMaskTransferScheme(BoolTree& t1, Int32Tree& t2)
407 : BaseT(t1, t2) {}
408
409 inline Int32 range(const Coord&, size_t) const { return 0; }
410 inline void rasterizePoint(const Coord& ijk, const Index, const CoordBBox&)
411 {
412 auto* const data = this->template buffer<1>();
413 const Index offset = points::PointDataTree::LeafNodeType::coordToOffset(ijk);
414 1 data[offset] += 1;
415 }
416 };
417
418 // Setup test data
419 std::vector<Vec3f> positions;
420
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 positions.emplace_back(Vec3f(0.0f, 0.0f, 0.0f));
421
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1 positions.emplace_back(Vec3f(1.0f, 1.0f, 1.0f));
422
423 const double voxelSize = 0.1;
424 math::Transform::Ptr transform =
425
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 math::Transform::createLinearTransform(voxelSize);
426
427 points::PointDataGrid::Ptr points =
428 points::createPointDataGrid<points::NullCodec,
429
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 points::PointDataGrid>(positions, *transform);
430
431
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Int32Tree::Ptr intTree(new Int32Tree);
432
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 BoolTree::Ptr topology(new BoolTree);
433 intTree->topologyUnion(points->tree());
434 1 topology->setValueOn(Coord(0,0,0));
435
436
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(intTree->isValueOn(Coord(10,10,10)));
437
438 CountPointsMaskTransferScheme transfer(*topology, *intTree);
439
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 points::rasterize(*points, transfer);
440
441 1 int count = intTree->getValue(Coord(0,0,0));
442
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, count);
443 1 count = intTree->getValue(Coord(10,10,10));
444
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(0, count);
445 1 }
446
447 // void
448 // TestPointRasterize::testMultiTreeRasterizeConstTopology()
449 // {
450 // // Test const-ness is respected and works at compile time through
451 // // the points::rasterize function (transfer function signatures should
452 // // respect the const flag of the topology mask leaf nodes)
453
454 // struct CountPointsConstMaskTransferScheme
455 // : public DefaultTransfer,
456 // : public points::VolumeTransfer<const BoolTree, Int32Tree>
457 // {
458 // using VolumeTransferT =
459 // points::rasterize_tree_containers::MultiTreeRasterizer
460 // <const BoolTree, Int32Tree>;
461
462 // using BufferT = VolumeTransferT::BufferT;
463 // using NodeMaskT = VolumeTransferT::NodeMaskT;
464
465 // static_assert(std::is_const<NodeMaskT>::value,
466 // "Node mask should be const");
467 // static_assert(std::is_const<VolumeTransferT::TopologyTreeT>::value,
468 // "TopologyTreeT should be const");
469
470 // inline Int32 range() const { return 0; }
471 // inline void initialize(BufferT, NodeMaskT&, const Coord&) {}
472 // inline void initLeaf(const points::PointDataTree::LeafNodeType&) {}
473 // inline void finalize(BufferT, NodeMaskT&, const Coord&) {}
474 // inline void rasterizePoint(const Coord&,
475 // const Index,
476 // const CoordBBox&,
477 // BufferT,
478 // NodeMaskT&) {}
479 // };
480
481 // points::PointDataTree tree;
482 // Int32Tree::Ptr intTree(new Int32Tree);
483 // BoolTree::Ptr topology(new BoolTree);
484
485 // CountPointsConstMaskTransferScheme transfer;
486 // CountPointsConstMaskTransferScheme::VolumeTransferT::TreeArrayT array = {intTree};
487 // CountPointsConstMaskTransferScheme::VolumeTransferT container(*topology, array);
488 // points::rasterize(tree, transfer, container);
489 // }
490