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>
59 template<
class Gr
idType,
class InterruptType = util::NullInterrupter>
92 void fracture(GridPtrList& grids,
const GridType& cutter,
bool segment =
false,
93 const Vec3sList* points = NULL,
const QuatsList* rotations = NULL,
94 bool cutterOverlap =
true);
100 void clear() { mFragments.clear(); }
107 return mInterrupter && mInterrupter->wasInterrupted(percent);
110 bool isValidFragment(GridType&)
const;
111 void segmentFragments(GridPtrList&)
const;
112 void process(GridPtrList&,
const GridType& cutter);
114 InterruptType* mInterrupter;
115 GridPtrList mFragments;
128 template<
typename Gr
idType,
typename InterruptType>
129 inline std::vector<typename GridType::Ptr>
130 segment(GridType& grid, InterruptType* interrupter = NULL)
132 typedef typename GridType::Ptr GridPtr;
133 typedef typename GridType::TreeType TreeType;
134 typedef typename TreeType::Ptr TreePtr;
135 typedef typename TreeType::ValueType ValueType;
137 std::vector<GridPtr> segments;
139 while (grid.activeVoxelCount() > 0) {
141 if (interrupter && interrupter->wasInterrupted())
break;
146 segment->setTransform(grid.transform().copy());
147 TreePtr tree(
new TreeType(grid.background()));
148 segment->setTree(tree);
150 std::deque<Coord> coordList;
151 coordList.push_back(grid.tree().beginLeaf()->beginValueOn().getCoord());
159 while (!coordList.empty()) {
161 if (interrupter && interrupter->wasInterrupted())
break;
163 ijk = coordList.back();
164 coordList.pop_back();
166 if (!sourceAcc.probeValue(ijk, value))
continue;
167 if (targetAcc.isValueOn(ijk))
continue;
170 sourceAcc.setValueOff(ijk);
172 for (
int n = 0; n < 6; n++) {
174 if (!targetAcc.isValueOn(n_ijk) && sourceAcc.isValueOn(n_ijk)) {
175 coordList.push_back(n_ijk);
182 segments.push_back(segment);
193 template<
class Gr
idType,
class InterruptType>
195 : mInterrupter(interrupter)
201 template<
class Gr
idType,
class InterruptType>
204 bool segmentation,
const Vec3sList* points,
const QuatsList* rotations,
bool cutterOverlap)
209 if (points && points->size() != 0) {
214 const bool hasInstanceRotations =
215 points && rotations && points->size() == rotations->size();
218 for (
size_t p = 0, P = points->size(); p < P; ++p) {
220 int percent = int((
float(p) /
float(P)) * 100.0);
223 GridType instCutterGrid;
224 instCutterGrid.setTransform(originalCutterTransform->copy());
227 if (hasInstanceRotations) {
232 xform->postTranslate((*points)[p]);
234 xform->postTranslate((*points)[p]);
237 cutterGrid.setTransform(xform);
243 if (mInterrupter != NULL) {
244 doResampleToMatch<BoxSampler>(cutterGrid, instCutterGrid, *mInterrupter);
247 doResampleToMatch<BoxSampler>(cutterGrid, instCutterGrid, interrupter);
250 if (cutterOverlap && !mFragments.empty()) process(mFragments, instCutterGrid);
251 process(grids, instCutterGrid);
256 if (cutterOverlap && !mFragments.empty()) process(mFragments, cutter);
257 process(grids, cutter);
261 segmentFragments(mFragments);
262 segmentFragments(grids);
267 template<
class Gr
idType,
class InterruptType>
271 typedef typename GridType::TreeType TreeType;
272 if (grid.activeVoxelCount() < 27)
return false;
278 minmax.runParallel();
280 if ((minmax.minVoxel() < 0) == (minmax.maxVoxel() < 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) {
297 std::vector<typename GridType::Ptr> segments =
internal::segment(*(*it), mInterrupter);
298 for (
size_t n = 0, N = segments.size(); n < N; ++n) {
302 if (isValidFragment(*segments[n])) {
303 newFragments.push_back(segments[n]);
308 grids.swap(newFragments);
312 template<
class Gr
idType,
class InterruptType>
314 LevelSetFracture<GridType, InterruptType>::process(
315 GridPtrList& grids,
const GridType& cutter)
317 typedef typename GridType::Ptr GridPtr;
319 GridPtrList newFragments;
321 for (GridPtrListIter it = grids.begin(); it != grids.end(); ++it) {
328 GridPtr fragment = grid->deepCopy();
333 if (!isValidFragment(*fragment))
continue;
336 GridPtr residual = grid->deepCopy();
341 if (!isValidFragment(*residual))
continue;
343 newFragments.push_back(fragment);
345 grid->tree().clear();
346 grid->tree().merge(residual->tree());
349 if (!newFragments.empty()) {
350 mFragments.splice(mFragments.end(), newFragments);
358 #endif // OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED
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:109
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:76
#define OPENVDB_VERSION_NAME
Definition: version.h:43
Definition: Exceptions.h:39
Miscellaneous utilities that operate primarily or exclusively on level set grids. ...
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:52
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:628
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:241