MeshLib
 
Loading...
Searching...
No Matches
MROpenVDBHelper.h
Go to the documentation of this file.
1#pragma once
2#include "MRMeshFwd.h"
3#ifndef MRMESH_NO_OPENVDB
4#include "openvdb/tree/TreeIterator.h"
5#include "openvdb/tree/Tree.h"
6#include "openvdb/tree/ValueAccessor.h"
8
9#if defined(MR_PARSING_FOR_PB11_BINDINGS) || defined(MR_COMPILING_PB11_BINDINGS)
10// We call functions from those files below. Without those includes, I get undefined references in the bindings, when importing them.
11// Maybe we should include those unconditionally, I'm not entirely sure.
12#include <openvdb/tools/ChangeBackground.h>
13#include <openvdb/tools/Prune.h>
14#include <openvdb/tools/SignedFloodFill.h>
15#endif
16
17namespace MR
18{
19
26template <class TreeT, typename Transformer>
28{
29public:
30 using InterruptFunc = std::function<bool( void )>;
31
32 using ValueT = typename TreeT::ValueType;
33
34 using LeafIterT = typename TreeT::LeafCIter;
35 using TileIterT = typename TreeT::ValueAllCIter;
36 using LeafRange = typename openvdb::tree::IteratorRange<LeafIterT>;
37 using TileRange = typename openvdb::tree::IteratorRange<TileIterT>;
38
39 using InTreeAccessor = typename openvdb::tree::ValueAccessor<const TreeT>;
40 using OutTreeAccessor = typename openvdb::tree::ValueAccessor<TreeT>;
41
42 RangeProcessor( const openvdb::math::CoordBBox& b, const TreeT& inT, TreeT& outT, const Transformer& xform ) :
43 mIsRoot( true ), mXform( xform ), mBBox( b ),
44 mInTree( inT ), mOutTree( &outT ), mInAcc( mInTree ), mOutAcc( *mOutTree )
45 {}
46
47 RangeProcessor( const openvdb::math::CoordBBox& b, const TreeT& inTree, const Transformer& xform ) :
48 mIsRoot( false ), mXform( xform ), mBBox( b ),
49 mInTree( inTree ), mOutTree( new TreeT( inTree.background() ) ),
50 mInAcc( mInTree ), mOutAcc( *mOutTree )
51 {}
52
54 {
55 if ( !mIsRoot ) delete mOutTree;
56 }
57
60 mIsRoot( false ),
61 mXform( other.mXform ),
62 mBBox( other.mBBox ),
63 mInTree( other.mInTree ),
64 mOutTree( new TreeT( mInTree.background() ) ),
65 mInAcc( mInTree ),
66 mOutAcc( *mOutTree ),
67 mInterrupt( other.mInterrupt )
68 {}
69
70 void setInterrupt( const InterruptFunc& f ) { mInterrupt = f; }
71
73 void operator()( const LeafRange& rCRef )
74 {
75 LeafRange r = rCRef;
76 for ( ; r; ++r )
77 {
78 if ( interrupt() ) break;
79
80 LeafIterT i = r.iterator();
81 openvdb::math::CoordBBox bbox = i->getNodeBoundingBox();
82 if ( !mBBox.empty() )
83 bbox.intersect( mBBox );
84
85 if ( !bbox.empty() )
86 {
87 for ( auto it = bbox.begin(); it != bbox.end(); ++it )
88 {
89 mXform( mInAcc, mOutAcc, *it );
90 }
91 }
92 }
93 }
94
96 void operator()( const TileRange& rCRef )
97 {
98 auto r = rCRef;
99 for ( ; r; ++r )
100 {
101 if ( interrupt() ) break;
102
103 TileIterT i = r.iterator();
104 // Skip voxels and background tiles.
105 if ( !i.isTileValue() ) continue;
106 if ( !i.isValueOn() && openvdb::math::isApproxEqual( *i, mOutTree->background() ) ) continue;
107
108 openvdb::math::CoordBBox bbox;
109 i.getBoundingBox( bbox );
110 if ( !mBBox.empty() )
111 {
112 // Intersect the tile's bounding box with mBBox.
113 bbox = openvdb::math::CoordBBox(
114 openvdb::math::Coord::maxComponent( bbox.min(), mBBox.min() ),
115 openvdb::math::Coord::minComponent( bbox.max(), mBBox.max() ) );
116 }
117 if ( !bbox.empty() )
118 {
119 for ( auto it = bbox.begin(); it != bbox.end(); ++it )
120 {
121 mXform( mInAcc, mOutAcc, *it );
122 }
123 }
124 }
125 }
126
129 {
130 if ( !interrupt() ) mOutTree->merge( *other.mOutTree );
131 }
132
133private:
134 bool interrupt() const { return mInterrupt && mInterrupt(); }
135
136 const bool mIsRoot; // true if mOutTree is the top-level tree
137 Transformer mXform;
138 openvdb::math::CoordBBox mBBox;
139 const TreeT& mInTree;
140 TreeT* mOutTree;
141 InTreeAccessor mInAcc;
142 OutTreeAccessor mOutAcc;
143 InterruptFunc mInterrupt;
144};
145
147template <typename TreeT>
149{
150public:
151 using InTreeAccessor = typename openvdb::tree::ValueAccessor<const TreeT>;
152 using OutTreeAccessor = typename openvdb::tree::ValueAccessor<TreeT>;
153 using ValueT = typename TreeT::ValueType;
154
155 void operator()( const InTreeAccessor& inAcc, OutTreeAccessor& outAcc, openvdb::math::Coord coord )
156 {
157 ValueT value = ValueT();
158 if ( inAcc.probeValue( coord, value ) )
159 outAcc.setValue( coord + shift_, value );
160 }
161 void setShift( const openvdb::math::Coord& shift ) { shift_ = shift; }
162private:
163 openvdb::math::Coord shift_;
164};
165
166template <typename GredT>
167void translateToZero( GredT& grid)
168{
169 using TreeT = typename GredT::TreeType;
170 typename TreeT::Ptr outTreePtr = std::make_shared<TreeT>();
171 TreeT& inTree = grid.tree();
172 const auto gridClass = grid.getGridClass();
173 if (gridClass == openvdb::GRID_LEVEL_SET)
174 openvdb::tools::changeLevelSetBackground( *outTreePtr, inTree.background() );
175
176 openvdb::math::CoordBBox bbox = grid.evalActiveVoxelBoundingBox();
177 if ( bbox.empty() || bbox.min() == openvdb::math::Coord() )
178 return;
179
180 //using RangeProc = RangeProcessor<TreeT, translateValue<TreeT, bbox.min()>>;
183 xform.setShift( -bbox.min() );
184 RangeProc proc( bbox, inTree, *outTreePtr, xform );
185
186 if ( gridClass != openvdb::GRID_LEVEL_SET )
187 {
188 // Independently transform the tiles of the input grid.
189 // Note: Tiles in level sets can only be background tiles, and they
190 // are handled more efficiently with a signed flood fill (see below).
191 typename RangeProc::TileIterT tileIter = inTree.cbeginValueAll();
192 tileIter.setMaxDepth( tileIter.getLeafDepth() - 1 ); // skip leaf nodes
193 typename RangeProc::TileRange tileRange( tileIter );
194 tbb::parallel_reduce( tileRange, proc );
195 }
196
197 typename RangeProc::LeafRange leafRange( inTree.cbeginLeaf() );
198 tbb::parallel_reduce( leafRange, proc );
199
200 if ( gridClass == openvdb::GRID_LEVEL_SET )
201 {
202 openvdb::tools::pruneLevelSet( *outTreePtr );
203 openvdb::tools::signedFloodFill( *outTreePtr );
204 }
205
206 grid.setTree( outTreePtr );
207}
208
212{
213public:
214 // Mode of parallel_reduce
215 enum class Mode
216 {
217 Leaves,
218 Tiles
219 };
221 size_{ size },
222 cb_{ cb },
223 mode_{ mode }
224 {
225 progressThreadId_ = std::this_thread::get_id();
226 }
227 // if leaves mode add `l` to counter,
228 // if tiles mode - add `t` to counter
229 void add( size_t l, size_t t )
230 {
231 if ( mode_ == Mode::Leaves )
232 counter_.fetch_add( l );
233 else
234 counter_.fetch_add( t );
235 }
236 // retorts progress if called from main thread, otherwise do nothing
237 bool reportProgress() const
238 {
239 if ( !cb_ || progressThreadId_ != std::this_thread::get_id() )
240 return true;
241 return cb_( float( counter_.load() ) / float( size_ ) );
242 }
243private:
244 std::atomic<size_t> counter_{ 0 };
245 size_t size_{ 0 };
247 std::thread::id progressThreadId_;
248 Mode mode_;
249};
250
256template <typename TreeT, typename Proc>
258{
259public:
260 using InterruptFunc = std::function<bool( void )>;
261 using ProgressHolder = std::shared_ptr<RangeProgress>;
262
263 using ValueT = typename TreeT::ValueType;
264
265 using LeafIterT = typename TreeT::LeafCIter;
266 using TileIterT = typename TreeT::ValueAllCIter;
267 using LeafRange = typename openvdb::tree::IteratorRange<LeafIterT>;
268 using TileRange = typename openvdb::tree::IteratorRange<TileIterT>;
269
270 using TreeAccessor = typename openvdb::tree::ValueAccessor<const TreeT>;
271
272 RangeProcessorSingle( const openvdb::math::CoordBBox& b, const TreeT& inT, const Proc& proc ) :
273 mProc( proc ), mBBox( b ), mInTree( inT ), mInAcc( mInTree )
274 {}
275
278 mProc( other.mProc ),
279 mBBox( other.mBBox ),
280 mInTree( other.mInTree ),
281 mInAcc( mInTree ),
282 mInterrupt( other.mInterrupt ),
283 mCanceled{ other.mCanceled },
284 mProgress( other.mProgress )
285 {}
286
287 void setInterrupt( const InterruptFunc& f ) { mInterrupt = f; }
288 void setProgressHolder( ProgressHolder progressHolder ) { mProgress = progressHolder; }
289
291 void operator()( const LeafRange& rCRef )
292 {
293 LeafRange r = rCRef;
294 leafCount = 0;
295 size_t leafCountLast = 0;
296 for ( ; r; ++r )
297 {
298 if ( interrupt() ) break;
299 if ( !( leafCount & 0x400 ) )
300 {
301 if ( !setProgress( leafCount - leafCountLast, tileCount ) )
302 break;
303 else
304 leafCountLast = leafCount;
305 }
306
307 LeafIterT i = r.iterator();
308 openvdb::math::CoordBBox bbox = i->getNodeBoundingBox();
309 if ( !mBBox.empty() )
310 bbox.intersect( mBBox );
311
312 if ( !bbox.empty() )
313 {
314 mProc.action( i, mInAcc, bbox );
315 ++leafCount;
316 }
317 }
318 setProgress( leafCount - leafCountLast, tileCount );
319 }
320
322 void operator()( const TileRange& rCRef )
323 {
324 auto r = rCRef;
325 tileCount = 0;
326 size_t tileCountLast = 0;
327 for ( ; r; ++r )
328 {
329 if ( interrupt() ) break;
330 if ( !( tileCount & 0x400 ) )
331 {
332 if ( !setProgress( leafCount, tileCount - tileCountLast ) )
333 break;
334 else
335 tileCountLast = tileCount;
336 }
337
338 TileIterT i = r.iterator();
339 // Skip voxels and background tiles.
340 if ( !i.isTileValue() ) continue;
341 if ( !i.isValueOn() ) continue;
342
343 openvdb::math::CoordBBox bbox;
344 i.getBoundingBox( bbox );
345 if ( !mBBox.empty() )
346 bbox.intersect( mBBox );
347
348 if ( !bbox.empty() )
349 {
350 mProc.action( i, mInAcc, bbox );
351 ++tileCount;
352 }
353 }
354 setProgress( leafCount, tileCount - tileCountLast );
355 }
356
359 {
360 if ( interrupt() )
361 return;
362 mProc.join( other.mProc );
363 }
364
365 Proc mProc;
366private:
367 bool interrupt() const
368 {
369 return mCanceled || ( mInterrupt && mInterrupt() );
370 }
371 bool setProgress( size_t l, size_t t )
372 {
373 if ( !mProgress )
374 return true;
375 mProgress->add( l, t );
376 if ( !mProgress->reportProgress() )
377 mCanceled = true;
378 return !mCanceled;
379 }
380
381 openvdb::math::CoordBBox mBBox;
382 const TreeT& mInTree;
383 TreeAccessor mInAcc;
384 InterruptFunc mInterrupt;
385 bool mCanceled{ false };
386 std::shared_ptr<RangeProgress> mProgress;
387
388 size_t leafCount = 0;
389 size_t tileCount = 0;
390};
391
392
394{
395 size_t leaf = 0;
396 size_t tile = 0;
397};
398
402template<typename TreeT>
404{
405public:
406 using ValueT = typename TreeT::ValueType;
407 using TreeAccessor = openvdb::tree::ValueAccessor<const TreeT>;
408 using LeafIterT = typename TreeT::LeafCIter;
409 using TileIterT = typename TreeT::ValueAllCIter;
410
412 {}
413
415 {}
416
417 void action( const LeafIterT&, const TreeAccessor&, const openvdb::math::CoordBBox& )
418 {
419 ++size.leaf;
420 }
421
422 void action( const TileIterT&, const TreeAccessor&, const openvdb::math::CoordBBox& )
423 {
424 ++size.tile;
425 }
426
427 void join( const RangeCounter& other )
428 {
429 size.leaf += other.size.leaf;
430 size.tile += other.size.tile;
431 }
432
434};
435
436template <typename GridT>
437RangeSize calculateRangeSize( const GridT& grid )
438{
439 using TreeT = typename GridT::TreeType;
440 using ProcessC = RangeCounter<TreeT>;
441 ProcessC proc;
442 using RangeProcessC = RangeProcessorSingle<TreeT, ProcessC>;
443 RangeProcessC calcCount( grid.evalActiveVoxelBoundingBox(), grid.tree(), proc );
444
445 typename RangeProcessC::TileIterT tileIter = grid.tree().cbeginValueAll();
446 tileIter.setMaxDepth( tileIter.getLeafDepth() - 1 ); // skip leaf nodes
447 typename RangeProcessC::TileRange tileRange( tileIter );
448 tbb::parallel_reduce( tileRange, calcCount );
449 typename RangeProcessC::LeafRange leafRange( grid.tree().cbeginLeaf() );
450 tbb::parallel_reduce( leafRange, calcCount );
451
452 return calcCount.mProc.size;
453}
454
455}
456
457#endif
functor to calculate tile and leaf valid nodes count
Definition MROpenVDBHelper.h:404
typename TreeT::LeafCIter LeafIterT
Definition MROpenVDBHelper.h:408
typename TreeT::ValueAllCIter TileIterT
Definition MROpenVDBHelper.h:409
openvdb::tree::ValueAccessor< const TreeT > TreeAccessor
Definition MROpenVDBHelper.h:407
void action(const TileIterT &, const TreeAccessor &, const openvdb::math::CoordBBox &)
Definition MROpenVDBHelper.h:422
RangeCounter()
Definition MROpenVDBHelper.h:411
typename TreeT::ValueType ValueT
Definition MROpenVDBHelper.h:406
void action(const LeafIterT &, const TreeAccessor &, const openvdb::math::CoordBBox &)
Definition MROpenVDBHelper.h:417
void join(const RangeCounter &other)
Definition MROpenVDBHelper.h:427
RangeCounter(const RangeCounter &)
Definition MROpenVDBHelper.h:414
RangeSize size
Definition MROpenVDBHelper.h:433
Class to use in tbb::parallel_reduce for tree operations that do not require an output tree.
Definition MROpenVDBHelper.h:258
typename TreeT::ValueType ValueT
Definition MROpenVDBHelper.h:263
std::shared_ptr< RangeProgress > ProgressHolder
Definition MROpenVDBHelper.h:261
Proc mProc
Definition MROpenVDBHelper.h:365
typename TreeT::LeafCIter LeafIterT
Definition MROpenVDBHelper.h:265
void operator()(const LeafRange &rCRef)
Transform each leaf node in the given range.
Definition MROpenVDBHelper.h:291
RangeProcessorSingle(const openvdb::math::CoordBBox &b, const TreeT &inT, const Proc &proc)
Definition MROpenVDBHelper.h:272
std::function< bool(void)> InterruptFunc
Definition MROpenVDBHelper.h:260
void setProgressHolder(ProgressHolder progressHolder)
Definition MROpenVDBHelper.h:288
typename openvdb::tree::IteratorRange< LeafIterT > LeafRange
Definition MROpenVDBHelper.h:267
RangeProcessorSingle(RangeProcessorSingle &other, tbb::split)
Splitting constructor: don't copy the original processor's output tree.
Definition MROpenVDBHelper.h:277
typename openvdb::tree::IteratorRange< TileIterT > TileRange
Definition MROpenVDBHelper.h:268
typename openvdb::tree::ValueAccessor< const TreeT > TreeAccessor
Definition MROpenVDBHelper.h:270
void operator()(const TileRange &rCRef)
Transform each non-background tile in the given range.
Definition MROpenVDBHelper.h:322
typename TreeT::ValueAllCIter TileIterT
Definition MROpenVDBHelper.h:266
void join(RangeProcessorSingle &other)
Merge another processor's output tree into this processor's tree.
Definition MROpenVDBHelper.h:358
void setInterrupt(const InterruptFunc &f)
Definition MROpenVDBHelper.h:287
Class to use in tbb::parallel_reduce for openvdb::tree transformation.
Definition MROpenVDBHelper.h:28
void setInterrupt(const InterruptFunc &f)
Definition MROpenVDBHelper.h:70
typename TreeT::LeafCIter LeafIterT
Definition MROpenVDBHelper.h:34
typename TreeT::ValueType ValueT
Definition MROpenVDBHelper.h:32
void operator()(const TileRange &rCRef)
Transform each non-background tile in the given range.
Definition MROpenVDBHelper.h:96
RangeProcessor(RangeProcessor &other, tbb::split)
Splitting constructor: don't copy the original processor's output tree.
Definition MROpenVDBHelper.h:59
typename openvdb::tree::ValueAccessor< const TreeT > InTreeAccessor
Definition MROpenVDBHelper.h:39
void join(RangeProcessor &other)
Merge another processor's output tree into this processor's tree.
Definition MROpenVDBHelper.h:128
typename openvdb::tree::IteratorRange< LeafIterT > LeafRange
Definition MROpenVDBHelper.h:36
typename TreeT::ValueAllCIter TileIterT
Definition MROpenVDBHelper.h:35
typename openvdb::tree::ValueAccessor< TreeT > OutTreeAccessor
Definition MROpenVDBHelper.h:40
~RangeProcessor()
Definition MROpenVDBHelper.h:53
std::function< bool(void)> InterruptFunc
Definition MROpenVDBHelper.h:30
typename openvdb::tree::IteratorRange< TileIterT > TileRange
Definition MROpenVDBHelper.h:37
RangeProcessor(const openvdb::math::CoordBBox &b, const TreeT &inTree, const Transformer &xform)
Definition MROpenVDBHelper.h:47
void operator()(const LeafRange &rCRef)
Transform each leaf node in the given range.
Definition MROpenVDBHelper.h:73
RangeProcessor(const openvdb::math::CoordBBox &b, const TreeT &inT, TreeT &outT, const Transformer &xform)
Definition MROpenVDBHelper.h:42
Definition MROpenVDBHelper.h:212
bool reportProgress() const
Definition MROpenVDBHelper.h:237
void add(size_t l, size_t t)
Definition MROpenVDBHelper.h:229
Mode
Definition MROpenVDBHelper.h:216
RangeProgress(ProgressCallback cb, size_t size, Mode mode)
Definition MROpenVDBHelper.h:220
functor for shifting voxels
Definition MROpenVDBHelper.h:149
typename openvdb::tree::ValueAccessor< TreeT > OutTreeAccessor
Definition MROpenVDBHelper.h:152
void operator()(const InTreeAccessor &inAcc, OutTreeAccessor &outAcc, openvdb::math::Coord coord)
Definition MROpenVDBHelper.h:155
void setShift(const openvdb::math::Coord &shift)
Definition MROpenVDBHelper.h:161
typename openvdb::tree::ValueAccessor< const TreeT > InTreeAccessor
Definition MROpenVDBHelper.h:151
typename TreeT::ValueType ValueT
Definition MROpenVDBHelper.h:153
std::function< bool(float)> ProgressCallback
Definition MRMesh/MRMeshFwd.h:589
Definition MRCameraOrientationPlugin.h:7
ImVec2 size(const ViewportRectangle &rect)
Definition MRViewport.h:32
void translateToZero(GredT &grid)
Definition MROpenVDBHelper.h:167
RangeSize calculateRangeSize(const GridT &grid)
Definition MROpenVDBHelper.h:437
Definition MROpenVDBHelper.h:394
size_t leaf
Definition MROpenVDBHelper.h:395
size_t tile
Definition MROpenVDBHelper.h:396