OpenVDB 5.1.0

PotentialFlow.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
36
37 #ifndef OPENVDB_TOOLS_POTENTIAL_FLOW_HAS_BEEN_INCLUDED
38 #define OPENVDB_TOOLS_POTENTIAL_FLOW_HAS_BEEN_INCLUDED
39
40 #include <openvdb/openvdb.h>
41
42 #include "GridOperators.h"
43 #include "GridTransformer.h"
44 #include "Mask.h" // interiorMask
45 #include "Morphology.h" // dilateVoxels, erodeVoxels
46 #include "PoissonSolver.h"
47
48
49 namespace openvdb {
50 OPENVDB_USE_VERSION_NAMESPACE
51 namespace OPENVDB_VERSION_NAME {
52 namespace tools {
53
55 template<typename VecGridT>
56 struct VectorToScalarGrid {
57 using Type =
58 typename VecGridT::template ValueConverter<typename VecGridT::ValueType::value_type>::Type;
59 using Ptr = typename Type::Ptr;
60 using ConstPtr = typename Type::ConstPtr;
61 };
62
63
69 template<typename GridT, typename MaskT = typename GridT::template ValueConverter<ValueMask>::Type>
70 inline typename MaskT::Ptr
71 createPotentialFlowMask(const GridT& grid, int dilation = 5);
72
73
83 template<typename Vec3T, typename GridT, typename MaskT>
84 inline typename GridT::template ValueConverter<Vec3T>::Type::Ptr
85 createPotentialFlowNeumannVelocities(const GridT& collider, const MaskT& domain,
86 const typename GridT::template ValueConverter<Vec3T>::Type::ConstPtr boundaryVelocity,
87 const Vec3T& backgroundVelocity);
88
89
101 template<typename Vec3GridT, typename MaskT, typename InterrupterT = util::NullInterrupter>
102 inline typename VectorToScalarGrid<Vec3GridT>::Ptr
103 computeScalarPotential(const MaskT& domain, const Vec3GridT& neumann, math::pcg::State& state,
104 InterrupterT* interrupter = nullptr);
105
106
113 template<typename Vec3GridT>
114 inline typename Vec3GridT::Ptr
115 computePotentialFlow(const typename VectorToScalarGrid<Vec3GridT>::Type& potential,
116 const Vec3GridT& neumann,
117 const typename Vec3GridT::ValueType backgroundVelocity =
118 zeroVal<typename Vec3GridT::TreeType::ValueType>());
119
120
122
123
124 namespace potential_flow_internal {
125
126
128 // helper function for retrieving a mask that comprises the outer-most layer of voxels
129 template<typename GridT>
130 inline typename GridT::TreeType::template ValueConverter<ValueMask>::Type::Ptr
131 extractOuterVoxelMask(GridT& inGrid)
132 {
133 using MaskTreeT = typename GridT::TreeType::template ValueConverter<ValueMask>::Type;
134 typename MaskTreeT::Ptr interiorMask(new MaskTreeT(inGrid.tree(), false, TopologyCopy()));
135 typename MaskTreeT::Ptr boundaryMask(new MaskTreeT(inGrid.tree(), false, TopologyCopy()));
136
137 erodeVoxels(*interiorMask, 1, NN_FACE);
138 boundaryMask->topologyDifference(*interiorMask);
139 return boundaryMask;
140 }
141
142
143 // computes Neumann velocities through sampling the gradient and velocities
144 template<typename Vec3GridT, typename GradientT>
145 struct ComputeNeumannVelocityOp
146 {
147 using ValueT = typename Vec3GridT::ValueType;
148 using VelocityAccessor = typename Vec3GridT::ConstAccessor;
149 using VelocitySamplerT = GridSampler<
150 typename Vec3GridT::ConstAccessor, BoxSampler>;
151 using GradientValueT = typename GradientT::TreeType::ValueType;
152
153 ComputeNeumannVelocityOp( const GradientT& gradient,
154 const Vec3GridT& velocity,
155 const ValueT& backgroundVelocity)
156 : mGradient(gradient)
157 , mVelocity(&velocity)
158 , mBackgroundVelocity(backgroundVelocity) { }
159
160 ComputeNeumannVelocityOp( const GradientT& gradient,
161 const ValueT& backgroundVelocity)
162 : mGradient(gradient)
163 , mBackgroundVelocity(backgroundVelocity) { }
164
165 void operator()(typename Vec3GridT::TreeType::LeafNodeType& leaf, size_t) const {
166 auto gradientAccessor = mGradient.getConstAccessor();
167
168 std::unique_ptr<VelocityAccessor> velocityAccessor;
169 std::unique_ptr<VelocitySamplerT> velocitySampler;
170 if (mVelocity) {
171 velocityAccessor.reset(new VelocityAccessor(mVelocity->getConstAccessor()));
172 velocitySampler.reset(new VelocitySamplerT(*velocityAccessor, mVelocity->transform()));
173 }
174
175 for (auto it = leaf.beginValueOn(); it; ++it) {
176 Coord ijk = it.getCoord();
177 auto gradient = gradientAccessor.getValue(ijk);
178 if (gradient.normalize()) {
179 const Vec3d xyz = mGradient.transform().indexToWorld(ijk);
180 const ValueT sampledVelocity = velocitySampler ?
181 velocitySampler->wsSample(xyz) : zeroVal<ValueT>();
182 auto velocity = sampledVelocity + mBackgroundVelocity;
183 auto value = gradient.dot(velocity) * gradient;
184 it.setValue(value);
185 }
186 else {
187 it.setValueOff();
188 }
189 }
190 }
191
192 private:
193 const GradientT& mGradient;
194 const Vec3GridT* mVelocity = nullptr;
195 const ValueT& mBackgroundVelocity;
196 }; // struct ComputeNeumannVelocityOp
197
198
199 // initalizes the boundary conditions for use in the Poisson Solver
200 template<typename Vec3GridT, typename MaskT>
201 struct SolveBoundaryOp
202 {
203 SolveBoundaryOp(const Vec3GridT& velGrid, const MaskT& domainGrid)
204 : mVoxelSize(domainGrid.voxelSize()[0])
205 , mVelGrid(velGrid)
206 , mDomainGrid(domainGrid)
207 { }
208
209 void operator()(const Coord& ijk, const Coord& neighbor,
210 double& source, double& diagonal) const {
211
212 typename Vec3GridT::ConstAccessor velGridAccessor = mVelGrid.getAccessor();
213 const Coord diff = (ijk - neighbor);
214
215 if (velGridAccessor.isValueOn(ijk)) { // Neumann
216 const typename Vec3GridT::ValueType& sampleVel = velGridAccessor.getValue(ijk);
217 source += mVoxelSize*diff[0]*sampleVel[0];
218 source += mVoxelSize*diff[1]*sampleVel[1];
219 source += mVoxelSize*diff[2]*sampleVel[2];
220 } else {
221 diagonal -= 1; // Zero Dirichlet
222 }
223
224 }
225
226 const double& mVoxelSize;
227 const Vec3GridT& mVelGrid;
228 const MaskT& mDomainGrid;
229 }; // struct SolveBoundaryOp
230
231
232 } // namespace potential_flow_internal
233
234
236
237 template<typename GridT, typename MaskT>
238 inline typename MaskT::Ptr
239 createPotentialFlowMask(const GridT& grid, int dilation)
240 {
241 using MaskTreeT = typename MaskT::TreeType;
242
243 if (!grid.hasUniformVoxels()) {
244 OPENVDB_THROW(ValueError, "Transform must have uniform voxels for Potential Flow mask.");
245 }
246
247 // construct a new mask grid representing the interior region
248 auto interior = interiorMask(grid);
249
250 // create a new mask grid from the interior topology
251 typename MaskTreeT::Ptr maskTree(new MaskTreeT(interior->tree(), false, TopologyCopy()));
252 typename MaskT::Ptr mask = MaskT::create(maskTree);
253 mask->setTransform(grid.transform().copy());
254
255 dilateActiveValues(*maskTree, dilation, NN_FACE_EDGE);
256
257 // subtract the interior region from the mask to leave just the exterior narrow band
258 mask->tree().topologyDifference(interior->tree());
259
260 return mask;
261 }
262
263
264 template<typename Vec3T, typename GridT, typename MaskT>
265 typename GridT::template ValueConverter<Vec3T>::Type::Ptr createPotentialFlowNeumannVelocities(
266 const GridT& collider,
267 const MaskT& domain,
268 const typename GridT::template ValueConverter<Vec3T>::Type::ConstPtr boundaryVelocity,
269 const Vec3T& backgroundVelocity)
270 {
271 using Vec3GridT = typename GridT::template ValueConverter<Vec3T>::Type;
272 using TreeT = typename Vec3GridT::TreeType;
273 using ValueT = typename TreeT::ValueType;
274 using GradientT = typename ScalarToVectorConverter<GridT>::Type;
275
276 using potential_flow_internal::ComputeNeumannVelocityOp;
277
278 // this method requires the collider to be a level set to generate the gradient
279 // use the tools::topologyToLevelset() method if you need to convert a mask into a level set
280 if (collider.getGridClass() != GRID_LEVEL_SET ||
281 !std::is_floating_point<typename GridT::TreeType::ValueType>::value) {
282 OPENVDB_THROW(TypeError, "Potential Flow expecting the collider to be a level set.");
283 }
284
285 // empty grid if there are no velocities
286 if (backgroundVelocity == zeroVal<Vec3T>() &&
287 (!boundaryVelocity || boundaryVelocity->empty())) {
288 auto neumann = Vec3GridT::create();
289 neumann->setTransform(collider.transform().copy());
290 return neumann;
291 }
292
293 // extract the intersection between the collider and the domain
294 using MaskTreeT = typename GridT::TreeType::template ValueConverter<ValueMask>::Type;
295 typename MaskTreeT::Ptr boundary(new MaskTreeT(domain.tree(), false, TopologyCopy()));
296 boundary->topologyIntersection(collider.tree());
297
298 typename TreeT::Ptr neumannTree(new TreeT(*boundary, zeroVal<ValueT>(), TopologyCopy()));
299 neumannTree->voxelizeActiveTiles();
300
301 // compute the gradient from the collider
302 const typename GradientT::Ptr gradient = tools::gradient(collider);
303
304 typename tree::LeafManager<TreeT> leafManager(*neumannTree);
305
306 if (boundaryVelocity && !boundaryVelocity->empty()) {
307 ComputeNeumannVelocityOp<Vec3GridT, GradientT>
308 neumannOp(*gradient, *boundaryVelocity, backgroundVelocity);
309 leafManager.foreach(neumannOp, false);
310 }
311 else {
312 ComputeNeumannVelocityOp<Vec3GridT, GradientT>
313 neumannOp(*gradient, backgroundVelocity);
314 leafManager.foreach(neumannOp, false);
315 }
316
317 // prune any inactive values
318 tools::pruneInactive(*neumannTree);
319
320 typename Vec3GridT::Ptr neumann(Vec3GridT::create(neumannTree));
321 neumann->setTransform(collider.transform().copy());
322
323 return neumann;
324 }
325
326
327 template<typename Vec3GridT, typename MaskT, typename InterrupterT>
328 inline typename VectorToScalarGrid<Vec3GridT>::Ptr
329 computeScalarPotential(const MaskT& domain, const Vec3GridT& neumann,
330 math::pcg::State& state, InterrupterT* interrupter)
331 {
332 using ScalarT = typename Vec3GridT::ValueType::value_type;
333 using ScalarTreeT = typename Vec3GridT::TreeType::template ValueConverter<ScalarT>::Type;
334 using ScalarGridT = typename Vec3GridT::template ValueConverter<ScalarT>::Type;
335
336 using potential_flow_internal::SolveBoundaryOp;
337
338 // create the solution tree and activate using domain topology
339 ScalarTreeT solveTree(domain.tree(), zeroVal<ScalarT>(), TopologyCopy());
340 solveTree.voxelizeActiveTiles();
341
342 util::NullInterrupter nullInterrupt;
343 if (!interrupter) interrupter = &nullInterrupt;
344
345 // solve for scalar potential
346 SolveBoundaryOp<Vec3GridT, MaskT> solve(neumann, domain);
347 typename ScalarTreeT::Ptr potentialTree =
348 poisson::solveWithBoundaryConditions(solveTree, solve, state, *interrupter, true);
349
350 auto potential = ScalarGridT::create(potentialTree);
351 potential->setTransform(domain.transform().copy());
352
353 return potential;
354 }
355
356
357 template<typename Vec3GridT>
358 inline typename Vec3GridT::Ptr
359 computePotentialFlow(const typename VectorToScalarGrid<Vec3GridT>::Type& potential,
360 const Vec3GridT& neumann,
361 const typename Vec3GridT::ValueType backgroundVelocity)
362 {
363 using Vec3T = const typename Vec3GridT::ValueType;
364 using potential_flow_internal::extractOuterVoxelMask;
365
366 // The VDB gradient op uses the background grid value, which is zero by default, when
367 // computing the gradient at the boundary. This works at the zero-dirichlet boundaries, but
368 // give spurious values at Neumann ones as the potential should be non-zero there. To avoid
369 // the extra error, we just substitute the Neumann condition on the boundaries.
370 // Technically, we should allow for some tangential velocity, coming from the gradient of
371 // potential. However, considering the voxelized nature of our solve, a decent approximation
372 // to a tangential derivative isn't probably worth our time. Any tangential component will be
373 // found in the next interior ring of voxels.
374
375 auto gradient = tools::gradient(potential);
376
377 // apply Neumann values to the gradient
378
379 auto applyNeumann = [&gradient, &neumann] (
380 const MaskGrid::TreeType::LeafNodeType& leaf, size_t)
381 {
382 typename Vec3GridT::Accessor gradientAccessor = gradient->getAccessor();
383 typename Vec3GridT::ConstAccessor neumannAccessor = neumann.getAccessor();
384 for (auto it = leaf.beginValueOn(); it; ++it) {
385 const Coord ijk = it.getCoord();
386 typename Vec3GridT::ValueType value;
387 if (neumannAccessor.probeValue(ijk, value)) {
388 gradientAccessor.setValue(ijk, value);
389 }
390 }
391 };
392
393 const MaskGrid::TreeType::Ptr boundary = extractOuterVoxelMask(*gradient);
394 typename tree::LeafManager<const typename MaskGrid::TreeType> leafManager(*boundary);
395 leafManager.foreach(applyNeumann);
396
397 // apply the background value to the gradient if supplied
398
399 if (backgroundVelocity != zeroVal<Vec3T>()) {
400 auto applyBackgroundVelocity = [&backgroundVelocity] (
401 typename Vec3GridT::TreeType::LeafNodeType& leaf, size_t)
402 {
403 for (auto it = leaf.beginValueOn(); it; ++it) {
404 it.setValue(it.getValue() - backgroundVelocity);
405 }
406 };
407
408 typename tree::LeafManager<typename Vec3GridT::TreeType> leafManager2(gradient->tree());
409 leafManager2.foreach(applyBackgroundVelocity);
410 }
411
412 return gradient;
413 }
414
415
417
418 } // namespace tools
419 } // namespace OPENVDB_VERSION_NAME
420 } // namespace openvdb
421
422 #endif // OPENVDB_TOOLS_POTENTIAL_FLOW_HAS_BEEN_INCLUDED
423
424 // Copyright (c) 2012-2018 DreamWorks Animation LLC
425 // All rights reserved. This software is distributed under the
426 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v5_1::tools::gradient
ScalarToVectorConverter< GridType >::Type::Ptr gradient(const GridType &grid, bool threaded, InterruptT *interrupt)
Compute the gradient of the given scalar grid.
Definition: GridOperators.h:1023
openvdb::v5_1::tools::potential_flow_internal::SolveBoundaryOp::SolveBoundaryOp
SolveBoundaryOp(const Vec3GridT &velGrid, const MaskT &domainGrid)
Definition: PotentialFlow.h:203
PoissonSolver.h
Solve Poisson&#39;s equation ∇2x = b for x, where b is a vector comprising the values of all of the acti...
openvdb::v5_1::tools::VectorToScalarGrid
Metafunction to convert a vector-valued grid type to a scalar grid type.
Definition: PotentialFlow.h:56
openvdb::v5_1::tools::VectorToScalarGrid::Type
typename VecGridT::template ValueConverter< typename VecGridT::ValueType::value_type >::Type Type
Definition: PotentialFlow.h:58
openvdb::v5_1::tools::computeScalarPotential
VectorToScalarGrid< Vec3GridT >::Ptr computeScalarPotential(const MaskT &domain, const Vec3GridT &neumann, math::pcg::State &state, InterrupterT *interrupter=nullptr)
Compute the Potential on the domain using the Neumann boundary conditions on solid boundaries...
Definition: PotentialFlow.h:329
openvdb::v5_1::tools::NN_FACE_EDGE
Definition: Morphology.h:85
openvdb::v5_1::tools::potential_flow_internal::ComputeNeumannVelocityOp::GradientValueT
typename GradientT::TreeType::ValueType GradientValueT
Definition: PotentialFlow.h:151
openvdb.h
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:109
GridOperators.h
Apply an operator to an input grid to produce an output grid with the same active voxel topology but ...
openvdb::v5_1::tools::createPotentialFlowNeumannVelocities
GridT::template ValueConverter< Vec3T >::Type::Ptr createPotentialFlowNeumannVelocities(const GridT &collider, const MaskT &domain, const typename GridT::template ValueConverter< Vec3T >::Type::ConstPtr boundaryVelocity, const Vec3T &backgroundVelocity)
Create a Potential Flow velocities grid for the Neumann boundary.
Definition: PotentialFlow.h:265
openvdb::v5_1::tools::potential_flow_internal::SolveBoundaryOp::mDomainGrid
const MaskT & mDomainGrid
Definition: PotentialFlow.h:228
openvdb::v5_1::tools::potential_flow_internal::ComputeNeumannVelocityOp::ValueT
typename Vec3GridT::ValueType ValueT
Definition: PotentialFlow.h:147
openvdb::v5_1::tools::BoxSampler
Definition: Interpolation.h:146
GridTransformer.h
Mask.h
Construct boolean mask grids from grids of arbitrary type.
openvdb::v5_1::tools::potential_flow_internal::ComputeNeumannVelocityOp
Definition: PotentialFlow.h:145
openvdb::v5_1::tools::interiorMask
GridType::template ValueConverter< bool >::Type::Ptr interiorMask(const GridType &grid, const double isovalue=0.0)
Given an input grid of any type, return a new, boolean grid whose active voxel topology matches the i...
Definition: Mask.h:138
openvdb::v5_1::TopologyCopy
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:515
openvdb::v5_1::tools::potential_flow_internal::SolveBoundaryOp::mVelGrid
const Vec3GridT & mVelGrid
Definition: PotentialFlow.h:227
openvdb::v5_1::tree::LeafManager
This class manages a linear array of pointers to a given tree&#39;s leaf nodes, as well as optional auxil...
Definition: LeafManager.h:110
openvdb::v5_1::tools::VectorToScalarGrid::ConstPtr
typename Type::ConstPtr ConstPtr
Definition: PotentialFlow.h:60
openvdb::v5_1::tools::NN_FACE
Definition: Morphology.h:85
openvdb::v5_1::tools::potential_flow_internal::ComputeNeumannVelocityOp::operator()
void operator()(typename Vec3GridT::TreeType::LeafNodeType &leaf, size_t) const
Definition: PotentialFlow.h:165
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
openvdb::v5_1::ValueError
Definition: Exceptions.h:92
openvdb::v5_1::math::Vec3d
Vec3< double > Vec3d
Definition: Vec3.h:679
openvdb::v5_1::tools::potential_flow_internal::SolveBoundaryOp::mVoxelSize
const double & mVoxelSize
Definition: PotentialFlow.h:226
openvdb::v5_1::tools::erodeVoxels
void erodeVoxels(TreeType &tree, int iterations=1, NearestNeighbors nn=NN_FACE)
Topologically erode all leaf-level active voxels in the given tree.
Definition: Morphology.h:877
openvdb::v5_1::math::pcg::State
Information about the state of a conjugate gradient solution.
Definition: ConjGradient.h:73
openvdb::v5_1::tools::potential_flow_internal::ComputeNeumannVelocityOp::ComputeNeumannVelocityOp
ComputeNeumannVelocityOp(const GradientT &gradient, const Vec3GridT &velocity, const ValueT &backgroundVelocity)
Definition: PotentialFlow.h:153
openvdb::v5_1::tools::VectorToScalarGrid::Ptr
typename Type::Ptr Ptr
Definition: PotentialFlow.h:59
Morphology.h
Implementation of morphological dilation and erosion.
openvdb
Definition: Exceptions.h:40
openvdb::v5_1::TypeError
Definition: Exceptions.h:91
openvdb::v5_1::GRID_LEVEL_SET
Definition: Types.h:274
openvdb::v5_1::tools::potential_flow_internal::SolveBoundaryOp::operator()
void operator()(const Coord &ijk, const Coord &neighbor, double &source, double &diagonal) const
Definition: PotentialFlow.h:209
openvdb::v5_1::tools::pruneInactive
void pruneInactive(TreeT &tree, bool threaded=true, size_t grainSize=1)
Reduce the memory footprint of a tree by replacing with background tiles any nodes whose values are a...
Definition: Prune.h:381
openvdb::v5_1::tools::ScalarToVectorConverter::Type
ScalarGridType::template ValueConverter< VectorValueT >::Type Type
Definition: GridOperators.h:68
openvdb::v5_1::tools::potential_flow_internal::SolveBoundaryOp
Definition: PotentialFlow.h:201
openvdb::v5_1::tools::createPotentialFlowMask
MaskT::Ptr createPotentialFlowMask(const GridT &grid, int dilation=5)
Construct a mask for the Potential Flow domain.
Definition: PotentialFlow.h:239
openvdb::v5_1::math::pcg::solve
State solve(const PositiveDefMatrix &A, const Vector< typename PositiveDefMatrix::ValueType > &b, Vector< typename PositiveDefMatrix::ValueType > &x, Preconditioner< typename PositiveDefMatrix::ValueType > &preconditioner, const State &termination=terminationDefaults< typename PositiveDefMatrix::ValueType >())
Solve Ax = b via the preconditioned conjugate gradient method.
Definition: ConjGradient.h:1639
openvdb::v5_1::Grid::Ptr
SharedPtr< Grid > Ptr
Definition: Grid.h:502
openvdb::v5_1::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
openvdb::v5_1::tools::poisson::solveWithBoundaryConditions
TreeType::Ptr solveWithBoundaryConditions(const TreeType &, const BoundaryOp &, math::pcg::State &, Interrupter &, bool staggered=false)
Solve ∇2x = b for x with user-specified boundary conditions, where b is a vector comprising the valu...
Definition: PoissonSolver.h:784
openvdb::v5_1::tools::potential_flow_internal::ComputeNeumannVelocityOp::ComputeNeumannVelocityOp
ComputeNeumannVelocityOp(const GradientT &gradient, const ValueT &backgroundVelocity)
Definition: PotentialFlow.h:160
openvdb::v5_1::tree::LeafManager::foreach
void foreach(const LeafOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that applies a user-supplied functor to each leaf node in the LeafManager.
Definition: LeafManager.h:524
openvdb::v5_1::tools::GridSampler
Class that provides the interface for continuous sampling of values in a tree.
Definition: Interpolation.h:310
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
openvdb::v5_1::tools::dilateActiveValues
void dilateActiveValues(TreeType &tree, int iterations=1, NearestNeighbors nn=NN_FACE, TilePolicy mode=PRESERVE_TILES)
Topologically dilate all active values (i.e. both voxels and tiles) in a tree using one of three near...
Definition: Morphology.h:1078
openvdb::v5_1::tools::computePotentialFlow
Vec3GridT::Ptr computePotentialFlow(const typename VectorToScalarGrid< Vec3GridT >::Type &potential, const Vec3GridT &neumann, const typename Vec3GridT::ValueType backgroundVelocity=zeroVal< typename Vec3GridT::TreeType::ValueType >())
Compute a vector Flow Field comprising the gradient of the potential with Neumann boundary conditions...
Definition: PotentialFlow.h:359
openvdb::v5_1::tools::potential_flow_internal::ComputeNeumannVelocityOp::VelocityAccessor
typename Vec3GridT::ConstAccessor VelocityAccessor
Definition: PotentialFlow.h:148
openvdb::v5_1::util::NullInterrupter
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:52