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 |