36 #ifndef OPENVDB_TOOLS_CLIP_HAS_BEEN_INCLUDED 37 #define OPENVDB_TOOLS_CLIP_HAS_BEEN_INCLUDED 44 #include <tbb/blocked_range.h> 45 #include <tbb/parallel_reduce.h> 46 #include <type_traits> 63 inline typename GridType::Ptr
64 clip(
const GridType& grid,
const BBoxd& bbox,
bool keepInterior =
true);
79 inline typename GridType::Ptr
80 clip(
const GridType& grid,
const Grid<MaskTreeType>& mask,
bool keepInterior =
true);
86 namespace clip_internal {
94 template<
typename TreeT>
98 using ValueT =
typename TreeT::ValueType;
103 template<
typename LeafNodeType>
106 const auto* refLeaf = mAcc.probeConstLeaf(leaf.origin());
108 for (
auto iter = leaf.beginValueOff(); iter; ++iter) {
109 const auto pos = iter.pos();
123 template<
typename TreeT>
127 using MaskTreeT =
typename TreeT::template ValueConverter<MaskValueType>::Type;
132 void run(
bool threaded =
true);
134 typename TreeT::Ptr
tree()
const {
return mNewTree; }
137 void operator()(
const tbb::blocked_range<size_t>&);
144 typename TreeT::Ptr mNewTree;
148 template<
typename TreeT>
151 , mLeafNodes(&leafNodes)
152 , mNewTree(new TreeT(mTree->background()))
157 template<
typename TreeT>
160 , mLeafNodes(rhs.mLeafNodes)
161 , mNewTree(new TreeT(mTree->background()))
166 template<
typename TreeT>
170 if (threaded) tbb::parallel_reduce(mLeafNodes->
getRange(), *
this);
171 else (*
this)(mLeafNodes->
getRange());
175 template<
typename TreeT>
182 for (
auto n = range.begin(); n != range.end(); ++n) {
183 const auto& maskLeaf = mLeafNodes->
leaf(n);
184 const auto& ijk = maskLeaf.origin();
190 for (
auto it = maskLeaf.cbeginValueOn(); it; ++it) {
191 const auto pos = it.pos();
192 newLeaf->setValueOnly(pos, refLeaf->getValue(pos));
193 newLeaf->setActiveState(pos, refLeaf->isValueOn(pos));
196 typename TreeT::ValueType value;
197 bool isActive = refAcc.
probeValue(ijk, value);
199 for (
auto it = maskLeaf.cbeginValueOn(); it; ++it) {
200 const auto pos = it.pos();
201 newLeaf->setValueOnly(pos, value);
202 newLeaf->setActiveState(pos, isActive);
214 static const char*
name() {
return "bin"; }
219 template<
class TreeT>
221 const Vec3R& inCoord,
typename TreeT::ValueType& result)
224 ijk[0] = int(std::floor(inCoord[0]));
225 ijk[1] = int(std::floor(inCoord[1]));
226 ijk[2] = int(std::floor(inCoord[2]));
227 return inTree.probeValue(ijk, result);
236 template<
typename FromGr
idT,
typename ToGr
idT>
246 template<
typename Gr
idT>
260 template<
typename Gr
idT>
261 inline typename std::enable_if<!std::is_same<MaskValueType, typename GridT::BuildType>::value,
262 typename GridT::template ValueConverter<MaskValueType>::Type::Ptr>::type
263 convertToMaskGrid(
const GridT& grid)
265 using MaskGridT =
typename GridT::template ValueConverter<MaskValueType>::Type;
266 auto mask = MaskGridT::create(
false);
267 mask->topologyUnion(grid);
268 mask->setTransform(grid.constTransform().copy());
274 template<
typename Gr
idT>
275 inline typename std::enable_if<std::is_same<MaskValueType, typename GridT::BuildType>::value,
276 typename GridT::ConstPtr>::type
277 convertToMaskGrid(
const GridT& grid)
287 template<
typename Gr
idType>
288 inline typename GridType::Ptr
290 const GridType& grid,
291 const typename GridType::template ValueConverter<MaskValueType>::Type& clipMask,
294 using TreeT =
typename GridType::TreeType;
295 using MaskTreeT =
typename GridType::TreeType::template ValueConverter<MaskValueType>::Type;
297 const auto gridClass = grid.getGridClass();
298 const auto&
tree = grid.tree();
301 gridMask.topologyUnion(
tree);
309 typename MaskTreeT::ValueAllIter iter(gridMask);
310 iter.setMaxDepth(MaskTreeT::ValueAllIter::LEAF_DEPTH - 1);
312 for ( ; iter; ++iter) {
318 gridMask.topologyIntersection(clipMask.constTree());
320 gridMask.topologyDifference(clipMask.constTree());
323 typename GridType::Ptr outGrid;
329 outGrid = GridType::create(maskOp.
tree());
336 typename TreeT::ValueAllIter it(outGrid->tree());
337 it.setMaxDepth(TreeT::ValueAllIter::LEAF_DEPTH - 1);
339 Coord ijk = it.getCoord();
342 typename TreeT::ValueType value;
343 bool isActive = refAcc.
probeValue(ijk, value);
346 if (!isActive) it.setValueOff();
351 outGrid->setTransform(grid.transform().copy());
352 if (gridClass !=
GRID_LEVEL_SET) outGrid->setGridClass(gridClass);
364 template<
typename Gr
idType>
366 inline typename GridType::Ptr
367 clip(
const GridType& grid,
const BBoxd& bbox,
bool keepInterior)
370 using MaskGridT =
typename GridType::template ValueConverter<MaskValueT>::Type;
373 Vec3d idxMin, idxMax;
375 CoordBBox region(Coord::floor(idxMin), Coord::floor(idxMax));
378 MaskGridT clipMask(
false);
379 clipMask.fill(region,
true,
true);
381 return clip_internal::doClip(grid, clipMask, keepInterior);
386 template<
typename SrcGr
idType,
typename ClipTreeType>
388 inline typename SrcGridType::Ptr
393 using SrcMaskGridType =
typename SrcGridType::template ValueConverter<MaskValueT>::Type;
394 using ClipMaskGridType =
typename ClipGridType::template ValueConverter<MaskValueT>::Type;
397 auto maskGrid = clip_internal::convertToMaskGrid(clipGrid);
400 if (srcGrid.constTransform() != maskGrid->constTransform()) {
401 auto resampledMask = ClipMaskGridType::create(
false);
402 resampledMask->setTransform(srcGrid.constTransform().copy());
403 tools::resampleToMatch<clip_internal::BoolSampler>(*maskGrid, *resampledMask);
405 maskGrid = resampledMask;
410 ClipMaskGridType, SrcMaskGridType>()(maskGrid);
413 return clip_internal::doClip(srcGrid, *clipMask, keepInterior);
420 #endif // OPENVDB_TOOLS_CLIP_HAS_BEEN_INCLUDED
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:115
OPENVDB_API void calculateBounds(const Transform &t, const Vec3d &minWS, const Vec3d &maxWS, Vec3d &minIS, Vec3d &maxIS)
Calculate an axis-aligned bounding box in index space from an axis-aligned bounding box in world spac...
RangeType getRange(size_t grainsize=1) const
Return a tbb::blocked_range of leaf array indices.
Definition: LeafManager.h:388
math::BBox< Vec3d > BBoxd
Definition: Types.h:87
Defined various multi-threaded utility functions for trees.
void foreach(const LeafOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that applies a user-supplied functor to each leaf node in the LeafManager.
Definition: LeafManager.h:525
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:354
const ValueType & getValue(const Coord &xyz) const
Return the value of the voxel at the given coordinates.
Definition: ValueAccessor.h:256
#define OPENVDB_VERSION_NAME
Definition: version.h:43
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:263
Vec3< double > Vec3d
Definition: Vec3.h:708
const LeafNodeT * probeConstLeaf(const Coord &xyz) const
Return a pointer to the leaf node that contains voxel (x, y, z), or nullptr if no such node exists...
Definition: ValueAccessor.h:429
Definition: Exceptions.h:39
LeafNodeT * touchLeaf(const Coord &xyz)
Return a pointer to the leaf node that contains voxel (x, y, z). If no such node exists, create one, but preserve the values and active states of all voxels.
Definition: ValueAccessor.h:393
const Vec3T & min() const
Return a const reference to the minimum point of the BBox.
Definition: BBox.h:84
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:54
const Vec3T & max() const
Return a const reference to the maximum point of the BBox.
Definition: BBox.h:87
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
bool probeValue(const Coord &xyz, ValueType &value) const
Return the active state of the voxel as well as its value.
Definition: ValueAccessor.h:266
LeafType & leaf(size_t leafIdx) const
Return a pointer to the leaf node at index leafIdx in the array.
Definition: LeafManager.h:364