GCC Code Coverage Report


Directory: ./
File: openvdb/openvdb/points/impl/PointRasterizeTrilinearImpl.h
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 103 112 92.0%
Functions: 34 136 25.0%
Branches: 130 366 35.5%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 //
4 /// @author Nick Avramoussis
5 ///
6 /// @file PointRasterizeTrilinearImpl.h
7 ///
8
9 #ifndef OPENVDB_POINTS_RASTERIZE_TRILINEAR_IMPL_HAS_BEEN_INCLUDED
10 #define OPENVDB_POINTS_RASTERIZE_TRILINEAR_IMPL_HAS_BEEN_INCLUDED
11
12 namespace openvdb {
13 OPENVDB_USE_VERSION_NAMESPACE
14 namespace OPENVDB_VERSION_NAME {
15 namespace points {
16
17 /// @cond OPENVDB_DOCS_INTERNAL
18
19 namespace rasterize_trilinear_internal {
20
21 template <typename TreeType,
22 typename PositionCodecT,
23 typename SourceValueT,
24 typename SourceCodecT>
25 struct TrilinearTransfer : public VolumeTransfer<TreeType>
26 {
27 using BaseT = VolumeTransfer<TreeType>;
28 using WeightT = typename TreeType::ValueType;
29 using PositionHandleT = points::AttributeHandle<Vec3f, PositionCodecT>;
30 using SourceHandleT = points::AttributeHandle<SourceValueT, SourceCodecT>;
31
32 // precision of kernel arithmetic - aliased to the floating point
33 // element type of the source attribute.
34 using SourceElementT = typename ValueTraits<SourceValueT>::ElementType;
35 using RealT = SourceElementT;
36
37 static_assert(std::is_floating_point<SourceElementT>::value,
38 "Trilinear rasterization only supports floating point values.");
39
40 static const Index NUM_VALUES = TreeType::LeafNodeType::NUM_VALUES;
41
42
8/64
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✓ Branch 58 taken 1 times.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✓ Branch 70 taken 1 times.
✗ Branch 71 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✓ Branch 82 taken 1 times.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✓ Branch 94 taken 1 times.
✗ Branch 95 not taken.
8 TrilinearTransfer(const size_t pidx,
43 const size_t sidx, TreeType& tree)
44 : BaseT(tree)
45 , mPIdx(pidx)
46 , mSIdx(sidx)
47 , mPHandle()
48 , mSHandle()
49
8/64
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✓ Branch 58 taken 1 times.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✓ Branch 70 taken 1 times.
✗ Branch 71 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✓ Branch 82 taken 1 times.
✗ Branch 83 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✓ Branch 94 taken 1 times.
✗ Branch 95 not taken.
8 , mWeights() {}
50
51 8 TrilinearTransfer(const TrilinearTransfer& other)
52 : BaseT(other)
53 8 , mPIdx(other.mPIdx)
54 8 , mSIdx(other.mSIdx)
55 , mPHandle()
56 , mSHandle()
57 8 , mWeights() {}
58
59 //// @note Kernel value evaluator
60 static inline RealT value(const RealT x)
61 {
62 256 const RealT abs_x = std::fabs(x);
63
36/144
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 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.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✓ Branch 36 taken 4 times.
✓ Branch 37 taken 8 times.
✓ Branch 38 taken 8 times.
✓ Branch 39 taken 4 times.
✓ Branch 40 taken 6 times.
✓ Branch 41 taken 12 times.
✓ Branch 42 taken 12 times.
✓ Branch 43 taken 6 times.
✓ Branch 44 taken 9 times.
✓ Branch 45 taken 18 times.
✓ Branch 46 taken 18 times.
✓ Branch 47 taken 9 times.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✓ Branch 66 taken 1 times.
✓ Branch 67 taken 1 times.
✓ Branch 68 taken 2 times.
✓ Branch 69 taken 2 times.
✓ Branch 70 taken 4 times.
✓ Branch 71 taken 4 times.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✓ Branch 108 taken 4 times.
✓ Branch 109 taken 8 times.
✓ Branch 110 taken 8 times.
✓ Branch 111 taken 4 times.
✓ Branch 112 taken 6 times.
✓ Branch 113 taken 12 times.
✓ Branch 114 taken 12 times.
✓ Branch 115 taken 6 times.
✓ Branch 116 taken 9 times.
✓ Branch 117 taken 18 times.
✓ Branch 118 taken 18 times.
✓ Branch 119 taken 9 times.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 135 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✓ Branch 138 taken 1 times.
✓ Branch 139 taken 1 times.
✓ Branch 140 taken 2 times.
✓ Branch 141 taken 2 times.
✓ Branch 142 taken 4 times.
✓ Branch 143 taken 4 times.
270 if (abs_x < RealT(1.0)) return RealT(1.0) - abs_x;
64 return RealT(0.0);
65 }
66
67 inline static Int32 range() { return 1; }
68 inline Int32 range(const Coord&, size_t) const { return this->range(); }
69
70 96 inline void initialize(const Coord& origin, const size_t idx, const CoordBBox& bounds)
71 {
72 112 this->BaseT::initialize(origin, idx, bounds);
73 96 mWeights.fill(openvdb::zeroVal<WeightT>());
74 }
75
76 128 inline bool startPointLeaf(const PointDataTree::LeafNodeType& leaf)
77 {
78
1/2
✓ Branch 3 taken 64 times.
✗ Branch 4 not taken.
128 mPHandle.reset(new PositionHandleT(leaf.constAttributeArray(mPIdx)));
79
1/2
✓ Branch 3 taken 64 times.
✗ Branch 4 not taken.
128 mSHandle.reset(new SourceHandleT(leaf.constAttributeArray(mSIdx)));
80 128 return true;
81 }
82
83 inline bool endPointLeaf(const PointDataTree::LeafNodeType&) { return true; }
84
85 protected:
86 const size_t mPIdx;
87 const size_t mSIdx;
88 typename PositionHandleT::UniquePtr mPHandle;
89 typename SourceHandleT::UniquePtr mSHandle;
90 std::array<WeightT, NUM_VALUES> mWeights;
91 };
92
93 template <typename TreeType,
94 typename PositionCodecT,
95 typename SourceValueT,
96 typename SourceCodecT>
97 4 struct StaggeredTransfer :
98 public TrilinearTransfer<TreeType, PositionCodecT, SourceValueT, SourceCodecT>
99 {
100 using BaseT = TrilinearTransfer<TreeType, PositionCodecT, SourceValueT, SourceCodecT>;
101 using RealT = typename BaseT::RealT;
102 using BaseT::value;
103
104 static_assert(VecTraits<typename TreeType::ValueType>::IsVec,
105 "Target Tree must be a vector tree for staggered rasterization");
106
107 static const Index DIM = TreeType::LeafNodeType::DIM;
108 static const Index LOG2DIM = TreeType::LeafNodeType::LOG2DIM;
109
110 StaggeredTransfer(const size_t pidx,
111 const size_t sidx, TreeType& tree)
112 : BaseT(pidx, sidx, tree) {}
113
114 64 void rasterizePoint(const Coord& ijk,
115 const Index id,
116 const CoordBBox& bounds)
117 {
118 64 CoordBBox intersectBox(ijk.offsetBy(-1), ijk.offsetBy(1));
119 64 intersectBox.intersect(bounds);
120 if (intersectBox.empty()) return;
121
122 auto* const data = this->buffer();
123 const auto& mask = *(this->mask());
124
125 64 const math::Vec3<RealT> P(this->mPHandle->get(id));
126 64 const SourceValueT s(this->mSHandle->get(id));
127
128 math::Vec3<RealT> centerw, macw;
129
130 const Coord& a(intersectBox.min());
131 const Coord& b(intersectBox.max());
132
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 32 times.
160 for (Coord c = a; c.x() <= b.x(); ++c.x()) {
133 // @todo can probably simplify the double call to value() in some way
134
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 32 times.
96 const Index i = ((c.x() & (DIM-1u)) << 2*LOG2DIM); // unsigned bit shift mult
135
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 16 times.
96 const RealT x = static_cast<RealT>(c.x()-ijk.x()); // distance from ijk to c
136
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 32 times.
96 centerw[0] = value(P.x() - x); // center dist
137
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
96 macw.x() = value(P.x() - (x-RealT(0.5))); // mac dist
138
139
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 48 times.
240 for (c.y() = a.y(); c.y() <= b.y(); ++c.y()) {
140
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 48 times.
144 const Index ij = i + ((c.y() & (DIM-1u)) << LOG2DIM);
141
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
144 const RealT y = static_cast<RealT>(c.y()-ijk.y());
142
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 48 times.
144 centerw[1] = value(P.y() - y);
143
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 24 times.
144 macw.y() = value(P.y() - (y-RealT(0.5)));
144
145
2/2
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 72 times.
360 for (c.z() = a.z(); c.z() <= b.z(); ++c.z()) {
146 assert(bounds.isInside(c));
147 216 const Index offset = ij + /*k*/(c.z() & (DIM-1u));
148
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 108 times.
216 if (!mask.isOn(offset)) continue;
149
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 36 times.
216 const RealT z = static_cast<RealT>(c.z()-ijk.z());
150
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 72 times.
216 centerw[2] = value(P.z() - z);
151
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 36 times.
216 macw.z() = value(P.z() - (z-RealT(0.5)));
152
153 216 const math::Vec3<RealT> r {
154 216 (macw[0] * centerw[1] * centerw[2]),
155 216 (macw[1] * centerw[0] * centerw[2]),
156 216 (macw[2] * centerw[0] * centerw[1])
157 };
158
159 216 data[offset] += s * r;
160 this->mWeights[offset] += r;
161 }
162 }
163 }
164 }
165
166 64 inline bool finalize(const Coord&, const size_t)
167 {
168 auto* const data = this->buffer();
169 const auto& mask = *(this->mask());
170
171
2/2
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 32 times.
344 for (auto iter = mask.beginOn(); iter; ++iter) {
172 const Index offset = iter.pos();
173 216 const auto& w = this->mWeights[offset];
174
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 100 times.
216 auto& v = data[offset];
175
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 100 times.
216 if (!math::isZero(w[0])) v[0] /= w[0];
176
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 100 times.
216 if (!math::isZero(w[1])) v[1] /= w[1];
177
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 100 times.
216 if (!math::isZero(w[2])) v[2] /= w[2];
178 }
179
180 64 return true;
181 }
182 };
183
184 template <typename TreeType,
185 typename PositionCodecT,
186 typename SourceValueT,
187 typename SourceCodecT>
188 4 struct CellCenteredTransfer :
189 public TrilinearTransfer<TreeType, PositionCodecT, SourceValueT, SourceCodecT>
190 {
191 using BaseT = TrilinearTransfer<TreeType, PositionCodecT, SourceValueT, SourceCodecT>;
192 using RealT = typename BaseT::RealT;
193 using BaseT::value;
194
195 static const Index DIM = TreeType::LeafNodeType::DIM;
196 static const Index LOG2DIM = TreeType::LeafNodeType::LOG2DIM;
197
198 CellCenteredTransfer(const size_t pidx,
199 const size_t sidx, TreeType& tree)
200 : BaseT(pidx, sidx, tree) {}
201
202 64 void rasterizePoint(const Coord& ijk,
203 const Index id,
204 const CoordBBox& bounds)
205 {
206 64 const Vec3f P(this->mPHandle->get(id));
207
208 // build area of influence depending on point position
209 CoordBBox intersectBox(ijk, ijk);
210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
64 if (P.x() < 0.0f) intersectBox.min().x() -= 1;
211 64 else intersectBox.max().x() += 1;
212
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
64 if (P.y() < 0.0f) intersectBox.min().y() -= 1;
213 64 else intersectBox.max().y() += 1;
214
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
64 if (P.z() < 0.0f) intersectBox.min().z() -= 1;
215 64 else intersectBox.max().z() += 1;
216
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
64 assert(intersectBox.volume() == 8);
217
218 64 intersectBox.intersect(bounds);
219 56 if (intersectBox.empty()) return;
220
221 auto* const data = this->buffer();
222 const auto& mask = *(this->mask());
223
224 8 const SourceValueT s(this->mSHandle->get(id));
225 math::Vec3<RealT> centerw;
226
227 const Coord& a(intersectBox.min());
228 const Coord& b(intersectBox.max());
229
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
24 for (Coord c = a; c.x() <= b.x(); ++c.x()) {
230
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
16 const Index i = ((c.x() & (DIM-1u)) << 2*LOG2DIM); // unsigned bit shift mult
231 16 const RealT x = static_cast<RealT>(c.x()-ijk.x()); // distance from ijk to c
232
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
16 centerw[0] = value(P.x() - x); // center dist
233
234
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
48 for (c.y() = a.y(); c.y() <= b.y(); ++c.y()) {
235
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
32 const Index ij = i + ((c.y() & (DIM-1u)) << LOG2DIM);
236 32 const RealT y = static_cast<RealT>(c.y()-ijk.y());
237
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
32 centerw[1] = value(P.y() - y);
238
239
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
96 for (c.z() = a.z(); c.z() <= b.z(); ++c.z()) {
240 assert(bounds.isInside(c));
241 64 const Index offset = ij + /*k*/(c.z() & (DIM-1u));
242
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
64 if (!mask.isOn(offset)) continue;
243 64 const RealT z = static_cast<RealT>(c.z()-ijk.z());
244
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
64 centerw[2] = value(P.z() - z);
245
246
2/4
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 32 times.
64 assert(centerw[0] >= 0.0f && centerw[0] <= 1.0f);
247
2/4
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 32 times.
64 assert(centerw[1] >= 0.0f && centerw[1] <= 1.0f);
248
2/4
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 32 times.
64 assert(centerw[2] >= 0.0f && centerw[2] <= 1.0f);
249
250 const RealT weight = centerw.product();
251 64 data[offset] += s * weight;
252 32 this->mWeights[offset] += weight;
253 }
254 }
255 }
256 }
257
258 64 inline bool finalize(const Coord&, const size_t)
259 {
260 auto* const data = this->buffer();
261 const auto& mask = *(this->mask());
262
263
2/2
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 32 times.
344 for (auto iter = mask.beginOn(); iter; ++iter) {
264 const Index offset = iter.pos();
265
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 2 times.
216 const auto& w = this->mWeights[offset];
266
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 54 times.
216 auto& v = data[offset];
267
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 52 times.
108 if (!math::isZero(w)) v /= w;
268 }
269 64 return true;
270 }
271 };
272
273 // @note If building with MSVC we have to use auto to deduce the return type
274 // due to a compiler bug. We can also use that for the public API - but
275 // we explicitly define it in non-msvc builds to ensure the API remains
276 // consistent
277 template <bool Staggered,
278 typename ValueT,
279 typename CodecT,
280 typename PositionCodecT,
281 typename FilterT,
282 typename PointDataTreeT>
283 inline
284 #ifndef _MSC_VER
285 typename TrilinearTraits<ValueT, Staggered>::template TreeT<PointDataTreeT>::Ptr
286 #else
287 auto
288 #endif
289 16 rasterizeTrilinear(const PointDataTreeT& points,
290 const size_t pidx,
291 const size_t sidx,
292 const FilterT& filter)
293 {
294 using TraitsT = TrilinearTraits<ValueT, Staggered>;
295 using TargetTreeT = typename TraitsT::template TreeT<PointDataTree>;
296 using TransferT = typename std::conditional<Staggered,
297 StaggeredTransfer<TargetTreeT, PositionCodecT, ValueT, CodecT>,
298 CellCenteredTransfer<TargetTreeT, PositionCodecT, ValueT, CodecT>
299 >::type;
300
301 16 typename TargetTreeT::Ptr tree(new TargetTreeT);
302 if (std::is_same<FilterT, NullFilter>::value) {
303 tree->topologyUnion(points);
304 }
305 else {
306 using MaskTreeT = typename PointDataTreeT::template ValueConverter<ValueMask>::Type;
307 auto mask = convertPointsToMask<PointDataTreeT, MaskTreeT>(points, filter);
308 tree->topologyUnion(*mask);
309 }
310
311 TransferT transfer(pidx, sidx, *tree);
312
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 tools::dilateActiveValues(*tree, transfer.range(),
313 tools::NN_FACE_EDGE_VERTEX, tools::EXPAND_TILES);
314
315
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 rasterize<PointDataTreeT, TransferT>(points, transfer, filter);
316 16 return tree;
317 }
318
319 } // namespace rasterize_trilinear_internal
320
321 /// @endcond
322
323 ///////////////////////////////////////////////////
324
325 template <bool Staggered,
326 typename ValueT,
327 typename FilterT,
328 typename PointDataTreeT>
329 inline auto
330 8 rasterizeTrilinear(const PointDataTreeT& points,
331 const std::string& attribute,
332 const FilterT& filter)
333 {
334 using TraitsT = TrilinearTraits<ValueT, Staggered>;
335 using TargetTreeT = typename TraitsT::template TreeT<PointDataTree>;
336
337 const auto iter = points.cbeginLeaf();
338 8 if (!iter) return typename TargetTreeT::Ptr(new TargetTreeT);
339
340 const AttributeSet::Descriptor& descriptor = iter->attributeSet().descriptor();
341 8 const size_t pidx = descriptor.find("P");
342 8 const size_t sidx = descriptor.find(attribute);
343 8 if (pidx == AttributeSet::INVALID_POS) {
344 OPENVDB_THROW(RuntimeError, "Failed to find position attribute");
345 }
346 8 if (sidx == AttributeSet::INVALID_POS) {
347 OPENVDB_THROW(RuntimeError, "Failed to find source attribute");
348 }
349
350 8 const NamePair& ptype = descriptor.type(pidx);
351 8 const NamePair& stype = descriptor.type(sidx);
352 8 if (ptype.second == NullCodec::name()) {
353 8 if (stype.second == NullCodec::name()) {
354 return rasterize_trilinear_internal::rasterizeTrilinear
355 <Staggered, ValueT, NullCodec, NullCodec>
356 8 (points, pidx, sidx, filter);
357 }
358 else {
359 return rasterize_trilinear_internal::rasterizeTrilinear
360 <Staggered, ValueT, UnknownCodec, NullCodec>
361 (points, pidx, sidx, filter);
362 }
363 }
364 else {
365 if (stype.second == NullCodec::name()) {
366 return rasterize_trilinear_internal::rasterizeTrilinear
367 <Staggered, ValueT, NullCodec, UnknownCodec>
368 (points, pidx, sidx, filter);
369 }
370 else {
371 return rasterize_trilinear_internal::rasterizeTrilinear
372 <Staggered, ValueT, UnknownCodec, UnknownCodec>
373 (points, pidx, sidx, filter);
374 }
375 }
376 }
377
378
379 } // namespace points
380 } // namespace OPENVDB_VERSION_NAME
381 } // namespace openvdb
382
383 #endif //OPENVDB_POINTS_RASTERIZE_TRILINEAR_IMPL_HAS_BEEN_INCLUDED
384