openvdb
openvdb copied to clipboard
[BUG] Save multiple times using the same file or std::ostream with io::Stream
Environment
Operating System: Linux Version / Commit SHA: OpenVDB 8.0 Other: compiler clang
Describe the bug
If we try to use the same std::ostream (or file) multiple times there is a segmentation fault due to bad data returned by pword
.
To Reproduce
Steps to reproduce the behavior:
- Build with OpenVDB with clang
- Build the example below
- Run the executable
Example:
#include <openvdb/io/Stream.h>
#include <openvdb/openvdb.h>
#include <openvdb/tools/LevelSetSphere.h>
#include <fstream>
#include <iostream>
int main ( int argc, char const *argv[] ) {
openvdb::initialize ();
// Create sphere
float radius = 5.0f;
openvdb::Vec3f center ( 1.0, 0.5, 0.3 );
float voxelSize = 0.3f;
std::vector<openvdb::FloatGrid::Ptr> spheres;
for ( size_t i = 0; i < 3; ++i )
spheres.push_back ( openvdb::tools::createLevelSetSphere<openvdb::FloatGrid> ( radius + 0.5 * i, center, voxelSize ) );
// Save grid to file
std::ofstream outFile ( "test.vdb", std::ios_base::binary );
for ( size_t i = 0; i < 1; ++i ) {
openvdb::GridPtrVecPtr grids ( new openvdb::GridPtrVec );
grids->push_back ( spheres[ i ] );
openvdb::io::Stream stream ( outFile );
stream.setCompression ( openvdb::io::COMPRESS_NONE );
stream.write ( *grids );
}
return 0;
}
Expected behavior
Each vector of grids is written to the same ostream.
Additional context
Adding io::clearStreamMetadataPtr(os);
at the end of void Archive::write(std::ostream& os, const GridCPtrVec& grids, bool seekable, const MetaMap& metadata) const
in Archive.cc fixed the issue for me.
Hi @lucapagani - sorry for the delayed response. I think I remember looking into this a while back and coming to the conclusion that, unfortunately, a openvdb::io::Stream
is not designed to be used this way. The write
methods on the stream/archive/file classes are designed to write an entire file, start to end, not to be able to append to an existing filestream in the way you're using it. I'm suprised this actually works after your change, I would have expected the contents of the stream to be overwritten by the last call?
We should at the very least try to turn this fault into an exception (your fix may even be more correct as it mutates the underlying static stream obj) and improve the documentation if the above is correct.
Hi @Idclip, thanks for the answer. Without any changes, it actually worked as expected sometimes on Windows, while it has always failed on Linux. It worked after that fix: the grids where correctly appended in the file, and there wasn't any problem in reading them. But I've tested few cases with a custom type, float and mask. In the end, we were able to append multiple grids in our file converting the grid to a std stream.