OpenVDB  6.1.0
LevelSetRebuild.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2018 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 
31 #ifndef OPENVDB_TOOLS_LEVELSETREBUILD_HAS_BEEN_INCLUDED
32 #define OPENVDB_TOOLS_LEVELSETREBUILD_HAS_BEEN_INCLUDED
33 
34 #include <openvdb/Grid.h>
35 #include <openvdb/Exceptions.h>
36 #include <openvdb/math/Math.h>
37 #include <openvdb/math/Transform.h>
41 #include <openvdb/util/Util.h>
42 #include <tbb/blocked_range.h>
43 #include <tbb/parallel_for.h>
44 #include <type_traits>
45 
46 
47 namespace openvdb {
49 namespace OPENVDB_VERSION_NAME {
50 namespace tools {
51 
52 
68 template<class GridType>
69 inline typename GridType::Ptr
70 levelSetRebuild(const GridType& grid, float isovalue = 0,
71  float halfWidth = float(LEVEL_SET_HALF_WIDTH), const math::Transform* xform = nullptr);
72 
73 
88 template<class GridType>
89 inline typename GridType::Ptr
90 levelSetRebuild(const GridType& grid, float isovalue, float exBandWidth, float inBandWidth,
91  const math::Transform* xform = nullptr);
92 
93 
109 template<class GridType, typename InterruptT>
110 inline typename GridType::Ptr
111 levelSetRebuild(const GridType& grid, float isovalue, float exBandWidth, float inBandWidth,
112  const math::Transform* xform = nullptr, InterruptT* interrupter = nullptr);
113 
114 
116 
117 
118 // Internal utility objects and implementation details
119 
120 namespace internal {
121 
123 {
124 public:
125  PointListTransform(const PointList& pointsIn, std::vector<Vec3s>& pointsOut,
126  const math::Transform& xform)
127  : mPointsIn(pointsIn)
128  , mPointsOut(&pointsOut)
129  , mXform(xform)
130  {
131  }
132 
133  void runParallel()
134  {
135  tbb::parallel_for(tbb::blocked_range<size_t>(0, mPointsOut->size()), *this);
136  }
137 
138  void runSerial()
139  {
140  (*this)(tbb::blocked_range<size_t>(0, mPointsOut->size()));
141  }
142 
143  inline void operator()(const tbb::blocked_range<size_t>& range) const
144  {
145  for (size_t n = range.begin(); n < range.end(); ++n) {
146  (*mPointsOut)[n] = Vec3s(mXform.worldToIndex(mPointsIn[n]));
147  }
148  }
149 
150 private:
151  const PointList& mPointsIn;
152  std::vector<Vec3s> * const mPointsOut;
153  const math::Transform& mXform;
154 };
155 
156 
157 class PrimCpy
158 {
159 public:
160  PrimCpy(const PolygonPoolList& primsIn, const std::vector<size_t>& indexList,
161  std::vector<Vec4I>& primsOut)
162  : mPrimsIn(primsIn)
163  , mIndexList(indexList)
164  , mPrimsOut(&primsOut)
165  {
166  }
167 
168  void runParallel()
169  {
170  tbb::parallel_for(tbb::blocked_range<size_t>(0, mIndexList.size()), *this);
171  }
172 
173  void runSerial()
174  {
175  (*this)(tbb::blocked_range<size_t>(0, mIndexList.size()));
176  }
177 
178  inline void operator()(const tbb::blocked_range<size_t>& range) const
179  {
180  openvdb::Vec4I quad;
181  quad[3] = openvdb::util::INVALID_IDX;
182  std::vector<Vec4I>& primsOut = *mPrimsOut;
183 
184  for (size_t n = range.begin(); n < range.end(); ++n) {
185  size_t index = mIndexList[n];
186  PolygonPool& polygons = mPrimsIn[n];
187 
188  // Copy quads
189  for (size_t i = 0, I = polygons.numQuads(); i < I; ++i) {
190  primsOut[index++] = polygons.quad(i);
191  }
192  polygons.clearQuads();
193 
194  // Copy triangles (adaptive mesh)
195  for (size_t i = 0, I = polygons.numTriangles(); i < I; ++i) {
196  const openvdb::Vec3I& triangle = polygons.triangle(i);
197  quad[0] = triangle[0];
198  quad[1] = triangle[1];
199  quad[2] = triangle[2];
200  primsOut[index++] = quad;
201  }
202 
203  polygons.clearTriangles();
204  }
205  }
206 
207 private:
208  const PolygonPoolList& mPrimsIn;
209  const std::vector<size_t>& mIndexList;
210  std::vector<Vec4I> * const mPrimsOut;
211 };
212 
213 } // namespace internal
214 
215 
217 
218 
219 //{
221 
228 template<class GridType, typename InterruptT>
229 inline typename std::enable_if<
230  std::is_floating_point<typename GridType::ValueType>::value, typename GridType::Ptr>::type
231 doLevelSetRebuild(const GridType& grid, typename GridType::ValueType iso,
232  typename GridType::ValueType exWidth, typename GridType::ValueType inWidth,
233  const math::Transform* xform, InterruptT* interrupter)
234 {
235  const float
236  isovalue = float(iso),
237  exBandWidth = float(exWidth),
238  inBandWidth = float(inWidth);
239 
240  tools::VolumeToMesh mesher(isovalue);
241  mesher(grid);
242 
243  math::Transform::Ptr transform = (xform != nullptr) ? xform->copy() : grid.transform().copy();
244 
245  std::vector<Vec3s> points(mesher.pointListSize());
246 
247  { // Copy and transform (required for MeshToVolume) points to grid space.
248  internal::PointListTransform ptnXForm(mesher.pointList(), points, *transform);
249  ptnXForm.runParallel();
250  mesher.pointList().reset(nullptr);
251  }
252 
253  std::vector<Vec4I> primitives;
254 
255  { // Copy primitives.
256  PolygonPoolList& polygonPoolList = mesher.polygonPoolList();
257 
258  size_t numPrimitives = 0;
259  std::vector<size_t> indexlist(mesher.polygonPoolListSize());
260 
261  for (size_t n = 0, N = mesher.polygonPoolListSize(); n < N; ++n) {
262  const openvdb::tools::PolygonPool& polygons = polygonPoolList[n];
263  indexlist[n] = numPrimitives;
264  numPrimitives += polygons.numQuads();
265  numPrimitives += polygons.numTriangles();
266  }
267 
268  primitives.resize(numPrimitives);
269  internal::PrimCpy primCpy(polygonPoolList, indexlist, primitives);
270  primCpy.runParallel();
271  }
272 
273  QuadAndTriangleDataAdapter<Vec3s, Vec4I> mesh(points, primitives);
274 
275  if (interrupter) {
276  return meshToVolume<GridType>(*interrupter, mesh, *transform, exBandWidth, inBandWidth,
277  DISABLE_RENORMALIZATION, nullptr);
278  }
279 
280  return meshToVolume<GridType>(mesh, *transform, exBandWidth, inBandWidth,
281  DISABLE_RENORMALIZATION, nullptr);
282 }
283 
284 
287 template<class GridType, typename InterruptT>
288 inline typename std::enable_if<
289  !std::is_floating_point<typename GridType::ValueType>::value, typename GridType::Ptr>::type
290 doLevelSetRebuild(const GridType&, typename GridType::ValueType /*isovalue*/,
291  typename GridType::ValueType /*exWidth*/, typename GridType::ValueType /*inWidth*/,
292  const math::Transform*, InterruptT*)
293 {
295  "level set rebuild is supported only for scalar, floating-point grids");
296 }
297 
299 //}
300 
301 
303 
304 
305 template<class GridType, typename InterruptT>
306 inline typename GridType::Ptr
307 levelSetRebuild(const GridType& grid, float iso, float exWidth, float inWidth,
308  const math::Transform* xform, InterruptT* interrupter)
309 {
310  using ValueT = typename GridType::ValueType;
311  ValueT
312  isovalue(zeroVal<ValueT>() + ValueT(iso)),
313  exBandWidth(zeroVal<ValueT>() + ValueT(exWidth)),
314  inBandWidth(zeroVal<ValueT>() + ValueT(inWidth));
315 
316  return doLevelSetRebuild(grid, isovalue, exBandWidth, inBandWidth, xform, interrupter);
317 }
318 
319 
320 template<class GridType>
321 inline typename GridType::Ptr
322 levelSetRebuild(const GridType& grid, float iso, float exWidth, float inWidth,
323  const math::Transform* xform)
324 {
325  using ValueT = typename GridType::ValueType;
326  ValueT
327  isovalue(zeroVal<ValueT>() + ValueT(iso)),
328  exBandWidth(zeroVal<ValueT>() + ValueT(exWidth)),
329  inBandWidth(zeroVal<ValueT>() + ValueT(inWidth));
330 
331  return doLevelSetRebuild<GridType, util::NullInterrupter>(
332  grid, isovalue, exBandWidth, inBandWidth, xform, nullptr);
333 }
334 
335 
336 template<class GridType>
337 inline typename GridType::Ptr
338 levelSetRebuild(const GridType& grid, float iso, float halfVal, const math::Transform* xform)
339 {
340  using ValueT = typename GridType::ValueType;
341  ValueT
342  isovalue(zeroVal<ValueT>() + ValueT(iso)),
343  halfWidth(zeroVal<ValueT>() + ValueT(halfVal));
344 
345  return doLevelSetRebuild<GridType, util::NullInterrupter>(
346  grid, isovalue, halfWidth, halfWidth, xform, nullptr);
347 }
348 
349 
350 } // namespace tools
351 } // namespace OPENVDB_VERSION_NAME
352 } // namespace openvdb
353 
354 #endif // OPENVDB_TOOLS_LEVELSETREBUILD_HAS_BEEN_INCLUDED
355 
356 // Copyright (c) 2012-2018 DreamWorks Animation LLC
357 // All rights reserved. This software is distributed under the
358 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
PrimCpy(const PolygonPoolList &primsIn, const std::vector< size_t > &indexList, std::vector< Vec4I > &primsOut)
Definition: LevelSetRebuild.h:160
boost::scoped_array< PolygonPool > PolygonPoolList
Point and primitive list types.
Definition: VolumeToMesh.h:180
Collection of quads and triangles.
Definition: VolumeToMesh.h:121
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
PolygonPoolList & polygonPoolList()
Definition: VolumeToMesh.h:207
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: LevelSetRebuild.h:143
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
Contiguous quad and triangle data adapter class.
Definition: MeshToVolume.h:192
Mesh any scalar grid that has a continuous isosurface.
Definition: VolumeToMesh.h:188
void clearQuads()
Definition: VolumeToMesh.h:4728
Definition: LevelSetRebuild.h:157
PointList & pointList()
Definition: VolumeToMesh.h:203
const size_t & numTriangles() const
Definition: VolumeToMesh.h:145
Definition: Mat4.h:51
Extract polygonal surfaces from scalar volumes.
openvdb::Vec4I & quad(size_t n)
Definition: VolumeToMesh.h:141
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:125
openvdb::Vec3I & triangle(size_t n)
Definition: VolumeToMesh.h:147
Definition: MeshToVolume.h:102
void runParallel()
Definition: LevelSetRebuild.h:133
Convert polygonal meshes that consist of quads and/or triangles into signed or unsigned distance fiel...
Definition: Exceptions.h:40
Ptr copy() const
Definition: Transform.h:77
OPENVDB_API const Index32 INVALID_IDX
Definition: Mat.h:197
Vec3< float > Vec3s
Definition: Vec3.h:688
SharedPtr< Transform > Ptr
Definition: Transform.h:69
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: LevelSetRebuild.h:178
Definition: Transform.h:66
void runSerial()
Definition: LevelSetRebuild.h:138
PointListTransform(const PointList &pointsIn, std::vector< Vec3s > &pointsOut, const math::Transform &xform)
Definition: LevelSetRebuild.h:125
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:307
void runSerial()
Definition: LevelSetRebuild.h:173
size_t polygonPoolListSize() const
Definition: VolumeToMesh.h:206
Definition: Exceptions.h:91
boost::scoped_array< openvdb::Vec3s > PointList
Point and primitive list types.
Definition: VolumeToMesh.h:179
static const Real LEVEL_SET_HALF_WIDTH
Definition: Types.h:510
void clearTriangles()
Definition: VolumeToMesh.h:4746
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:177
size_t pointListSize() const
Definition: VolumeToMesh.h:202
void runParallel()
Definition: LevelSetRebuild.h:168
const size_t & numQuads() const
Definition: VolumeToMesh.h:139