10 #ifndef OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED
11 #define OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED
26 #include <tbb/blocked_range.h>
27 #include <tbb/parallel_reduce.h>
36 template<
class Gr
idType,
class InterruptType = util::NullInterrupter>
69 void fracture(
GridPtrList& grids,
const GridType& cutter,
bool segment =
false,
71 bool cutterOverlap =
true);
77 void clear() { mFragments.clear(); }
84 return mInterrupter && mInterrupter->wasInterrupted(percent);
87 bool isValidFragment(GridType&)
const;
88 void segmentFragments(GridPtrList&)
const;
89 void process(GridPtrList&,
const GridType& cutter);
91 InterruptType* mInterrupter;
92 GridPtrList mFragments;
101 namespace level_set_fracture_internal {
104 template<
typename LeafNodeType>
111 , maxValue(-minValue)
112 , mNodes(nodes.empty() ? nullptr : &nodes.front())
118 , maxValue(-minValue)
124 for (
size_t n = range.begin(), N = range.end(); n < N; ++n) {
125 const ValueType* data = mNodes[n]->buffer().data();
126 for (
Index i = 0; i < LeafNodeType::SIZE; ++i) {
127 minValue =
std::min(minValue, data[i]);
128 maxValue =
std::max(maxValue, data[i]);
140 LeafNodeType
const *
const *
const mNodes;
150 template<
class Gr
idType,
class InterruptType>
152 : mInterrupter(interrupter)
158 template<
class Gr
idType,
class InterruptType>
161 bool segmentation,
const Vec3sList* points,
const QuatsList* rotations,
bool cutterOverlap)
166 if (points && points->size() != 0) {
170 GridType cutterGrid(*
const_cast<GridType*
>(&cutter),
ShallowCopy());
172 const bool hasInstanceRotations =
173 points && rotations && points->size() == rotations->size();
176 for (
size_t p = 0, P = points->size(); p < P; ++p) {
177 int percent = int((
float(p) /
float(P)) * 100.0);
180 GridType instCutterGrid;
181 instCutterGrid.setTransform(originalCutterTransform->copy());
184 if (hasInstanceRotations) {
189 xform->postTranslate((*points)[p]);
191 xform->postTranslate((*points)[p]);
194 cutterGrid.setTransform(xform);
198 if (mInterrupter !=
nullptr) {
200 if (hasInstanceRotations) {
201 doResampleToMatch<BoxSampler>(cutterGrid, instCutterGrid, *mInterrupter);
203 doResampleToMatch<PointSampler>(cutterGrid, instCutterGrid, *mInterrupter);
207 if (hasInstanceRotations) {
208 doResampleToMatch<BoxSampler>(cutterGrid, instCutterGrid, interrupter);
210 doResampleToMatch<PointSampler>(cutterGrid, instCutterGrid, interrupter);
216 if (cutterOverlap && !mFragments.empty()) process(mFragments, instCutterGrid);
217 process(grids, instCutterGrid);
222 if (cutterOverlap && !mFragments.empty()) process(mFragments, cutter);
223 process(grids, cutter);
227 segmentFragments(mFragments);
228 segmentFragments(grids);
233 template<
class Gr
idType,
class InterruptType>
237 using LeafNodeType =
typename GridType::TreeType::LeafNodeType;
239 if (grid.tree().leafCount() < 9) {
241 std::vector<const LeafNodeType*> nodes;
242 grid.tree().getNodes(nodes);
246 for (
size_t n = 0, N = nodes.size(); n < N; ++n) {
247 activeVoxelCount += nodes[n]->onVoxelCount();
250 if (activeVoxelCount < 27)
return false;
252 level_set_fracture_internal::FindMinMaxVoxelValue<LeafNodeType> op(nodes);
253 tbb::parallel_reduce(tbb::blocked_range<size_t>(0, nodes.size()), op);
255 if ((op.minValue < 0) == (op.maxValue < 0))
return false;
262 template<
class Gr
idType,
class InterruptType>
264 LevelSetFracture<GridType, InterruptType>::segmentFragments(GridPtrList& grids)
const
266 GridPtrList newFragments;
268 for (GridPtrListIter it = grids.begin(); it != grids.end(); ++it) {
270 std::vector<typename GridType::Ptr> segments;
273 for (
size_t n = 0, N = segments.size(); n < N; ++n) {
274 newFragments.push_back(segments[n]);
278 grids.swap(newFragments);
282 template<
class Gr
idType,
class InterruptType>
284 LevelSetFracture<GridType, InterruptType>::process(
285 GridPtrList& grids,
const GridType& cutter)
287 using GridPtr =
typename GridType::Ptr;
288 GridPtrList newFragments;
290 for (GridPtrListIter it = grids.begin(); it != grids.end(); ++it) {
297 if (!isValidFragment(*fragment))
continue;
300 if (!isValidFragment(*residual))
continue;
302 newFragments.push_back(fragment);
304 grid->tree().clear();
305 grid->tree().merge(residual->tree());
308 if (!newFragments.empty()) {
309 mFragments.splice(mFragments.end(), newFragments);
Functions to efficiently perform various compositing operations on grids.
Miscellaneous utility methods that operate primarily or exclusively on level set grids.
Tag dispatch class that distinguishes shallow copy constructors from deep copy constructors.
Definition: openvdb/Types.h:539
@ Z_AXIS
Definition: Math.h:907
@ X_AXIS
Definition: Math.h:905
@ Y_AXIS
Definition: Math.h:906
Vec3< float > Vec3s
Definition: Vec3.h:667
@ XYZ_ROTATION
Definition: Math.h:912
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:49
Index32 Index
Definition: openvdb/Types.h:32
uint64_t Index64
Definition: openvdb/Types.h:31
openvdb::GridBase::Ptr GridPtr
Definition: openvdb_houdini/openvdb_houdini/Utils.h:34
Definition: openvdb/Exceptions.h:13
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:26
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:101
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:153