GCC Code Coverage Report


Directory: ./
File: openvdb/openvdb/util/Util.h
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 30 30 100.0%
Functions: 5 5 100.0%
Branches: 18 36 50.0%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 #ifndef OPENVDB_UTIL_UTIL_HAS_BEEN_INCLUDED
5 #define OPENVDB_UTIL_UTIL_HAS_BEEN_INCLUDED
6
7 #include <openvdb/Types.h>
8 #include <openvdb/tree/Tree.h>
9 #include <openvdb/tools/ValueTransformer.h>
10 #include <openvdb/tools/Prune.h>// for tree::pruneInactive
11
12
13 namespace openvdb {
14 OPENVDB_USE_VERSION_NAMESPACE
15 namespace OPENVDB_VERSION_NAME {
16 namespace util {
17
18 OPENVDB_API extern const Index32 INVALID_IDX;
19
20 /// @brief coordinate offset table for neighboring voxels
21 OPENVDB_API extern const Coord COORD_OFFSETS[26];
22
23
24 ////////////////////////////////////////
25
26
27 /// Return @a voxelCoord rounded to the closest integer coordinates.
28 inline Coord
29 2 nearestCoord(const Vec3d& voxelCoord)
30 {
31 Coord ijk;
32 2 ijk[0] = int(std::floor(voxelCoord[0]));
33 2 ijk[1] = int(std::floor(voxelCoord[1]));
34 2 ijk[2] = int(std::floor(voxelCoord[2]));
35 2 return ijk;
36 }
37
38
39 ////////////////////////////////////////
40
41
42 /// @brief Functor for use with tools::foreach() to compute the boolean intersection
43 /// between the value masks of corresponding leaf nodes in two trees
44 template<class TreeType1, class TreeType2>
45 class LeafTopologyIntOp
46 {
47 public:
48 2 LeafTopologyIntOp(const TreeType2& tree): mOtherTree(&tree) {}
49
50 189 inline void operator()(const typename TreeType1::LeafIter& lIter) const
51 {
52 189 const Coord xyz = lIter->origin();
53 189 const typename TreeType2::LeafNodeType* leaf = mOtherTree->probeConstLeaf(xyz);
54
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 61 times.
189 if (leaf) {//leaf node
55 lIter->topologyIntersection(*leaf, zeroVal<typename TreeType1::ValueType>());
56
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
61 } else if (!mOtherTree->isValueOn(xyz)) {//inactive tile
57 lIter->setValuesOff();
58 }
59 189 }
60
61 private:
62 const TreeType2* mOtherTree;
63 };
64
65
66 /// @brief Functor for use with tools::foreach() to compute the boolean difference
67 /// between the value masks of corresponding leaf nodes in two trees
68 template<class TreeType1, class TreeType2>
69 class LeafTopologyDiffOp
70 {
71 public:
72 2 LeafTopologyDiffOp(const TreeType2& tree): mOtherTree(&tree) {}
73
74 189 inline void operator()(const typename TreeType1::LeafIter& lIter) const
75 {
76 189 const Coord xyz = lIter->origin();
77 189 const typename TreeType2::LeafNodeType* leaf = mOtherTree->probeConstLeaf(xyz);
78
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 61 times.
189 if (leaf) {//leaf node
79 128 lIter->topologyDifference(*leaf, zeroVal<typename TreeType1::ValueType>());
80
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 61 times.
61 } else if (mOtherTree->isValueOn(xyz)) {//active tile
81 lIter->setValuesOff();
82 }
83 189 }
84
85 private:
86 const TreeType2* mOtherTree;
87 };
88
89
90 ////////////////////////////////////////
91
92
93 /// @brief Perform a boolean intersection between two leaf nodes' topology masks.
94 /// @return a pointer to a new, boolean-valued tree containing the overlapping voxels.
95 template<class TreeType1, class TreeType2>
96 inline typename TreeType1::template ValueConverter<bool>::Type::Ptr
97 2 leafTopologyIntersection(const TreeType1& lhs, const TreeType2& rhs, bool threaded = true)
98 {
99 typedef typename TreeType1::template ValueConverter<bool>::Type BoolTreeType;
100
101
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 typename BoolTreeType::Ptr topologyTree(new BoolTreeType(
102 lhs, /*inactiveValue=*/false, /*activeValue=*/true, TopologyCopy()));
103
104
3/8
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
2 tools::foreach(topologyTree->beginLeaf(),
105 LeafTopologyIntOp<BoolTreeType, TreeType2>(rhs), threaded);
106
107
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 tools::pruneInactive(*topologyTree, threaded);
108 2 return topologyTree;
109 }
110
111
112 /// @brief Perform a boolean difference between two leaf nodes' topology masks.
113 /// @return a pointer to a new, boolean-valued tree containing the non-overlapping
114 /// voxels from the lhs.
115 template<class TreeType1, class TreeType2>
116 inline typename TreeType1::template ValueConverter<bool>::Type::Ptr
117 2 leafTopologyDifference(const TreeType1& lhs, const TreeType2& rhs, bool threaded = true)
118 {
119 typedef typename TreeType1::template ValueConverter<bool>::Type BoolTreeType;
120
121
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 typename BoolTreeType::Ptr topologyTree(new BoolTreeType(
122 lhs, /*inactiveValue=*/false, /*activeValue=*/true, TopologyCopy()));
123
124
3/8
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
2 tools::foreach(topologyTree->beginLeaf(),
125 LeafTopologyDiffOp<BoolTreeType, TreeType2>(rhs), threaded);
126
127
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 tools::pruneInactive(*topologyTree, threaded);
128 2 return topologyTree;
129 }
130
131 } // namespace util
132 } // namespace OPENVDB_VERSION_NAME
133 } // namespace openvdb
134
135 #endif // OPENVDB_UTIL_UTIL_HAS_BEEN_INCLUDED
136