37 #ifndef OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED 38 #define OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED 51 #include <tbb/blocked_range.h> 52 #include <tbb/parallel_reduce.h> 61 template<
class Gr
idType,
class InterruptType = util::NullInterrupter>
94 void fracture(
GridPtrList& grids,
const GridType& cutter,
bool segment =
false,
96 bool cutterOverlap =
true);
102 void clear() { mFragments.clear(); }
109 return mInterrupter && mInterrupter->wasInterrupted(percent);
112 bool isValidFragment(GridType&)
const;
113 void segmentFragments(GridPtrList&)
const;
114 void process(GridPtrList&,
const GridType& cutter);
116 InterruptType* mInterrupter;
117 GridPtrList mFragments;
126 namespace level_set_fracture_internal {
129 template<
typename LeafNodeType>
136 , maxValue(-minValue)
137 , mNodes(nodes.empty() ? NULL : &nodes.front())
143 , maxValue(-minValue)
149 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
150 const ValueType* data = mNodes[n]->buffer().data();
151 for (
Index i = 0; i < LeafNodeType::SIZE; ++i) {
152 minValue =
std::min(minValue, data[i]);
153 maxValue =
std::max(maxValue, data[i]);
165 LeafNodeType
const *
const *
const mNodes;
175 template<
class Gr
idType,
class InterruptType>
177 : mInterrupter(interrupter)
183 template<
class Gr
idType,
class InterruptType>
186 bool segmentation,
const Vec3sList* points,
const QuatsList* rotations,
bool cutterOverlap)
191 if (points && points->size() != 0) {
195 GridType cutterGrid(*const_cast<GridType*>(&cutter),
ShallowCopy());
197 const bool hasInstanceRotations =
198 points && rotations && points->size() == rotations->size();
201 for (
size_t p = 0, P = points->size(); p < P; ++p) {
202 int percent = int((
float(p) /
float(P)) * 100.0);
205 GridType instCutterGrid;
206 instCutterGrid.setTransform(originalCutterTransform->copy());
209 if (hasInstanceRotations) {
214 xform->postTranslate((*points)[p]);
216 xform->postTranslate((*points)[p]);
219 cutterGrid.setTransform(xform);
223 if (mInterrupter != NULL) {
225 if (hasInstanceRotations) {
226 doResampleToMatch<BoxSampler>(cutterGrid, instCutterGrid, *mInterrupter);
228 doResampleToMatch<PointSampler>(cutterGrid, instCutterGrid, *mInterrupter);
232 if (hasInstanceRotations) {
233 doResampleToMatch<BoxSampler>(cutterGrid, instCutterGrid, interrupter);
235 doResampleToMatch<PointSampler>(cutterGrid, instCutterGrid, interrupter);
241 if (cutterOverlap && !mFragments.empty()) process(mFragments, instCutterGrid);
242 process(grids, instCutterGrid);
247 if (cutterOverlap && !mFragments.empty()) process(mFragments, cutter);
248 process(grids, cutter);
252 segmentFragments(mFragments);
253 segmentFragments(grids);
258 template<
class Gr
idType,
class InterruptType>
262 typedef typename GridType::TreeType::LeafNodeType LeafNodeType;
264 if (grid.tree().leafCount() < 9) {
266 std::vector<const LeafNodeType*> nodes;
267 grid.tree().getNodes(nodes);
271 for (
size_t n = 0, N = nodes.size(); n < N; ++n) {
272 activeVoxelCount += nodes[n]->onVoxelCount();
275 if (activeVoxelCount < 27)
return false;
277 level_set_fracture_internal::FindMinMaxVoxelValue<LeafNodeType> op(nodes);
278 tbb::parallel_reduce(tbb::blocked_range<size_t>(0, nodes.size()), op);
280 if ((op.minValue < 0) == (op.maxValue < 0))
return false;
287 template<
class Gr
idType,
class InterruptType>
289 LevelSetFracture<GridType, InterruptType>::segmentFragments(GridPtrList& grids)
const 291 GridPtrList newFragments;
293 for (GridPtrListIter it = grids.begin(); it != grids.end(); ++it) {
295 std::vector<typename GridType::Ptr> segments;
298 for (
size_t n = 0, N = segments.size(); n < N; ++n) {
299 newFragments.push_back(segments[n]);
303 grids.swap(newFragments);
307 template<
class Gr
idType,
class InterruptType>
309 LevelSetFracture<GridType, InterruptType>::process(
310 GridPtrList& grids,
const GridType& cutter)
312 typedef typename GridType::Ptr GridPtr;
313 GridPtrList newFragments;
315 for (GridPtrListIter it = grids.begin(); it != grids.end(); ++it) {
322 if (!isValidFragment(*fragment))
continue;
325 if (!isValidFragment(*residual))
continue;
327 newFragments.push_back(fragment);
329 grid->tree().clear();
330 grid->tree().merge(residual->tree());
333 if (!newFragments.empty()) {
334 mFragments.splice(mFragments.end(), newFragments);
342 #endif // OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED
Index32 Index
Definition: Types.h:61
uint64_t Index64
Definition: Types.h:60
Functions to efficiently perform various compositing operations on grids.
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:76
Tag dispatch class that distinguishes shallow copy constructors from deep copy constructors.
Definition: Types.h:515
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
Definition: Exceptions.h:40
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:52
Miscellaneous utility methods that operate primarily or exclusively on level set grids.
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
Vec3< float > Vec3s
Definition: Vec3.h:678