| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright Contributors to the OpenVDB Project | ||
| 2 | // SPDX-License-Identifier: MPL-2.0 | ||
| 3 | |||
| 4 | #include "GridDescriptor.h" | ||
| 5 | |||
| 6 | #include <openvdb/Exceptions.h> | ||
| 7 | #include <boost/algorithm/string/predicate.hpp> // for boost::ends_with() | ||
| 8 | #include <boost/algorithm/string/erase.hpp> // for boost::erase_last() | ||
| 9 | #include <sstream> | ||
| 10 | |||
| 11 | |||
| 12 | namespace openvdb { | ||
| 13 | OPENVDB_USE_VERSION_NAMESPACE | ||
| 14 | namespace OPENVDB_VERSION_NAME { | ||
| 15 | namespace io { | ||
| 16 | |||
| 17 | namespace { | ||
| 18 | |||
| 19 | // In order not to break backward compatibility with existing VDB files, | ||
| 20 | // grids stored using 16-bit half floats are flagged by adding the following | ||
| 21 | // suffix to the grid's type name on output. The suffix is removed on input | ||
| 22 | // and the grid's "save float as half" flag set accordingly. | ||
| 23 | const char* HALF_FLOAT_TYPENAME_SUFFIX = "_HalfFloat"; | ||
| 24 | |||
| 25 | const char* SEP = "\x1e"; // ASCII "record separator" | ||
| 26 | |||
| 27 | } | ||
| 28 | |||
| 29 | |||
| 30 | 265 | GridDescriptor::GridDescriptor(): | |
| 31 | mSaveFloatAsHalf(false), | ||
| 32 | mGridPos(0), | ||
| 33 | mBlockPos(0), | ||
| 34 | 265 | mEndPos(0) | |
| 35 | { | ||
| 36 | 265 | } | |
| 37 | |||
| 38 | 168 | GridDescriptor::GridDescriptor(const Name &name, const Name &type, bool half): | |
| 39 | mGridName(stripSuffix(name)), | ||
| 40 | mUniqueName(name), | ||
| 41 | mGridType(type), | ||
| 42 | mSaveFloatAsHalf(half), | ||
| 43 | mGridPos(0), | ||
| 44 | mBlockPos(0), | ||
| 45 |
2/4✓ Branch 2 taken 168 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 168 times.
✗ Branch 6 not taken.
|
168 | mEndPos(0) |
| 46 | { | ||
| 47 | 168 | } | |
| 48 | |||
| 49 | 664 | GridDescriptor::~GridDescriptor() | |
| 50 | { | ||
| 51 | 664 | } | |
| 52 | |||
| 53 | void | ||
| 54 | 164 | GridDescriptor::writeHeader(std::ostream &os) const | |
| 55 | { | ||
| 56 | 164 | writeString(os, mUniqueName); | |
| 57 | |||
| 58 | 164 | Name gridType = mGridType; | |
| 59 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 163 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
164 | if (mSaveFloatAsHalf) gridType += HALF_FLOAT_TYPENAME_SUFFIX; |
| 60 |
1/2✓ Branch 1 taken 164 times.
✗ Branch 2 not taken.
|
164 | writeString(os, gridType); |
| 61 | |||
| 62 |
1/2✓ Branch 1 taken 164 times.
✗ Branch 2 not taken.
|
164 | writeString(os, mInstanceParentName); |
| 63 | 164 | } | |
| 64 | |||
| 65 | void | ||
| 66 | 312 | GridDescriptor::writeStreamPos(std::ostream &os) const | |
| 67 | { | ||
| 68 | 312 | os.write(reinterpret_cast<const char*>(&mGridPos), sizeof(int64_t)); | |
| 69 | 312 | os.write(reinterpret_cast<const char*>(&mBlockPos), sizeof(int64_t)); | |
| 70 | 312 | os.write(reinterpret_cast<const char*>(&mEndPos), sizeof(int64_t)); | |
| 71 | 312 | } | |
| 72 | |||
| 73 | GridBase::Ptr | ||
| 74 | 127 | GridDescriptor::read(std::istream &is) | |
| 75 | { | ||
| 76 | // Read in the name. | ||
| 77 | 127 | mUniqueName = readString(is); | |
| 78 | 127 | mGridName = stripSuffix(mUniqueName); | |
| 79 | |||
| 80 | // Read in the grid type. | ||
| 81 | 254 | mGridType = readString(is); | |
| 82 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 126 times.
|
127 | if (boost::ends_with(mGridType, HALF_FLOAT_TYPENAME_SUFFIX)) { |
| 83 | 1 | mSaveFloatAsHalf = true; | |
| 84 | 1 | boost::erase_last(mGridType, HALF_FLOAT_TYPENAME_SUFFIX); | |
| 85 | } | ||
| 86 | |||
| 87 |
1/2✓ Branch 1 taken 127 times.
✗ Branch 2 not taken.
|
127 | if (getFormatVersion(is) >= OPENVDB_FILE_VERSION_GRID_INSTANCING) { |
| 88 | 254 | mInstanceParentName = readString(is); | |
| 89 | } | ||
| 90 | |||
| 91 | // Create the grid of the type if it has been registered. | ||
| 92 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 125 times.
|
127 | if (!GridBase::isRegistered(mGridType)) { |
| 93 |
2/6✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
10 | OPENVDB_THROW(LookupError, "Cannot read grid." << |
| 94 | " Grid type " << mGridType << " is not registered."); | ||
| 95 | } | ||
| 96 | // else | ||
| 97 | 125 | GridBase::Ptr grid = GridBase::createGrid(mGridType); | |
| 98 |
2/4✓ Branch 0 taken 125 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 125 times.
✗ Branch 4 not taken.
|
125 | if (grid) grid->setSaveFloatAsHalf(mSaveFloatAsHalf); |
| 99 | |||
| 100 | // Read in the offsets. | ||
| 101 |
1/2✓ Branch 1 taken 125 times.
✗ Branch 2 not taken.
|
125 | is.read(reinterpret_cast<char*>(&mGridPos), sizeof(int64_t)); |
| 102 |
1/2✓ Branch 1 taken 125 times.
✗ Branch 2 not taken.
|
125 | is.read(reinterpret_cast<char*>(&mBlockPos), sizeof(int64_t)); |
| 103 |
1/2✓ Branch 1 taken 125 times.
✗ Branch 2 not taken.
|
125 | is.read(reinterpret_cast<char*>(&mEndPos), sizeof(int64_t)); |
| 104 | |||
| 105 | 125 | return grid; | |
| 106 | } | ||
| 107 | |||
| 108 | void | ||
| 109 | 122 | GridDescriptor::seekToGrid(std::istream &is) const | |
| 110 | { | ||
| 111 | 122 | is.seekg(mGridPos, std::ios_base::beg); | |
| 112 | 122 | } | |
| 113 | |||
| 114 | void | ||
| 115 | 3 | GridDescriptor::seekToBlocks(std::istream &is) const | |
| 116 | { | ||
| 117 | 3 | is.seekg(mBlockPos, std::ios_base::beg); | |
| 118 | 3 | } | |
| 119 | |||
| 120 | void | ||
| 121 | 103 | GridDescriptor::seekToEnd(std::istream &is) const | |
| 122 | { | ||
| 123 | 103 | is.seekg(mEndPos, std::ios_base::beg); | |
| 124 | 103 | } | |
| 125 | |||
| 126 | |||
| 127 | void | ||
| 128 | ✗ | GridDescriptor::seekToGrid(std::ostream &os) const | |
| 129 | { | ||
| 130 | ✗ | os.seekp(mGridPos, std::ios_base::beg); | |
| 131 | } | ||
| 132 | |||
| 133 | void | ||
| 134 | ✗ | GridDescriptor::seekToBlocks(std::ostream &os) const | |
| 135 | { | ||
| 136 | ✗ | os.seekp(mBlockPos, std::ios_base::beg); | |
| 137 | } | ||
| 138 | |||
| 139 | void | ||
| 140 | 148 | GridDescriptor::seekToEnd(std::ostream &os) const | |
| 141 | { | ||
| 142 | 148 | os.seekp(mEndPos, std::ios_base::beg); | |
| 143 | 148 | } | |
| 144 | |||
| 145 | |||
| 146 | //////////////////////////////////////// | ||
| 147 | |||
| 148 | |||
| 149 | // static | ||
| 150 | Name | ||
| 151 | 198 | GridDescriptor::addSuffix(const Name& name, int n) | |
| 152 | { | ||
| 153 | 396 | std::ostringstream ostr; | |
| 154 |
2/4✓ Branch 1 taken 198 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 198 times.
✗ Branch 5 not taken.
|
198 | ostr << name << SEP << n; |
| 155 | 198 | return ostr.str(); | |
| 156 | } | ||
| 157 | |||
| 158 | |||
| 159 | // static | ||
| 160 | Name | ||
| 161 | 329 | GridDescriptor::stripSuffix(const Name& name) | |
| 162 | { | ||
| 163 | 329 | return name.substr(0, name.find(SEP)); | |
| 164 | } | ||
| 165 | |||
| 166 | |||
| 167 | // static | ||
| 168 | std::string | ||
| 169 | 41 | GridDescriptor::nameAsString(const Name& name) | |
| 170 | { | ||
| 171 | 41 | std::string::size_type pos = name.find(SEP); | |
| 172 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 28 times.
|
41 | if (pos == std::string::npos) return name; |
| 173 | |||
| 174 |
4/8✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 28 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 28 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 28 times.
✗ Branch 12 not taken.
|
56 | return name.substr(0, pos) + "[" + name.substr(pos + 1) + "]"; |
| 175 | } | ||
| 176 | |||
| 177 | |||
| 178 | //static | ||
| 179 | Name | ||
| 180 | 82 | GridDescriptor::stringAsUniqueName(const std::string& s) | |
| 181 | { | ||
| 182 | 82 | Name ret = s; | |
| 183 |
4/6✓ Branch 0 taken 82 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 82 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 30 times.
✓ Branch 6 taken 52 times.
|
82 | if (!ret.empty() && *ret.rbegin() == ']') { // found trailing ']' |
| 184 | std::string::size_type pos = ret.find("["); | ||
| 185 | // Replace "[N]" with SEP "N". | ||
| 186 |
1/2✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
|
30 | if (pos != std::string::npos) { |
| 187 |
1/2✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
|
30 | ret.resize(ret.size() - 1); // drop trailing ']' |
| 188 |
1/2✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
|
30 | ret.replace(ret.find("["), 1, SEP); |
| 189 | } | ||
| 190 | } | ||
| 191 | 82 | return ret; | |
| 192 | } | ||
| 193 | |||
| 194 | } // namespace io | ||
| 195 | } // namespace OPENVDB_VERSION_NAME | ||
| 196 | } // namespace openvdb | ||
| 197 |