OpenVDB 13.2.0
Loading...
Searching...
No Matches
Codec Struct Referenceabstract

Abstract base class for grid I/O codecs. More...

#include <openvdb/io/Codec.h>

Public Types

using Ptr = std::unique_ptr<Codec>

Public Member Functions

virtual ~Codec ()=default
virtual CodecData::Ptr createData ()=0
 Allocate per-operation codec state, including the target grid.
virtual void beginRead (CodecData &, const ReadOptions &, ReadDiagnostics &) const
 Begin a read. Called by the I/O layer once before the first phase of every read of a grid, for every read mode, after the metadata and the transform are read. It is not called for instances, which have no phases.
virtual void readTopology (std::istream &, CodecData &, const ReadOptions &, ReadDiagnostics &) const
 Deserialize the grid topology (tree structure and active-voxel mask) from is into the grid held by data.
virtual void readBuffers (std::istream &, int64_t, CodecData &, const ReadOptions &, ReadDiagnostics &) const
 Deserialize all voxel-value buffers from is into the grid held by data.
virtual void finishRead (CodecData &, const ReadOptions &, ReadDiagnostics &) const
 Finish a read. Called by the I/O layer after the last phase of every read of a grid, for every read mode and whether or not readTopology() and readBuffers() were called, so work that a codec started in an earlier phase has one place to be joined. It is not called for instances, which have no phases.
virtual void writeTopology (std::ostream &, const GridBase &, const WriteOptions &) const
 Serialize the grid topology (tree structure and active-voxel mask) from grid to os.
virtual void writeBuffers (std::ostream &, const GridBase &, const WriteOptions &) const
 Serialize all voxel-value buffers from grid to os.

Detailed Description

Abstract base class for grid I/O codecs.

A codec encapsulates the serialization and deserialization logic for a specific grid type (or family of grid types). The I/O subsystem selects a codec by name at runtime, calls createData() to allocate per-operation state, and then dispatches to the appropriate read or write methods.

Codecs must be stateless: all mutable per-operation state is stored in a CodecData object (see above) that is created fresh for each grid read or write. This ensures that a single registered codec instance can safely handle concurrent I/O operations.

Implementing a new codec
  1. Declare the codec struct, deriving publicly from Codec (or from a convenience intermediate that already handles topology, if one exists for the grid family in question):
    struct MyCodec : public io::Codec { ... };
    Abstract base class for grid I/O codecs.
    Definition Codec.h:395
  2. **Provide a static name() method** that returns the unique string identifier under which the codec will be registered. Any globally unique ASCII string is acceptable:
    static std::string name() { return "mycodec"; }
  3. **Override createData()** (the only pure-virtual method). Allocate a CodecData (or a derived subclass if extra per-operation state is needed), create the appropriate GridBase subclass, assign it to CodecData::grid, and return the object:
    auto data = std::make_unique<io::CodecData>();
    data->grid = MyGridType::create();
    return data;
    }
    std::unique_ptr< CodecData > Ptr
    Definition Codec.h:301
    virtual CodecData::Ptr createData()=0
    Allocate per-operation codec state, including the target grid.
  4. Override the read and/or write methods as required. All four methods have default no-op implementations, so override only those that the codec actually uses. The I/O layer separates topology (the tree structure and active/inactive voxel mask) from value buffers (the actual voxel data), allowing callers to request topology-only reads via ReadOptions::readMode. Implementations should honour that setting:

    void readTopology(std::istream& is, io::CodecData& data,
    const io::ReadOptions& options,
    io::ReadDiagnostics& diagnostics) const override
    {
    MyGridType& grid = static_cast<MyGridType&>(*data.grid);
    // Deserialize the tree structure into grid...
    }
    void readBuffers(std::istream& is, int64_t size, CodecData& data,
    const io::ReadOptions& options,
    io::ReadDiagnostics& diagnostics) const override
    {
    if (options.readMode == io::ReadMode::TopologyOnly) return;
    MyGridType& grid = static_cast<MyGridType&>(*data.grid);
    // Deserialize voxel values into grid...
    }
    @ TopologyOnly
    Definition Codec.h:92
    Mutable per-operation state created by Codec::createData() and passed into every read and write call ...
    Definition Codec.h:300
    SharedPtr< GridBase > grid
    The grid being populated on read, or being serialized on write.
    Definition Codec.h:306
    virtual void readBuffers(std::istream &, int64_t, CodecData &, const ReadOptions &, ReadDiagnostics &) const
    Deserialize all voxel-value buffers from is into the grid held by data.
    Definition Codec.h:443
    virtual void readTopology(std::istream &, CodecData &, const ReadOptions &, ReadDiagnostics &) const
    Deserialize the grid topology (tree structure and active-voxel mask) from is into the grid held by da...
    Definition Codec.h:426
    Thread-safe collection of read diagnostics accumulated during a codec read.
    Definition Codec.h:211
    Global read configuration passed to every codec during deserialization.
    Definition Codec.h:167
    ReadMode readMode
    Definition Codec.h:174

    If a requested option (e.g. spatial clipping) cannot be honoured natively, record a warning via diagnostics.addWarning() rather than silently ignoring it.

    A grid is read in four phases: beginRead() => readTopology() => readBuffers() => finishRead().

    For non-instance grid reading, only beginRead and finishRead are guaranteed to run. A topology-only read will skip the readBuffers() phase for example. Compute tasks may continue asynchronously across phases, the codec owns that work and is responsible for starting and ending it.

  5. Register the codec once at start-up, typically from the library's initialize() function, using CodecRegistry::registerCodec<MyCodec>():
Note
The codec struct itself is never copied; the registry takes ownership of a single heap-allocated instance via Codec::Ptr (std::unique_ptr<Codec>).

Member Typedef Documentation

◆ Ptr

using Ptr = std::unique_ptr<Codec>

Constructor & Destructor Documentation

◆ ~Codec()

virtual ~Codec ( )
virtualdefault

Member Function Documentation

◆ beginRead()

virtual void beginRead ( CodecData & ,
const ReadOptions & ,
ReadDiagnostics &  ) const
inlinevirtual

Begin a read. Called by the I/O layer once before the first phase of every read of a grid, for every read mode, after the metadata and the transform are read. It is not called for instances, which have no phases.

This is the place to start work that later phases use, for example a thread pool, or to choose a strategy from the read options, the metadata and the transform. Until finishRead() returns the caller does not touch the tree of the grid. If this throws, no other phase is called, including finishRead(), so the destructor of the CodecData must release anything started here. The default implementation does nothing.

◆ createData()

virtual CodecData::Ptr createData ( )
pure virtual

Allocate per-operation codec state, including the target grid.

This is the only pure-virtual method. Implementations must create a concrete GridBase subclass appropriate for the codec, store it in CodecData::grid, and return the CodecData (or a derived subclass carrying additional state). The returned object is passed by reference to every subsequent read or write call for the same grid.

Returns
A fully initialized CodecData whose grid field is non-null.

◆ finishRead()

virtual void finishRead ( CodecData & ,
const ReadOptions & ,
ReadDiagnostics &  ) const
inlinevirtual

Finish a read. Called by the I/O layer after the last phase of every read of a grid, for every read mode and whether or not readTopology() and readBuffers() were called, so work that a codec started in an earlier phase has one place to be joined. It is not called for instances, which have no phases.

Until this returns the caller does not touch the tree of the grid. It may read and change the metadata and the transform. An error from work started in an earlier phase is thrown from here, on the calling thread. The default implementation does nothing.

◆ readBuffers()

virtual void readBuffers ( std::istream & ,
int64_t ,
CodecData & ,
const ReadOptions & ,
ReadDiagnostics &  ) const
inlinevirtual

Deserialize all voxel-value buffers from is into the grid held by data.

The default implementation is a no-op. Override to populate leaf-node value buffers after topology has been established. When options.readMode is ReadMode::TopologyOnly this method will not be called by the I/O layer, so implementations may also guard against that mode internally for safety. If options.clipBBox is non-empty, restrict the loaded data to the region that intersects it; if the codec cannot honour clipping natively, fall back to a post-process and record a warning via diagnostics. The size argument is the number of bytes occupied by the readBuffers data section, measured from the stream position at which this method is called, or -1 when the size is not known (a non-seekable stream, or a stream without grid offsets).

◆ readTopology()

virtual void readTopology ( std::istream & ,
CodecData & ,
const ReadOptions & ,
ReadDiagnostics &  ) const
inlinevirtual

Deserialize the grid topology (tree structure and active-voxel mask) from is into the grid held by data.

◆ writeBuffers()

virtual void writeBuffers ( std::ostream & ,
const GridBase & ,
const WriteOptions &  ) const
inlinevirtual

Serialize all voxel-value buffers from grid to os.

The default implementation is a no-op. Override to write the leaf-node value buffers that follow the topology section.

◆ writeTopology()

virtual void writeTopology ( std::ostream & ,
const GridBase & ,
const WriteOptions &  ) const
inlinevirtual

Serialize the grid topology (tree structure and active-voxel mask) from grid to os.

The default implementation is a no-op. Override when the codec stores topology as a distinct section that precedes the value buffers in the stream.