37 #ifndef OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED 38 #define OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED 40 #include <openvdb/Grid.h> 41 #include <openvdb/math/Quat.h> 42 #include <openvdb/tree/LeafManager.h> 43 #include <openvdb/tools/Prune.h> 44 #include <openvdb/tools/SignedFloodFill.h> 45 #include <openvdb/util/NullInterrupter.h> 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>
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);
310 if (wasInterrupted(percent))
break;
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);
328 if (wasInterrupted())
break;
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>
384 if (wasInterrupted())
break;
386 std::vector<typename GridType::Ptr> segments =
internal::segment(*(*it), mInterrupter);
387 for (
size_t n = 0, N = segments.size(); n < N; ++n) {
389 if (wasInterrupted())
break;
391 if (isValidFragment(*segments[n])) {
392 newFragments.push_back(segments[n]);
397 grids.swap(newFragments);
401 template<
class Gr
idType,
class InterruptType>
406 typedef typename GridType::Ptr GridPtr;
412 if (wasInterrupted())
break;
417 GridPtr fragment = grid->deepCopy();
420 if (wasInterrupted())
break;
422 if (!isValidFragment(*fragment))
continue;
425 GridPtr residual = grid->deepCopy();
428 if (wasInterrupted())
break;
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
LeafType & leaf(size_t leafIdx) const
Return a pointer to the leaf node at index leafIdx in the array.
Definition: LeafManager.h:323
#define OPENVDB_VERSION_NAME
Definition: version.h:43
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:52
Definition: Exceptions.h:39
RangeType getRange(size_t grainsize=1) const
Return a tbb::blocked_range of leaf array indices.
Definition: LeafManager.h:347
OPENVDB_API const Coord COORD_OFFSETS[26]
coordinate offset table for neighboring voxels
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
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