37 #ifndef OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED
38 #define OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED
60 template<
class Gr
idType,
class InterruptType = util::NullInterrupter>
93 void fracture(GridPtrList& grids,
const GridType& cutter,
bool segment =
false,
94 const Vec3sList* points = NULL,
const QuatsList* rotations = NULL,
95 bool cutterOverlap =
true);
101 void clear() { mFragments.clear(); }
108 return mInterrupter && mInterrupter->wasInterrupted(percent);
111 bool isValidFragment(GridType&)
const;
112 void segmentFragments(GridPtrList&)
const;
113 void process(GridPtrList&,
const GridType& cutter);
115 InterruptType* mInterrupter;
116 GridPtrList mFragments;
129 template<
typename Gr
idType,
typename InterruptType>
130 inline std::vector<typename GridType::Ptr>
131 segment(GridType& grid, InterruptType* interrupter = NULL)
133 typedef typename GridType::Ptr GridPtr;
134 typedef typename GridType::TreeType TreeType;
135 typedef typename TreeType::Ptr TreePtr;
136 typedef typename TreeType::ValueType ValueType;
138 std::vector<GridPtr> segments;
140 while (grid.activeVoxelCount() > 0) {
142 if (interrupter && interrupter->wasInterrupted())
break;
147 segment->setTransform(grid.transform().copy());
148 TreePtr tree(
new TreeType(grid.background()));
149 segment->setTree(tree);
151 std::deque<Coord> coordList;
152 coordList.push_back(grid.tree().beginLeaf()->beginValueOn().getCoord());
160 while (!coordList.empty()) {
162 if (interrupter && interrupter->wasInterrupted())
break;
164 ijk = coordList.back();
165 coordList.pop_back();
167 if (!sourceAcc.probeValue(ijk, value))
continue;
168 if (targetAcc.isValueOn(ijk))
continue;
171 sourceAcc.setValueOff(ijk);
173 for (
int n = 0; n < 6; n++) {
175 if (!targetAcc.isValueOn(n_ijk) && sourceAcc.isValueOn(n_ijk)) {
176 coordList.push_back(n_ijk);
183 segments.push_back(segment);
189 template<
class TreeType>
206 inline void operator()(
const tbb::blocked_range<size_t>&);
210 LeafArray& mLeafArray;
211 ValueType mMin, mMax;
215 template <
class TreeType>
224 template <
class TreeType>
227 : mLeafArray(rhs.mLeafArray)
234 template <
class TreeType>
238 tbb::parallel_reduce(mLeafArray.getRange(), *
this);
242 template <
class TreeType>
246 (*this)(mLeafArray.getRange());
250 template <
class TreeType>
254 typename TreeType::LeafNodeType::ValueOnCIter iter;
256 for (
size_t n = range.begin(); n < range.end(); ++n) {
257 iter = mLeafArray.leaf(n).cbeginValueOn();
258 for (; iter; ++iter) {
267 template <
class TreeType>
282 template<
class Gr
idType,
class InterruptType>
284 : mInterrupter(interrupter)
290 template<
class Gr
idType,
class InterruptType>
293 bool segmentation,
const Vec3sList* points,
const QuatsList* rotations,
bool cutterOverlap)
298 if (points && points->size() != 0) {
303 const bool hasInstanceRotations =
304 points && rotations && points->size() == rotations->size();
307 for (
size_t p = 0, P = points->size(); p < P; ++p) {
309 int percent = int((
float(p) /
float(P)) * 100.0);
312 GridType instCutterGrid;
313 instCutterGrid.setTransform(originalCutterTransform->copy());
316 if (hasInstanceRotations) {
321 xform->postTranslate((*points)[p]);
323 xform->postTranslate((*points)[p]);
326 cutterGrid.setTransform(xform);
332 if (mInterrupter != NULL) {
333 doResampleToMatch<BoxSampler>(cutterGrid, instCutterGrid, *mInterrupter);
336 doResampleToMatch<BoxSampler>(cutterGrid, instCutterGrid, interrupter);
339 if (cutterOverlap && !mFragments.empty()) process(mFragments, instCutterGrid);
340 process(grids, instCutterGrid);
345 if (cutterOverlap && !mFragments.empty()) process(mFragments, cutter);
346 process(grids, cutter);
350 segmentFragments(mFragments);
351 segmentFragments(grids);
356 template<
class Gr
idType,
class InterruptType>
360 typedef typename GridType::TreeType TreeType;
361 if (grid.activeVoxelCount() < 27)
return false;
367 minmax.runParallel();
369 if ((minmax.minVoxel() < 0) == (minmax.maxVoxel() < 0))
return false;
376 template<
class Gr
idType,
class InterruptType>
378 LevelSetFracture<GridType, InterruptType>::segmentFragments(GridPtrList& grids)
const
380 GridPtrList newFragments;
382 for (GridPtrListIter it = grids.begin(); it != grids.end(); ++it) {
386 std::vector<typename GridType::Ptr> segments =
internal::segment(*(*it), mInterrupter);
387 for (
size_t n = 0, N = segments.size(); n < N; ++n) {
391 if (isValidFragment(*segments[n])) {
392 newFragments.push_back(segments[n]);
397 grids.swap(newFragments);
401 template<
class Gr
idType,
class InterruptType>
403 LevelSetFracture<GridType, InterruptType>::process(
404 GridPtrList& grids,
const GridType& cutter)
406 typedef typename GridType::Ptr GridPtr;
408 GridPtrList newFragments;
410 for (GridPtrListIter it = grids.begin(); it != grids.end(); ++it) {
417 GridPtr fragment = grid->deepCopy();
422 if (!isValidFragment(*fragment))
continue;
425 GridPtr residual = grid->deepCopy();
430 if (!isValidFragment(*residual))
continue;
432 newFragments.push_back(fragment);
434 grid->tree().clear();
435 grid->tree().merge(residual->tree());
438 if (!newFragments.empty()) {
439 mFragments.splice(mFragments.end(), newFragments);
447 #endif // OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:76
Functions to efficiently perform various compositing operations on grids.
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:114
Defined various multi-threaded utility functions for trees.
#define OPENVDB_VERSION_NAME
Definition: version.h:43
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:52
Propagates the sign of distance values from the active voxels in the narrow band to the inactive valu...
Definition: Exceptions.h:39
OPENVDB_API const Coord COORD_OFFSETS[26]
coordinate offset table for neighboring voxels
#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...
Vec3< float > Vec3s
Definition: Vec3.h:642
void setValue(const Coord &xyz, const ValueType &value)
Set the value of the voxel at the given coordinates and mark the voxel as active. ...
Definition: ValueAccessor.h:287