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