101template<
typename TreeType>
 
  102typename TreeType::Ptr
 
  105template<
typename TreeType, 
typename Interrupter>
 
  106typename TreeType::Ptr
 
  142template<
typename TreeType, 
typename BoundaryOp, 
typename Interrupter>
 
  143typename TreeType::Ptr
 
  149    bool staggered = 
false);
 
  152    typename PreconditionerType,
 
  155    typename Interrupter>
 
  156typename TreeType::Ptr
 
  162    bool staggered = 
false);
 
  165    typename PreconditionerType,
 
  167    typename DomainTreeType,
 
  169    typename Interrupter>
 
  170typename TreeType::Ptr
 
  173    const DomainTreeType&,
 
  177    bool staggered = 
false);
 
  187template<
typename VIndexTreeType>
 
  193template<
typename TreeType>
 
  194typename TreeType::template ValueConverter<VIndex>::Type::Ptr
 
  204template<
typename VectorValueType, 
typename SourceTreeType>
 
  207    const SourceTreeType& source,
 
  208    const typename SourceTreeType::template ValueConverter<VIndex>::Type& index);
 
  218template<
typename TreeValueType, 
typename VIndexTreeType, 
typename VectorValueType>
 
  219typename VIndexTreeType::template ValueConverter<TreeValueType>::Type::Ptr
 
  222    const VIndexTreeType& index,
 
  223    const TreeValueType& background);
 
  230template<
typename BoolTreeType>
 
  233    const typename BoolTreeType::template ValueConverter<VIndex>::Type& vectorIndexTree,
 
  235    bool staggered = 
false);
 
  257template<
typename BoolTreeType, 
typename BoundaryOp>
 
  260    const typename BoolTreeType::template ValueConverter<VIndex>::Type& vectorIndexTree,
 
  262    const BoundaryOp& boundaryOp,
 
  264    bool staggered = 
false);
 
  270template<
typename ValueType>
 
  290template<
typename LeafType>
 
  294    LeafCountOp(VIndex* count_): count(count_) {}
 
  295    void operator()(
const LeafType& leaf, 
size_t leafIdx)
 const {
 
  296        count[leafIdx] = 
static_cast<VIndex
>(leaf.onVoxelCount());
 
  303template<
typename LeafType>
 
  307    LeafIndexOp(
const VIndex* count_): count(count_) {}
 
  308    void operator()(LeafType& leaf, 
size_t leafIdx)
 const {
 
  309        VIndex idx = (leafIdx == 0) ? 0 : count[leafIdx - 1];
 
  310        for (
typename LeafType::ValueOnIter it = leaf.beginValueOn(); it; ++it) {
 
  320template<
typename VIndexTreeType>
 
  324    using LeafT = 
typename VIndexTreeType::LeafNodeType;
 
  328    LeafMgrT leafManager(result);
 
  329    const size_t leafCount = leafManager.leafCount();
 
  331    if (leafCount == 0) 
return;
 
  334    std::unique_ptr<VIndex[]> perLeafCount(
new VIndex[leafCount]);
 
  335    VIndex* perLeafCountPtr = perLeafCount.get();
 
  336    leafManager.foreach(internal::LeafCountOp<LeafT>(perLeafCountPtr));
 
  340    for (
size_t i = 1; i < leafCount; ++i) {
 
  341        perLeafCount[i] += perLeafCount[i - 1];
 
  349    leafManager.foreach(internal::LeafIndexOp<LeafT>(perLeafCountPtr));
 
 
  353template<
typename TreeType>
 
  354inline typename TreeType::template ValueConverter<VIndex>::Type::Ptr
 
  357    using VIdxTreeT = 
typename TreeType::template ValueConverter<VIndex>::Type;
 
  360    const VIndex invalidIdx = -1;
 
  361    typename VIdxTreeT::Ptr result(
 
  365    result->voxelizeActiveTiles();
 
 
  381template<
typename VectorValueType, 
typename SourceTreeType>
 
  384    using VIdxTreeT = 
typename SourceTreeType::template ValueConverter<VIndex>::Type;
 
  385    using VIdxLeafT = 
typename VIdxTreeT::LeafNodeType;
 
  386    using LeafT = 
typename SourceTreeType::LeafNodeType;
 
  387    using TreeValueT = 
typename SourceTreeType::ValueType;
 
  390    const SourceTreeType* 
tree;
 
  393    CopyToVecOp(
const SourceTreeType& t, VectorT& v): 
tree(&t), vector(&v) {}
 
  395    void operator()(
const VIdxLeafT& idxLeaf, 
size_t )
 const 
  397        VectorT& vec = *vector;
 
  398        if (
const LeafT* leaf = 
tree->probeLeaf(idxLeaf.origin())) {
 
  401            for (
typename VIdxLeafT::ValueOnCIter it = idxLeaf.cbeginValueOn(); it; ++it) {
 
  402                vec[*it] = leaf->getValue(it.pos());
 
  407            const TreeValueT& value = tree->getValue(idxLeaf.origin());
 
  408            for (
typename VIdxLeafT::ValueOnCIter it = idxLeaf.cbeginValueOn(); it; ++it) {
 
  419template<
typename VectorValueType, 
typename SourceTreeType>
 
  420inline typename math::pcg::Vector<VectorValueType>::Ptr
 
  422    const typename SourceTreeType::template ValueConverter<VIndex>::Type& idxTree)
 
  424    using VIdxTreeT = 
typename SourceTreeType::template ValueConverter<VIndex>::Type;
 
  429    const size_t numVoxels = idxTree.activeVoxelCount();
 
  434    VIdxLeafMgrT leafManager(idxTree);
 
  435    leafManager.foreach(internal::CopyToVecOp<VectorValueType, SourceTreeType>(
tree, *result));
 
 
  449template<
typename TreeValueType, 
typename VIndexTreeType, 
typename VectorValueType>
 
  452    using OutTreeT = 
typename VIndexTreeType::template ValueConverter<TreeValueType>::Type;
 
  453    using OutLeafT = 
typename OutTreeT::LeafNodeType;
 
  454    using VIdxLeafT = 
typename VIndexTreeType::LeafNodeType;
 
  457    const VectorT* vector;
 
  460    CopyFromVecOp(
const VectorT& v, 
OutTreeT& t): vector(&v), 
tree(&t) {}
 
  462    void operator()(
const VIdxLeafT& idxLeaf, 
size_t )
 const 
  464        const VectorT& vec = *vector;
 
  465        OutLeafT* leaf = 
tree->probeLeaf(idxLeaf.origin());
 
  467        for (
typename VIdxLeafT::ValueOnCIter it = idxLeaf.cbeginValueOn(); it; ++it) {
 
  468            leaf->setValueOnly(it.pos(), 
static_cast<TreeValueType
>(vec[*it]));
 
  477template<
typename TreeValueType, 
typename VIndexTreeType, 
typename VectorValueType>
 
  478inline typename VIndexTreeType::template ValueConverter<TreeValueType>::Type::Ptr
 
  481    const VIndexTreeType& idxTree,
 
  482    const TreeValueType& background)
 
  484    using OutTreeT = 
typename VIndexTreeType::template ValueConverter<TreeValueType>::Type;
 
  493    VIdxLeafMgrT leafManager(idxTree);
 
  495        internal::CopyFromVecOp<TreeValueType, VIndexTreeType, VectorValueType>(vector, 
tree));
 
 
  508template<
typename BoolTreeType, 
typename BoundaryOp>
 
  509struct ISStaggeredLaplacianOp
 
  511    using VIdxTreeT = 
typename BoolTreeType::template ValueConverter<VIndex>::Type;
 
  512    using VIdxLeafT = 
typename VIdxTreeT::LeafNodeType;
 
  513    using ValueT = LaplacianMatrix::ValueType;
 
  517    const VIdxTreeT* idxTree;
 
  519    const BoundaryOp boundaryOp;
 
  522    ISStaggeredLaplacianOp(LaplacianMatrix& m, 
const VIdxTreeT& idx,
 
  523        const BoolTreeType& mask, 
const BoundaryOp& 
op, VectorT& src):
 
  526    void operator()(
const VIdxLeafT& idxLeaf, 
size_t )
 const 
  534        const ValueT diagonal = -6.f, offDiagonal = 1.f;
 
  537        for (
typename VIdxLeafT::ValueOnCIter it = idxLeaf.cbeginValueOn(); it; ++it) {
 
  541            LaplacianMatrix::RowEditor row = laplacian->getRowEditor(rowNum);
 
  544            if (interior.isValueOn(ijk)) {
 
  549                row.setValue(vectorIdx.getValue(ijk.
offsetBy(-1, 0, 0)), offDiagonal);
 
  551                row.setValue(vectorIdx.getValue(ijk.
offsetBy(0, -1, 0)), offDiagonal);
 
  553                row.setValue(vectorIdx.getValue(ijk.
offsetBy(0, 0, -1)), offDiagonal);
 
  555                row.setValue(rowNum, diagonal);
 
  557                row.setValue(vectorIdx.getValue(ijk.
offsetBy(0, 0, 1)), offDiagonal);
 
  559                row.setValue(vectorIdx.getValue(ijk.
offsetBy(0, 1, 0)), offDiagonal);
 
  561                row.setValue(vectorIdx.getValue(ijk.
offsetBy(1, 0, 0)), offDiagonal);
 
  567                ValueT modifiedDiagonal = 0.f;
 
  570                if (vectorIdx.probeValue(ijk.
offsetBy(-1, 0, 0), column)) {
 
  571                    row.setValue(column, offDiagonal);
 
  572                    modifiedDiagonal -= 1;
 
  574                    boundaryOp(ijk, ijk.
offsetBy(-1, 0, 0), source->at(rowNum), modifiedDiagonal);
 
  577                if (vectorIdx.probeValue(ijk.
offsetBy(0, -1, 0), column)) {
 
  578                    row.setValue(column, offDiagonal);
 
  579                    modifiedDiagonal -= 1;
 
  581                    boundaryOp(ijk, ijk.
offsetBy(0, -1, 0), source->at(rowNum), modifiedDiagonal);
 
  584                if (vectorIdx.probeValue(ijk.
offsetBy(0, 0, -1), column)) {
 
  585                    row.setValue(column, offDiagonal);
 
  586                    modifiedDiagonal -= 1;
 
  588                    boundaryOp(ijk, ijk.
offsetBy(0, 0, -1), source->at(rowNum), modifiedDiagonal);
 
  591                if (vectorIdx.probeValue(ijk.
offsetBy(0, 0, 1), column)) {
 
  592                    row.setValue(column, offDiagonal);
 
  593                    modifiedDiagonal -= 1;
 
  595                    boundaryOp(ijk, ijk.
offsetBy(0, 0, 1), source->at(rowNum), modifiedDiagonal);
 
  598                if (vectorIdx.probeValue(ijk.
offsetBy(0, 1, 0), column)) {
 
  599                    row.setValue(column, offDiagonal);
 
  600                    modifiedDiagonal -= 1;
 
  602                    boundaryOp(ijk, ijk.
offsetBy(0, 1, 0), source->at(rowNum), modifiedDiagonal);
 
  605                if (vectorIdx.probeValue(ijk.
offsetBy(1, 0, 0), column)) {
 
  606                    row.setValue(column, offDiagonal);
 
  607                    modifiedDiagonal -= 1;
 
  609                    boundaryOp(ijk, ijk.
offsetBy(1, 0, 0), source->at(rowNum), modifiedDiagonal);
 
  612                row.setValue(rowNum, modifiedDiagonal);
 
  622#define OPENVDB_TOOLS_POISSON_LAPLACIAN_STENCIL 2 
  625template<
typename VIdxTreeT, 
typename BoundaryOp>
 
  628    using VIdxLeafT = 
typename VIdxTreeT::LeafNodeType;
 
  629    using ValueT = LaplacianMatrix::ValueType;
 
  630    using VectorT = 
typename math::pcg::Vector<ValueT>;
 
  633    const VIdxTreeT* idxTree;
 
  634    const BoundaryOp boundaryOp;
 
  637    ISLaplacianOp(LaplacianMatrix& m, 
const VIdxTreeT& idx, 
const BoundaryOp& op, VectorT& src):
 
  638        laplacian(&m), idxTree(&idx), boundaryOp(
op), source(&src) {}
 
  640    void operator()(
const VIdxLeafT& idxLeaf, 
size_t )
 const 
  642        typename tree::ValueAccessor<const VIdxTreeT> vectorIdx(*idxTree);
 
  644        const int kNumOffsets = 6;
 
  645        const Coord ijkOffset[kNumOffsets] = {
 
  646#if OPENVDB_TOOLS_POISSON_LAPLACIAN_STENCIL == 1 
  647            Coord(-1,0,0), Coord(1,0,0), Coord(0,-1,0), Coord(0,1,0), Coord(0,0,-1), Coord(0,0,1)
 
  649            Coord(-2,0,0), Coord(2,0,0), Coord(0,-2,0), Coord(0,2,0), Coord(0,0,-2), Coord(0,0,2)
 
  654        for (
typename VIdxLeafT::ValueOnCIter it = idxLeaf.cbeginValueOn(); it; ++it) {
 
  657            const Coord ijk = it.getCoord();
 
  658            const math::pcg::SizeType rowNum = 
static_cast<math::pcg::SizeType
>(it.getValue());
 
  660            LaplacianMatrix::RowEditor row = 
laplacian->getRowEditor(rowNum);
 
  662            ValueT modifiedDiagonal = 0.f;
 
  665            for (
int dir = 0; dir < kNumOffsets; ++dir) {
 
  666                const Coord neighbor = ijk + ijkOffset[dir];
 
  671#if OPENVDB_TOOLS_POISSON_LAPLACIAN_STENCIL == 1 
  672                const bool ijkIsInterior = (vectorIdx.probeValue(neighbor + ijkOffset[dir], column)
 
  673                    && vectorIdx.isValueOn(neighbor));
 
  675                const bool ijkIsInterior = vectorIdx.probeValue(neighbor, column);
 
  680                    row.setValue(column, 1.f);
 
  681                    modifiedDiagonal -= 1.f;
 
  685                    boundaryOp(ijk, neighbor, source->at(rowNum), modifiedDiagonal);
 
  689            row.setValue(rowNum, modifiedDiagonal);
 
  699template<
typename BoolTreeType>
 
  700inline LaplacianMatrix::Ptr
 
  712template<
typename BoolTreeType, 
typename BoundaryOp>
 
  713inline LaplacianMatrix::Ptr
 
  715    const typename BoolTreeType::template ValueConverter<VIndex>::Type& idxTree,
 
  717    const BoundaryOp& boundaryOp,
 
  721    using VIdxTreeT = 
typename BoolTreeType::template ValueConverter<VIndex>::Type;
 
  725    const Index64 numDoF = idxTree.activeVoxelCount();
 
  733    VIdxLeafMgrT idxLeafManager(idxTree);
 
  735        idxLeafManager.foreach(internal::ISStaggeredLaplacianOp<BoolTreeType, BoundaryOp>(
 
  738        idxLeafManager.foreach(internal::ISLaplacianOp<VIdxTreeT, BoundaryOp>(
 
  739            laplacian, idxTree, boundaryOp, source));
 
 
  749template<
typename TreeType>
 
  750typename TreeType::Ptr
 
  754    return solve(inTree, state, interrupter, staggered);
 
 
  758template<
typename TreeType, 
typename Interrupter>
 
  759typename TreeType::Ptr
 
  767template<
typename TreeType, 
typename BoundaryOp, 
typename Interrupter>
 
  768typename TreeType::Ptr
 
  774        inTree, boundaryOp, state, interrupter, staggered);
 
 
  779    typename PreconditionerType,
 
  782    typename Interrupter>
 
  783typename TreeType::Ptr
 
  785    const TreeType& inTree,
 
  786    const BoundaryOp& boundaryOp,
 
  788    Interrupter& interrupter,
 
  792        inTree, inTree, boundaryOp, state, interrupter, staggered);
 
 
  796    typename PreconditionerType,
 
  798    typename DomainTreeType,
 
  800    typename Interrupter>
 
  801typename TreeType::Ptr
 
  803    const TreeType& inTree,
 
  804    const DomainTreeType& domainMask,
 
  805    const BoundaryOp& boundaryOp,
 
  807    Interrupter& interrupter,
 
  810    using TreeValueT = 
typename TreeType::ValueType;
 
  813    using VIdxTreeT = 
typename TreeType::template ValueConverter<VIndex>::Type;
 
  814    using MaskTreeT = 
typename TreeType::template ValueConverter<bool>::Type;
 
 
  855#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION 
  857#ifdef OPENVDB_INSTANTIATE_POISSONSOLVER 
  861#define _FUNCTION(TreeT) \ 
  862    TreeT::Ptr solveWithBoundaryConditionsAndPreconditioner< \ 
  863        math::pcg::IncompleteCholeskyPreconditioner<LaplacianMatrix>>( \ 
  864            const TreeT&, const TreeT&, const DirichletBoundaryOp<LaplacianMatrix::ValueType>&, \ 
  865            math::pcg::State&, util::NullInterrupter&, bool) 
  869#define _FUNCTION(TreeT) \ 
  870    TreeT::Ptr solveWithBoundaryConditionsAndPreconditioner< \ 
  871        math::pcg::IncompleteCholeskyPreconditioner<LaplacianMatrix>>( \ 
  872            const TreeT&, const BoolTree&, const DirichletBoundaryOp<LaplacianMatrix::ValueType>&, \ 
  873            math::pcg::State&, util::NullInterrupter&, bool) 
  877#define _FUNCTION(TreeT) \ 
  878    TreeT::Ptr solveWithBoundaryConditionsAndPreconditioner< \ 
  879        math::pcg::JacobiPreconditioner<LaplacianMatrix>>( \ 
  880            const TreeT&, const TreeT&, const DirichletBoundaryOp<LaplacianMatrix::ValueType>&, \ 
  881            math::pcg::State&, util::NullInterrupter&, bool) 
  885#define _FUNCTION(TreeT) \ 
  886    TreeT::Ptr solveWithBoundaryConditionsAndPreconditioner< \ 
  887        math::pcg::JacobiPreconditioner<LaplacianMatrix>>( \ 
  888            const TreeT&, const BoolTree&, const DirichletBoundaryOp<LaplacianMatrix::ValueType>&, \ 
  889            math::pcg::State&, util::NullInterrupter&, bool)