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/util/NullInterrupter.h>
57 template<
class Gr
idType,
class InterruptType = util::NullInterrupter>
92 bool cutterOverlap =
true);
98 void clear() { mFragments.clear(); }
105 return mInterrupter && mInterrupter->wasInterrupted(percent);
108 bool isValidFragment(GridType&)
const;
109 void segmentFragments(GridPtrList&)
const;
110 void process(GridPtrList&,
const GridType& cutter);
112 InterruptType* mInterrupter;
113 GridPtrList mFragments;
126 template<
typename Gr
idType,
typename InterruptType>
127 inline std::vector<typename GridType::Ptr>
128 segment(GridType& grid, InterruptType* interrupter = NULL)
130 typedef typename GridType::Ptr GridPtr;
131 typedef typename GridType::TreeType TreeType;
132 typedef typename TreeType::Ptr TreePtr;
133 typedef typename TreeType::ValueType ValueType;
135 std::vector<GridPtr> segments;
137 while (grid.activeVoxelCount() > 0) {
139 if (interrupter && interrupter->wasInterrupted())
break;
144 segment->setTransform(grid.transform().copy());
145 TreePtr tree(
new TreeType(grid.background()));
146 segment->setTree(tree);
148 std::deque<Coord> coordList;
149 coordList.push_back(grid.tree().beginLeaf()->beginValueOn().getCoord());
157 while (!coordList.empty()) {
159 if (interrupter && interrupter->wasInterrupted())
break;
161 ijk = coordList.back();
162 coordList.pop_back();
164 if (!sourceAcc.probeValue(ijk, value))
continue;
165 if (targetAcc.isValueOn(ijk))
continue;
168 sourceAcc.setValueOff(ijk);
170 for (
int n = 0; n < 6; n++) {
172 if (!targetAcc.isValueOn(n_ijk) && sourceAcc.isValueOn(n_ijk)) {
173 coordList.push_back(n_ijk);
178 grid.tree().pruneInactive();
179 segment->tree().signedFloodFill();
180 segments.push_back(segment);
191 template<
class Gr
idType,
class InterruptType>
193 : mInterrupter(interrupter)
199 template<
class Gr
idType,
class InterruptType>
202 bool segmentation,
const Vec3sList* points,
const QuatsList* rotations,
bool cutterOverlap)
207 if (points && points->size() != 0) {
212 const bool hasInstanceRotations =
213 points && rotations && points->size() == rotations->size();
216 for (
size_t p = 0, P = points->size(); p < P; ++p) {
218 int percent = int((
float(p) /
float(P)) * 100.0);
221 GridType instCutterGrid;
222 instCutterGrid.setTransform(originalCutterTransform->copy());
225 if (hasInstanceRotations) {
230 xform->postTranslate((*points)[p]);
232 xform->postTranslate((*points)[p]);
235 cutterGrid.setTransform(xform);
241 if (mInterrupter != NULL) {
242 doResampleToMatch<BoxSampler>(cutterGrid, instCutterGrid, *mInterrupter);
245 doResampleToMatch<BoxSampler>(cutterGrid, instCutterGrid, interrupter);
248 if (cutterOverlap && !mFragments.empty()) process(mFragments, instCutterGrid);
249 process(grids, instCutterGrid);
254 if (cutterOverlap && !mFragments.empty()) process(mFragments, cutter);
255 process(grids, cutter);
259 segmentFragments(mFragments);
260 segmentFragments(grids);
265 template<
class Gr
idType,
class InterruptType>
269 typedef typename GridType::TreeType TreeType;
270 if (grid.activeVoxelCount() < 27)
return false;
276 minmax.runParallel();
278 if ((minmax.minVoxel() < 0) == (minmax.maxVoxel() < 0))
return false;
285 template<
class Gr
idType,
class InterruptType>
287 LevelSetFracture<GridType, InterruptType>::segmentFragments(GridPtrList& grids)
const
289 GridPtrList newFragments;
291 for (GridPtrListIter it = grids.begin(); it != grids.end(); ++it) {
295 std::vector<typename GridType::Ptr> segments =
internal::segment(*(*it), mInterrupter);
296 for (
size_t n = 0, N = segments.size(); n < N; ++n) {
300 if (isValidFragment(*segments[n])) {
301 newFragments.push_back(segments[n]);
306 grids.swap(newFragments);
310 template<
class Gr
idType,
class InterruptType>
312 LevelSetFracture<GridType, InterruptType>::process(
313 GridPtrList& grids,
const GridType& cutter)
315 typedef typename GridType::Ptr GridPtr;
317 GridPtrList newFragments;
319 for (GridPtrListIter it = grids.begin(); it != grids.end(); ++it) {
326 GridPtr fragment = grid->deepCopy();
331 if (!isValidFragment(*fragment))
continue;
334 GridPtr residual = grid->deepCopy();
339 if (!isValidFragment(*residual))
continue;
341 newFragments.push_back(fragment);
343 grid->tree().clear();
344 grid->tree().merge(residual->tree());
347 if (!newFragments.empty()) {
348 mFragments.splice(mFragments.end(), newFragments);
356 #endif // OPENVDB_TOOLS_LEVELSETFRACTURE_HAS_BEEN_INCLUDED
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
Functions to efficiently perform various compositing operations on grids.
Vec3< float > Vec3s
Definition: Vec3.h:604
#define OPENVDB_VERSION_NAME
Definition: version.h:45
Miscellaneous utilities that operate primarily or exclusively on level set grids. ...
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:56
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:109
OPENVDB_API const Coord COORD_OFFSETS[26]
coordinate offset table for neighboring voxels
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:76
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:52