GCC Code Coverage Report


Directory: ./
File: openvdb/openvdb/Grid.cc
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 119 158 75.3%
Functions: 23 30 76.7%
Branches: 123 296 41.6%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 #include "Grid.h"
5
6 #include <openvdb/Metadata.h>
7 #include <boost/algorithm/string/case_conv.hpp>
8 #include <boost/algorithm/string/trim.hpp>
9 #include <mutex>
10
11
12 namespace openvdb {
13 OPENVDB_USE_VERSION_NAMESPACE
14 namespace OPENVDB_VERSION_NAME {
15
16 /// @note For Houdini compatibility, boolean-valued metadata names
17 /// should begin with "is_".
18 const char
19 * const GridBase::META_GRID_CLASS = "class",
20 * const GridBase::META_GRID_CREATOR = "creator",
21 * const GridBase::META_GRID_NAME = "name",
22 * const GridBase::META_SAVE_HALF_FLOAT = "is_saved_as_half_float",
23 * const GridBase::META_IS_LOCAL_SPACE = "is_local_space",
24 * const GridBase::META_VECTOR_TYPE = "vector_type",
25 * const GridBase::META_FILE_BBOX_MIN = "file_bbox_min",
26 * const GridBase::META_FILE_BBOX_MAX = "file_bbox_max",
27 * const GridBase::META_FILE_COMPRESSION = "file_compression",
28 * const GridBase::META_FILE_MEM_BYTES = "file_mem_bytes",
29 * const GridBase::META_FILE_VOXEL_COUNT = "file_voxel_count",
30 * const GridBase::META_FILE_DELAYED_LOAD = "file_delayed_load";
31
32
33 ////////////////////////////////////////
34
35
36 namespace {
37
38 using GridFactoryMap = std::map<Name, GridBase::GridFactory>;
39 using GridFactoryMapCIter = GridFactoryMap::const_iterator;
40
41 struct LockedGridRegistry {
42 LockedGridRegistry() {}
43 std::mutex mMutex;
44 GridFactoryMap mMap;
45 };
46
47
48 // Global function for accessing the registry
49 LockedGridRegistry*
50 5450 getGridRegistry()
51 {
52
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5448 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
5450 static LockedGridRegistry registry;
53 5450 return &registry;
54 }
55
56 } // unnamed namespace
57
58
59 bool
60 606 GridBase::isRegistered(const Name& name)
61 {
62 606 LockedGridRegistry* registry = getGridRegistry();
63 606 std::lock_guard<std::mutex> lock(registry->mMutex);
64
65
1/2
✓ Branch 0 taken 606 times.
✗ Branch 1 not taken.
606 return (registry->mMap.find(name) != registry->mMap.end());
66 }
67
68
69 void
70 3910 GridBase::registerGrid(const Name& name, GridFactory factory)
71 {
72 3910 LockedGridRegistry* registry = getGridRegistry();
73 3910 std::lock_guard<std::mutex> lock(registry->mMutex);
74
75
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3909 times.
3910 if (registry->mMap.find(name) != registry->mMap.end()) {
76
2/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
5 OPENVDB_THROW(KeyError, "Grid type " << name << " is already registered");
77 }
78
79
2/4
✓ Branch 1 taken 3909 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3909 times.
✗ Branch 4 not taken.
3909 registry->mMap[name] = factory;
80 3909 }
81
82
83 void
84 2 GridBase::unregisterGrid(const Name& name)
85 {
86 2 LockedGridRegistry* registry = getGridRegistry();
87 2 std::lock_guard<std::mutex> lock(registry->mMutex);
88
89 registry->mMap.erase(name);
90 2 }
91
92
93 GridBase::Ptr
94 249 GridBase::createGrid(const Name& name)
95 {
96 249 LockedGridRegistry* registry = getGridRegistry();
97 249 std::lock_guard<std::mutex> lock(registry->mMutex);
98
99
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 249 times.
249 GridFactoryMapCIter iter = registry->mMap.find(name);
100
101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 249 times.
249 if (iter == registry->mMap.end()) {
102 OPENVDB_THROW(LookupError, "Cannot create grid of unregistered type " << name);
103 }
104
105
1/2
✓ Branch 1 taken 249 times.
✗ Branch 2 not taken.
498 return (iter->second)();
106 }
107
108
109 void
110 683 GridBase::clearRegistry()
111 {
112 683 LockedGridRegistry* registry = getGridRegistry();
113 683 std::lock_guard<std::mutex> lock(registry->mMutex);
114
115 registry->mMap.clear();
116 683 }
117
118
119 ////////////////////////////////////////
120
121
122 GridClass
123 257 GridBase::stringToGridClass(const std::string& s)
124 {
125 GridClass ret = GRID_UNKNOWN;
126 257 std::string str = s;
127
1/2
✓ Branch 2 taken 257 times.
✗ Branch 3 not taken.
257 boost::trim(str);
128
1/2
✓ Branch 2 taken 257 times.
✗ Branch 3 not taken.
257 boost::to_lower(str);
129
3/4
✓ Branch 1 taken 257 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 41 times.
✓ Branch 5 taken 216 times.
257 if (str == gridClassToString(GRID_LEVEL_SET)) {
130 ret = GRID_LEVEL_SET;
131
3/4
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 37 times.
41 } else if (str == gridClassToString(GRID_FOG_VOLUME)) {
132 ret = GRID_FOG_VOLUME;
133
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 } else if (str == gridClassToString(GRID_STAGGERED)) {
134 ret = GRID_STAGGERED;
135 }
136 257 return ret;
137 }
138
139
140 std::string
141
4/5
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 774 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
846 GridBase::gridClassToString(GridClass cls)
142 {
143 std::string ret;
144
4/5
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 774 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
846 switch (cls) {
145
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 case GRID_UNKNOWN: ret = "unknown"; break;
146
1/2
✓ Branch 1 taken 774 times.
✗ Branch 2 not taken.
774 case GRID_LEVEL_SET: ret = "level set"; break;
147
1/2
✓ Branch 1 taken 60 times.
✗ Branch 2 not taken.
60 case GRID_FOG_VOLUME: ret = "fog volume"; break;
148
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 case GRID_STAGGERED: ret = "staggered"; break;
149 }
150 846 return ret;
151 }
152
153 std::string
154 GridBase::gridClassToMenuName(GridClass cls)
155 {
156 std::string ret;
157 switch (cls) {
158 case GRID_UNKNOWN: ret = "Other"; break;
159 case GRID_LEVEL_SET: ret = "Level Set"; break;
160 case GRID_FOG_VOLUME: ret = "Fog Volume"; break;
161 case GRID_STAGGERED: ret = "Staggered Vector Field"; break;
162 }
163 return ret;
164 }
165
166
167
168 GridClass
169 594 GridBase::getGridClass() const
170 {
171 GridClass cls = GRID_UNKNOWN;
172
4/6
✓ Branch 1 taken 594 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 594 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 256 times.
✓ Branch 7 taken 338 times.
1188 if (StringMetadata::ConstPtr s = this->getMetadata<StringMetadata>(META_GRID_CLASS)) {
173
1/2
✓ Branch 1 taken 256 times.
✗ Branch 2 not taken.
256 cls = stringToGridClass(s->value());
174 }
175 594 return cls;
176 }
177
178
179 void
180 544 GridBase::setGridClass(GridClass cls)
181 {
182
2/4
✓ Branch 2 taken 544 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 544 times.
✗ Branch 6 not taken.
1632 this->insertMeta(META_GRID_CLASS, StringMetadata(gridClassToString(cls)));
183 544 }
184
185
186 void
187 GridBase::clearGridClass()
188 {
189 this->removeMeta(META_GRID_CLASS);
190 }
191
192
193 ////////////////////////////////////////
194
195
196 VecType
197 7 GridBase::stringToVecType(const std::string& s)
198 {
199 VecType ret = VEC_INVARIANT;
200 7 std::string str = s;
201
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 boost::trim(str);
202
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 boost::to_lower(str);
203
3/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 3 times.
7 if (str == vecTypeToString(VEC_COVARIANT)) {
204 ret = VEC_COVARIANT;
205
3/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1 times.
4 } else if (str == vecTypeToString(VEC_COVARIANT_NORMALIZE)) {
206 ret = VEC_COVARIANT_NORMALIZE;
207
3/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 1 times.
3 } else if (str == vecTypeToString(VEC_CONTRAVARIANT_RELATIVE)) {
208 ret = VEC_CONTRAVARIANT_RELATIVE;
209
3/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
2 } else if (str == vecTypeToString(VEC_CONTRAVARIANT_ABSOLUTE)) {
210 ret = VEC_CONTRAVARIANT_ABSOLUTE;
211 }
212 7 return ret;
213 }
214
215
216 std::string
217
5/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
55 GridBase::vecTypeToString(VecType typ)
218 {
219 std::string ret;
220
5/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
55 switch (typ) {
221
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 case VEC_INVARIANT: ret = "invariant"; break;
222
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 case VEC_COVARIANT: ret = "covariant"; break;
223
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 case VEC_COVARIANT_NORMALIZE: ret = "covariant normalize"; break;
224
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 case VEC_CONTRAVARIANT_RELATIVE: ret = "contravariant relative"; break;
225
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 case VEC_CONTRAVARIANT_ABSOLUTE: ret = "contravariant absolute"; break;
226 }
227 55 return ret;
228 }
229
230
231 std::string
232 GridBase::vecTypeExamples(VecType typ)
233 {
234 std::string ret;
235 switch (typ) {
236 case VEC_INVARIANT: ret = "Tuple/Color/UVW"; break;
237 case VEC_COVARIANT: ret = "Gradient/Normal"; break;
238 case VEC_COVARIANT_NORMALIZE: ret = "Unit Normal"; break;
239 case VEC_CONTRAVARIANT_RELATIVE: ret = "Displacement/Velocity/Acceleration"; break;
240 case VEC_CONTRAVARIANT_ABSOLUTE: ret = "Position"; break;
241 }
242 return ret;
243 }
244
245
246 std::string
247 GridBase::vecTypeDescription(VecType typ)
248 {
249 std::string ret;
250 switch (typ) {
251 case VEC_INVARIANT:
252 ret = "Does not transform";
253 break;
254 case VEC_COVARIANT:
255 ret = "Apply the inverse-transpose transform matrix but ignore translation";
256 break;
257 case VEC_COVARIANT_NORMALIZE:
258 ret = "Apply the inverse-transpose transform matrix but ignore translation"
259 " and renormalize vectors";
260 break;
261 case VEC_CONTRAVARIANT_RELATIVE:
262 ret = "Apply the forward transform matrix but ignore translation";
263 break;
264 case VEC_CONTRAVARIANT_ABSOLUTE:
265 ret = "Apply the forward transform matrix, including translation";
266 break;
267 }
268 return ret;
269 }
270
271
272 VecType
273 7 GridBase::getVectorType() const
274 {
275 VecType typ = VEC_INVARIANT;
276
3/6
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
14 if (StringMetadata::ConstPtr s = this->getMetadata<StringMetadata>(META_VECTOR_TYPE)) {
277
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 typ = stringToVecType(s->value());
278 }
279 7 return typ;
280 }
281
282
283 void
284 39 GridBase::setVectorType(VecType typ)
285 {
286
2/4
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 39 times.
✗ Branch 6 not taken.
117 this->insertMeta(META_VECTOR_TYPE, StringMetadata(vecTypeToString(typ)));
287 39 }
288
289
290 void
291 GridBase::clearVectorType()
292 {
293 this->removeMeta(META_VECTOR_TYPE);
294 }
295
296
297 ////////////////////////////////////////
298
299
300 std::string
301 51308 GridBase::getName() const
302 {
303
3/4
✓ Branch 2 taken 51028 times.
✓ Branch 3 taken 280 times.
✓ Branch 5 taken 51028 times.
✗ Branch 6 not taken.
102616 if (Metadata::ConstPtr meta = (*this)[META_GRID_NAME]) return meta->str();
304 280 return "";
305 }
306
307
308 void
309 8349 GridBase::setName(const std::string& name)
310 {
311
2/4
✓ Branch 1 taken 8349 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8349 times.
✗ Branch 5 not taken.
16698 this->removeMeta(META_GRID_NAME);
312
2/4
✓ Branch 1 taken 8349 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8349 times.
✗ Branch 5 not taken.
16698 this->insertMeta(META_GRID_NAME, StringMetadata(name));
313 8349 }
314
315
316 ////////////////////////////////////////
317
318
319 std::string
320 GridBase::getCreator() const
321 {
322 if (Metadata::ConstPtr meta = (*this)[META_GRID_CREATOR]) return meta->str();
323 return "";
324 }
325
326
327 void
328 GridBase::setCreator(const std::string& creator)
329 {
330 this->removeMeta(META_GRID_CREATOR);
331 this->insertMeta(META_GRID_CREATOR, StringMetadata(creator));
332 }
333
334
335 ////////////////////////////////////////
336
337
338 bool
339 1349 GridBase::saveFloatAsHalf() const
340 {
341
2/2
✓ Branch 2 taken 168 times.
✓ Branch 3 taken 1181 times.
2698 if (Metadata::ConstPtr meta = (*this)[META_SAVE_HALF_FLOAT]) {
342
1/2
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
168 return meta->asBool();
343 }
344 1181 return false;
345 }
346
347
348 void
349 275 GridBase::setSaveFloatAsHalf(bool saveAsHalf)
350 {
351
3/6
✓ Branch 1 taken 275 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 275 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 275 times.
✗ Branch 8 not taken.
550 this->removeMeta(META_SAVE_HALF_FLOAT);
352
2/4
✓ Branch 1 taken 275 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 275 times.
✗ Branch 5 not taken.
275 this->insertMeta(META_SAVE_HALF_FLOAT, BoolMetadata(saveAsHalf));
353 275 }
354
355
356 ////////////////////////////////////////
357
358
359 bool
360 7 GridBase::isInWorldSpace() const
361 {
362 bool local = false;
363
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 6 times.
14 if (Metadata::ConstPtr meta = (*this)[META_IS_LOCAL_SPACE]) {
364
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 local = meta->asBool();
365 }
366 7 return !local;
367 }
368
369
370 void
371 1 GridBase::setIsInWorldSpace(bool world)
372 {
373
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 this->removeMeta(META_IS_LOCAL_SPACE);
374
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 this->insertMeta(META_IS_LOCAL_SPACE, BoolMetadata(!world));
375 1 }
376
377
378 ////////////////////////////////////////
379
380
381 void
382 141 GridBase::addStatsMetadata()
383 {
384 141 const CoordBBox bbox = this->evalActiveVoxelBoundingBox();
385
2/4
✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
141 this->removeMeta(META_FILE_BBOX_MIN);
386
2/4
✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
141 this->removeMeta(META_FILE_BBOX_MAX);
387
2/4
✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
141 this->removeMeta(META_FILE_MEM_BYTES);
388
3/6
✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 141 times.
✗ Branch 8 not taken.
282 this->removeMeta(META_FILE_VOXEL_COUNT);
389
3/6
✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 141 times.
✗ Branch 8 not taken.
282 this->insertMeta(META_FILE_BBOX_MIN, Vec3IMetadata(bbox.min().asVec3i()));
390
2/4
✓ Branch 1 taken 141 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 141 times.
✗ Branch 5 not taken.
141 this->insertMeta(META_FILE_BBOX_MAX, Vec3IMetadata(bbox.max().asVec3i()));
391
2/4
✓ Branch 2 taken 141 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 141 times.
✗ Branch 6 not taken.
141 this->insertMeta(META_FILE_MEM_BYTES, Int64Metadata(this->memUsage()));
392
2/4
✓ Branch 2 taken 141 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 141 times.
✗ Branch 6 not taken.
141 this->insertMeta(META_FILE_VOXEL_COUNT, Int64Metadata(this->activeVoxelCount()));
393 141 }
394
395
396 MetaMap::Ptr
397 8 GridBase::getStatsMetadata() const
398 {
399 8 const char* const fields[] = {
400 META_FILE_BBOX_MIN,
401 META_FILE_BBOX_MAX,
402 META_FILE_MEM_BYTES,
403 META_FILE_VOXEL_COUNT,
404 nullptr
405 };
406
407 /// @todo Check that the fields are of the correct type?
408 8 MetaMap::Ptr ret(new MetaMap);
409
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 8 times.
40 for (int i = 0; fields[i] != nullptr; ++i) {
410
2/6
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
64 if (Metadata::ConstPtr m = (*this)[fields[i]]) {
411
2/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
64 ret->insertMeta(fields[i], *m);
412 }
413 }
414 8 return ret;
415 }
416
417
418 ////////////////////////////////////////
419
420
421 void
422 6 GridBase::clipGrid(const BBoxd& worldBBox)
423 {
424 const CoordBBox indexBBox =
425 6 this->constTransform().worldToIndexNodeCentered(worldBBox);
426 6 this->clip(indexBBox);
427 6 }
428
429 } // namespace OPENVDB_VERSION_NAME
430 } // namespace openvdb
431