Skip to content

Commit df828f9

Browse files
committed
Add BoolCodec, Codec Registry and Archive integration
Signed-off-by: Dan Bailey <danbailey@ilm.com>
1 parent 9215a42 commit df828f9

10 files changed

Lines changed: 937 additions & 18 deletions

File tree

openvdb/openvdb/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ configure_file(version.h.in openvdb/version.h)
329329
set(OPENVDB_LIBRARY_SOURCE_FILES
330330
Grid.cc
331331
io/Archive.cc
332+
io/Codec.cc
332333
io/Compression.cc
333334
io/File.cc
334335
io/GridDescriptor.cc
@@ -364,6 +365,11 @@ set(OPENVDB_LIBRARY_INCLUDE_FILES
364365
TypeList.h
365366
)
366367

368+
set(OPENVDB_LIBRARY_CODECS_INCLUDE_FILES
369+
codecs/BoolCodec.h
370+
codecs/TopologyCodec.h
371+
)
372+
367373
set(OPENVDB_LIBRARY_IO_INCLUDE_FILES
368374
io/Archive.h
369375
io/Codec.h
@@ -559,6 +565,7 @@ if(USE_EXPLICIT_INSTANTIATION)
559565
# inexpensive to generate in this case.
560566
set(OPENVDB_LIBRARY_INSTANTIATION_HEADERS
561567
${OPENVDB_LIBRARY_TOOLS_INCLUDE_FILES}
568+
${OPENVDB_LIBRARY_CODECS_INCLUDE_FILES}
562569
)
563570

564571
# A new source file is generated by CMake for every header

openvdb/openvdb/codecs/BoolCodec.h

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// Copyright Contributors to the OpenVDB Project
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#ifndef OPENVDB_IO_CODECS_BOOLCODEC_HAS_BEEN_INCLUDED
5+
#define OPENVDB_IO_CODECS_BOOLCODEC_HAS_BEEN_INCLUDED
6+
7+
#include <openvdb/io/Codec.h>
8+
9+
#include <openvdb/openvdb.h>
10+
11+
#include "TopologyCodec.h"
12+
13+
namespace openvdb {
14+
OPENVDB_USE_VERSION_NAMESPACE
15+
namespace OPENVDB_VERSION_NAME {
16+
namespace codecs {
17+
namespace internal {
18+
19+
template <typename GridT>
20+
struct ReadBoolBuffersOp
21+
{
22+
using TreeT = typename GridT::TreeType;
23+
using RootT = typename TreeT::RootNodeType;
24+
using LeafT = typename TreeT::LeafNodeType;
25+
using ValueT = typename TreeT::ValueType;
26+
27+
ReadBoolBuffersOp(std::istream& _is, bool _saveFloatAsHalf,
28+
const ValueT& _background, const CoordBBox* _clipBBox)
29+
: is(_is)
30+
, saveFloatAsHalf(_saveFloatAsHalf)
31+
, background(_background)
32+
, clipBBox(_clipBBox) { }
33+
34+
void operator()(RootT& root, size_t)
35+
{
36+
// Clip root-level tiles and prune children that were clipped.
37+
if (clipBBox) {
38+
root.clip(*clipBBox);
39+
}
40+
}
41+
42+
template <typename NodeT>
43+
void operator()(NodeT& node, size_t)
44+
{
45+
// Clip internal node tiles and prune children that were clipped.
46+
if (clipBBox) {
47+
node.clip(*clipBBox, background);
48+
}
49+
}
50+
51+
void operator()(LeafT& leaf, size_t)
52+
{
53+
// Read in the value mask.
54+
leaf.getValueMask().load(is);
55+
// Read in the origin.
56+
Coord origin;
57+
is.read(reinterpret_cast<char*>(&origin), sizeof(Coord::ValueType) * 3);
58+
leaf.setOrigin(origin);
59+
60+
// Read in the mask for the voxel values.
61+
typename LeafT::Buffer::NodeMaskType nodeMask;
62+
nodeMask.load(is);
63+
typename LeafT::Buffer temp(nodeMask);
64+
leaf.swap(temp);
65+
}
66+
67+
std::istream& is;
68+
const bool saveFloatAsHalf;
69+
const ValueT& background;
70+
const CoordBBox* clipBBox = nullptr;
71+
}; // struct ReadBoolBuffersOp
72+
73+
template <typename GridT>
74+
struct WriteBoolBuffersOp
75+
{
76+
using TreeT = typename GridT::TreeType;
77+
using LeafT = typename TreeT::LeafNodeType;
78+
79+
WriteBoolBuffersOp(std::ostream& _os, bool _saveFloatAsHalf)
80+
: os(_os)
81+
, saveFloatAsHalf(_saveFloatAsHalf) { }
82+
83+
template <typename NodeT>
84+
void operator()(const NodeT&, size_t) { }
85+
86+
void operator()(const LeafT& leaf, size_t)
87+
{
88+
// Write out the value mask.
89+
leaf.getValueMask().save(os);
90+
91+
// Write out the origin.
92+
os.write(reinterpret_cast<const char*>(&leaf.origin()), sizeof(Coord::ValueType) * 3);
93+
94+
// Write out the voxel values.
95+
leaf.buffer().storage().save(os);
96+
}
97+
98+
std::ostream& os;
99+
const bool saveFloatAsHalf;
100+
}; // struct WriteBoolBuffersOp
101+
102+
} // namespace internal
103+
104+
template <typename GridT>
105+
struct OPENVDB_API BoolCodec : public TopologyCodec<GridT>
106+
{
107+
using Ptr = std::unique_ptr<BoolCodec<GridT>>;
108+
109+
~BoolCodec() noexcept = default;
110+
111+
static inline std::string name() { return GridT::gridType(); }
112+
113+
void readBuffers(std::istream& is, io::CodecData& data, const io::ReadOptions& options) final
114+
{
115+
GridT& grid = static_cast<GridT&>(*data.grid);
116+
117+
if (grid.hasMultiPassIO()) {
118+
OPENVDB_THROW(IoError, "Multi-pass IO is not supported in BoolCodec");
119+
}
120+
121+
io::checkFormatVersion(is);
122+
123+
bool saveFloatAsHalf = grid.saveFloatAsHalf();
124+
125+
auto& tree = grid.tree();
126+
tree.clearAllAccessors();
127+
128+
std::unique_ptr<CoordBBox> clipIndexBBox;
129+
if (options.clipBBox.isSorted()) {
130+
clipIndexBBox = std::make_unique<CoordBBox>(grid.constTransform().worldToIndexNodeCentered(options.clipBBox));
131+
}
132+
133+
internal::ReadBoolBuffersOp<GridT> readBuffersOp(is, saveFloatAsHalf, tree.background(), clipIndexBBox.get());
134+
tools::visitNodesDepthFirst(grid.tree(), readBuffersOp, /*idx=*/0, /*topDown=*/false);
135+
}
136+
137+
void writeBuffers(std::ostream& os, const GridBase& gridBase, const io::WriteOptions&) final
138+
{
139+
const GridT& grid = static_cast<const GridT&>(gridBase);
140+
141+
if (grid.hasMultiPassIO()) {
142+
OPENVDB_THROW(IoError, "Multi-pass IO is not supported in BoolCodec");
143+
}
144+
145+
internal::WriteBoolBuffersOp<GridT> writeBuffersOp(os, grid.saveFloatAsHalf());
146+
tools::visitNodesDepthFirst(grid.tree(), writeBuffersOp);
147+
}
148+
}; // struct BoolCodec
149+
150+
} // namespace codecs
151+
} // namespace OPENVDB_VERSION_NAME
152+
} // namespace openvdb
153+
154+
#endif // OPENVDB_IO_CODECS_BOOLCODEC_HAS_BEEN_INCLUDED

0 commit comments

Comments
 (0)