OpenVDB: PointMask.h Source File

OpenVDB 5.1.0

PointMask.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2018 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30
36
37 #ifndef OPENVDB_POINTS_POINT_MASK_HAS_BEEN_INCLUDED
38 #define OPENVDB_POINTS_POINT_MASK_HAS_BEEN_INCLUDED
39
40 #include <openvdb/openvdb.h>
41 #include <openvdb/tools/ValueTransformer.h> // valxform::SumOp
42
43 #include "PointDataGrid.h"
44 #include "IndexFilter.h"
45
46 #include <tbb/combinable.h>
47
48 #include <type_traits>
49 #include <vector>
50
51
52 namespace openvdb {
53 OPENVDB_USE_VERSION_NAMESPACE
54 namespace OPENVDB_VERSION_NAME {
55 namespace points {
56
57
63 template <typename PointDataGridT,
64 typename MaskT = typename PointDataGridT::template ValueConverter<bool>::Type>
65 inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
66 typename MaskT::Ptr>::type
67 convertPointsToMask(const PointDataGridT& grid,
68 const std::vector<Name>& includeGroups = std::vector<Name>(),
69 const std::vector<Name>& excludeGroups = std::vector<Name>());
70
71
78 template <typename PointDataGridT,
79 typename MaskT = typename PointDataGridT::template ValueConverter<bool>::Type>
80 inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
81 typename MaskT::Ptr>::type
82 convertPointsToMask(const PointDataGridT& grid,
83 const openvdb::math::Transform& transform,
84 const std::vector<Name>& includeGroups = std::vector<Name>(),
85 const std::vector<Name>& excludeGroups = std::vector<Name>());
86
87
89
90
91 namespace point_mask_internal {
92
95 template<typename GridT>
96 struct GridCombinerOp
97 {
98 using CombinableT = typename tbb::combinable<GridT>;
99
100 using TreeT = typename GridT::TreeType;
101 using LeafT = typename TreeT::LeafNodeType;
102 using ValueType = typename TreeT::ValueType;
103 using SumOp = tools::valxform::SumOp<typename TreeT::ValueType>;
104
105 GridCombinerOp(GridT& grid)
106 : mTree(grid.tree()) {}
107
108 void operator()(const GridT& grid)
109 {
110 for (auto leaf = grid.tree().beginLeaf(); leaf; ++leaf) {
111 auto* newLeaf = mTree.probeLeaf(leaf->origin());
112 if (!newLeaf) {
113 // if the leaf doesn't yet exist in the new tree, steal it
114 auto& tree = const_cast<GridT&>(grid).tree();
115 mTree.addLeaf(tree.template stealNode<LeafT>(leaf->origin(),
116 zeroVal<ValueType>(), false));
117 }
118 else {
119 // otherwise increment existing values
120 for (auto iter = leaf->cbeginValueOn(); iter; ++iter) {
121 newLeaf->modifyValue(iter.getCoord(), SumOp(*iter));
122 }
123 }
124 }
125 }
126
127 private:
128 TreeT& mTree;
129 }; // struct GridCombinerOp
130
131
133 template <typename GridT, typename PointDataGridT, typename FilterT>
134 struct PointsToScalarOp
135 {
136 using TreeT = typename GridT::TreeType;
137 using LeafManagerT = typename tree::LeafManager<TreeT>;
138 using ValueT = typename TreeT::LeafNodeType::ValueType;
139
140 PointsToScalarOp(const PointDataGridT& grid,
141 const FilterT& filter)
142 : mPointDataAccessor(grid.getConstAccessor())
143 , mFilter(filter) { }
144
145 void operator()(const typename LeafManagerT::LeafRange& range) const {
146
147 for (auto leaf = range.begin(); leaf; ++leaf) {
148
149 const auto* const pointLeaf =
150 mPointDataAccessor.probeConstLeaf(leaf->origin());
151
152 // assumes matching topology
153 assert(pointLeaf);
154
155 for (auto value = leaf->beginValueOn(); value; ++value) {
156 const Index64 count = points::iterCount(
157 pointLeaf->beginIndexVoxel(value.getCoord(), mFilter));
158 if (count > Index64(0)) {
159 value.setValue(static_cast<ValueT>(count));}
160 else {
161 // disable any empty voxels
162 value.setValueOn(false);
163 }
164 }
165 }
166 }
167
168 private:
169 const typename PointDataGridT::ConstAccessor mPointDataAccessor;
170 const FilterT& mFilter;
171 }; // struct PointsToScalarOp
172
173
176 template <typename GridT, typename PointDataGridT, typename FilterT>
177 struct PointsToTransformedScalarOp
178 {
179 using LeafManagerT = tree::LeafManager<const typename PointDataGridT::TreeType>;
180 using ValueType = typename GridT::TreeType::LeafNodeType::ValueType;
181 using HandleT = AttributeHandle<Vec3f>;
182 using CombinableT = typename GridCombinerOp<GridT>::CombinableT;
183
184 PointsToTransformedScalarOp(const math::Transform& newTransform,
185 const math::Transform& transform,
186 const FilterT& filter,
187 CombinableT& combinable)
188 : mNewTransform(newTransform)
189 , mTransform(transform)
190 , mFilter(filter)
191 , mCombinable(combinable) { }
192
193 void operator()(const typename LeafManagerT::LeafRange& range) const
194 {
195 auto& grid = mCombinable.local();
196 auto& countTree = grid.tree();
197 tree::ValueAccessor<typename GridT::TreeType> accessor(countTree);
198
199 for (auto leaf = range.begin(); leaf; ++leaf) {
200
201 auto handle = HandleT::create(leaf->constAttributeArray("P"));
202
203 for (auto iter = leaf->beginIndexOn(mFilter); iter; iter++) {
204 const Vec3d position = mTransform.indexToWorld(handle->get(*iter) +
205 iter.getCoord().asVec3d());
206 const Coord ijk = mNewTransform.worldToIndexCellCentered(position);
207
208 accessor.modifyValue(ijk, tools::valxform::SumOp<ValueType>(1));
209 }
210 }
211 }
212
213 private:
214 const openvdb::math::Transform& mNewTransform;
215 const openvdb::math::Transform& mTransform;
216 const FilterT& mFilter;
217 CombinableT& mCombinable;
218 }; // struct PointsToTransformedScalarOp
219
220
221 template<typename PointDataGridT, typename GridT>
222 inline typename GridT::Ptr convertPointsToScalar(
223 const PointDataGridT& points,
224 const std::vector<Name>& includeGroups,
225 const std::vector<Name>& excludeGroups)
226 {
227 using point_mask_internal::PointsToScalarOp;
228
229 using GridTreeT = typename GridT::TreeType;
230 using ValueT = typename GridTreeT::ValueType;
231
232 // copy the topology from the points grid
233
234 typename GridTreeT::Ptr tree(new GridTreeT(points.constTree(),
235 false, openvdb::TopologyCopy()));
236 typename GridT::Ptr grid = GridT::create(tree);
237 grid->setTransform(points.transform().copy());
238
239 // early exit if no leaves
240
241 if (points.constTree().leafCount() == 0) return grid;
242
243 const bool useGroup = !includeGroups.empty() || !excludeGroups.empty();
244
245 // early exit if mask and no group logic
246
247 if (std::is_same<ValueT, bool>::value && !useGroup) return grid;
248
249 // evaluate point group filters to produce a subset of the generated mask
250
251 tree::LeafManager<GridTreeT> leafManager(*tree);
252
253 if (useGroup) {
254 // build mask from points in parallel only where filter evaluates to true
255 const auto leaf = points.constTree().cbeginLeaf();
256 MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
257 PointsToScalarOp<GridT, PointDataGridT, MultiGroupFilter> pointsToScalarOp(
258 points, filter);
259 tbb::parallel_for(leafManager.leafRange(), pointsToScalarOp);
260 }
261 else {
262 NullFilter filter;
263 PointsToScalarOp<GridT, PointDataGridT, NullFilter> pointsToScalarOp(
264 points, filter);
265 tbb::parallel_for(leafManager.leafRange(), pointsToScalarOp);
266 }
267
268 return grid;
269 }
270
271
272 template<typename PointDataGridT, typename GridT>
273 inline typename GridT::Ptr convertPointsToScalar(
274 const PointDataGridT& points,
275 const openvdb::math::Transform& transform,
276 const std::vector<Name>& includeGroups,
277 const std::vector<Name>& excludeGroups)
278 {
279 using point_mask_internal::PointsToTransformedScalarOp;
280 using point_mask_internal::GridCombinerOp;
281
282 using CombinerOpT = GridCombinerOp<GridT>;
283 using CombinableT = typename GridCombinerOp<GridT>::CombinableT;
284
285 // use the simpler method if the requested transform matches the existing one
286
287 const openvdb::math::Transform& pointsTransform = points.constTransform();
288
289 if (transform == pointsTransform) {
290 return convertPointsToScalar<PointDataGridT, GridT>(
291 points, includeGroups, excludeGroups);
292 }
293
294 typename GridT::Ptr grid = GridT::create();
295 grid->setTransform(transform.copy());
296
297 // early exit if no leaves
298
299 if (points.constTree().leafCount() == 0) return grid;
300
301 // compute mask grids in parallel using new transform
302
303 CombinableT combiner;
304
305 tree::LeafManager<const typename PointDataGridT::TreeType> leafManager(points.tree());
306
307 const bool useGroup = !includeGroups.empty() || !excludeGroups.empty();
308
309 if (useGroup) {
310 const auto leaf = points.constTree().cbeginLeaf();
311 MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
312 PointsToTransformedScalarOp<GridT, PointDataGridT, MultiGroupFilter> pointsToScalarOp(
313 transform, pointsTransform, filter, combiner);
314 tbb::parallel_for(leafManager.leafRange(), pointsToScalarOp);
315 }
316 else {
317 NullFilter filter;
318 PointsToTransformedScalarOp<GridT, PointDataGridT, NullFilter> pointsToScalarOp(
319 transform, pointsTransform, filter, combiner);
320 tbb::parallel_for(leafManager.leafRange(), pointsToScalarOp);
321 }
322
323 // combine the mask grids into one
324
325 CombinerOpT combineOp(*grid);
326 combiner.combine_each(combineOp);
327
328 return grid;
329 }
330
331
332 } // namespace point_mask_internal
333
334
336
337
338 template<typename PointDataGridT, typename MaskT>
339 inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
340 typename MaskT::Ptr>::type
341 convertPointsToMask(
342 const PointDataGridT& points,
343 const std::vector<Name>& includeGroups,
344 const std::vector<Name>& excludeGroups)
345 {
346 return point_mask_internal::convertPointsToScalar<PointDataGridT, MaskT>(
347 points, includeGroups, excludeGroups);
348 }
349
350
351 template<typename PointDataGridT, typename MaskT>
352 inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
353 typename MaskT::Ptr>::type
354 convertPointsToMask(
355 const PointDataGridT& points,
356 const openvdb::math::Transform& transform,
357 const std::vector<Name>& includeGroups,
358 const std::vector<Name>& excludeGroups)
359 {
360 return point_mask_internal::convertPointsToScalar<PointDataGridT, MaskT>(
361 points, transform, includeGroups, excludeGroups);
362 }
363
364
366
367
368 } // namespace points
369 } // namespace OPENVDB_VERSION_NAME
370 } // namespace openvdb
371
372 #endif // OPENVDB_POINTS_POINT_MASK_HAS_BEEN_INCLUDED
373
374 // Copyright (c) 2012-2018 DreamWorks Animation LLC
375 // All rights reserved. This software is distributed under the
376 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v5_1::points::MultiGroupFilter
Definition: IndexFilter.h:104
openvdb::v5_1::points::point_mask_internal::GridCombinerOp::TreeT
typename GridT::TreeType TreeT
Definition: PointMask.h:100
openvdb::v5_1::tree::LeafManager::LeafRange::begin
Iterator begin() const
Definition: LeafManager.h:181
openvdb::v5_1::points::point_mask_internal::GridCombinerOp::CombinableT
typename tbb::combinable< GridT > CombinableT
Definition: PointMask.h:98
ValueTransformer.h
openvdb::v5_1::points::point_mask_internal::PointsToTransformedScalarOp::ValueType
typename GridT::TreeType::LeafNodeType::ValueType ValueType
Definition: PointMask.h:180
openvdb::v5_1::points::point_mask_internal::PointsToScalarOp
Compute scalar grid from PointDataGrid while evaluating the point filter.
Definition: PointMask.h:134
openvdb.h
openvdb::v5_1::points::point_mask_internal::PointsToTransformedScalarOp::CombinableT
typename GridCombinerOp< GridT >::CombinableT CombinableT
Definition: PointMask.h:182
openvdb::v5_1::points::point_mask_internal::PointsToScalarOp::TreeT
typename GridT::TreeType TreeT
Definition: PointMask.h:136
openvdb::v5_1::points::AttributeHandle
Definition: AttributeArray.h:644
openvdb::v5_1::tools::valxform::SumOp
Definition: ValueTransformer.h:277
openvdb::v5_1::points::point_mask_internal::GridCombinerOp::ValueType
typename TreeT::ValueType ValueType
Definition: PointMask.h:102
openvdb::v5_1::points::point_mask_internal::GridCombinerOp::operator()
void operator()(const GridT &grid)
Definition: PointMask.h:108
openvdb::v5_1::points::point_mask_internal::PointsToScalarOp::ValueT
typename TreeT::LeafNodeType::ValueType ValueT
Definition: PointMask.h:138
openvdb::v5_1::TopologyCopy
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:515
openvdb::v5_1::tree::LeafManager
This class manages a linear array of pointers to a given tree&#39;s leaf nodes, as well as optional auxil...
Definition: LeafManager.h:110
IndexFilter.h
Index filters primarily designed to be used with a FilterIndexIter.
openvdb::v5_1::points::NullFilter
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:62
openvdb::v5_1::points::point_mask_internal::PointsToScalarOp::LeafManagerT
typename tree::LeafManager< TreeT > LeafManagerT
Definition: PointMask.h:137
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
openvdb::v5_1::math::Transform
Definition: Transform.h:66
openvdb::v5_1::math::Vec3d
Vec3< double > Vec3d
Definition: Vec3.h:679
openvdb::v5_1::Index64
uint64_t Index64
Definition: Types.h:60
openvdb::v5_1::points::point_mask_internal::GridCombinerOp
Combines multiple grids into one by stealing leaf nodes and summing voxel values This class is design...
Definition: PointMask.h:96
openvdb::v5_1::points::iterCount
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition: IndexIterator.h:313
openvdb
Definition: Exceptions.h:40
openvdb::v5_1::tree::LeafManager::LeafRange
Definition: LeafManager.h:127
openvdb::v5_1::points::point_mask_internal::GridCombinerOp::GridCombinerOp
GridCombinerOp(GridT &grid)
Definition: PointMask.h:105
openvdb::v5_1::points::point_mask_internal::GridCombinerOp::LeafT
typename TreeT::LeafNodeType LeafT
Definition: PointMask.h:101
openvdb::v5_1::tree::ValueAccessor::modifyValue
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: ValueAccessor.h:322
openvdb::v5_1::points::convertPointsToMask
std::enable_if< std::is_same< typename MaskT::ValueType, bool >::value, typename MaskT::Ptr >::type convertPointsToMask(const PointDataGridT &grid, const openvdb::math::Transform &transform, const std::vector< Name > &includeGroups=std::vector< Name >(), const std::vector< Name > &excludeGroups=std::vector< Name >())
Extract a Mask Grid from a Point Data Grid using a new transform.
Definition: PointMask.h:354
openvdb::v5_1::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
openvdb::v5_1::points::point_mask_internal::PointsToScalarOp::operator()
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointMask.h:145
PointDataGrid.h
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
openvdb::v5_1::tree::LeafManager::leafRange
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:386
openvdb::v5_1::points::point_mask_internal::PointsToTransformedScalarOp::PointsToTransformedScalarOp
PointsToTransformedScalarOp(const math::Transform &newTransform, const math::Transform &transform, const FilterT &filter, CombinableT &combinable)
Definition: PointMask.h:184
openvdb::v5_1::tree::ValueAccessor
Definition: ValueAccessor.h:220
openvdb::v5_1::points::point_mask_internal::PointsToTransformedScalarOp
Compute scalar grid from PointDataGrid using a different transform and while evaluating the point fil...
Definition: PointMask.h:177
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
openvdb::v5_1::points::point_mask_internal::convertPointsToScalar
GridT::Ptr convertPointsToScalar(const PointDataGridT &points, const openvdb::math::Transform &transform, const std::vector< Name > &includeGroups, const std::vector< Name > &excludeGroups)
Definition: PointMask.h:273
openvdb::v5_1::points::point_mask_internal::PointsToScalarOp::PointsToScalarOp
PointsToScalarOp(const PointDataGridT &grid, const FilterT &filter)
Definition: PointMask.h:140
openvdb::v5_1::points::point_mask_internal::PointsToTransformedScalarOp::operator()
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointMask.h:193