13#ifndef OPENVDB_TOOLS_POLYSOUP_TO_LEVELSET_HAS_BEEN_INCLUDED
14#define OPENVDB_TOOLS_POLYSOUP_TO_LEVELSET_HAS_BEEN_INCLUDED
43 std::vector<Vec3s>
vtx;
44 std::vector<Vec3I>
tri;
57template <
typename Gr
idType = FloatGr
id>
82template<
typename Gr
idType,
class ShrinkWrapT = ShrinkWrapLimit,
class ProgressT =
void>
87 float voxelSize = 0.0,
88 const ShrinkWrapT &D = ShrinkWrapT(),
90 ProgressT *progress =
nullptr,
115template<
typename Gr
idType,
class ShrinkWrapT = ShrinkWrapLimit,
class ProgressT =
void>
116std::vector<typename GridType::Ptr>
120 std::vector<Vec3s>& vtx,
121 std::vector<Vec3I>& tri,
122 std::vector<Vec4I>& quad,
123 const ShrinkWrapT &D = ShrinkWrapT(),
125 ProgressT *progress =
nullptr,
126 int offset_mode = 0);
150template<
typename Gr
idType,
class ShrinkWrapT = ShrinkWrapLimit,
class ProgressT =
void>
151std::vector<typename GridType::Ptr>
155 std::vector<Vec3s>& vtx,
156 std::vector<Vec3I>& tri,
157 std::vector<Vec4I>& quad,
158 const ShrinkWrapT &D = ShrinkWrapT(),
160 ProgressT *progress =
nullptr,
161 int offset_mode = 0);
168template<
typename Gr
idType>
194 template<
class ShrinkWrapT,
class ProgressT>
195 void process(
const ShrinkWrapT &D, ProgressT *progress,
int mode = 0);
203 typename GridType::Ptr
grid(
int n = 0)
const {
return mGrids[n];}
207 std::vector<typename GridType::Ptr>
grids()
const {
return mGrids;}
216 const PolySoup&
mesh(
int n = 0,
float adaptivity = 0.005f,
float isoValue = 0.0f)
218 volumeToMesh(*mGrids[n], mPoly.vtx, mPoly.tri, mPoly.quad, isoValue, adaptivity);
231 auto offset(
float dx,
int mode = 0);
246 float mMinVoxelSize, mMaxVoxelSize, mHalfWidth;
247 std::vector<typename GridType::Ptr> mGrids;
251 auto upsample(
const GridType &inGrid);
254 auto shrinkWrap(GridType &grid,
const GridType &gridB,
float &d);
260template<
typename Gr
idType>
262 : mPoly(poly), mHalfWidth(width)
264 if constexpr(!std::is_floating_point<typename GridType::ValueType>::value) {
267 if (!(mHalfWidth > 0.0f)) {
275 const float maxLength = mPoly.bbox.extents()[mPoly.bbox.maxExtent()];
276 if (!(maxLength > 0.0f)) {
279 mMinVoxelSize = maxLength/(float(dim) - 2.0f*(mHalfWidth + 1.0f));
280 mMaxVoxelSize = maxLength / 2.0f;
286 "finite and positive (is dim too small for the given halfWidth?)");
293template<
typename Gr
idType>
295 : mPoly(poly), mMinVoxelSize(voxelSize), mHalfWidth(width)
297 if constexpr(!std::is_floating_point<typename GridType::ValueType>::value) {
300 if (!(mHalfWidth > 0.0f)) {
309 const float maxLength = mPoly.bbox.extents()[mPoly.bbox.maxExtent()];
310 if (!(maxLength > 0.0f)) {
313 mMaxVoxelSize = maxLength / 2.0f;
322template<
typename Gr
idType>
323template<
class ShrinkWrapT,
class ProgressT>
326 auto myProgress = [&](
const std::string &s){
if constexpr(!std::is_same<ProgressT,void>::value)
if (progress) (*progress)(s);};
329 for (
float dx = mMinVoxelSize; dx <= mMaxVoxelSize; dx *= 2.0f) {
330 myProgress(
"Offset: dx=" + std::to_string(dx)+
", range: "+std::to_string(mMinVoxelSize)+
" -> "+std::to_string(mMaxVoxelSize));
331 mGrids.push_back(this->
offset(dx, offset_mode));
335 double vol[2] = {0.0, 0.0};
338 auto grid = mGrids.back();
341 for (
auto iter = mGrids.rbegin(), end = mGrids.rend(); iter != end; ++iter) {
343 for (
float d = 0.0f, dx =
float(
grid->voxelSize()[0]), Ddx = D(dx); d < Ddx; vol[0] = vol[1]) {
344 myProgress(
"Shrink wrap d=" + std::to_string(d) +
", D("+std::to_string(dx) +
")=" + std::to_string(Ddx));
345 grid = this->shrinkWrap(*
grid, **iter, d);
356template<
typename Gr
idType>
359 using RangeT = tbb::blocked_range<std::vector<Vec3s>::const_iterator>;
360 RangeT range(vtx.begin(), vtx.end(), 1024);
364 BBoxOp(BBoxOp& s, tbb::split) : bbox(s.bbox) {}
365 void operator()(
const RangeT& r) {
for (
auto p=r.begin(); p!=r.end(); ++p) bbox.
expand(*p);}
366 void join(BBoxOp& rhs) {bbox.
expand(rhs.bbox);}
371 tbb::parallel_reduce(range, tmp);
378template<
typename Gr
idType>
382 typename GridType::Ptr
grid(
nullptr);
391 tools::foreach(
grid->beginValueOn(), [dx](
const typename GridType::ValueOnIter& it){it.setValue(*it - dx);},
true,
true);
411template<
typename Gr
idType>
412auto PolySoupToLevelSet<GridType>::upsample(
const GridType &inGrid)
422template<
typename Gr
idType>
423auto PolySoupToLevelSet<GridType>::shrinkWrap(GridType &grid,
const GridType &gridB,
float &d)
425 const float maxDist = 2.0f;
426 LevelSetFilter<GridType> filter(grid);
427 filter.setNormCount(3);
435 if (mIsGridSDF ==
false) {
439 filter.offset(
static_cast<typename GridType::ValueType
>(maxDist * grid.voxelSize()[0]));
448 const float mErode, mThres;
450 ShrinkWrapLimit(
float erode = 8.0f,
float thres = 0.0f) : mErode(erode), mThres(thres) {}
452 return dx>=2*mThres ? mErode : dx<=mThres ? 1.0f : 1.0f + (mErode-1.0f)*(dx-mThres)/mThres;
458template<
typename Gr
idType,
class ShrinkWrapT,
class ProgressT>
459typename GridType::Ptr
464 const ShrinkWrapT &D,
469 static_assert(std::is_floating_point<typename GridType::ValueType>::value,
470 "polySoupToLevelSet requires an SDF grid with floating-point values");
472 auto ptr = voxelSize > 0.0f ? std::make_unique<T>(std::move(poly), voxelSize, halfWidth) :
473 std::make_unique<T>(std::move(poly), dim, halfWidth);
474 ptr->process(D, progress, offset_mode);
480template<
typename Gr
idType,
class ShrinkWrapT,
class ProgressT>
481std::vector<typename GridType::Ptr>
485 std::vector<Vec3s>& vtx,
486 std::vector<Vec3I>& tri,
487 std::vector<Vec4I>& quad,
488 const ShrinkWrapT &D,
493 static_assert(std::is_floating_point<typename GridType::ValueType>::value,
494 "polySoupToLevelSet requires an SDF grid with floating-point values");
495 PolySoup poly{std::move(vtx), std::move(tri), std::move(quad), bbox};
497 tmp.
process(D, progress, offset_mode);
503template<
typename Gr
idType,
class ShrinkWrapT,
class ProgressT>
504std::vector<typename GridType::Ptr>
508 std::vector<Vec3s>& vtx,
509 std::vector<Vec3I>& tri,
510 std::vector<Vec4I>& quad,
511 const ShrinkWrapT &D,
516 static_assert(std::is_floating_point<typename GridType::ValueType>::value,
517 "polySoupToLevelSet requires an SDF grid with floating-point values");
518 PolySoup poly{std::move(vtx), std::move(tri), std::move(quad), bbox};
520 tmp.
process(D, progress, offset_mode);
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
Functions to efficiently perform various compositing operations on grids.
Defined the six functions {fog,sdf}To{Sdf,Ext,SdfAndExt} in addition to the two functions maskSdf and...
Generate a narrow-band level set of a dilated surface mesh.
Performs various types of level set deformations with interface tracking. These unrestricted deformat...
Miscellaneous utility methods that operate primarily or exclusively on level set grids.
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Convert polygonal meshes that consist of quads and/or triangles into signed or unsigned distance fiel...
Extract polygonal surfaces from scalar volumes.
Definition Exceptions.h:56
Definition Exceptions.h:64
Definition Exceptions.h:65
Axis-aligned bounding box.
Definition BBox.h:24
void expand(ElementType padding)
Pad this bounding box.
Definition BBox.h:321
@ TVD_RK1
Definition FiniteDifference.h:235
@ TVD_RK3
Definition FiniteDifference.h:237
bool isApproxZero(const Type &x, const Type &tolerance)
Return true if x is equal to zero to within the given tolerance.
Definition Math.h:360
bool isFinite(const float x)
Return true if x is finite.
Definition Math.h:385
@ FIRST_BIAS
Definition FiniteDifference.h:166
@ HJWENO5_BIAS
Definition FiniteDifference.h:170
static const Real LEVEL_SET_HALF_WIDTH
Definition Types.h:532
GridType::Ptr createLevelSet(Real voxelSize=1.0, Real halfWidth=LEVEL_SET_HALF_WIDTH)
Create a new grid of type GridType classified as a "Level Set", i.e., a narrow-band level set.
Definition Grid.h:1774
Definition Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:284