MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
MayaFlux::IO::VolumeReader Class Reference

tinyvdb-backed loader for volumetric grid files. More...

#include <VolumeReader.hpp>

+ Inheritance diagram for MayaFlux::IO::VolumeReader:
+ Collaboration diagram for MayaFlux::IO::VolumeReader:

Public Member Functions

bool can_read (const std::string &filepath) const override
 Check if a file can be read by this reader.
 
void close () override
 Close the currently open file.
 
std::shared_ptr< Kakshya::SignalSourceContainercreate_container () override
 No-op.
 
std::optional< Kakshya::VolumeDataextract (const Kinesis::Lattice3D &lattice, const VolumeReadOptions &options={}) const
 Extract every selected grid onto a caller-supplied lattice.
 
std::optional< Kakshya::VolumeDataextract (const VolumeReadOptions &options={}) const
 Extract every selected grid after open() has already been called.
 
std::type_index get_container_type () const override
 Get the container type this reader creates.
 
std::type_index get_data_type () const override
 Get the data type this reader produces.
 
std::vector< uint64_t > get_dimension_sizes () const override
 Get size of each dimension in the file data.
 
std::string get_last_error () const override
 Get the last error message.
 
std::optional< FileMetadataget_metadata () const override
 Get metadata from the open file.
 
size_t get_num_dimensions () const override
 Get the dimensionality of the file data.
 
uint64_t get_preferred_chunk_size () const override
 Get the preferred chunk size for streaming.
 
std::vector< uint64_t > get_read_position () const override
 Get current read position in primary dimension.
 
std::vector< FileRegionget_regions () const override
 Get semantic regions from the file.
 
std::vector< std::string > get_supported_extensions () const override
 Get supported file extensions for this reader.
 
bool is_open () const override
 Check if a file is currently open.
 
std::optional< Kakshya::VolumeDataload (const std::string &filepath, const Kinesis::Lattice3D &lattice, const VolumeReadOptions &options={})
 Load every selected grid onto a caller-supplied lattice.
 
std::optional< Kakshya::VolumeDataload (const std::string &filepath, const VolumeReadOptions &options={})
 Load every selected grid from a file in one call.
 
bool load_into_container (std::shared_ptr< Kakshya::SignalSourceContainer > container) override
 No-op.
 
bool open (const std::string &filepath, FileReadOptions options=FileReadOptions::ALL) override
 Open a file for reading.
 
std::vector< Kakshya::DataVariantread_all () override
 Read all data from the file into memory.
 
std::vector< Kakshya::DataVariantread_region (const FileRegion &) override
 Read a specific region of data.
 
bool seek (const std::vector< uint64_t > &) override
 Seek to a specific position in the file.
 
bool supports_streaming () const override
 Check if streaming is supported for the current file.
 
 VolumeReader ()
 
 ~VolumeReader () override
 
- Public Member Functions inherited from MayaFlux::IO::FileReader
virtual ~FileReader ()=default
 

Private Member Functions

std::optional< Kakshya::VolumeDatamaterialize (const std::vector< size_t > &indices, const glm::ivec3 &region_min, const Kinesis::Lattice3D &lattice) const
 Build VolumeData from selected grids over an explicit region.
 
void set_error (std::string msg) const
 

Private Attributes

std::unique_ptr< Detail::VDBArchivem_archive
 
std::string m_filepath
 
bool m_is_open { false }
 
std::string m_last_error
 

Additional Inherited Members

- Static Public Member Functions inherited from MayaFlux::IO::FileReader
static std::string resolve_path (const std::string &filepath)
 Resolve a filepath against the project source root if not found as-is.
 
- Static Protected Member Functions inherited from MayaFlux::IO::FileReader
static std::unordered_map< std::string, Kakshya::RegionGroupregions_to_groups (const std::vector< FileRegion > &regions)
 Convert file regions to region groups.
 

Detailed Description

tinyvdb-backed loader for volumetric grid files.

Parallels ModelReader: a FileReader subclass whose primary API is open()+extract() or the one-shot load(), producing Kakshya::VolumeData — one lattice and every selected grid as a named VolumeField over it. create_container() and load_into_container() are no-ops, as for ModelReader; volume data does not go through the SignalSourceContainer streaming path.

Supported formats: .vdb, via Detail::VDBArchive's read path.

Lattice reconstruction

A .vdb carries a transform and, per grid, an active-voxel bounding box — not a resolution and world bounds the way Lattice3D wants. VolumeData needs one lattice shared by every field, so this reader offers two ways to get one:

  • extract()/load() with no lattice: the output lattice is the union of every selected grid's active bbox, in voxel-index space, with voxel size and translation taken from the first selected grid's transform. This is what a DCC user expects — the file's own content decides the size — and is exact when every grid in the file shares one transform, which every file MayaFlux writes does and most single-purpose exports from another DCC do too.
  • extract()/load() with a caller-supplied Lattice3D: region_min is derived from the lattice's world bounds through the first selected grid's transform, snapped to the nearest voxel index — no interpolation. This is the only path that round-trips exactly: pass the same Lattice3D a VDBWriter call was given and the cell values come back unpermuted and unresampled, which is what verify_volume_export's round-trip check exercises.

Both paths assume every selected grid shares the first grid's voxel size and translation. A file with per-grid transforms that actually differ is not resampled into agreement — each grid's raw voxel indices are read directly against the shared region, which misplaces that grid's content relative to the others. materialize() logs an MF_WARN naming the mismatched grid so this is a loud failure rather than a silent one, but it does not correct it — actual per-grid resampling would need to materialize the mismatched grid separately in its own index space and interpolate into the shared lattice, which is not implemented. This is a real limitation for a file assembled by hand from mismatched sources; it is not a limitation for output produced by a single simulation or DCC export, which is what this reader exists to consume.

Inactive cells

VolumeData is dense: every cell in the output lattice that is not covered by an active leaf takes the grid's own background value (root.background in exchange), narrowed the same way an active cell's value is if the grid's own type needs it — see below. This means a sparse simulation export expands to full density in host memory: six fields at 256 cubed is roughly 400 MB, before whatever the caller does with it next. A tile whose inactive fill differs from the plain background — a level set's sign-flood-filled interior/exterior tiles are the standard example — is not reconstructed; every non-leaf cell reads as the one background value regardless of which side of the surface it is on. A foreign narrow-band level set is therefore the case most likely to come back wrong; a fog volume or a carried scalar, where every non-leaf cell genuinely is the background, round-trips correctly.

Type narrowing

VolumeData's variant holds float and glm::vec3 only. A grid whose leaf value type is double, int32, int64, bool or half is narrowed to float; a vec3d or vec3i grid is narrowed to glm::vec3, via MayaFlux::try_convert per element (per component, for vectors). This is logged once per grid at MF_WARN, distinguishing a narrowing that round-tripped every element exactly from one where at least one element actually lost precision — the common case for a double or int64 grid whose range exceeds float, uncommon for a value meant to feed a float GPU field in the first place, which is the purpose this reader is built for. Accepted as the cost of a single representable type rather than widening VolumeData to carry every tinyvdb value type.

Definition at line 105 of file VolumeReader.hpp.


The documentation for this class was generated from the following files: