4#ifndef OPENVDB_TOOLS_LEVELSETREBUILD_HAS_BEEN_INCLUDED
5#define OPENVDB_TOOLS_LEVELSETREBUILD_HAS_BEEN_INCLUDED
15#define OPENVDB_USE_ORACLE_IN_REBUILD 0
21#if OPENVDB_USE_ORACLE_IN_REBUILD
33#include <tbb/blocked_range.h>
34#include <tbb/parallel_for.h>
59template<
class Gr
idType>
61levelSetRebuild(
const GridType& grid,
float isovalue = 0,
62 float halfWidth =
float(LEVEL_SET_HALF_WIDTH),
const math::Transform* xform =
nullptr);
79template<
class Gr
idType>
81levelSetRebuild(
const GridType& grid,
float isovalue,
float exBandWidth,
float inBandWidth,
82 const math::Transform* xform =
nullptr);
100template<
class Gr
idType,
typename InterruptT>
101typename GridType::Ptr
102levelSetRebuild(
const GridType& grid,
float isovalue,
float exBandWidth,
float inBandWidth,
103 const math::Transform* xform =
nullptr, InterruptT* interrupter =
nullptr);
114class PointListTransform
117 PointListTransform(
const PointList& pointsIn, std::vector<Vec3s>& pointsOut,
118 const math::Transform& xform)
119 : mPointsIn(pointsIn)
120 , mPointsOut(&pointsOut)
127 tbb::parallel_for(tbb::blocked_range<size_t>(0, mPointsOut->size()), *
this);
132 (*this)(tbb::blocked_range<size_t>(0, mPointsOut->size()));
135 inline void operator()(
const tbb::blocked_range<size_t>& range)
const
137 for (
size_t n = range.begin(); n < range.end(); ++n) {
138 (*mPointsOut)[n] = Vec3s(mXform.worldToIndex(mPointsIn[n]));
143 const PointList& mPointsIn;
144 std::vector<Vec3s> *
const mPointsOut;
145 const math::Transform& mXform;
152 PrimCpy(
const PolygonPoolList& primsIn,
const std::vector<size_t>& indexList,
153 std::vector<Vec4I>& primsOut)
155 , mIndexList(indexList)
156 , mPrimsOut(&primsOut)
162 tbb::parallel_for(tbb::blocked_range<size_t>(0, mIndexList.size()), *
this);
167 (*this)(tbb::blocked_range<size_t>(0, mIndexList.size()));
170 inline void operator()(
const tbb::blocked_range<size_t>& range)
const
173 quad[3] = openvdb::util::INVALID_IDX;
174 std::vector<Vec4I>& primsOut = *mPrimsOut;
176 for (
size_t n = range.begin(); n < range.end(); ++n) {
177 size_t index = mIndexList[n];
178 PolygonPool& polygons = mPrimsIn[n];
181 for (
size_t i = 0, I = polygons.numQuads(); i < I; ++i) {
182 primsOut[index++] = polygons.quad(i);
184 polygons.clearQuads();
187 for (
size_t i = 0, I = polygons.numTriangles(); i < I; ++i) {
189 quad[0] = triangle[0];
190 quad[1] = triangle[1];
191 quad[2] = triangle[2];
192 primsOut[index++] = quad;
195 polygons.clearTriangles();
200 const PolygonPoolList& mPrimsIn;
201 const std::vector<size_t>& mIndexList;
202 std::vector<Vec4I> *
const mPrimsOut;
221template<
class Gr
idType,
typename InterruptT>
222inline typename std::enable_if<
223 std::is_floating_point<typename GridType::ValueType>::value,
typename GridType::Ptr>::type
224doLevelSetRebuild(
const GridType& grid,
typename GridType::ValueType iso,
225 typename GridType::ValueType exWidth,
typename GridType::ValueType inWidth,
226 const math::Transform* xform, InterruptT* interrupter)
229 isovalue = float(iso),
230 exBandWidth = float(exWidth),
231 inBandWidth = float(inWidth);
233 tools::VolumeToMesh mesher(isovalue);
236 math::Transform::Ptr transform = (xform !=
nullptr) ? xform->copy() : grid.transform().copy();
238 std::vector<Vec3s> points(mesher.pointListSize());
241 internal::PointListTransform ptnXForm(mesher.pointList(), points, *transform);
242 ptnXForm.runParallel();
243 mesher.pointList().reset(
nullptr);
246 std::vector<Vec4I> primitives;
249 PolygonPoolList& polygonPoolList = mesher.polygonPoolList();
251 size_t numPrimitives = 0;
252 std::vector<size_t> indexlist(mesher.polygonPoolListSize());
254 for (
size_t n = 0, N = mesher.polygonPoolListSize(); n < N; ++n) {
255 const openvdb::tools::PolygonPool& polygons = polygonPoolList[n];
256 indexlist[n] = numPrimitives;
257 numPrimitives += polygons.numQuads();
258 numPrimitives += polygons.numTriangles();
261 primitives.resize(numPrimitives);
262 internal::PrimCpy primCpy(polygonPoolList, indexlist, primitives);
263 primCpy.runParallel();
266 QuadAndTriangleDataAdapter<Vec3s, Vec4I> mesh(points, primitives);
268#if OPENVDB_USE_ORACLE_IN_REBUILD
269 auto backToOldGrid = [&xform, &grid](
const Coord& coord) -> openvdb::math::Vec3d {
270 return grid.transform().worldToIndex(xform->indexToWorld(coord));
273 auto interiorTest = [acc = grid.getConstAccessor(), &backToOldGrid, &xform](
const Coord& coord) ->
bool {
274 if (xform ==
nullptr) {
275 return acc.getValue(coord) <= 0 ? true :
false;
277 float value = openvdb::tools::BoxSampler::sample(acc, backToOldGrid(coord));
278 return value <= 0 ? true :
false;
284 return meshToVolume<GridType>(*interrupter, mesh, *transform, exBandWidth, inBandWidth,
285 DISABLE_RENORMALIZATION,
nullptr
287 , interiorTest, EVAL_EVERY_VOXEL
292 return meshToVolume<GridType>(mesh, *transform, exBandWidth, inBandWidth,
293 DISABLE_RENORMALIZATION,
nullptr
295 , interiorTest, EVAL_EVERY_VOXEL
303template<
class Gr
idType,
typename InterruptT>
304inline typename std::enable_if<
305 !std::is_floating_point<typename GridType::ValueType>::value,
typename GridType::Ptr>::type
306doLevelSetRebuild(
const GridType&,
typename GridType::ValueType ,
307 typename GridType::ValueType ,
typename GridType::ValueType ,
308 const math::Transform*, InterruptT*)
311 "level set rebuild is supported only for scalar, floating-point grids");
321template<
class Gr
idType,
typename InterruptT>
322typename GridType::Ptr
326 using ValueT =
typename GridType::ValueType;
328 isovalue(zeroVal<ValueT>() + ValueT(iso)),
329 exBandWidth(zeroVal<ValueT>() + ValueT(exWidth)),
330 inBandWidth(zeroVal<ValueT>() + ValueT(inWidth));
332 return doLevelSetRebuild(grid, isovalue, exBandWidth, inBandWidth, xform, interrupter);
336template<
class Gr
idType>
337typename GridType::Ptr
341 using ValueT =
typename GridType::ValueType;
343 isovalue(zeroVal<ValueT>() + ValueT(iso)),
344 exBandWidth(zeroVal<ValueT>() + ValueT(exWidth)),
345 inBandWidth(zeroVal<ValueT>() + ValueT(inWidth));
347 return doLevelSetRebuild<GridType, util::NullInterrupter>(
348 grid, isovalue, exBandWidth, inBandWidth, xform,
nullptr);
352template<
class Gr
idType>
353typename GridType::Ptr
356 using ValueT =
typename GridType::ValueType;
358 isovalue(zeroVal<ValueT>() + ValueT(iso)),
359 halfWidth(zeroVal<ValueT>() + ValueT(halfVal));
361 return doLevelSetRebuild<GridType, util::NullInterrupter>(
362 grid, isovalue, halfWidth, halfWidth, xform,
nullptr);
371#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION
373#ifdef OPENVDB_INSTANTIATE_LEVELSETREBUILD
377#define _FUNCTION(TreeT) \
378 Grid<TreeT>::Ptr levelSetRebuild(const Grid<TreeT>&, float, float, const math::Transform*)
382#define _FUNCTION(TreeT) \
383 Grid<TreeT>::Ptr levelSetRebuild(const Grid<TreeT>&, float, float, float, const math::Transform*)
387#define _FUNCTION(TreeT) \
388 Grid<TreeT>::Ptr levelSetRebuild(const Grid<TreeT>&, float, float, float, const math::Transform*, \
389 util::NullInterrupter*)
#define OPENVDB_USE_ORACLE_IN_REBUILD
Definition LevelSetRebuild.h:15
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: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:212
#define OPENVDB_REAL_TREE_INSTANTIATE(Function)
Definition version.h.in:157