-
New Feature
-
Resolution: Unresolved
-
Medium
-
None
-
None
-
None
Starting out with a simply merge function signature such as:
template <typename GridT> void merge(std::vector<GridT>& grids);
To extend this to support stealing, there are three states of each VDB Grid that are acceptable to the merge method:
- Const
- Non-Const, Non-Unique
- Non-Const, Unique (and hence Stealable)
One such implementation could thus be:
template <typename GridT> void merge(std::vector<typename GridT::Ptr>& nonConstGrids, std::vector<typename GridT::ConstPtr>& constGrids) { for (auto& grid : nonConstGrids) { if (grid->tree().isUnique()) // steal else // deep-copy } for (const auto& grid : constGrids) { // deep-copy } }
Another possible approach is to introduce a VDB Primitive along the same kind of lines as the Houdini GEO_PrimVDB:
template <typename GridT> struct VDBPrimitive { using PtrT = typename GridT::Ptr; using ConstPtrT = typename GridT::ConstPtr; explicit VDBPrimitive(ConstPtrT& grid) : mGrid(grid) { } explicit VDBPrimitive(PtrT& grid) : mGrid(grid), mConst(false) { } ConstPtrT getConst() const { return mGrid; } PtrT get() { return mConst ? PtrT() : openvdb::ConstPtrCast<gridT>(mGrid); } private: ConstPtrT mGrid; bool mConst = true; };
The VDBPrimitive approach would have two main benefits - being able to intersperse const and non-const grids in a single container as desired and to be able to provide a simpler function signature such as:
template <typename GridT> void merge(std::vector<VDBPrimitive<GridT>>& grids);
I'm not confident that this approach is the right way to go, so I'm not so much proposing using a VDBPrimitive as I am simply floating the idea and looking for feedback.