openvdb icon indicating copy to clipboard operation
openvdb copied to clipboard

`touchLeaf` should let you know if it did any work, ala `std::map::emplace` and `::try_emplace`.

Open BenFrantzDale opened this issue 3 years ago • 0 comments

Is your feature request related to a problem? Please describe.

Right now touchLeaf(Coord) returns a LeafNodeT* to the (possibly new) leaf.

Describe the solution you'd like

I'd like to get a std::pair<LeafNode*, bool> returned so I know if the leaf is new or not. (Better: Return a std::pair<LeafNode*, std::uint8_t> indicating how many levels it added to create the leaf.)

The function is

template<typename ChildT, Index Log2Dim>
inline typename ChildT::LeafNodeType*
InternalNode<ChildT, Log2Dim>::touchLeaf(const Coord& xyz)
{
    const Index n = this->coordToOffset(xyz);
    ChildT* child = nullptr;
    if (mChildMask.isOff(n)) {
        child = new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
        this->setChildNode(n, child);
    } else {
        child = mNodes[n].getChild();
    }
    return child->touchLeaf(xyz);
}

https://www.openvdb.org/documentation/doxygen/InternalNode_8h_source.html

Describe alternatives you've considered

I could write this as a free function, but it seems like the better for the function to return the bool that it trivially "knows". Maybe call it emplaceLeaf to match the std associative-containers:

template<typename ChildT, Index Log2Dim>
std::pair<typename ChildT::LeafNodeType*, std::uint8_t>
InternalNode<ChildT, Log2Dim>::emplaceLeaf(const Coord& xyz)
{
    const Index n = this->coordToOffset(xyz);
    ChildT* child = nullptr;
    std::uint8_t addedLevels = 0;
    if (mChildMask.isOff(n)) {
        addedLevels = 1;
        child = new ChildT(xyz, mNodes[n].getValue(), mValueMask.isOn(n));
        this->setChildNode(n, child);
    } else {
        child = mNodes[n].getChild();
    }
    auto result = child->touchLeaf(xyz);
    result.second += addedLevels;
    return result;
}

Additional context

Again, it looks like I can write this as a free function just fine, but if we are going to have a function that can easily tell us if it did work, we may as well.

My use case is I'd like to touch a bunch of leaves before doing an algorithm, then consider only the leaves I added for pruning. Knowing if I added something would let me keep a std::vector<LeafNodeT*> of those added-for-bookeeping-only leaves so I could quickly revisit them after the algorithm to see if any should be removed.

BenFrantzDale avatar Sep 09 '22 20:09 BenFrantzDale