37 #ifndef OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED 38 #define OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED 53 #include <tbb/blocked_range.h> 54 #include <tbb/parallel_reduce.h> 63 template<
class Gr
idType,
class InterruptType = util::NullInterrupter>
96 void fracture(
GridPtrList& grids,
const GridType& cutter,
bool segment =
false,
98 bool cutterOverlap =
true);
104 void clear() { mFragments.clear(); }
111 return mInterrupter && mInterrupter->wasInterrupted(percent);
114 bool isValidFragment(GridType&)
const;
115 void segmentFragments(GridPtrList&)
const;
116 void process(GridPtrList&,
const GridType& cutter);
118 InterruptType* mInterrupter;
119 GridPtrList mFragments;
128 namespace level_set_fracture_internal {
131 template<
typename LeafNodeType>
138 , maxValue(-minValue)
139 , mNodes(nodes.empty() ? nullptr : &nodes.front())
145 , maxValue(-minValue)
151 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
152 const ValueType* data = mNodes[n]->buffer().data();
153 for (
Index i = 0; i < LeafNodeType::SIZE; ++i) {
154 minValue =
std::min(minValue, data[i]);
155 maxValue =
std::max(maxValue, data[i]);
167 LeafNodeType
const *
const *
const mNodes;
177 template<
class Gr
idType,
class InterruptType>
179 : mInterrupter(interrupter)
185 template<
class Gr
idType,
class InterruptType>
188 bool segmentation,
const Vec3sList* points,
const QuatsList* rotations,
bool cutterOverlap)
193 if (points && points->size() != 0) {
197 GridType cutterGrid(*const_cast<GridType*>(&cutter),
ShallowCopy());
199 const bool hasInstanceRotations =
200 points && rotations && points->size() == rotations->size();
203 for (
size_t p = 0, P = points->size(); p < P; ++p) {
204 int percent = int((
float(p) /
float(P)) * 100.0);
207 GridType instCutterGrid;
208 instCutterGrid.setTransform(originalCutterTransform->copy());
211 if (hasInstanceRotations) {
216 xform->postTranslate((*points)[p]);
218 xform->postTranslate((*points)[p]);
221 cutterGrid.setTransform(xform);
225 if (mInterrupter !=
nullptr) {
227 if (hasInstanceRotations) {
228 doResampleToMatch<BoxSampler>(cutterGrid, instCutterGrid, *mInterrupter);
230 doResampleToMatch<PointSampler>(cutterGrid, instCutterGrid, *mInterrupter);
234 if (hasInstanceRotations) {
235 doResampleToMatch<BoxSampler>(cutterGrid, instCutterGrid, interrupter);
237 doResampleToMatch<PointSampler>(cutterGrid, instCutterGrid, interrupter);
243 if (cutterOverlap && !mFragments.empty()) process(mFragments, instCutterGrid);
244 process(grids, instCutterGrid);
249 if (cutterOverlap && !mFragments.empty()) process(mFragments, cutter);
250 process(grids, cutter);
254 segmentFragments(mFragments);
255 segmentFragments(grids);
260 template<
class Gr
idType,
class InterruptType>
264 using LeafNodeType =
typename GridType::TreeType::LeafNodeType;
266 if (grid.tree().leafCount() < 9) {
268 std::vector<const LeafNodeType*> nodes;
269 grid.tree().getNodes(nodes);
273 for (
size_t n = 0, N = nodes.size(); n < N; ++n) {
274 activeVoxelCount += nodes[n]->onVoxelCount();
277 if (activeVoxelCount < 27)
return false;
279 level_set_fracture_internal::FindMinMaxVoxelValue<LeafNodeType> op(nodes);
280 tbb::parallel_reduce(tbb::blocked_range<size_t>(0, nodes.size()), op);
282 if ((op.minValue < 0) == (op.maxValue < 0))
return false;
289 template<
class Gr
idType,
class InterruptType>
291 LevelSetFracture<GridType, InterruptType>::segmentFragments(GridPtrList& grids)
const 293 GridPtrList newFragments;
295 for (GridPtrListIter it = grids.begin(); it != grids.end(); ++it) {
297 std::vector<typename GridType::Ptr> segments;
300 for (
size_t n = 0, N = segments.size(); n < N; ++n) {
301 newFragments.push_back(segments[n]);
305 grids.swap(newFragments);
309 template<
class Gr
idType,
class InterruptType>
311 LevelSetFracture<GridType, InterruptType>::process(
312 GridPtrList& grids,
const GridType& cutter)
314 using GridPtr =
typename GridType::Ptr;
315 GridPtrList newFragments;
317 for (GridPtrListIter it = grids.begin(); it != grids.end(); ++it) {
324 if (!isValidFragment(*fragment))
continue;
327 if (!isValidFragment(*residual))
continue;
329 newFragments.push_back(fragment);
331 grid->tree().clear();
332 grid->tree().merge(residual->tree());
335 if (!newFragments.empty()) {
336 mFragments.splice(mFragments.end(), newFragments);
344 #endif // OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED
Functions to efficiently perform various compositing operations on grids.
Index32 Index
Definition: Types.h:61
Tag dispatch class that distinguishes shallow copy constructors from deep copy constructors.
Definition: Types.h:747
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:128
Definition: Exceptions.h:40
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:52
Vec3< float > Vec3s
Definition: Vec3.h:688
uint64_t Index64
Definition: Types.h:60
Miscellaneous utility methods that operate primarily or exclusively on level set grids.
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:180
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:76