OpenVDB  2.1.0
LevelSetRebuild.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2013 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>
38 #include <openvdb/tools/VolumeToMesh.h>
39 #include <openvdb/tools/MeshToVolume.h>
40 #include <openvdb/util/NullInterrupter.h>
41 #include <openvdb/util/Util.h>
42 #include <boost/type_traits/is_floating_point.hpp>
43 #include <boost/utility/enable_if.hpp>
44 #include <tbb/blocked_range.h>
45 #include <tbb/parallel_for.h>
46 
47 
48 namespace openvdb {
50 namespace OPENVDB_VERSION_NAME {
51 namespace tools {
52 
53 
69 template<class GridType>
70 inline typename GridType::Ptr
71 levelSetRebuild(const GridType& grid, float isovalue = 0,
72  float halfWidth = float(LEVEL_SET_HALF_WIDTH), const math::Transform* xform = NULL);
73 
74 
89 template<class GridType>
90 inline typename GridType::Ptr
91 levelSetRebuild(const GridType& grid, float isovalue, float exBandWidth, float inBandWidth,
92  const math::Transform* xform = NULL);
93 
94 
110 template<class GridType, typename InterruptT>
111 inline typename GridType::Ptr
112 levelSetRebuild(const GridType& grid, float isovalue, float exBandWidth, float inBandWidth,
113  const math::Transform* xform = NULL, InterruptT* interrupter = NULL);
114 
115 
117 
118 
119 // Internal utility objects and implementation details
120 
121 namespace internal {
122 
124 {
125 public:
126  PointListTransform(const PointList& pointsIn, std::vector<Vec3s>& pointsOut,
127  const math::Transform& xform)
128  : mPointsIn(pointsIn)
129  , mPointsOut(&pointsOut)
130  , mXform(xform)
131  {
132  }
133 
134  void runParallel()
135  {
136  tbb::parallel_for(tbb::blocked_range<size_t>(0, mPointsOut->size()), *this);
137  }
138 
139  void runSerial()
140  {
141  (*this)(tbb::blocked_range<size_t>(0, mPointsOut->size()));
142  }
143 
144  inline void operator()(const tbb::blocked_range<size_t>& range) const
145  {
146  for (size_t n = range.begin(); n < range.end(); ++n) {
147  (*mPointsOut)[n] = mXform.worldToIndex(mPointsIn[n]);
148  }
149  }
150 
151 private:
152  const PointList& mPointsIn;
153  std::vector<Vec3s> * const mPointsOut;
154  const math::Transform& mXform;
155 };
156 
157 
158 class PrimCpy
159 {
160 public:
161  PrimCpy(const PolygonPoolList& primsIn, const std::vector<size_t>& indexList,
162  std::vector<Vec4I>& primsOut)
163  : mPrimsIn(primsIn)
164  , mIndexList(indexList)
165  , mPrimsOut(&primsOut)
166  {
167  }
168 
169  void runParallel()
170  {
171  tbb::parallel_for(tbb::blocked_range<size_t>(0, mIndexList.size()), *this);
172  }
173 
174  void runSerial()
175  {
176  (*this)(tbb::blocked_range<size_t>(0, mIndexList.size()));
177  }
178 
179  inline void operator()(const tbb::blocked_range<size_t>& range) const
180  {
181  openvdb::Vec4I quad;
182  quad[3] = openvdb::util::INVALID_IDX;
183  std::vector<Vec4I>& primsOut = *mPrimsOut;
184 
185  for (size_t n = range.begin(); n < range.end(); ++n) {
186  size_t index = mIndexList[n];
187  PolygonPool& polygons = mPrimsIn[n];
188 
189  // Copy quads
190  for (size_t i = 0, I = polygons.numQuads(); i < I; ++i) {
191  primsOut[index++] = polygons.quad(i);
192  }
193  polygons.clearQuads();
194 
195  // Copy triangles (adaptive mesh)
196  for (size_t i = 0, I = polygons.numTriangles(); i < I; ++i) {
197  const openvdb::Vec3I& triangle = polygons.triangle(i);
198  quad[0] = triangle[0];
199  quad[1] = triangle[1];
200  quad[2] = triangle[2];
201  primsOut[index++] = quad;
202  }
203 
204  polygons.clearTriangles();
205  }
206  }
207 
208 private:
209  const PolygonPoolList& mPrimsIn;
210  const std::vector<size_t>& mIndexList;
211  std::vector<Vec4I> * const mPrimsOut;
212 };
213 
214 } // namespace internal
215 
216 
218 
219 
226 template<class GridType, typename InterruptT>
227 inline typename boost::enable_if<boost::is_floating_point<typename GridType::ValueType>,
228 typename GridType::Ptr>::type
229 doLevelSetRebuild(const GridType& grid, typename GridType::ValueType iso,
230  typename GridType::ValueType exWidth, typename GridType::ValueType inWidth,
231  const math::Transform* xform, InterruptT* interrupter)
232 {
233  const float
234  isovalue = float(iso),
235  exBandWidth = float(exWidth),
236  inBandWidth = float(inWidth);
237 
238  tools::VolumeToMesh mesher(isovalue, 0.0005);
239  mesher(grid);
240 
241  math::Transform::Ptr transform = (xform != NULL) ? xform->copy() : grid.transform().copy();
242 
243  std::vector<Vec3s> points(mesher.pointListSize());
244 
245  { // Copy and transform (required for MeshToVolume) points to grid space.
246  internal::PointListTransform ptnXForm(mesher.pointList(), points, *transform);
247  ptnXForm.runParallel();
248  mesher.pointList().reset(NULL);
249  }
250 
251  std::vector<Vec4I> primitives;
252 
253  { // Copy primitives.
254  PolygonPoolList& polygonPoolList = mesher.polygonPoolList();
255 
256  size_t numPrimitives = 0;
257  std::vector<size_t> indexlist(mesher.polygonPoolListSize());
258 
259  for (size_t n = 0, N = mesher.polygonPoolListSize(); n < N; ++n) {
260  const openvdb::tools::PolygonPool& polygons = polygonPoolList[n];
261  indexlist[n] = numPrimitives;
262  numPrimitives += polygons.numQuads();
263  numPrimitives += polygons.numTriangles();
264  }
265 
266  primitives.resize(numPrimitives);
267  internal::PrimCpy primCpy(polygonPoolList, indexlist, primitives);
268  primCpy.runParallel();
269  }
270 
271  MeshToVolume<GridType, InterruptT> vol(transform, OUTPUT_RAW_DATA, interrupter);
272  vol.convertToLevelSet(points, primitives, exBandWidth, inBandWidth);
273 
274  return vol.distGridPtr();
275 }
276 
277 
280 template<class GridType, typename InterruptT>
281 inline typename boost::disable_if<boost::is_floating_point<typename GridType::ValueType>,
282 typename GridType::Ptr>::type
283 doLevelSetRebuild(const GridType&, typename GridType::ValueType /*isovalue*/,
284  typename GridType::ValueType /*exWidth*/, typename GridType::ValueType /*inWidth*/,
285  const math::Transform*, InterruptT*)
286 {
288  "level set rebuild is supported only for scalar, floating-point grids");
289 }
290 
291 
293 
294 
295 template<class GridType, typename InterruptT>
296 inline typename GridType::Ptr
297 levelSetRebuild(const GridType& grid, float iso, float exWidth, float inWidth,
298  const math::Transform* xform, InterruptT* interrupter)
299 {
300  typedef typename GridType::ValueType ValueT;
301  ValueT
302  isovalue(zeroVal<ValueT>() + iso),
303  exBandWidth(zeroVal<ValueT>() + exWidth),
304  inBandWidth(zeroVal<ValueT>() + inWidth);
305 
306  return doLevelSetRebuild(grid, isovalue, exBandWidth, inBandWidth, xform, interrupter);
307 }
308 
309 
310 template<class GridType>
311 inline typename GridType::Ptr
312 levelSetRebuild(const GridType& grid, float iso, float exWidth, float inWidth,
313  const math::Transform* xform)
314 {
315  typedef typename GridType::ValueType ValueT;
316  ValueT
317  isovalue(zeroVal<ValueT>() + iso),
318  exBandWidth(zeroVal<ValueT>() + exWidth),
319  inBandWidth(zeroVal<ValueT>() + inWidth);
320 
321  return doLevelSetRebuild<GridType, util::NullInterrupter>(
322  grid, isovalue, exBandWidth, inBandWidth, xform, NULL);
323 }
324 
325 
326 template<class GridType>
327 inline typename GridType::Ptr
328 levelSetRebuild(const GridType& grid, float iso, float halfVal, const math::Transform* xform)
329 {
330  typedef typename GridType::ValueType ValueT;
331  ValueT
332  isovalue(zeroVal<ValueT>() + iso),
333  halfWidth(zeroVal<ValueT>() + halfVal);
334 
335  return doLevelSetRebuild<GridType, util::NullInterrupter>(
336  grid, isovalue, halfWidth, halfWidth, xform, NULL);
337 }
338 
339 
340 } // namespace tools
341 } // namespace OPENVDB_VERSION_NAME
342 } // namespace openvdb
343 
344 #endif // OPENVDB_TOOLS_LEVELSETREBUILD_HAS_BEEN_INCLUDED
345 
346 // Copyright (c) 2012-2013 DreamWorks Animation LLC
347 // All rights reserved. This software is distributed under the
348 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
OPENVDB_API const Index32 INVALID_IDX
Ptr copy() const
Definition: Transform.h:76
Definition: Mat.h:150
boost::shared_ptr< Transform > Ptr
Definition: Transform.h:68
static const Real LEVEL_SET_HALF_WIDTH
Definition: Types.h:143
void runSerial()
Definition: LevelSetRebuild.h:139
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: LevelSetRebuild.h:144
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
void runSerial()
Definition: LevelSetRebuild.h:174
Definition: Exceptions.h:87
GridType::Ptr levelSetRebuild(const GridType &grid, float isovalue=0, float halfWidth=float(LEVEL_SET_HALF_WIDTH), const math::Transform *xform=NULL)
Return a new grid of type GridType that contains a narrow-band level set representation of an isosurf...
Definition: LevelSetRebuild.h:328
Calculate an axis-aligned bounding box in index space from a bounding sphere in world space...
Definition: Transform.h:65
const size_t & numTriangles() const
Definition: VolumeToMesh.h:133
boost::scoped_array< PolygonPool > PolygonPoolList
Point and primitive list types.
Definition: VolumeToMesh.h:168
openvdb::Vec4I & quad(size_t n)
Definition: VolumeToMesh.h:129
#define OPENVDB_VERSION_NAME
Definition: version.h:45
const size_t & pointListSize() const
Definition: VolumeToMesh.h:3976
const size_t & polygonPoolListSize() const
Definition: VolumeToMesh.h:3997
const size_t & numQuads() const
Definition: VolumeToMesh.h:127
Definition: MeshToVolume.h:196
void clearQuads()
Definition: VolumeToMesh.h:3857
Definition: MeshToVolume.h:191
PointListTransform(const PointList &pointsIn, std::vector< Vec3s > &pointsOut, const math::Transform &xform)
Definition: LevelSetRebuild.h:126
boost::enable_if< boost::is_floating_point< typename GridType::ValueType >, typename GridType::Ptr >::type doLevelSetRebuild(const GridType &grid, typename GridType::ValueType iso, typename GridType::ValueType exWidth, typename GridType::ValueType inWidth, const math::Transform *xform, InterruptT *interrupter)
Definition: LevelSetRebuild.h:229
void runParallel()
Definition: LevelSetRebuild.h:169
Collection of quads and triangles.
Definition: VolumeToMesh.h:108
void clearTriangles()
Definition: VolumeToMesh.h:3875
Mesh any scalar grid that has a continuous isosurface.
Definition: VolumeToMesh.h:176
void convertToLevelSet(const std::vector< Vec3s > &pointList, const std::vector< Vec4I > &polygonList, FloatValueT exBandWidth=FloatValueT(LEVEL_SET_HALF_WIDTH), FloatValueT inBandWidth=FloatValueT(LEVEL_SET_HALF_WIDTH))
Mesh to Level Set / Signed Distance Field conversion.
Definition: MeshToVolume.h:2264
PolygonPoolList & polygonPoolList()
Definition: VolumeToMesh.h:3983
Definition: LevelSetRebuild.h:158
void runParallel()
Definition: LevelSetRebuild.h:134
openvdb::Vec3I & triangle(size_t n)
Definition: VolumeToMesh.h:135
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:67
boost::scoped_array< openvdb::Vec3s > PointList
Point and primitive list types.
Definition: VolumeToMesh.h:167
Definition: Mat4.h:51
PointList & pointList()
Definition: VolumeToMesh.h:3969
PrimCpy(const PolygonPoolList &primsIn, const std::vector< size_t > &indexList, std::vector< Vec4I > &primsOut)
Definition: LevelSetRebuild.h:161
void operator()(const tbb::blocked_range< size_t > &range) const
Definition: LevelSetRebuild.h:179
FloatGridT::Ptr distGridPtr() const
Returns a narrow-band (signed) distance field / level set grid.
Definition: MeshToVolume.h:240