OpenVDB
5.2.0
|
Starting in OpenVDB 0.98.0, Tree and Transform objects (and Grid objects in the context of Houdini SOPs) are passed and accessed primarily by reference rather than by shared pointer. (This is partly for performance reasons; the overhead of copying shared pointers, especially in a threaded environment, can be significant.) Furthermore, those objects now exhibit copy-on-write semantics, so that in most cases it is no longer necessary to make explicit deep copies. These changes were, for the most part, requested and implemented by Side Effects.
Accessor methods like Grid::tree, Grid::transform and GEO_PrimVDB::getGrid
that used to return shared pointers now return const references. Variants like Grid::constTree
, which returned const shared pointers, have been removed, and new read/write accessors have been added. The latter, including Grid::treeRW()
, Grid::transformRW()
and GEO_PrimVDB::getGridRW
, return non-const references, but they also ensure that ownership of the returned object is exclusive to the container (that is, they ensure that the grid has exclusive ownership of the tree or transform and that the primitive has exclusive ownership of the grid). The logic is as follows: if a grid, for example, has sole ownership of a tree, then Grid::treeRW()
returns a non-const reference to that tree; but if the tree is shared (with other grids, perhaps), then Grid::treeRW()
assigns the grid a new, deep copy of the tree and returns a non-const reference to the new tree.
Shared pointers to Tree
, Transform
and Grid
objects can still be requested from their respective containers via Grid::sharedTree()
, Grid::sharedTransform()
and GEO_PrimVDB::getSharedGrid
, but their use is now discouraged.
For Houdini SOPs, there are additional changes. First, VDB primitives are now normally processed in-place. That is, rather than extract a primitive's grid, make a deep copy of it and construct a new primitive to hold the copy, one now requests read/write access to a primitive's grid and then modifies the resulting grid. (SOPs that generate primitives or that replace grids of one type with another type can still do so using the old approach, however.)
Second, grid metadata such as a grid's class (level set, fog volume, etc.), value type (float
, vec3s
, etc.), background value and so on (the full list is hardcoded into GEO_PrimVDB
) is now exposed via "intrinsic" attributes of grid primitives, rather than via primitive attributes as before. As a result, this information no longer appears in a SOP's geometry spreadsheet, nor does any extra metadata that a SOP might add to a grid during processing. The metadata is still preserved in the Grid
objects, though.
Third, openvdb_houdini::processTypedGrid
, which passes a shared grid pointer to a functor that also takes a shared pointer, is now deprecated in favor of openvdb_houdini::UTvdbProcessTypedGrid
, which accepts shared pointers, raw pointers or references to grids (provided that the functor accepts an argument of the same kind). Below is a comparison of the old and new usage in the typical case of a SOP that processes input grids:
Old API (0.97.0 and earlier)
New API (0.98.0 and later)
Notes
In the old API, Grid::tree returned either a shared, non-const pointer to a tree or a shared const pointer, depending on whether the grid itself was non-const or const. In the new API, Grid::tree always returns a const reference, and Grid::treeRW()
always returns a non-const reference.
openvdb_houdini::processTypedGrid
(old API) accepts only shared pointers to grids (or shared pointers to const grids), together with functors that accept shared pointers to grids. openvdb_houdini::UTvdbProcessTypedGrid
(new API) accepts const and non-const references, shared pointers and raw pointers, together with matching functors. That is, all of the following are valid pairs of grid and functor arguments to UTvdbProcessTypedGrid()
:
In the old API, input grid primitives were (usually) deleted after processing, and a new primitive was created for each output grid. openvdb_houdini::replaceVdbPrimitive()
did both operations in one step and had the side effect of transferring the output grid's metadata to primitive attributes. In the new API, replaceVdbPrimitive()
is rarely needed, because input grids can usually be processed in-place, and most commonly-used metadata is exposed via intrinsic attributes, which don't need to be manually updated.
openvdb_houdini::UTvdbProcessTypedGrid()
is the grid's storage type, which can be retrieved either by passing the grid to openvdb_houdini::UTvdbGetGridType()
or by calling GEO_PrimVDB::getStorageType()
on the primitive.