OpenVDB  0.104.0
LevelSetRebuild.h
Go to the documentation of this file.
1 
2 //
3 // Copyright (c) 2012 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_LEVEL_SET_REBUILD_HAS_BEEN_INCLUDED
32 #define OPENVDB_TOOLS_LEVEL_SET_REBUILD_HAS_BEEN_INCLUDED
33 
34 #include <openvdb/Grid.h>
35 #include <openvdb/math/Math.h>
36 #include <openvdb/math/Transform.h>
37 #include <openvdb/tools/VolumeToMesh.h>
38 #include <openvdb/tools/MeshToVolume.h>
39 #include <openvdb/util/NullInterrupter.h>
40 #include <openvdb/util/Util.h>
41 
42 #include <tbb/blocked_range.h>
43 #include <tbb/parallel_reduce.h>
44 
45 
46 namespace openvdb {
48 namespace OPENVDB_VERSION_NAME {
49 namespace tools {
50 
51 
60 template<class GridType>
61 inline typename GridType::Ptr
62 levelSetRebuild(const GridType& grid, float isovalue, float halfWidth = 3.0f,
63  const math::Transform* xform = NULL);
64 
65 
75 template<class GridType>
76 inline typename GridType::Ptr
77 levelSetRebuild(const GridType& grid, float isovalue, float exBandWidth, float inBandWidth,
78  const math::Transform* xform = NULL);
79 
80 
91 template<class GridType, typename InterruptT>
92 inline typename GridType::Ptr
93 levelSetRebuild(const GridType& grid, float isovalue, float exBandWidth, float inBandWidth,
94  const math::Transform* xform = NULL, InterruptT* interrupter = NULL);
95 
96 
97 
98 
99 
102 
103 // Internal utility objects and implementation details
104 
105 namespace internal {
106 
108 public:
109  PointTransform(const PointList& pointsIn, std::vector<Vec3s>& pointsOut,
110  const math::Transform& xform)
111  : mPointsIn(pointsIn)
112  , mPointsOut(&pointsOut)
113  , mXform(xform)
114  {
115  }
116 
117  void runParallel()
118  {
119  tbb::parallel_for(tbb::blocked_range<size_t>(0, mPointsOut->size()), *this);
120  }
121 
122  void runSerial()
123  {
124  (*this)(tbb::blocked_range<size_t>(0, mPointsOut->size()));
125  }
126 
127  inline void operator()(const tbb::blocked_range<size_t>& range) const
128  {
129  for (size_t n = range.begin(); n < range.end(); ++n) {
130  (*mPointsOut)[n] = mXform.worldToIndex(mPointsIn[n]);
131  }
132  }
133 
134 private:
135  const PointList& mPointsIn;
136  std::vector<Vec3s> * const mPointsOut;
137  const math::Transform& mXform;
138 };
139 
140 
141 class PrimCpy {
142 public:
143  PrimCpy(const PolygonPoolList& primsIn, const std::vector<size_t>& indexList,
144  std::vector<Vec4I>& primsOut)
145  : mPrimsIn(primsIn)
146  , mIndexList(indexList)
147  , mPrimsOut(&primsOut)
148  {
149  }
150 
151  void runParallel()
152  {
153  tbb::parallel_for(tbb::blocked_range<size_t>(0, mIndexList.size()), *this);
154  }
155 
156  void runSerial()
157  {
158  (*this)(tbb::blocked_range<size_t>(0, mIndexList.size()));
159  }
160 
161  inline void operator()(const tbb::blocked_range<size_t>& range) const
162  {
163  openvdb::Vec4I quad;
164  quad[3] = openvdb::util::INVALID_IDX;
165  std::vector<Vec4I>& primsOut = *mPrimsOut;
166 
167  for (size_t n = range.begin(); n < range.end(); ++n) {
168  size_t index = mIndexList[n];
169  PolygonPool& polygons = mPrimsIn[n];
170 
171  // Copy quads
172  for (size_t i = 0, I = polygons.numQuads(); i < I; ++i) {
173  primsOut[index++] = polygons.quad(i);
174  }
175  polygons.clearQuads();
176 
177  // Copy triangles (adaptive mesh)
178  for (size_t i = 0, I = polygons.numTriangles(); i < I; ++i) {
179  const openvdb::Vec3I& triangle = polygons.triangle(i);
180  quad[0] = triangle[0];
181  quad[1] = triangle[1];
182  quad[2] = triangle[2];
183  primsOut[index++] = quad;
184  }
185 
186  polygons.clearTriangles();
187  }
188  }
189 
190 private:
191  const PolygonPoolList& mPrimsIn;
192  const std::vector<size_t>& mIndexList;
193  std::vector<Vec4I> * const mPrimsOut;
194 };
195 
196 } // namespace internal
197 
198 
200 
201 
202 template<class GridType, typename InterruptT>
203 inline typename GridType::Ptr
204 levelSetRebuild(const GridType& grid, float isovalue, float exBandWidth, float inBandWidth,
205  const math::Transform* xform, InterruptT* interrupter)
206 {
207  tools::VolumeToMesh mesher(isovalue, 0.0005);
208  mesher(grid);
209 
210  math::Transform::Ptr transform = (xform != NULL) ? xform->copy() : grid.transform().copy();
211 
212  std::vector<Vec3s> points(mesher.pointListSize());
213 
214  { // Copy and transform (required for MeshToVolume) points to grid space.
215  internal::PointTransform ptnXForm(mesher.pointList(), points, *transform);
216  ptnXForm.runParallel();
217  mesher.pointList().reset(NULL);
218  }
219 
220  std::vector<Vec4I> primitives;
221 
222  { // Copy primitives.
223  PolygonPoolList& polygonPoolList = mesher.polygonPoolList();
224 
225  size_t numPrimitives = 0;
226  std::vector<size_t> indexlist(mesher.polygonPoolListSize());
227 
228  for (size_t n = 0, N = mesher.polygonPoolListSize(); n < N; ++n) {
229  const openvdb::tools::PolygonPool& polygons = polygonPoolList[n];
230  indexlist[n] = numPrimitives;
231  numPrimitives += polygons.numQuads();
232  numPrimitives += polygons.numTriangles();
233  }
234 
235  primitives.resize(numPrimitives);
236  internal::PrimCpy primCpy(polygonPoolList, indexlist, primitives);
237  primCpy.runParallel();
238  }
239 
240  MeshToVolume<GridType, InterruptT> vol(transform, 0, interrupter);
241  vol.convertToLevelSet(points, primitives, exBandWidth, inBandWidth);
242  return vol.distGridPtr();
243 }
244 
245 
246 template<class GridType>
247 inline typename GridType::Ptr
248 levelSetRebuild(const GridType& grid, float isovalue, float exBandWidth, float inBandWidth,
249  const math::Transform* xform)
250 {
251  return levelSetRebuild<GridType, util::NullInterrupter>(
252  grid, isovalue, exBandWidth, inBandWidth, xform, NULL);
253 }
254 
255 
256 template<class GridType>
257 inline typename GridType::Ptr
258 levelSetRebuild(const GridType& grid, float isovalue, float halfWidth,
259  const math::Transform* xform)
260 {
261  return levelSetRebuild<GridType, util::NullInterrupter>(
262  grid, isovalue, halfWidth, halfWidth, xform, NULL);
263 }
264 
265 
266 } // namespace tools
267 } // namespace OPENVDB_VERSION_NAME
268 } // namespace openvdb
269 
270 #endif // OPENVDB_TOOLS_LEVEL_SET_REBUILD_HAS_BEEN_INCLUDED
271 
272 // Copyright (c) 2012 DreamWorks Animation LLC
273 // All rights reserved. This software is distributed under the
274 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )