MeshLib C++ Docs
Loading...
Searching...
No Matches
MROpenVDBHelper.h
Go to the documentation of this file.
1#pragma once
2#include "MRVoxelsFwd.h"
3
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_ANY_BINDINGS) || defined(MR_COMPILING_ANY_BINDINGS)
12#include <openvdb/tools/ChangeBackground.h>
13#include <openvdb/tools/Prune.h>
14#include <openvdb/tools/SignedFloodFill.h>
15#endif
16
17#include <thread>
18
19namespace MR
20{
23
24
31template <class TreeT, typename Transformer>
33{
34public:
35 using InterruptFunc = std::function<bool( void )>;
36
37 using ValueT = typename TreeT::ValueType;
38
39 using LeafIterT = typename TreeT::LeafCIter;
40 using TileIterT = typename TreeT::ValueAllCIter;
41 using LeafRange = typename openvdb::tree::IteratorRange<LeafIterT>;
42 using TileRange = typename openvdb::tree::IteratorRange<TileIterT>;
43
44 using InTreeAccessor = typename openvdb::tree::ValueAccessor<const TreeT>;
45 using OutTreeAccessor = typename openvdb::tree::ValueAccessor<TreeT>;
46
47 RangeProcessor( const openvdb::math::CoordBBox& b, const TreeT& inT, TreeT& outT, const Transformer& xform ) :
48 mIsRoot( true ), mXform( xform ), mBBox( b ),
49 mInTree( inT ), mOutTree( &outT ), mInAcc( mInTree ), mOutAcc( *mOutTree )
50 {}
51
52 RangeProcessor( const openvdb::math::CoordBBox& b, const TreeT& inTree, const Transformer& xform ) :
53 mIsRoot( false ), mXform( xform ), mBBox( b ),
54 mInTree( inTree ), mOutTree( new TreeT( inTree.background() ) ),
55 mInAcc( mInTree ), mOutAcc( *mOutTree )
56 {}
57
59 {
60 if ( !mIsRoot ) delete mOutTree;
61 }
62
65 mIsRoot( false ),
66 mXform( other.mXform ),
67 mBBox( other.mBBox ),
68 mInTree( other.mInTree ),
69 mOutTree( new TreeT( mInTree.background() ) ),
70 mInAcc( mInTree ),
71 mOutAcc( *mOutTree ),
72 mInterrupt( other.mInterrupt )
73 {}
74
75 void setInterrupt( const InterruptFunc& f ) { mInterrupt = f; }
76
78 void operator()( const LeafRange& rCRef )
79 {
80 LeafRange r = rCRef;
81 for ( ; r; ++r )
82 {
83 if ( interrupt() ) break;
84
85 LeafIterT i = r.iterator();
86 openvdb::math::CoordBBox bbox = i->getNodeBoundingBox();
87 if ( !mBBox.empty() )
88 bbox.intersect( mBBox );
89
90 if ( !bbox.empty() )
91 {
92 for ( auto it = bbox.begin(); it != bbox.end(); ++it )
93 {
94 mXform( mInAcc, mOutAcc, *it );
95 }
96 }
97 }
98 }
99
101 void operator()( const TileRange& rCRef )
102 {
103 auto r = rCRef;
104 for ( ; r; ++r )
105 {
106 if ( interrupt() ) break;
107
108 TileIterT i = r.iterator();
110 if ( !i.isTileValue() ) continue;
111 if ( !i.isValueOn() && openvdb::math::isApproxEqual( *i, mOutTree->background() ) ) continue;
112
113 openvdb::math::CoordBBox bbox;
114 i.getBoundingBox( bbox );
115 if ( !mBBox.empty() )
116 {
118 bbox = openvdb::math::CoordBBox(
119 openvdb::math::Coord::maxComponent( bbox.min(), mBBox.min() ),
120 openvdb::math::Coord::minComponent( bbox.max(), mBBox.max() ) );
121 }
122 if ( !bbox.empty() )
123 {
124 for ( auto it = bbox.begin(); it != bbox.end(); ++it )
125 {
126 mXform( mInAcc, mOutAcc, *it );
127 }
128 }
129 }
130 }
131
134 {
135 if ( !interrupt() ) mOutTree->merge( *other.mOutTree );
136 }
137
138private:
139 bool interrupt() const { return mInterrupt && mInterrupt(); }
140
141 const bool mIsRoot;
142 Transformer mXform;
143 openvdb::math::CoordBBox mBBox;
144 const TreeT& mInTree;
145 TreeT* mOutTree;
146 InTreeAccessor mInAcc;
147 OutTreeAccessor mOutAcc;
148 InterruptFunc mInterrupt;
149};
150
152template <typename TreeT>
154{
155public:
156 using InTreeAccessor = typename openvdb::tree::ValueAccessor<const TreeT>;
157 using OutTreeAccessor = typename openvdb::tree::ValueAccessor<TreeT>;
158 using ValueT = typename TreeT::ValueType;
159
160 void operator()( const InTreeAccessor& inAcc, OutTreeAccessor& outAcc, openvdb::math::Coord coord )
161 {
162 ValueT value = ValueT();
163 if ( inAcc.probeValue( coord, value ) )
164 outAcc.setValue( coord + shift_, value );
165 }
166 void setShift( const openvdb::math::Coord& shift ) { shift_ = shift; }
167private:
168 openvdb::math::Coord shift_;
169};
170
171MRVOXELS_API void translateToZero( openvdb::FloatGrid & grid );
172
176{
177public:
179 enum class Mode
180 {
181 Leaves,
182 Tiles
183 };
184 RangeProgress( ProgressCallback cb, size_t size, Mode mode ) :
185 size_{ size },
186 cb_{ cb },
187 mode_{ mode }
188 {
189 progressThreadId_ = std::this_thread::get_id();
190 }
193 void add( size_t l, size_t t )
194 {
195 if ( mode_ == Mode::Leaves )
196 counter_.fetch_add( l );
197 else
198 counter_.fetch_add( t );
199 }
201 bool reportProgress() const
202 {
203 if ( !cb_ || progressThreadId_ != std::this_thread::get_id() )
204 return true;
205 return cb_( float( counter_.load() ) / float( size_ ) );
206 }
207private:
208 std::atomic<size_t> counter_{ 0 };
209 size_t size_{ 0 };
210 ProgressCallback cb_;
211 std::thread::id progressThreadId_;
212 Mode mode_;
213};
214
220template <typename TreeT, typename Proc>
222{
223public:
224 using InterruptFunc = std::function<bool( void )>;
225 using ProgressHolder = std::shared_ptr<RangeProgress>;
226
227 using ValueT = typename TreeT::ValueType;
228
229 using LeafIterT = typename TreeT::LeafCIter;
230 using TileIterT = typename TreeT::ValueAllCIter;
231 using LeafRange = typename openvdb::tree::IteratorRange<LeafIterT>;
232 using TileRange = typename openvdb::tree::IteratorRange<TileIterT>;
233
234 using TreeAccessor = typename openvdb::tree::ValueAccessor<const TreeT>;
235
236 RangeProcessorSingle( const openvdb::math::CoordBBox& b, const TreeT& inT, const Proc& proc ) :
237 mProc( proc ), mBBox( b ), mInTree( inT ), mInAcc( mInTree )
238 {}
239
242 mProc( other.mProc ),
243 mBBox( other.mBBox ),
244 mInTree( other.mInTree ),
245 mInAcc( mInTree ),
246 mInterrupt( other.mInterrupt ),
247 mCanceled{ other.mCanceled },
248 mProgress( other.mProgress )
249 {}
250
251 void setInterrupt( const InterruptFunc& f ) { mInterrupt = f; }
252 void setProgressHolder( ProgressHolder progressHolder ) { mProgress = progressHolder; }
253
255 void operator()( const LeafRange& rCRef )
256 {
257 LeafRange r = rCRef;
258 leafCount = 0;
259 size_t leafCountLast = 0;
260 for ( ; r; ++r )
261 {
262 if ( interrupt() ) break;
263 if ( !( leafCount & 0x400 ) )
264 {
265 if ( !setProgress( leafCount - leafCountLast, tileCount ) )
266 break;
267 else
268 leafCountLast = leafCount;
269 }
270
271 LeafIterT i = r.iterator();
272 openvdb::math::CoordBBox bbox = i->getNodeBoundingBox();
273 if ( !mBBox.empty() )
274 bbox.intersect( mBBox );
275
276 if ( !bbox.empty() )
277 {
278 mProc.action( i, mInAcc, bbox );
279 ++leafCount;
280 }
281 }
282 setProgress( leafCount - leafCountLast, tileCount );
283 }
284
286 void operator()( const TileRange& rCRef )
287 {
288 auto r = rCRef;
289 tileCount = 0;
290 size_t tileCountLast = 0;
291 for ( ; r; ++r )
292 {
293 if ( interrupt() ) break;
294 if ( !( tileCount & 0x400 ) )
295 {
296 if ( !setProgress( leafCount, tileCount - tileCountLast ) )
297 break;
298 else
299 tileCountLast = tileCount;
300 }
301
302 TileIterT i = r.iterator();
304 if ( !i.isTileValue() ) continue;
305 if ( !i.isValueOn() ) continue;
306
307 openvdb::math::CoordBBox bbox;
308 i.getBoundingBox( bbox );
309 if ( !mBBox.empty() )
310 bbox.intersect( mBBox );
311
312 if ( !bbox.empty() )
313 {
314 mProc.action( i, mInAcc, bbox );
315 ++tileCount;
316 }
317 }
318 setProgress( leafCount, tileCount - tileCountLast );
319 }
320
323 {
324 if ( interrupt() )
325 return;
326 mProc.join( other.mProc );
327 }
328
329 Proc mProc;
330private:
331 bool interrupt() const
332 {
333 return mCanceled || ( mInterrupt && mInterrupt() );
334 }
335 bool setProgress( size_t l, size_t t )
336 {
337 if ( !mProgress )
338 return true;
339 mProgress->add( l, t );
340 if ( !mProgress->reportProgress() )
341 mCanceled = true;
342 return !mCanceled;
343 }
344
345 openvdb::math::CoordBBox mBBox;
346 const TreeT& mInTree;
347 TreeAccessor mInAcc;
348 InterruptFunc mInterrupt;
349 bool mCanceled{ false };
350 std::shared_ptr<RangeProgress> mProgress;
351
352 size_t leafCount = 0;
353 size_t tileCount = 0;
354};
355
356
358{
359 size_t leaf = 0;
360 size_t tile = 0;
361};
362
366template<typename TreeT>
368{
369public:
370 using ValueT = typename TreeT::ValueType;
371 using TreeAccessor = openvdb::tree::ValueAccessor<const TreeT>;
372 using LeafIterT = typename TreeT::LeafCIter;
373 using TileIterT = typename TreeT::ValueAllCIter;
374
376 {}
377
379 {}
380
381 void action( const LeafIterT&, const TreeAccessor&, const openvdb::math::CoordBBox& )
382 {
383 ++size.leaf;
384 }
385
386 void action( const TileIterT&, const TreeAccessor&, const openvdb::math::CoordBBox& )
387 {
388 ++size.tile;
389 }
390
391 void join( const RangeCounter& other )
392 {
393 size.leaf += other.size.leaf;
394 size.tile += other.size.tile;
395 }
396
398};
399
400template <typename GridT>
401RangeSize calculateRangeSize( const GridT& grid )
402{
403 using TreeT = typename GridT::TreeType;
404 using ProcessC = RangeCounter<TreeT>;
405 ProcessC proc;
406 using RangeProcessC = RangeProcessorSingle<TreeT, ProcessC>;
407 RangeProcessC calcCount( grid.evalActiveVoxelBoundingBox(), grid.tree(), proc );
408
409 typename RangeProcessC::TileIterT tileIter = grid.tree().cbeginValueAll();
410 tileIter.setMaxDepth( tileIter.getLeafDepth() - 1 );
411 typename RangeProcessC::TileRange tileRange( tileIter );
412 tbb::parallel_reduce( tileRange, calcCount );
413 typename RangeProcessC::LeafRange leafRange( grid.tree().cbeginLeaf() );
414 tbb::parallel_reduce( leafRange, calcCount );
415
416 return calcCount.mProc.size;
417}
418
419}
functor to calculate tile and leaf valid nodes count
Definition MROpenVDBHelper.h:368
Class to use in tbb::parallel_reduce for tree operations that do not require an output tree.
Definition MROpenVDBHelper.h:222
void operator()(const TileRange &rCRef)
Transform each non-background tile in the given range.
Definition MROpenVDBHelper.h:286
Class to use in tbb::parallel_reduce for openvdb::tree transformation.
Definition MROpenVDBHelper.h:33
void operator()(const TileRange &rCRef)
Transform each non-background tile in the given range.
Definition MROpenVDBHelper.h:101
Definition MROpenVDBHelper.h:176
functor for shifting voxels
Definition MROpenVDBHelper.h:154
typename openvdb::tree::ValueAccessor< TreeT > OutTreeAccessor
Definition MROpenVDBHelper.h:157
typename TreeT::ValueType ValueT
Definition MROpenVDBHelper.h:227
void setInterrupt(const InterruptFunc &f)
Definition MROpenVDBHelper.h:75
void operator()(const InTreeAccessor &inAcc, OutTreeAccessor &outAcc, openvdb::math::Coord coord)
Definition MROpenVDBHelper.h:160
std::shared_ptr< RangeProgress > ProgressHolder
Definition MROpenVDBHelper.h:225
void setShift(const openvdb::math::Coord &shift)
Definition MROpenVDBHelper.h:166
typename openvdb::tree::ValueAccessor< const TreeT > InTreeAccessor
Definition MROpenVDBHelper.h:156
Proc mProc
Definition MROpenVDBHelper.h:329
typename TreeT::LeafCIter LeafIterT
Definition MROpenVDBHelper.h:229
typename TreeT::LeafCIter LeafIterT
Definition MROpenVDBHelper.h:39
typename TreeT::LeafCIter LeafIterT
Definition MROpenVDBHelper.h:372
void operator()(const LeafRange &rCRef)
Transform each leaf node in the given range.
Definition MROpenVDBHelper.h:255
ImVec2 size(const ViewportRectangle &rect)
Definition MRViewport.h:32
typename TreeT::ValueAllCIter TileIterT
Definition MROpenVDBHelper.h:373
typename TreeT::ValueType ValueT
Definition MROpenVDBHelper.h:37
RangeProcessorSingle(const openvdb::math::CoordBBox &b, const TreeT &inT, const Proc &proc)
Definition MROpenVDBHelper.h:236
std::function< bool(void)> InterruptFunc
Definition MROpenVDBHelper.h:224
void setProgressHolder(ProgressHolder progressHolder)
Definition MROpenVDBHelper.h:252
typename openvdb::tree::IteratorRange< LeafIterT > LeafRange
Definition MROpenVDBHelper.h:231
RangeProcessor(RangeProcessor &other, tbb::split)
Splitting constructor: don't copy the original processor's output tree.
Definition MROpenVDBHelper.h:64
typename openvdb::tree::ValueAccessor< const TreeT > InTreeAccessor
Definition MROpenVDBHelper.h:44
size_t leaf
Definition MROpenVDBHelper.h:359
openvdb::tree::ValueAccessor< const TreeT > TreeAccessor
Definition MROpenVDBHelper.h:371
RangeProcessorSingle(RangeProcessorSingle &other, tbb::split)
Splitting constructor: don't copy the original processor's output tree.
Definition MROpenVDBHelper.h:241
void join(RangeProcessor &other)
Merge another processor's output tree into this processor's tree.
Definition MROpenVDBHelper.h:133
typename openvdb::tree::IteratorRange< TileIterT > TileRange
Definition MROpenVDBHelper.h:232
typename openvdb::tree::ValueAccessor< const TreeT > TreeAccessor
Definition MROpenVDBHelper.h:234
void action(const TileIterT &, const TreeAccessor &, const openvdb::math::CoordBBox &)
Definition MROpenVDBHelper.h:386
size_t tile
Definition MROpenVDBHelper.h:360
typename openvdb::tree::IteratorRange< LeafIterT > LeafRange
Definition MROpenVDBHelper.h:41
typename TreeT::ValueAllCIter TileIterT
Definition MROpenVDBHelper.h:230
bool reportProgress() const
retorts progress if called from main thread, otherwise do nothing
Definition MROpenVDBHelper.h:201
typename TreeT::ValueAllCIter TileIterT
Definition MROpenVDBHelper.h:40
void add(size_t l, size_t t)
Definition MROpenVDBHelper.h:193
RangeCounter()
Definition MROpenVDBHelper.h:375
typename openvdb::tree::ValueAccessor< TreeT > OutTreeAccessor
Definition MROpenVDBHelper.h:45
~RangeProcessor()
Definition MROpenVDBHelper.h:58
std::function< bool(void)> InterruptFunc
Definition MROpenVDBHelper.h:35
Mode
Mode of parallel_reduce.
Definition MROpenVDBHelper.h:180
RangeProgress(ProgressCallback cb, size_t size, Mode mode)
Definition MROpenVDBHelper.h:184
typename TreeT::ValueType ValueT
Definition MROpenVDBHelper.h:370
void action(const LeafIterT &, const TreeAccessor &, const openvdb::math::CoordBBox &)
Definition MROpenVDBHelper.h:381
typename openvdb::tree::IteratorRange< TileIterT > TileRange
Definition MROpenVDBHelper.h:42
RangeProcessor(const openvdb::math::CoordBBox &b, const TreeT &inTree, const Transformer &xform)
Definition MROpenVDBHelper.h:52
void join(RangeProcessorSingle &other)
Merge another processor's output tree into this processor's tree.
Definition MROpenVDBHelper.h:322
typename TreeT::ValueType ValueT
Definition MROpenVDBHelper.h:158
MRVOXELS_API void translateToZero(openvdb::FloatGrid &grid)
void join(const RangeCounter &other)
Definition MROpenVDBHelper.h:391
void setInterrupt(const InterruptFunc &f)
Definition MROpenVDBHelper.h:251
RangeCounter(const RangeCounter &)
Definition MROpenVDBHelper.h:378
void operator()(const LeafRange &rCRef)
Transform each leaf node in the given range.
Definition MROpenVDBHelper.h:78
RangeProcessor(const openvdb::math::CoordBBox &b, const TreeT &inT, TreeT &outT, const Transformer &xform)
Definition MROpenVDBHelper.h:47
RangeSize calculateRangeSize(const GridT &grid)
Definition MROpenVDBHelper.h:401
RangeSize size
Definition MROpenVDBHelper.h:397
@ other
Angle, normally float. Measure in radians.
only for bindings generation
Definition MRCameraOrientationPlugin.h:8
Definition MROpenVDBHelper.h:358