OpenVDB  7.0.0
LevelSetRebuild.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
4 #ifndef OPENVDB_TOOLS_LEVELSETREBUILD_HAS_BEEN_INCLUDED
5 #define OPENVDB_TOOLS_LEVELSETREBUILD_HAS_BEEN_INCLUDED
6 
7 #include <openvdb/Grid.h>
8 #include <openvdb/Exceptions.h>
9 #include <openvdb/math/Math.h>
10 #include <openvdb/math/Transform.h>
14 #include <openvdb/util/Util.h>
15 #include <tbb/blocked_range.h>
16 #include <tbb/parallel_for.h>
17 #include <type_traits>
18 
19 
20 namespace openvdb {
22 namespace OPENVDB_VERSION_NAME {
23 namespace tools {
24 
25 
41 template<class GridType>
42 inline typename GridType::Ptr
43 levelSetRebuild(const GridType& grid, float isovalue = 0,
44  float halfWidth = float(LEVEL_SET_HALF_WIDTH), const math::Transform* xform = nullptr);
45 
46 
61 template<class GridType>
62 inline typename GridType::Ptr
63 levelSetRebuild(const GridType& grid, float isovalue, float exBandWidth, float inBandWidth,
64  const math::Transform* xform = nullptr);
65 
66 
82 template<class GridType, typename InterruptT>
83 inline typename GridType::Ptr
84 levelSetRebuild(const GridType& grid, float isovalue, float exBandWidth, float inBandWidth,
85  const math::Transform* xform = nullptr, InterruptT* interrupter = nullptr);
86 
87 
89 
90 
91 // Internal utility objects and implementation details
92 
93 namespace internal {
94 
96 {
97 public:
98  PointListTransform(const PointList& pointsIn, std::vector<Vec3s>& pointsOut,
99  const math::Transform& xform)
100  : mPointsIn(pointsIn)
101  , mPointsOut(&pointsOut)
102  , mXform(xform)
103  {
104  }
105 
106  void runParallel()
107  {
108  tbb::parallel_for(tbb::blocked_range<size_t>(0, mPointsOut->size()), *this);
109  }
110 
111  void runSerial()
112  {
113  (*this)(tbb::blocked_range<size_t>(0, mPointsOut->size()));
114  }
115 
116  inline void operator()(const tbb::blocked_range<size_t>& range) const
117  {
118  for (size_t n = range.begin(); n < range.end(); ++n) {
119  (*mPointsOut)[n] = Vec3s(mXform.worldToIndex(mPointsIn[n]));
120  }
121  }
122 
123 private:
124  const PointList& mPointsIn;
125  std::vector<Vec3s> * const mPointsOut;
126  const math::Transform& mXform;
127 };
128 
129 
130 class PrimCpy
131 {
132 public:
133  PrimCpy(const PolygonPoolList& primsIn, const std::vector<size_t>& indexList,
134  std::vector<Vec4I>& primsOut)
135  : mPrimsIn(primsIn)
136  , mIndexList(indexList)
137  , mPrimsOut(&primsOut)
138  {
139  }
140 
141  void runParallel()
142  {
143  tbb::parallel_for(tbb::blocked_range<size_t>(0, mIndexList.size()), *this);
144  }
145 
146  void runSerial()
147  {
148  (*this)(tbb::blocked_range<size_t>(0, mIndexList.size()));
149  }
150 
151  inline void operator()(const tbb::blocked_range<size_t>& range) const
152  {
153  openvdb::Vec4I quad;
154  quad[3] = openvdb::util::INVALID_IDX;
155  std::vector<Vec4I>& primsOut = *mPrimsOut;
156 
157  for (size_t n = range.begin(); n < range.end(); ++n) {
158  size_t index = mIndexList[n];
159  PolygonPool& polygons = mPrimsIn[n];
160 
161  // Copy quads
162  for (size_t i = 0, I = polygons.numQuads(); i < I; ++i) {
163  primsOut[index++] = polygons.quad(i);
164  }
165  polygons.clearQuads();
166 
167  // Copy triangles (adaptive mesh)
168  for (size_t i = 0, I = polygons.numTriangles(); i < I; ++i) {
169  const openvdb::Vec3I& triangle = polygons.triangle(i);
170  quad[0] = triangle[0];
171  quad[1] = triangle[1];
172  quad[2] = triangle[2];
173  primsOut[index++] = quad;
174  }
175 
176  polygons.clearTriangles();
177  }
178  }
179 
180 private:
181  const PolygonPoolList& mPrimsIn;
182  const std::vector<size_t>& mIndexList;
183  std::vector<Vec4I> * const mPrimsOut;
184 };
185 
186 } // namespace internal
187 
188 
190 
191 
192 //{
194 
201 template<class GridType, typename InterruptT>
202 inline typename std::enable_if<
203  std::is_floating_point<typename GridType::ValueType>::value, typename GridType::Ptr>::type
204 doLevelSetRebuild(const GridType& grid, typename GridType::ValueType iso,
205  typename GridType::ValueType exWidth, typename GridType::ValueType inWidth,
206  const math::Transform* xform, InterruptT* interrupter)
207 {
208  const float
209  isovalue = float(iso),
210  exBandWidth = float(exWidth),
211  inBandWidth = float(inWidth);
212 
213  tools::VolumeToMesh mesher(isovalue);
214  mesher(grid);
215 
216  math::Transform::Ptr transform = (xform != nullptr) ? xform->copy() : grid.transform().copy();
217 
218  std::vector<Vec3s> points(mesher.pointListSize());
219 
220  { // Copy and transform (required for MeshToVolume) points to grid space.
221  internal::PointListTransform ptnXForm(mesher.pointList(), points, *transform);
222  ptnXForm.runParallel();
223  mesher.pointList().reset(nullptr);
224  }
225 
226  std::vector<Vec4I> primitives;
227 
228  { // Copy primitives.
229  PolygonPoolList& polygonPoolList = mesher.polygonPoolList();
230 
231  size_t numPrimitives = 0;
232  std::vector<size_t> indexlist(mesher.polygonPoolListSize());
233 
234  for (size_t n = 0, N = mesher.polygonPoolListSize(); n < N; ++n) {
235  const openvdb::tools::PolygonPool& polygons = polygonPoolList[n];
236  indexlist[n] = numPrimitives;
237  numPrimitives += polygons.numQuads();
238  numPrimitives += polygons.numTriangles();
239  }
240 
241  primitives.resize(numPrimitives);
242  internal::PrimCpy primCpy(polygonPoolList, indexlist, primitives);
243  primCpy.runParallel();
244  }
245 
246  QuadAndTriangleDataAdapter<Vec3s, Vec4I> mesh(points, primitives);
247 
248  if (interrupter) {
249  return meshToVolume<GridType>(*interrupter, mesh, *transform, exBandWidth, inBandWidth,
250  DISABLE_RENORMALIZATION, nullptr);
251  }
252 
253  return meshToVolume<GridType>(mesh, *transform, exBandWidth, inBandWidth,
254  DISABLE_RENORMALIZATION, nullptr);
255 }
256 
257 
260 template<class GridType, typename InterruptT>
261 inline typename std::enable_if<
262  !std::is_floating_point<typename GridType::ValueType>::value, typename GridType::Ptr>::type
263 doLevelSetRebuild(const GridType&, typename GridType::ValueType /*isovalue*/,
264  typename GridType::ValueType /*exWidth*/, typename GridType::ValueType /*inWidth*/,
265  const math::Transform*, InterruptT*)
266 {
268  "level set rebuild is supported only for scalar, floating-point grids");
269 }
270 
272 //}
273 
274 
276 
277 
278 template<class GridType, typename InterruptT>
279 inline typename GridType::Ptr
280 levelSetRebuild(const GridType& grid, float iso, float exWidth, float inWidth,
281  const math::Transform* xform, InterruptT* interrupter)
282 {
283  using ValueT = typename GridType::ValueType;
284  ValueT
285  isovalue(zeroVal<ValueT>() + ValueT(iso)),
286  exBandWidth(zeroVal<ValueT>() + ValueT(exWidth)),
287  inBandWidth(zeroVal<ValueT>() + ValueT(inWidth));
288 
289  return doLevelSetRebuild(grid, isovalue, exBandWidth, inBandWidth, xform, interrupter);
290 }
291 
292 
293 template<class GridType>
294 inline typename GridType::Ptr
295 levelSetRebuild(const GridType& grid, float iso, float exWidth, float inWidth,
296  const math::Transform* xform)
297 {
298  using ValueT = typename GridType::ValueType;
299  ValueT
300  isovalue(zeroVal<ValueT>() + ValueT(iso)),
301  exBandWidth(zeroVal<ValueT>() + ValueT(exWidth)),
302  inBandWidth(zeroVal<ValueT>() + ValueT(inWidth));
303 
304  return doLevelSetRebuild<GridType, util::NullInterrupter>(
305  grid, isovalue, exBandWidth, inBandWidth, xform, nullptr);
306 }
307 
308 
309 template<class GridType>
310 inline typename GridType::Ptr
311 levelSetRebuild(const GridType& grid, float iso, float halfVal, const math::Transform* xform)
312 {
313  using ValueT = typename GridType::ValueType;
314  ValueT
315  isovalue(zeroVal<ValueT>() + ValueT(iso)),
316  halfWidth(zeroVal<ValueT>() + ValueT(halfVal));
317 
318  return doLevelSetRebuild<GridType, util::NullInterrupter>(
319  grid, isovalue, halfWidth, halfWidth, xform, nullptr);
320 }
321 
322 
323 } // namespace tools
324 } // namespace OPENVDB_VERSION_NAME
325 } // namespace openvdb
326 
327 #endif // OPENVDB_TOOLS_LEVELSETREBUILD_HAS_BEEN_INCLUDED
const size_t & numTriangles() const
Definition: VolumeToMesh.h:116
OPENVDB_API const Index32 INVALID_IDX
std::unique_ptr< PolygonPool[]> PolygonPoolList
Point and primitive list types.
Definition: VolumeToMesh.h:151
static const Real LEVEL_SET_HALF_WIDTH
Definition: Types.h:460
openvdb::Vec3I & triangle(size_t n)
Definition: VolumeToMesh.h:118
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Contiguous quad and triangle data adapter class.
Definition: MeshToVolume.h:165
void runParallel()
Definition: LevelSetRebuild.h:106
std::unique_ptr< openvdb::Vec3s[]> PointList
Point and primitive list types.
Definition: VolumeToMesh.h:150
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: LevelSetRebuild.h:116
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:82
openvdb::Vec4I & quad(size_t n)
Definition: VolumeToMesh.h:112
size_t pointListSize() const
Definition: VolumeToMesh.h:173
PointList & pointList()
Definition: VolumeToMesh.h:174
Ptr copy() const
Definition: Transform.h:50
void clearQuads()
Definition: VolumeToMesh.h:4699
Extract polygonal surfaces from scalar volumes.
size_t polygonPoolListSize() const
Definition: VolumeToMesh.h:177
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:102
void runSerial()
Definition: LevelSetRebuild.h:111
const size_t & numQuads() const
Definition: VolumeToMesh.h:110
Collection of quads and triangles.
Definition: VolumeToMesh.h:92
Convert polygonal meshes that consist of quads and/or triangles into signed or unsigned distance fiel...
Definition: Mat4.h:24
Definition: Exceptions.h:13
Definition: LevelSetRebuild.h:130
Definition: Transform.h:39
Mesh any scalar grid that has a continuous isosurface.
Definition: VolumeToMesh.h:159
PointListTransform(const PointList &pointsIn, std::vector< Vec3s > &pointsOut, const math::Transform &xform)
Definition: LevelSetRebuild.h:98
Vec3< float > Vec3s
Definition: Vec3.h:661
Definition: Mat.h:170
void runSerial()
Definition: LevelSetRebuild.h:146
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: LevelSetRebuild.h:151
void runParallel()
Definition: LevelSetRebuild.h:141
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:154
void clearTriangles()
Definition: VolumeToMesh.h:4717
PrimCpy(const PolygonPoolList &primsIn, const std::vector< size_t > &indexList, std::vector< Vec4I > &primsOut)
Definition: LevelSetRebuild.h:133
GridType::Ptr levelSetRebuild(const GridType &grid, float isovalue, float exBandWidth, float inBandWidth, const math::Transform *xform=nullptr, InterruptT *interrupter=nullptr)
Return a new grid of type GridType that contains a narrow-band level set representation of an isosurf...
Definition: LevelSetRebuild.h:280
Definition: Exceptions.h:64
PolygonPoolList & polygonPoolList()
Definition: VolumeToMesh.h:178
SharedPtr< Transform > Ptr
Definition: Transform.h:42