GCC Code Coverage Report


Directory: ./
File: openvdb/openvdb/tree/RootNode.h
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 756 927 81.6%
Functions: 1948 3950 49.3%
Branches: 2346 5921 39.6%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 ///
4 /// @file RootNode.h
5 ///
6 /// @brief The root node of an OpenVDB tree
7
8 #ifndef OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED
9 #define OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED
10
11 #include <openvdb/Exceptions.h>
12 #include <openvdb/Types.h>
13 #include <openvdb/io/Compression.h> // for truncateRealToHalf()
14 #include <openvdb/math/Math.h> // for isZero(), isExactlyEqual(), etc.
15 #include <openvdb/math/BBox.h>
16 #include <openvdb/util/NodeMasks.h> // for backward compatibility only (see readTopology())
17 #include <openvdb/version.h>
18 #include <tbb/parallel_for.h>
19 #include <map>
20 #include <set>
21 #include <sstream>
22 #include <vector>
23
24
25 namespace openvdb {
26 OPENVDB_USE_VERSION_NAMESPACE
27 namespace OPENVDB_VERSION_NAME {
28 namespace tree {
29
30 // Forward declarations
31 template<typename HeadType, int HeadLevel> struct NodeChain;
32 template<typename, typename> struct SameRootConfig;
33 template<typename, typename, bool> struct RootNodeCopyHelper;
34 template<typename, typename, typename, bool> struct RootNodeCombineHelper;
35
36
37 template<typename ChildType>
38 class RootNode
39 {
40 public:
41 using ChildNodeType = ChildType;
42 using LeafNodeType = typename ChildType::LeafNodeType;
43 using ValueType = typename ChildType::ValueType;
44 using BuildType = typename ChildType::BuildType;
45
46 static const Index LEVEL = 1 + ChildType::LEVEL; // level 0 = leaf
47
48 /// NodeChainType is a list of this tree's node types, from LeafNodeType to RootNode.
49 using NodeChainType = typename NodeChain<RootNode, LEVEL>::Type;
50 static_assert(NodeChainType::Size == LEVEL + 1,
51 "wrong number of entries in RootNode node chain");
52
53 /// @brief ValueConverter<T>::Type is the type of a RootNode having the same
54 /// child hierarchy as this node but a different value type, T.
55 template<typename OtherValueType>
56 struct ValueConverter {
57 using Type = RootNode<typename ChildType::template ValueConverter<OtherValueType>::Type>;
58 };
59
60 /// @brief SameConfiguration<OtherNodeType>::value is @c true if and only if
61 /// OtherNodeType is the type of a RootNode whose ChildNodeType has the same
62 /// configuration as this node's ChildNodeType.
63 template<typename OtherNodeType>
64 struct SameConfiguration {
65 static const bool value = SameRootConfig<ChildNodeType, OtherNodeType>::value;
66 };
67
68
69 /// Construct a new tree with a background value of 0.
70 RootNode();
71
72 /// Construct a new tree with the given background value.
73 explicit RootNode(const ValueType& background);
74
75
1/2
✓ Branch 1 taken 2281 times.
✗ Branch 2 not taken.
4562 RootNode(const RootNode& other) { *this = other; }
76
77 /// @brief Construct a new tree that reproduces the topology and active states
78 /// of a tree of a different ValueType but the same configuration (levels,
79 /// node dimensions and branching factors). Cast the other tree's values to
80 /// this tree's ValueType.
81 /// @throw TypeError if the other tree's configuration doesn't match this tree's
82 /// or if this tree's ValueType is not constructible from the other tree's ValueType.
83 template<typename OtherChildType>
84
1/2
✓ Branch 1 taken 742 times.
✗ Branch 2 not taken.
752 explicit RootNode(const RootNode<OtherChildType>& other) { *this = other; }
85
86 /// @brief Construct a new tree that reproduces the topology and active states of
87 /// another tree (which may have a different ValueType), but not the other tree's values.
88 /// @details All tiles and voxels that are active in the other tree are set to
89 /// @a foreground in the new tree, and all inactive tiles and voxels are set to @a background.
90 /// @param other the root node of a tree having (possibly) a different ValueType
91 /// @param background the value to which inactive tiles and voxels are initialized
92 /// @param foreground the value to which active tiles and voxels are initialized
93 /// @throw TypeError if the other tree's configuration doesn't match this tree's.
94 template<typename OtherChildType>
95 RootNode(const RootNode<OtherChildType>& other,
96 const ValueType& background, const ValueType& foreground, TopologyCopy);
97
98 /// @brief Construct a new tree that reproduces the topology and active states of
99 /// another tree (which may have a different ValueType), but not the other tree's values.
100 /// All tiles and voxels in the new tree are set to @a background regardless of
101 /// their active states in the other tree.
102 /// @param other the root node of a tree having (possibly) a different ValueType
103 /// @param background the value to which inactive tiles and voxels are initialized
104 /// @note This copy constructor is generally faster than the one that takes both
105 /// a foreground and a background value. Its main application is in multithreaded
106 /// operations where the topology of the output tree exactly matches the input tree.
107 /// @throw TypeError if the other tree's configuration doesn't match this tree's.
108 template<typename OtherChildType>
109 RootNode(const RootNode<OtherChildType>& other, const ValueType& background, TopologyCopy);
110
111 /// @brief Copy a root node of the same type as this node.
112 RootNode& operator=(const RootNode& other);
113 /// @brief Copy a root node of the same tree configuration as this node
114 /// but a different ValueType.
115 /// @throw TypeError if the other tree's configuration doesn't match this tree's.
116 /// @note This node's ValueType must be constructible from the other node's ValueType.
117 /// For example, a root node with values of type float can be assigned to a root node
118 /// with values of type Vec3s, because a Vec3s can be constructed from a float.
119 /// But a Vec3s root node cannot be assigned to a float root node.
120 template<typename OtherChildType>
121 RootNode& operator=(const RootNode<OtherChildType>& other);
122
123 52470 ~RootNode() { this->clear(); }
124
125 private:
126
1/11
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
148 struct Tile {
127
1/11
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 183 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
180647 Tile(): value(zeroVal<ValueType>()), active(false) {}
128
0/25
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
5582 Tile(const ValueType& v, bool b): value(v), active(b) {}
129 ValueType value;
130 bool active;
131 };
132
133 // This lightweight struct pairs child pointers and tiles.
134
4/20
✓ Branch 1 taken 90 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 22 taken 183 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
286 struct NodeStruct {
135 ChildType* child;
136 Tile tile;
137
138
3/11
✓ Branch 1 taken 102 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 182 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
95093 NodeStruct(): child(nullptr) {}
139
28/137
✓ Branch 1 taken 106 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 565 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 50 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 16 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 34 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 8 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 38 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 16 times.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 16 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 73 times.
✓ Branch 37 taken 16 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 21 times.
✓ Branch 40 taken 16 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✓ Branch 45 taken 20 times.
✓ Branch 46 taken 24 times.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✓ Branch 49 taken 25 times.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✓ Branch 54 taken 3 times.
✓ Branch 55 taken 24 times.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✓ Branch 58 taken 82 times.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✓ Branch 99 taken 114 times.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✓ Branch 105 taken 112 times.
✗ Branch 106 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✓ Branch 111 taken 114 times.
✗ Branch 112 not taken.
✗ Branch 114 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✓ Branch 117 taken 130 times.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✓ Branch 123 taken 188 times.
✗ Branch 124 not taken.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✓ Branch 129 taken 160 times.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
✓ Branch 135 taken 98 times.
✗ Branch 136 not taken.
✗ Branch 138 not taken.
✗ Branch 139 not taken.
✓ Branch 141 taken 98 times.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
✗ Branch 144 not taken.
✗ Branch 145 not taken.
✗ Branch 146 not taken.
✓ Branch 147 taken 98 times.
✗ Branch 148 not taken.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 155 not taken.
✗ Branch 156 not taken.
80683 NodeStruct(ChildType& c): child(&c) {}
140
1/26
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
205 NodeStruct(const Tile& t): child(nullptr), tile(t) {}
141
1/7
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 45 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
45 NodeStruct(const NodeStruct&) = default;
142 NodeStruct& operator=(const NodeStruct&) = default;
143 2484 ~NodeStruct() {} ///< @note doesn't delete child
144
145
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
70369573 bool isChild() const { return child != nullptr; }
146
0/28
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
88893019 bool isTile() const { return child == nullptr; }
147
150/320
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 55 times.
✓ Branch 10 taken 13 times.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 65 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 4 times.
✓ Branch 17 taken 412 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 58 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 3 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 625 times.
✓ Branch 26 taken 37 times.
✓ Branch 27 taken 327 times.
✓ Branch 28 taken 28 times.
✓ Branch 29 taken 278 times.
✓ Branch 30 taken 23 times.
✓ Branch 31 taken 66 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 104 times.
✓ Branch 34 taken 10 times.
✓ Branch 35 taken 290 times.
✓ Branch 36 taken 4 times.
✓ Branch 37 taken 14 times.
✓ Branch 38 taken 2 times.
✓ Branch 39 taken 63 times.
✓ Branch 40 taken 17 times.
✓ Branch 41 taken 74 times.
✓ Branch 42 taken 10 times.
✓ Branch 43 taken 76 times.
✗ Branch 44 not taken.
✓ Branch 45 taken 15075212 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 8 times.
✓ Branch 48 taken 2 times.
✓ Branch 49 taken 8121 times.
✓ Branch 50 taken 4 times.
✓ Branch 51 taken 82 times.
✓ Branch 52 taken 1435 times.
✓ Branch 53 taken 2727 times.
✓ Branch 54 taken 1411 times.
✓ Branch 55 taken 74642 times.
✓ Branch 56 taken 1 times.
✓ Branch 57 taken 32 times.
✓ Branch 58 taken 3 times.
✓ Branch 59 taken 17615168 times.
✓ Branch 60 taken 3 times.
✓ Branch 61 taken 83 times.
✗ Branch 62 not taken.
✓ Branch 63 taken 1 times.
✗ Branch 64 not taken.
✓ Branch 65 taken 83 times.
✗ Branch 66 not taken.
✓ Branch 67 taken 89 times.
✗ Branch 68 not taken.
✓ Branch 69 taken 16 times.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✓ Branch 73 taken 135841 times.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✓ Branch 76 taken 210 times.
✓ Branch 77 taken 268085 times.
✓ Branch 78 taken 210 times.
✓ Branch 79 taken 305 times.
✗ Branch 80 not taken.
✓ Branch 81 taken 34 times.
✓ Branch 82 taken 4 times.
✓ Branch 83 taken 39 times.
✓ Branch 84 taken 4 times.
✓ Branch 85 taken 423 times.
✗ Branch 86 not taken.
✓ Branch 87 taken 142 times.
✗ Branch 88 not taken.
✓ Branch 89 taken 34 times.
✓ Branch 90 taken 9 times.
✓ Branch 91 taken 289 times.
✓ Branch 92 taken 9 times.
✓ Branch 93 taken 10 times.
✓ Branch 94 taken 2 times.
✓ Branch 95 taken 110 times.
✓ Branch 96 taken 2 times.
✓ Branch 97 taken 3 times.
✗ Branch 98 not taken.
✓ Branch 99 taken 316 times.
✗ Branch 100 not taken.
✓ Branch 101 taken 17 times.
✗ Branch 102 not taken.
✓ Branch 103 taken 73 times.
✗ Branch 104 not taken.
✓ Branch 105 taken 1 times.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✓ Branch 109 taken 45118 times.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✓ Branch 115 taken 75 times.
✗ Branch 116 not taken.
✓ Branch 117 taken 77 times.
✗ Branch 118 not taken.
✓ Branch 119 taken 48 times.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✓ Branch 123 taken 43027 times.
✗ Branch 124 not taken.
✓ Branch 125 taken 2 times.
✗ Branch 126 not taken.
✓ Branch 127 taken 132 times.
✗ Branch 128 not taken.
✓ Branch 129 taken 174 times.
✗ Branch 130 not taken.
✓ Branch 131 taken 9 times.
✗ Branch 132 not taken.
✓ Branch 133 taken 13972 times.
✗ Branch 134 not taken.
✓ Branch 135 taken 22 times.
✗ Branch 136 not taken.
✓ Branch 137 taken 6 times.
✗ Branch 138 not taken.
✓ Branch 139 taken 4485 times.
✗ Branch 140 not taken.
✓ Branch 141 taken 2 times.
✗ Branch 142 not taken.
✓ Branch 143 taken 43035 times.
✗ Branch 144 not taken.
✓ Branch 145 taken 32 times.
✗ Branch 146 not taken.
✓ Branch 147 taken 95 times.
✗ Branch 148 not taken.
✓ Branch 149 taken 42 times.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 152 not taken.
✓ Branch 153 taken 43034 times.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✗ Branch 156 not taken.
✓ Branch 157 taken 4322 times.
✗ Branch 158 not taken.
✓ Branch 159 taken 52 times.
✗ Branch 160 not taken.
✓ Branch 161 taken 43027 times.
✗ Branch 162 not taken.
✗ Branch 163 not taken.
✗ Branch 164 not taken.
✓ Branch 165 taken 2 times.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 168 not taken.
✓ Branch 169 taken 4 times.
✓ Branch 170 taken 2 times.
✓ Branch 171 taken 99616 times.
✗ Branch 172 not taken.
✓ Branch 173 taken 209 times.
✗ Branch 174 not taken.
✗ Branch 175 not taken.
✗ Branch 176 not taken.
✓ Branch 177 taken 19 times.
✗ Branch 178 not taken.
✓ Branch 179 taken 9 times.
✗ Branch 180 not taken.
✓ Branch 181 taken 13620 times.
✗ Branch 182 not taken.
✓ Branch 183 taken 449 times.
✗ Branch 184 not taken.
✓ Branch 185 taken 2 times.
✗ Branch 186 not taken.
✗ Branch 187 not taken.
✗ Branch 188 not taken.
✓ Branch 189 taken 21 times.
✓ Branch 190 taken 1 times.
✗ Branch 191 not taken.
✗ Branch 192 not taken.
✓ Branch 193 taken 2 times.
✓ Branch 194 taken 1 times.
✓ Branch 195 taken 38 times.
✓ Branch 196 taken 1 times.
✓ Branch 197 taken 169 times.
✗ Branch 198 not taken.
✓ Branch 199 taken 1 times.
✗ Branch 200 not taken.
✗ Branch 201 not taken.
✗ Branch 202 not taken.
✓ Branch 203 taken 8 times.
✗ Branch 204 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✓ Branch 207 taken 286 times.
✗ Branch 208 not taken.
✗ Branch 209 not taken.
✓ Branch 210 taken 1 times.
✓ Branch 211 taken 4 times.
✗ Branch 212 not taken.
✓ Branch 213 taken 1 times.
✗ Branch 214 not taken.
✓ Branch 215 taken 1 times.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✗ Branch 218 not taken.
✓ Branch 219 taken 107 times.
✗ Branch 220 not taken.
✗ Branch 221 not taken.
✗ Branch 222 not taken.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✗ Branch 225 not taken.
✗ Branch 226 not taken.
✗ Branch 227 not taken.
✗ Branch 228 not taken.
✓ Branch 229 taken 90 times.
✗ Branch 230 not taken.
✗ Branch 231 not taken.
✗ Branch 232 not taken.
✓ Branch 233 taken 96 times.
✓ Branch 234 taken 4 times.
✓ Branch 235 taken 12 times.
✗ Branch 236 not taken.
✓ Branch 237 taken 106 times.
✗ Branch 238 not taken.
✗ Branch 239 not taken.
✗ Branch 240 not taken.
✓ Branch 241 taken 100 times.
✗ Branch 242 not taken.
✓ Branch 243 taken 3236 times.
✗ Branch 244 not taken.
✓ Branch 245 taken 102 times.
✗ Branch 246 not taken.
✓ Branch 247 taken 398 times.
✗ Branch 248 not taken.
✓ Branch 249 taken 114 times.
✗ Branch 250 not taken.
✗ Branch 251 not taken.
✗ Branch 252 not taken.
✓ Branch 253 taken 112 times.
✗ Branch 254 not taken.
✗ Branch 255 not taken.
✗ Branch 256 not taken.
✓ Branch 257 taken 114 times.
✗ Branch 258 not taken.
✗ Branch 259 not taken.
✗ Branch 260 not taken.
✓ Branch 261 taken 130 times.
✗ Branch 262 not taken.
✓ Branch 263 taken 720 times.
✗ Branch 264 not taken.
✓ Branch 265 taken 190 times.
✗ Branch 266 not taken.
✗ Branch 267 not taken.
✗ Branch 268 not taken.
✓ Branch 269 taken 162 times.
✗ Branch 270 not taken.
✓ Branch 271 taken 2 times.
✗ Branch 272 not taken.
✓ Branch 273 taken 98 times.
✗ Branch 274 not taken.
✗ Branch 275 not taken.
✗ Branch 276 not taken.
✓ Branch 277 taken 98 times.
✗ Branch 278 not taken.
✗ Branch 279 not taken.
✗ Branch 280 not taken.
✓ Branch 281 taken 98 times.
✗ Branch 282 not taken.
✗ Branch 283 not taken.
✗ Branch 284 not taken.
✓ Branch 285 taken 590 times.
✗ Branch 286 not taken.
✗ Branch 287 not taken.
✗ Branch 288 not taken.
✓ Branch 289 taken 68 times.
✗ Branch 290 not taken.
✗ Branch 291 not taken.
✗ Branch 292 not taken.
✓ Branch 293 taken 352 times.
✗ Branch 294 not taken.
✗ Branch 295 not taken.
✗ Branch 296 not taken.
✓ Branch 297 taken 178 times.
✗ Branch 298 not taken.
✗ Branch 299 not taken.
✗ Branch 300 not taken.
✓ Branch 301 taken 306 times.
✗ Branch 302 not taken.
✗ Branch 303 not taken.
✗ Branch 304 not taken.
✓ Branch 305 taken 356 times.
✗ Branch 306 not taken.
✗ Branch 307 not taken.
✓ Branch 308 taken 2 times.
✓ Branch 309 taken 2 times.
✓ Branch 310 taken 2 times.
✗ Branch 311 not taken.
✗ Branch 312 not taken.
✗ Branch 313 not taken.
✗ Branch 314 not taken.
✗ Branch 315 not taken.
✗ Branch 316 not taken.
✗ Branch 317 not taken.
✗ Branch 318 not taken.
✗ Branch 319 not taken.
33549430 bool isTileOff() const { return isTile() && !tile.active; }
148
127/360
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 392 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 675 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 8070 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 15 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 14 times.
✓ Branch 10 taken 2 times.
✓ Branch 11 taken 8144 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 14 times.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 21 times.
✓ Branch 16 taken 10 times.
✓ Branch 17 taken 851 times.
✓ Branch 18 taken 3 times.
✓ Branch 19 taken 46 times.
✓ Branch 20 taken 27 times.
✓ Branch 21 taken 8678 times.
✓ Branch 22 taken 10 times.
✓ Branch 23 taken 18 times.
✓ Branch 24 taken 36 times.
✓ Branch 25 taken 23 times.
✓ Branch 26 taken 3 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 31 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 15 times.
✓ Branch 31 taken 74525 times.
✓ Branch 32 taken 2 times.
✓ Branch 33 taken 15075196 times.
✓ Branch 34 taken 2 times.
✓ Branch 35 taken 17615170 times.
✓ Branch 36 taken 1 times.
✓ Branch 37 taken 267026 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 11 times.
✓ Branch 40 taken 12 times.
✓ Branch 41 taken 2 times.
✓ Branch 42 taken 5 times.
✓ Branch 43 taken 9 times.
✓ Branch 44 taken 6 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 2 times.
✓ Branch 47 taken 4 times.
✓ Branch 48 taken 15 times.
✓ Branch 49 taken 148 times.
✓ Branch 50 taken 9 times.
✓ Branch 51 taken 6 times.
✓ Branch 52 taken 1 times.
✓ Branch 53 taken 134603 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 5 times.
✓ Branch 56 taken 1 times.
✓ Branch 57 taken 28 times.
✓ Branch 58 taken 2 times.
✓ Branch 59 taken 1079 times.
✓ Branch 60 taken 4356 times.
✓ Branch 61 taken 2850 times.
✓ Branch 62 taken 2 times.
✓ Branch 63 taken 5385 times.
✓ Branch 64 taken 18 times.
✓ Branch 65 taken 4 times.
✓ Branch 66 taken 2 times.
✓ Branch 67 taken 20 times.
✓ Branch 68 taken 11 times.
✓ Branch 69 taken 18 times.
✗ Branch 70 not taken.
✓ Branch 71 taken 11 times.
✓ Branch 72 taken 15 times.
✓ Branch 73 taken 3 times.
✓ Branch 74 taken 3 times.
✓ Branch 75 taken 13 times.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✓ Branch 79 taken 43 times.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✓ Branch 88 taken 10 times.
✗ Branch 89 not taken.
✓ Branch 90 taken 1 times.
✓ Branch 91 taken 9 times.
✓ Branch 92 taken 17 times.
✗ Branch 93 not taken.
✓ Branch 94 taken 1 times.
✓ Branch 95 taken 18 times.
✓ Branch 96 taken 4 times.
✓ Branch 97 taken 3 times.
✓ Branch 98 taken 2 times.
✓ Branch 99 taken 45107 times.
✗ Branch 100 not taken.
✓ Branch 101 taken 7 times.
✗ Branch 102 not taken.
✓ Branch 103 taken 3 times.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✓ Branch 107 taken 173 times.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✓ Branch 113 taken 6 times.
✗ Branch 114 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✓ Branch 117 taken 2 times.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✗ Branch 120 not taken.
✓ Branch 121 taken 134 times.
✓ Branch 122 taken 1 times.
✗ Branch 123 not taken.
✓ Branch 124 taken 1 times.
✓ Branch 125 taken 187 times.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 129 not taken.
✓ Branch 130 taken 1 times.
✗ Branch 131 not taken.
✗ Branch 132 not taken.
✓ Branch 133 taken 3 times.
✗ Branch 134 not taken.
✗ Branch 135 not taken.
✗ Branch 136 not taken.
✓ Branch 137 taken 201 times.
✗ Branch 138 not taken.
✓ Branch 139 taken 2 times.
✗ Branch 140 not taken.
✗ Branch 141 not taken.
✗ Branch 142 not taken.
✓ Branch 143 taken 4 times.
✗ Branch 144 not taken.
✗ Branch 145 not taken.
✗ Branch 146 not taken.
✗ Branch 147 not taken.
✗ Branch 148 not taken.
✓ Branch 149 taken 186 times.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 152 not taken.
✗ Branch 153 not taken.
✗ Branch 154 not taken.
✓ Branch 155 taken 20 times.
✗ Branch 156 not taken.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
✓ Branch 159 taken 43027 times.
✗ Branch 160 not taken.
✓ Branch 161 taken 201 times.
✗ Branch 162 not taken.
✓ Branch 163 taken 172 times.
✗ Branch 164 not taken.
✗ Branch 165 not taken.
✗ Branch 166 not taken.
✓ Branch 167 taken 13972 times.
✗ Branch 168 not taken.
✗ Branch 169 not taken.
✗ Branch 170 not taken.
✓ Branch 171 taken 4323 times.
✗ Branch 172 not taken.
✓ Branch 173 taken 189 times.
✓ Branch 174 taken 2 times.
✓ Branch 175 taken 43028 times.
✗ Branch 176 not taken.
✗ Branch 177 not taken.
✗ Branch 178 not taken.
✓ Branch 179 taken 28 times.
✗ Branch 180 not taken.
✗ Branch 181 not taken.
✗ Branch 182 not taken.
✓ Branch 183 taken 43027 times.
✗ Branch 184 not taken.
✓ Branch 185 taken 192 times.
✗ Branch 186 not taken.
✓ Branch 187 taken 4322 times.
✗ Branch 188 not taken.
✗ Branch 189 not taken.
✗ Branch 190 not taken.
✓ Branch 191 taken 43027 times.
✗ Branch 192 not taken.
✗ Branch 193 not taken.
✗ Branch 194 not taken.
✗ Branch 195 not taken.
✗ Branch 196 not taken.
✓ Branch 197 taken 201 times.
✗ Branch 198 not taken.
✓ Branch 199 taken 99561 times.
✗ Branch 200 not taken.
✗ Branch 201 not taken.
✗ Branch 202 not taken.
✓ Branch 203 taken 13 times.
✗ Branch 204 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✓ Branch 207 taken 13620 times.
✗ Branch 208 not taken.
✓ Branch 209 taken 213 times.
✗ Branch 210 not taken.
✗ Branch 211 not taken.
✗ Branch 212 not taken.
✗ Branch 213 not taken.
✗ Branch 214 not taken.
✗ Branch 215 not taken.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✗ Branch 218 not taken.
✗ Branch 219 not taken.
✗ Branch 220 not taken.
✓ Branch 221 taken 334 times.
✗ Branch 222 not taken.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✗ Branch 225 not taken.
✗ Branch 226 not taken.
✗ Branch 227 not taken.
✗ Branch 228 not taken.
✗ Branch 229 not taken.
✗ Branch 230 not taken.
✗ Branch 231 not taken.
✗ Branch 232 not taken.
✓ Branch 233 taken 384 times.
✗ Branch 234 not taken.
✗ Branch 235 not taken.
✗ Branch 236 not taken.
✗ Branch 237 not taken.
✗ Branch 238 not taken.
✗ Branch 239 not taken.
✗ Branch 240 not taken.
✗ Branch 241 not taken.
✗ Branch 242 not taken.
✗ Branch 243 not taken.
✗ Branch 244 not taken.
✓ Branch 245 taken 141 times.
✗ Branch 246 not taken.
✗ Branch 247 not taken.
✗ Branch 248 not taken.
✗ Branch 249 not taken.
✗ Branch 250 not taken.
✗ Branch 251 not taken.
✗ Branch 252 not taken.
✗ Branch 253 not taken.
✗ Branch 254 not taken.
✗ Branch 255 not taken.
✗ Branch 256 not taken.
✓ Branch 257 taken 141 times.
✗ Branch 258 not taken.
✗ Branch 259 not taken.
✗ Branch 260 not taken.
✗ Branch 261 not taken.
✗ Branch 262 not taken.
✗ Branch 263 not taken.
✗ Branch 264 not taken.
✗ Branch 265 not taken.
✗ Branch 266 not taken.
✗ Branch 267 not taken.
✗ Branch 268 not taken.
✓ Branch 269 taken 141 times.
✗ Branch 270 not taken.
✗ Branch 271 not taken.
✗ Branch 272 not taken.
✗ Branch 273 not taken.
✗ Branch 274 not taken.
✗ Branch 275 not taken.
✗ Branch 276 not taken.
✗ Branch 277 not taken.
✗ Branch 278 not taken.
✗ Branch 279 not taken.
✗ Branch 280 not taken.
✓ Branch 281 taken 1331 times.
✗ Branch 282 not taken.
✗ Branch 283 not taken.
✗ Branch 284 not taken.
✗ Branch 285 not taken.
✗ Branch 286 not taken.
✗ Branch 287 not taken.
✗ Branch 288 not taken.
✗ Branch 289 not taken.
✗ Branch 290 not taken.
✗ Branch 291 not taken.
✗ Branch 292 not taken.
✓ Branch 293 taken 102 times.
✗ Branch 294 not taken.
✗ Branch 295 not taken.
✗ Branch 296 not taken.
✗ Branch 297 not taken.
✗ Branch 298 not taken.
✗ Branch 299 not taken.
✗ Branch 300 not taken.
✗ Branch 301 not taken.
✗ Branch 302 not taken.
✗ Branch 303 not taken.
✗ Branch 304 not taken.
✓ Branch 305 taken 819 times.
✗ Branch 306 not taken.
✗ Branch 307 not taken.
✗ Branch 308 not taken.
✗ Branch 309 not taken.
✗ Branch 310 not taken.
✗ Branch 311 not taken.
✗ Branch 312 not taken.
✗ Branch 313 not taken.
✗ Branch 314 not taken.
✗ Branch 315 not taken.
✗ Branch 316 not taken.
✓ Branch 317 taken 279 times.
✗ Branch 318 not taken.
✗ Branch 319 not taken.
✗ Branch 320 not taken.
✗ Branch 321 not taken.
✗ Branch 322 not taken.
✗ Branch 323 not taken.
✗ Branch 324 not taken.
✗ Branch 325 not taken.
✗ Branch 326 not taken.
✗ Branch 327 not taken.
✓ Branch 328 taken 6 times.
✓ Branch 329 taken 813 times.
✗ Branch 330 not taken.
✓ Branch 331 taken 6 times.
✗ Branch 332 not taken.
✗ Branch 333 not taken.
✗ Branch 334 not taken.
✗ Branch 335 not taken.
✗ Branch 336 not taken.
✗ Branch 337 not taken.
✗ Branch 338 not taken.
✗ Branch 339 not taken.
✗ Branch 340 not taken.
✓ Branch 341 taken 1176 times.
✗ Branch 342 not taken.
✗ Branch 343 not taken.
✗ Branch 344 not taken.
✗ Branch 345 not taken.
✗ Branch 346 not taken.
✗ Branch 347 not taken.
✓ Branch 348 taken 1 times.
✗ Branch 349 not taken.
✓ Branch 350 taken 1 times.
✗ Branch 351 not taken.
✗ Branch 352 not taken.
✗ Branch 353 not taken.
✗ Branch 354 not taken.
✗ Branch 355 not taken.
✗ Branch 356 not taken.
✗ Branch 357 not taken.
✗ Branch 358 not taken.
✗ Branch 359 not taken.
33564078 bool isTileOn() const { return isTile() && tile.active; }
149
150
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 437 times.
876 void set(ChildType& c) { delete child; child = &c; }
151
2/2
✓ Branch 0 taken 2470 times.
✓ Branch 1 taken 2963 times.
10862 void set(const Tile& t) { delete child; child = nullptr; tile = t; }
152
1/2
✓ Branch 1 taken 285 times.
✗ Branch 2 not taken.
45508 ChildType& steal(const Tile& t) { ChildType* c=child; child=nullptr; tile=t; return *c; }
153 };
154
155 using MapType = std::map<Coord, NodeStruct>;
156 using MapIter = typename MapType::iterator;
157 using MapCIter = typename MapType::const_iterator;
158
159 using CoordSet = std::set<Coord>;
160 using CoordSetIter = typename CoordSet::iterator;
161 using CoordSetCIter = typename CoordSet::const_iterator;
162
163
0/56
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
5420 static void setTile(const MapIter& i, const Tile& t) { i->second.set(t); }
164 437 static void setChild(const MapIter& i, ChildType& c) { i->second.set(c); }
165 static Tile& getTile(const MapIter& i) { return i->second.tile; }
166 static const Tile& getTile(const MapCIter& i) { return i->second.tile; }
167
19/48
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 134 times.
✓ Branch 3 taken 3776 times.
✓ Branch 4 taken 406 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 23 times.
✓ Branch 7 taken 118 times.
✓ Branch 8 taken 158 times.
✓ Branch 9 taken 427 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1273 times.
✓ Branch 13 taken 1476 times.
✓ Branch 14 taken 116 times.
✓ Branch 15 taken 96 times.
✓ Branch 16 taken 9 times.
✓ Branch 17 taken 173 times.
✓ Branch 18 taken 2 times.
✓ Branch 19 taken 43 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✓ Branch 46 taken 2 times.
✓ Branch 47 taken 2 times.
9948 static ChildType& getChild(const MapIter& i) { return *(i->second.child); }
168
83/153
✓ Branch 0 taken 358 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 74 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 13858 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 570 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 252 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 81 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 597 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 224 times.
✓ Branch 15 taken 1 times.
✓ Branch 16 taken 171 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 9 times.
✓ Branch 19 taken 1 times.
✓ Branch 20 taken 1029 times.
✓ Branch 21 taken 8 times.
✓ Branch 22 taken 5607 times.
✓ Branch 23 taken 1 times.
✓ Branch 24 taken 6 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 163 times.
✓ Branch 27 taken 1 times.
✓ Branch 28 taken 4 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✓ Branch 31 taken 1 times.
✓ Branch 32 taken 8 times.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✓ Branch 35 taken 1 times.
✓ Branch 36 taken 2 times.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✓ Branch 39 taken 1 times.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✓ Branch 46 taken 129 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 144 times.
✗ Branch 49 not taken.
✓ Branch 50 taken 96 times.
✓ Branch 51 taken 1 times.
✓ Branch 52 taken 144 times.
✗ Branch 53 not taken.
✓ Branch 54 taken 65 times.
✗ Branch 55 not taken.
✓ Branch 56 taken 80 times.
✓ Branch 57 taken 1 times.
✓ Branch 58 taken 96 times.
✗ Branch 59 not taken.
✓ Branch 60 taken 80 times.
✓ Branch 61 taken 1 times.
✓ Branch 62 taken 176 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 401 times.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✓ Branch 68 taken 1 times.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✓ Branch 71 taken 1 times.
✓ Branch 72 taken 1232 times.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✓ Branch 76 taken 832 times.
✗ Branch 77 not taken.
✓ Branch 78 taken 80 times.
✓ Branch 79 taken 1 times.
✓ Branch 80 taken 960 times.
✗ Branch 81 not taken.
✓ Branch 82 taken 1765 times.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✓ Branch 85 taken 1 times.
✗ Branch 86 not taken.
✓ Branch 88 taken 1 times.
✗ Branch 89 not taken.
✓ Branch 92 taken 1 times.
✗ Branch 93 not taken.
✓ Branch 96 taken 1 times.
✗ Branch 97 not taken.
✓ Branch 100 taken 1 times.
✗ Branch 101 not taken.
✓ Branch 105 taken 1 times.
✗ Branch 106 not taken.
✓ Branch 108 taken 1 times.
✗ Branch 109 not taken.
✓ Branch 112 taken 1 times.
✗ Branch 113 not taken.
✓ Branch 115 taken 1 times.
✗ Branch 116 not taken.
✓ Branch 118 taken 1 times.
✗ Branch 119 not taken.
✓ Branch 121 taken 1 times.
✗ Branch 122 not taken.
✓ Branch 128 taken 1 times.
✗ Branch 129 not taken.
✓ Branch 131 taken 1 times.
✗ Branch 132 not taken.
✓ Branch 141 taken 1 times.
✗ Branch 142 not taken.
✓ Branch 144 taken 1 times.
✗ Branch 145 not taken.
✓ Branch 147 taken 1 times.
✗ Branch 148 not taken.
✓ Branch 150 taken 1 times.
✗ Branch 151 not taken.
✓ Branch 153 taken 1 times.
✗ Branch 154 not taken.
✓ Branch 156 taken 1 times.
✗ Branch 157 not taken.
✓ Branch 159 taken 1 times.
✗ Branch 160 not taken.
✓ Branch 162 taken 1 times.
✗ Branch 163 not taken.
✓ Branch 165 taken 1 times.
✗ Branch 166 not taken.
✓ Branch 168 taken 1 times.
✗ Branch 169 not taken.
✓ Branch 172 taken 1 times.
✗ Branch 173 not taken.
✓ Branch 176 taken 1 times.
✗ Branch 177 not taken.
✓ Branch 180 taken 1 times.
✗ Branch 181 not taken.
✓ Branch 185 taken 1 times.
✗ Branch 186 not taken.
✓ Branch 188 taken 1 times.
✗ Branch 189 not taken.
✓ Branch 192 taken 1 times.
✗ Branch 193 not taken.
✓ Branch 195 taken 1 times.
✗ Branch 196 not taken.
✓ Branch 198 taken 1 times.
✗ Branch 199 not taken.
✓ Branch 201 taken 1 times.
✗ Branch 202 not taken.
✓ Branch 208 taken 1 times.
✗ Branch 209 not taken.
✓ Branch 211 taken 1 times.
✗ Branch 212 not taken.
394779 static const ChildType& getChild(const MapCIter& i) { return *(i->second.child); }
169 static ChildType& stealChild(const MapIter& i, const Tile& t) {return i->second.steal(t);}
170 static const ChildType& stealChild(const MapCIter& i,const Tile& t) {return i->second.steal(t);}
171
172 static bool isChild(const MapCIter& i) { return i->second.isChild(); }
173 static bool isChild(const MapIter& i) { return i->second.isChild(); }
174 static bool isTile(const MapCIter& i) { return i->second.isTile(); }
175 static bool isTile(const MapIter& i) { return i->second.isTile(); }
176 static bool isTileOff(const MapCIter& i) { return i->second.isTileOff(); }
177 static bool isTileOff(const MapIter& i) { return i->second.isTileOff(); }
178 static bool isTileOn(const MapCIter& i) { return i->second.isTileOn(); }
179 static bool isTileOn(const MapIter& i) { return i->second.isTileOn(); }
180
181 struct NullPred {
182 static inline bool test(const MapIter&) { return true; }
183 static inline bool test(const MapCIter&) { return true; }
184 };
185 struct ValueOnPred {
186 static inline bool test(const MapIter& i) { return isTileOn(i); }
187 static inline bool test(const MapCIter& i) { return isTileOn(i); }
188 };
189 struct ValueOffPred {
190 static inline bool test(const MapIter& i) { return isTileOff(i); }
191 static inline bool test(const MapCIter& i) { return isTileOff(i); }
192 };
193 struct ValueAllPred {
194 static inline bool test(const MapIter& i) { return isTile(i); }
195 static inline bool test(const MapCIter& i) { return isTile(i); }
196 };
197 struct ChildOnPred {
198 static inline bool test(const MapIter& i) { return isChild(i); }
199 static inline bool test(const MapCIter& i) { return isChild(i); }
200 };
201 struct ChildOffPred {
202 static inline bool test(const MapIter& i) { return isTile(i); }
203 static inline bool test(const MapCIter& i) { return isTile(i); }
204 };
205
206 template<typename _RootNodeT, typename _MapIterT, typename FilterPredT>
207 class BaseIter
208 {
209 public:
210 using RootNodeT = _RootNodeT;
211 using MapIterT = _MapIterT; // either MapIter or MapCIter
212
213 bool operator==(const BaseIter& other) const
214 {
215 return (mParentNode == other.mParentNode) && (mIter == other.mIter);
216 }
217 bool operator!=(const BaseIter& other) const { return !(*this == other); }
218
219
25/52
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 512 times.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 1024 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 4096 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 12288 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 32768 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 98304 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 2 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 2 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 1 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 2 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 2 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 1 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 2 times.
✗ Branch 44 not taken.
✓ Branch 45 taken 6 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 6 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 3 times.
✗ Branch 50 not taken.
✓ Branch 51 taken 3 times.
157733 RootNodeT* getParentNode() const { return mParentNode; }
220 /// Return a reference to the node over which this iterator iterates.
221 298030 RootNodeT& parent() const
222 {
223
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 149015 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
298030 if (!mParentNode) OPENVDB_THROW(ValueError, "iterator references a null parent node");
224 298030 return *mParentNode;
225 }
226
227
598/1699
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1124 times.
✓ Branch 5 taken 343 times.
✓ Branch 6 taken 35 times.
✓ Branch 7 taken 58 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 9 times.
✓ Branch 10 taken 170 times.
✓ Branch 11 taken 56 times.
✓ Branch 12 taken 60 times.
✓ Branch 13 taken 4938 times.
✓ Branch 14 taken 18 times.
✓ Branch 15 taken 26 times.
✓ Branch 16 taken 162 times.
✓ Branch 17 taken 104 times.
✓ Branch 18 taken 9 times.
✓ Branch 19 taken 251 times.
✓ Branch 20 taken 8 times.
✓ Branch 21 taken 27 times.
✓ Branch 22 taken 221 times.
✓ Branch 23 taken 19 times.
✓ Branch 24 taken 790 times.
✓ Branch 25 taken 9 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 13 times.
✓ Branch 29 taken 656 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 98 times.
✓ Branch 32 taken 327 times.
✓ Branch 33 taken 86 times.
✓ Branch 34 taken 9 times.
✓ Branch 35 taken 18 times.
✓ Branch 36 taken 873 times.
✓ Branch 37 taken 17 times.
✓ Branch 38 taken 13 times.
✓ Branch 39 taken 753 times.
✓ Branch 40 taken 9 times.
✓ Branch 41 taken 148 times.
✓ Branch 42 taken 6910 times.
✓ Branch 43 taken 21 times.
✓ Branch 44 taken 49 times.
✓ Branch 45 taken 12946 times.
✓ Branch 46 taken 16 times.
✓ Branch 47 taken 364 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 244 times.
✓ Branch 50 taken 6565 times.
✓ Branch 51 taken 16 times.
✓ Branch 52 taken 116 times.
✓ Branch 53 taken 7290 times.
✓ Branch 54 taken 8 times.
✓ Branch 55 taken 120 times.
✓ Branch 56 taken 7126 times.
✓ Branch 57 taken 9 times.
✓ Branch 58 taken 24 times.
✓ Branch 59 taken 85 times.
✓ Branch 60 taken 705 times.
✗ Branch 61 not taken.
✓ Branch 62 taken 189 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 8 times.
✓ Branch 65 taken 12 times.
✓ Branch 66 taken 54 times.
✓ Branch 67 taken 95 times.
✓ Branch 68 taken 128 times.
✓ Branch 69 taken 25 times.
✓ Branch 70 taken 4 times.
✓ Branch 71 taken 69 times.
✓ Branch 72 taken 12 times.
✓ Branch 73 taken 4 times.
✓ Branch 74 taken 16 times.
✓ Branch 75 taken 3837 times.
✗ Branch 76 not taken.
✓ Branch 77 taken 8 times.
✓ Branch 78 taken 108 times.
✗ Branch 79 not taken.
✓ Branch 80 taken 8 times.
✓ Branch 81 taken 185 times.
✓ Branch 82 taken 2 times.
✓ Branch 83 taken 29 times.
✓ Branch 84 taken 63 times.
✓ Branch 85 taken 6 times.
✓ Branch 86 taken 13217 times.
✗ Branch 87 not taken.
✓ Branch 88 taken 4 times.
✓ Branch 89 taken 418 times.
✓ Branch 90 taken 72 times.
✓ Branch 91 taken 2 times.
✓ Branch 92 taken 411 times.
✓ Branch 93 taken 150 times.
✓ Branch 94 taken 126 times.
✓ Branch 95 taken 13187 times.
✓ Branch 96 taken 81 times.
✗ Branch 97 not taken.
✓ Branch 98 taken 12 times.
✓ Branch 99 taken 373 times.
✓ Branch 100 taken 2 times.
✓ Branch 101 taken 7 times.
✓ Branch 102 taken 122 times.
✓ Branch 103 taken 12 times.
✓ Branch 104 taken 11 times.
✓ Branch 105 taken 80 times.
✓ Branch 106 taken 110990 times.
✓ Branch 107 taken 677 times.
✓ Branch 108 taken 70 times.
✗ Branch 109 not taken.
✓ Branch 110 taken 76 times.
✗ Branch 111 not taken.
✓ Branch 112 taken 921 times.
✓ Branch 113 taken 12 times.
✓ Branch 114 taken 17 times.
✓ Branch 115 taken 483 times.
✗ Branch 116 not taken.
✓ Branch 117 taken 3 times.
✓ Branch 118 taken 221129 times.
✓ Branch 119 taken 12 times.
✓ Branch 120 taken 127 times.
✓ Branch 121 taken 84 times.
✓ Branch 122 taken 1 times.
✓ Branch 123 taken 529 times.
✓ Branch 124 taken 110628 times.
✓ Branch 125 taken 2 times.
✓ Branch 126 taken 14738 times.
✓ Branch 127 taken 1 times.
✓ Branch 128 taken 11 times.
✓ Branch 129 taken 5570 times.
✗ Branch 130 not taken.
✓ Branch 131 taken 9 times.
✓ Branch 132 taken 16 times.
✓ Branch 133 taken 373 times.
✓ Branch 134 taken 10 times.
✓ Branch 135 taken 6 times.
✓ Branch 136 taken 227 times.
✓ Branch 137 taken 29 times.
✓ Branch 138 taken 290 times.
✓ Branch 139 taken 628 times.
✓ Branch 140 taken 11 times.
✓ Branch 141 taken 490 times.
✓ Branch 142 taken 111939 times.
✓ Branch 143 taken 12 times.
✓ Branch 144 taken 951 times.
✓ Branch 145 taken 481 times.
✓ Branch 146 taken 11 times.
✓ Branch 147 taken 134 times.
✓ Branch 148 taken 604 times.
✓ Branch 149 taken 3 times.
✓ Branch 150 taken 62 times.
✓ Branch 151 taken 13456 times.
✓ Branch 152 taken 4 times.
✓ Branch 153 taken 21 times.
✓ Branch 154 taken 14459 times.
✓ Branch 155 taken 9 times.
✓ Branch 156 taken 63 times.
✓ Branch 157 taken 117 times.
✓ Branch 158 taken 10 times.
✗ Branch 159 not taken.
✓ Branch 160 taken 117 times.
✓ Branch 161 taken 8 times.
✓ Branch 162 taken 521 times.
✗ Branch 163 not taken.
✓ Branch 164 taken 2 times.
✗ Branch 165 not taken.
✓ Branch 166 taken 66 times.
✓ Branch 167 taken 7 times.
✓ Branch 168 taken 57 times.
✓ Branch 169 taken 66 times.
✓ Branch 170 taken 14 times.
✓ Branch 171 taken 8 times.
✓ Branch 172 taken 45 times.
✓ Branch 173 taken 11 times.
✓ Branch 174 taken 12773 times.
✓ Branch 175 taken 98 times.
✗ Branch 176 not taken.
✓ Branch 177 taken 5032 times.
✓ Branch 178 taken 53 times.
✓ Branch 179 taken 150 times.
✓ Branch 180 taken 467 times.
✓ Branch 181 taken 92 times.
✓ Branch 182 taken 8 times.
✗ Branch 183 not taken.
✓ Branch 184 taken 344 times.
✓ Branch 185 taken 31 times.
✓ Branch 186 taken 48 times.
✓ Branch 187 taken 10 times.
✓ Branch 188 taken 223 times.
✓ Branch 189 taken 17 times.
✓ Branch 190 taken 14467 times.
✓ Branch 191 taken 167 times.
✗ Branch 192 not taken.
✓ Branch 193 taken 175 times.
✓ Branch 194 taken 25 times.
✗ Branch 195 not taken.
✓ Branch 196 taken 1673 times.
✓ Branch 197 taken 182 times.
✓ Branch 198 taken 13 times.
✓ Branch 199 taken 167 times.
✓ Branch 200 taken 41 times.
✓ Branch 201 taken 14 times.
✓ Branch 202 taken 139 times.
✓ Branch 203 taken 330 times.
✓ Branch 204 taken 16165 times.
✓ Branch 205 taken 148 times.
✓ Branch 206 taken 1439 times.
✗ Branch 207 not taken.
✓ Branch 208 taken 1 times.
✓ Branch 209 taken 4929 times.
✗ Branch 210 not taken.
✓ Branch 211 taken 2 times.
✓ Branch 212 taken 44 times.
✓ Branch 213 taken 2 times.
✓ Branch 214 taken 2 times.
✓ Branch 215 taken 18 times.
✗ Branch 216 not taken.
✓ Branch 217 taken 46 times.
✓ Branch 218 taken 132 times.
✗ Branch 219 not taken.
✓ Branch 220 taken 44 times.
✓ Branch 221 taken 303 times.
✓ Branch 222 taken 64 times.
✓ Branch 223 taken 11 times.
✓ Branch 224 taken 80 times.
✓ Branch 225 taken 6 times.
✓ Branch 226 taken 51 times.
✓ Branch 227 taken 170 times.
✗ Branch 228 not taken.
✓ Branch 229 taken 47 times.
✓ Branch 230 taken 69 times.
✗ Branch 231 not taken.
✓ Branch 232 taken 658 times.
✓ Branch 233 taken 71 times.
✗ Branch 234 not taken.
✓ Branch 235 taken 4 times.
✓ Branch 236 taken 90 times.
✗ Branch 237 not taken.
✓ Branch 238 taken 671 times.
✓ Branch 239 taken 2 times.
✗ Branch 240 not taken.
✓ Branch 241 taken 10 times.
✓ Branch 242 taken 33 times.
✓ Branch 243 taken 1256 times.
✓ Branch 244 taken 5 times.
✓ Branch 245 taken 13 times.
✓ Branch 246 taken 1 times.
✓ Branch 247 taken 5 times.
✓ Branch 248 taken 48 times.
✓ Branch 249 taken 1 times.
✓ Branch 250 taken 4878 times.
✓ Branch 251 taken 32 times.
✓ Branch 252 taken 20 times.
✗ Branch 253 not taken.
✓ Branch 254 taken 24 times.
✓ Branch 255 taken 20 times.
✗ Branch 256 not taken.
✓ Branch 257 taken 8 times.
✓ Branch 258 taken 41 times.
✓ Branch 259 taken 1 times.
✓ Branch 260 taken 16 times.
✓ Branch 261 taken 40 times.
✓ Branch 262 taken 22 times.
✗ Branch 263 not taken.
✓ Branch 264 taken 19 times.
✓ Branch 265 taken 2 times.
✓ Branch 266 taken 24 times.
✓ Branch 267 taken 164 times.
✓ Branch 268 taken 3 times.
✓ Branch 269 taken 14 times.
✓ Branch 270 taken 4 times.
✓ Branch 271 taken 18 times.
✓ Branch 272 taken 18 times.
✗ Branch 273 not taken.
✓ Branch 274 taken 5 times.
✓ Branch 275 taken 1 times.
✓ Branch 276 taken 872 times.
✓ Branch 277 taken 6 times.
✓ Branch 278 taken 25 times.
✓ Branch 279 taken 51 times.
✓ Branch 280 taken 26 times.
✓ Branch 281 taken 9 times.
✓ Branch 282 taken 54 times.
✓ Branch 283 taken 24 times.
✓ Branch 284 taken 21 times.
✓ Branch 285 taken 22 times.
✓ Branch 286 taken 36 times.
✓ Branch 287 taken 1 times.
✓ Branch 288 taken 61 times.
✓ Branch 289 taken 62 times.
✓ Branch 290 taken 1 times.
✗ Branch 291 not taken.
✓ Branch 292 taken 25 times.
✓ Branch 293 taken 35 times.
✓ Branch 294 taken 15 times.
✓ Branch 295 taken 43 times.
✓ Branch 296 taken 420 times.
✓ Branch 297 taken 449 times.
✓ Branch 298 taken 23 times.
✓ Branch 299 taken 431 times.
✗ Branch 300 not taken.
✓ Branch 301 taken 2 times.
✓ Branch 302 taken 26 times.
✗ Branch 303 not taken.
✓ Branch 304 taken 6 times.
✓ Branch 305 taken 9 times.
✓ Branch 306 taken 423 times.
✓ Branch 307 taken 94 times.
✓ Branch 308 taken 19 times.
✗ Branch 309 not taken.
✓ Branch 310 taken 14 times.
✓ Branch 311 taken 128 times.
✗ Branch 312 not taken.
✓ Branch 313 taken 147 times.
✓ Branch 314 taken 211 times.
✗ Branch 315 not taken.
✓ Branch 316 taken 4 times.
✓ Branch 317 taken 22 times.
✗ Branch 318 not taken.
✓ Branch 319 taken 19 times.
✓ Branch 320 taken 316 times.
✗ Branch 321 not taken.
✓ Branch 322 taken 7 times.
✓ Branch 323 taken 68 times.
✓ Branch 324 taken 9 times.
✓ Branch 325 taken 6 times.
✓ Branch 326 taken 4 times.
✓ Branch 327 taken 9 times.
✓ Branch 328 taken 12 times.
✓ Branch 329 taken 22 times.
✓ Branch 330 taken 11 times.
✗ Branch 331 not taken.
✓ Branch 332 taken 16 times.
✓ Branch 333 taken 22 times.
✓ Branch 334 taken 50 times.
✓ Branch 335 taken 32 times.
✓ Branch 336 taken 11 times.
✓ Branch 337 taken 398 times.
✓ Branch 338 taken 4 times.
✓ Branch 339 taken 50 times.
✓ Branch 340 taken 1190 times.
✓ Branch 341 taken 162 times.
✓ Branch 342 taken 2 times.
✓ Branch 343 taken 14 times.
✓ Branch 344 taken 8 times.
✓ Branch 345 taken 62 times.
✓ Branch 346 taken 5766 times.
✓ Branch 347 taken 16 times.
✓ Branch 348 taken 97 times.
✓ Branch 349 taken 166 times.
✓ Branch 350 taken 78 times.
✓ Branch 351 taken 81 times.
✗ Branch 352 not taken.
✓ Branch 353 taken 30 times.
✗ Branch 354 not taken.
✗ Branch 355 not taken.
✓ Branch 356 taken 260 times.
✓ Branch 357 taken 1 times.
✗ Branch 358 not taken.
✓ Branch 359 taken 3 times.
✓ Branch 360 taken 1 times.
✗ Branch 361 not taken.
✓ Branch 362 taken 19 times.
✗ Branch 363 not taken.
✗ Branch 364 not taken.
✓ Branch 365 taken 27 times.
✗ Branch 366 not taken.
✓ Branch 367 taken 9 times.
✓ Branch 368 taken 433 times.
✗ Branch 369 not taken.
✗ Branch 370 not taken.
✓ Branch 371 taken 7 times.
✗ Branch 372 not taken.
✗ Branch 373 not taken.
✓ Branch 374 taken 31 times.
✗ Branch 375 not taken.
✗ Branch 376 not taken.
✓ Branch 377 taken 34 times.
✗ Branch 378 not taken.
✗ Branch 379 not taken.
✓ Branch 380 taken 3 times.
✗ Branch 381 not taken.
✓ Branch 382 taken 3 times.
✓ Branch 383 taken 39 times.
✗ Branch 384 not taken.
✓ Branch 385 taken 116 times.
✓ Branch 386 taken 169 times.
✗ Branch 387 not taken.
✓ Branch 388 taken 196 times.
✓ Branch 389 taken 39 times.
✗ Branch 390 not taken.
✓ Branch 391 taken 53 times.
✓ Branch 392 taken 169 times.
✓ Branch 393 taken 4 times.
✓ Branch 394 taken 54 times.
✓ Branch 395 taken 20 times.
✗ Branch 396 not taken.
✓ Branch 397 taken 1081 times.
✓ Branch 398 taken 32 times.
✓ Branch 399 taken 4 times.
✓ Branch 400 taken 1030 times.
✓ Branch 401 taken 8 times.
✗ Branch 402 not taken.
✓ Branch 403 taken 25 times.
✓ Branch 404 taken 8 times.
✗ Branch 405 not taken.
✓ Branch 406 taken 5606 times.
✓ Branch 407 taken 12 times.
✗ Branch 408 not taken.
✓ Branch 409 taken 5612 times.
✓ Branch 410 taken 9 times.
✗ Branch 411 not taken.
✓ Branch 412 taken 3 times.
✗ Branch 413 not taken.
✗ Branch 414 not taken.
✗ Branch 415 not taken.
✓ Branch 416 taken 441 times.
✗ Branch 417 not taken.
✓ Branch 418 taken 4 times.
✗ Branch 419 not taken.
✗ Branch 420 not taken.
✓ Branch 421 taken 129 times.
✓ Branch 422 taken 5 times.
✗ Branch 423 not taken.
✓ Branch 424 taken 2 times.
✓ Branch 425 taken 2 times.
✗ Branch 426 not taken.
✗ Branch 427 not taken.
✓ Branch 428 taken 2 times.
✗ Branch 429 not taken.
✗ Branch 430 not taken.
✓ Branch 431 taken 3 times.
✗ Branch 432 not taken.
✓ Branch 433 taken 1 times.
✓ Branch 434 taken 6 times.
✗ Branch 435 not taken.
✓ Branch 436 taken 29 times.
✓ Branch 437 taken 22 times.
✗ Branch 438 not taken.
✗ Branch 439 not taken.
✗ Branch 440 not taken.
✗ Branch 441 not taken.
✓ Branch 442 taken 163 times.
✗ Branch 443 not taken.
✓ Branch 444 taken 8 times.
✗ Branch 445 not taken.
✗ Branch 446 not taken.
✓ Branch 447 taken 1032 times.
✓ Branch 448 taken 258 times.
✗ Branch 449 not taken.
✓ Branch 450 taken 1032 times.
✗ Branch 451 not taken.
✗ Branch 452 not taken.
✓ Branch 453 taken 1032 times.
✓ Branch 454 taken 2 times.
✗ Branch 455 not taken.
✓ Branch 456 taken 5628 times.
✓ Branch 457 taken 8 times.
✗ Branch 458 not taken.
✗ Branch 459 not taken.
✓ Branch 460 taken 6 times.
✗ Branch 461 not taken.
✗ Branch 462 not taken.
✓ Branch 463 taken 2 times.
✗ Branch 464 not taken.
✗ Branch 465 not taken.
✓ Branch 466 taken 135 times.
✓ Branch 467 taken 2 times.
✓ Branch 468 taken 65 times.
✓ Branch 469 taken 2 times.
✗ Branch 470 not taken.
✓ Branch 471 taken 16 times.
✓ Branch 472 taken 4 times.
✗ Branch 473 not taken.
✗ Branch 474 not taken.
✗ Branch 475 not taken.
✗ Branch 476 not taken.
✗ Branch 477 not taken.
✗ Branch 478 not taken.
✗ Branch 479 not taken.
✗ Branch 480 not taken.
✗ Branch 481 not taken.
✗ Branch 482 not taken.
✗ Branch 483 not taken.
✗ Branch 484 not taken.
✗ Branch 485 not taken.
✓ Branch 486 taken 29 times.
✗ Branch 487 not taken.
✗ Branch 488 not taken.
✓ Branch 489 taken 10 times.
✗ Branch 490 not taken.
✗ Branch 491 not taken.
✗ Branch 492 not taken.
✗ Branch 493 not taken.
✗ Branch 494 not taken.
✓ Branch 495 taken 36 times.
✗ Branch 496 not taken.
✗ Branch 497 not taken.
✗ Branch 498 not taken.
✗ Branch 499 not taken.
✗ Branch 500 not taken.
✗ Branch 501 not taken.
✗ Branch 502 not taken.
✗ Branch 503 not taken.
✓ Branch 504 taken 36 times.
✗ Branch 505 not taken.
✗ Branch 506 not taken.
✓ Branch 507 taken 53 times.
✓ Branch 508 taken 2 times.
✗ Branch 509 not taken.
✓ Branch 510 taken 7 times.
✗ Branch 511 not taken.
✗ Branch 512 not taken.
✗ Branch 513 not taken.
✗ Branch 514 not taken.
✗ Branch 515 not taken.
✗ Branch 516 not taken.
✗ Branch 517 not taken.
✗ Branch 518 not taken.
✗ Branch 519 not taken.
✗ Branch 520 not taken.
✗ Branch 521 not taken.
✗ Branch 522 not taken.
✗ Branch 523 not taken.
✗ Branch 524 not taken.
✗ Branch 525 not taken.
✗ Branch 526 not taken.
✗ Branch 527 not taken.
✗ Branch 528 not taken.
✗ Branch 529 not taken.
✗ Branch 530 not taken.
✗ Branch 531 not taken.
✗ Branch 532 not taken.
✗ Branch 533 not taken.
✗ Branch 534 not taken.
✗ Branch 535 not taken.
✗ Branch 536 not taken.
✗ Branch 537 not taken.
✗ Branch 538 not taken.
✗ Branch 539 not taken.
✗ Branch 540 not taken.
✓ Branch 541 taken 13 times.
✗ Branch 542 not taken.
✗ Branch 543 not taken.
✗ Branch 544 not taken.
✗ Branch 545 not taken.
✗ Branch 546 not taken.
✗ Branch 547 not taken.
✗ Branch 548 not taken.
✗ Branch 549 not taken.
✓ Branch 550 taken 36 times.
✗ Branch 551 not taken.
✗ Branch 552 not taken.
✗ Branch 553 not taken.
✗ Branch 554 not taken.
✗ Branch 555 not taken.
✗ Branch 556 not taken.
✗ Branch 557 not taken.
✗ Branch 558 not taken.
✓ Branch 559 taken 54 times.
✗ Branch 560 not taken.
✗ Branch 561 not taken.
✓ Branch 562 taken 7195 times.
✗ Branch 563 not taken.
✓ Branch 564 taken 31 times.
✓ Branch 565 taken 7197 times.
✗ Branch 566 not taken.
✓ Branch 567 taken 71 times.
✗ Branch 568 not taken.
✗ Branch 569 not taken.
✗ Branch 570 not taken.
✗ Branch 571 not taken.
✗ Branch 572 not taken.
✗ Branch 573 not taken.
✗ Branch 574 not taken.
✗ Branch 575 not taken.
✗ Branch 576 not taken.
✗ Branch 577 not taken.
✗ Branch 578 not taken.
✓ Branch 579 taken 264 times.
✗ Branch 580 not taken.
✗ Branch 581 not taken.
✗ Branch 582 not taken.
✗ Branch 583 not taken.
✗ Branch 584 not taken.
✓ Branch 585 taken 18 times.
✗ Branch 586 not taken.
✗ Branch 587 not taken.
✓ Branch 588 taken 179 times.
✗ Branch 589 not taken.
✗ Branch 590 not taken.
✓ Branch 591 taken 30 times.
✗ Branch 592 not taken.
✗ Branch 593 not taken.
✗ Branch 594 not taken.
✗ Branch 595 not taken.
✓ Branch 596 taken 2 times.
✗ Branch 597 not taken.
✗ Branch 598 not taken.
✗ Branch 599 not taken.
✗ Branch 600 not taken.
✗ Branch 601 not taken.
✓ Branch 602 taken 53 times.
✓ Branch 603 taken 78 times.
✗ Branch 604 not taken.
✗ Branch 605 not taken.
✓ Branch 606 taken 161 times.
✗ Branch 607 not taken.
✗ Branch 608 not taken.
✓ Branch 609 taken 191 times.
✗ Branch 610 not taken.
✗ Branch 611 not taken.
✓ Branch 612 taken 18 times.
✗ Branch 613 not taken.
✗ Branch 614 not taken.
✗ Branch 615 not taken.
✗ Branch 616 not taken.
✗ Branch 617 not taken.
✓ Branch 618 taken 1 times.
✗ Branch 619 not taken.
✗ Branch 620 not taken.
✓ Branch 621 taken 276 times.
✗ Branch 622 not taken.
✗ Branch 623 not taken.
✓ Branch 624 taken 300 times.
✓ Branch 625 taken 6 times.
✗ Branch 626 not taken.
✗ Branch 627 not taken.
✗ Branch 628 not taken.
✗ Branch 629 not taken.
✗ Branch 630 not taken.
✗ Branch 631 not taken.
✗ Branch 632 not taken.
✗ Branch 633 not taken.
✗ Branch 634 not taken.
✗ Branch 635 not taken.
✗ Branch 636 not taken.
✗ Branch 637 not taken.
✗ Branch 638 not taken.
✗ Branch 639 not taken.
✗ Branch 640 not taken.
✗ Branch 641 not taken.
✗ Branch 642 not taken.
✗ Branch 643 not taken.
✗ Branch 644 not taken.
✗ Branch 645 not taken.
✓ Branch 646 taken 1 times.
✗ Branch 647 not taken.
✗ Branch 648 not taken.
✗ Branch 649 not taken.
✗ Branch 650 not taken.
✗ Branch 651 not taken.
✓ Branch 652 taken 27 times.
✗ Branch 653 not taken.
✓ Branch 654 taken 83 times.
✗ Branch 655 not taken.
✓ Branch 656 taken 27 times.
✗ Branch 657 not taken.
✗ Branch 658 not taken.
✓ Branch 659 taken 2839 times.
✗ Branch 660 not taken.
✗ Branch 661 not taken.
✓ Branch 662 taken 4362 times.
✗ Branch 663 not taken.
✗ Branch 664 not taken.
✗ Branch 665 not taken.
✗ Branch 666 not taken.
✗ Branch 667 not taken.
✗ Branch 668 not taken.
✗ Branch 669 not taken.
✗ Branch 670 not taken.
✗ Branch 671 not taken.
✗ Branch 672 not taken.
✗ Branch 673 not taken.
✗ Branch 674 not taken.
✗ Branch 675 not taken.
✗ Branch 676 not taken.
✗ Branch 677 not taken.
✗ Branch 678 not taken.
✗ Branch 679 not taken.
✗ Branch 680 not taken.
✗ Branch 681 not taken.
✗ Branch 682 not taken.
✓ Branch 683 taken 8 times.
✗ Branch 684 not taken.
✗ Branch 685 not taken.
✗ Branch 686 not taken.
✗ Branch 687 not taken.
✗ Branch 688 not taken.
✗ Branch 689 not taken.
✗ Branch 690 not taken.
✗ Branch 691 not taken.
✗ Branch 692 not taken.
✗ Branch 693 not taken.
✗ Branch 694 not taken.
✗ Branch 695 not taken.
✗ Branch 696 not taken.
✗ Branch 697 not taken.
✓ Branch 698 taken 3 times.
✗ Branch 699 not taken.
✗ Branch 700 not taken.
✓ Branch 701 taken 3 times.
✗ Branch 702 not taken.
✗ Branch 703 not taken.
✓ Branch 704 taken 3 times.
✗ Branch 705 not taken.
✗ Branch 706 not taken.
✓ Branch 707 taken 3 times.
✗ Branch 708 not taken.
✗ Branch 709 not taken.
✓ Branch 710 taken 2 times.
✗ Branch 711 not taken.
✓ Branch 712 taken 3 times.
✓ Branch 713 taken 2 times.
✗ Branch 714 not taken.
✗ Branch 715 not taken.
✗ Branch 716 not taken.
✗ Branch 717 not taken.
✗ Branch 718 not taken.
✗ Branch 719 not taken.
✗ Branch 720 not taken.
✗ Branch 721 not taken.
✗ Branch 722 not taken.
✗ Branch 723 not taken.
✗ Branch 724 not taken.
✗ Branch 725 not taken.
✗ Branch 726 not taken.
✗ Branch 727 not taken.
✗ Branch 728 not taken.
✗ Branch 729 not taken.
✗ Branch 730 not taken.
✗ Branch 731 not taken.
✗ Branch 732 not taken.
✗ Branch 733 not taken.
✗ Branch 734 not taken.
✗ Branch 735 not taken.
✗ Branch 736 not taken.
✗ Branch 737 not taken.
✗ Branch 738 not taken.
✗ Branch 739 not taken.
✗ Branch 740 not taken.
✗ Branch 741 not taken.
✗ Branch 742 not taken.
✗ Branch 743 not taken.
✗ Branch 744 not taken.
✗ Branch 745 not taken.
✗ Branch 746 not taken.
✗ Branch 747 not taken.
✗ Branch 748 not taken.
✗ Branch 749 not taken.
✗ Branch 750 not taken.
✗ Branch 751 not taken.
✗ Branch 752 not taken.
✗ Branch 753 not taken.
✗ Branch 754 not taken.
✗ Branch 755 not taken.
✗ Branch 756 not taken.
✗ Branch 757 not taken.
✗ Branch 758 not taken.
✗ Branch 759 not taken.
✗ Branch 760 not taken.
✗ Branch 761 not taken.
✗ Branch 762 not taken.
✗ Branch 763 not taken.
✗ Branch 764 not taken.
✗ Branch 765 not taken.
✗ Branch 766 not taken.
✗ Branch 767 not taken.
✗ Branch 768 not taken.
✗ Branch 769 not taken.
✗ Branch 770 not taken.
✗ Branch 771 not taken.
✗ Branch 772 not taken.
✗ Branch 773 not taken.
✗ Branch 774 not taken.
✗ Branch 775 not taken.
✗ Branch 776 not taken.
✗ Branch 777 not taken.
✗ Branch 778 not taken.
✗ Branch 779 not taken.
✗ Branch 780 not taken.
✗ Branch 781 not taken.
✗ Branch 782 not taken.
✗ Branch 783 not taken.
✗ Branch 784 not taken.
✗ Branch 785 not taken.
✗ Branch 786 not taken.
✗ Branch 787 not taken.
✗ Branch 788 not taken.
✗ Branch 789 not taken.
✗ Branch 790 not taken.
✗ Branch 791 not taken.
✗ Branch 792 not taken.
✓ Branch 793 taken 30 times.
✗ Branch 794 not taken.
✗ Branch 795 not taken.
✗ Branch 796 not taken.
✗ Branch 797 not taken.
✗ Branch 798 not taken.
✗ Branch 799 not taken.
✗ Branch 800 not taken.
✗ Branch 801 not taken.
✗ Branch 802 not taken.
✗ Branch 803 not taken.
✗ Branch 804 not taken.
✗ Branch 805 not taken.
✗ Branch 806 not taken.
✗ Branch 807 not taken.
✗ Branch 808 not taken.
✗ Branch 809 not taken.
✗ Branch 810 not taken.
✗ Branch 811 not taken.
✗ Branch 812 not taken.
✗ Branch 813 not taken.
✗ Branch 814 not taken.
✗ Branch 815 not taken.
✗ Branch 816 not taken.
✗ Branch 817 not taken.
✗ Branch 818 not taken.
✗ Branch 819 not taken.
✗ Branch 820 not taken.
✗ Branch 821 not taken.
✗ Branch 822 not taken.
✗ Branch 823 not taken.
✗ Branch 824 not taken.
✗ Branch 825 not taken.
✗ Branch 826 not taken.
✗ Branch 827 not taken.
✗ Branch 828 not taken.
✗ Branch 829 not taken.
✗ Branch 830 not taken.
✗ Branch 831 not taken.
✗ Branch 832 not taken.
✗ Branch 833 not taken.
✗ Branch 834 not taken.
✗ Branch 835 not taken.
✗ Branch 836 not taken.
✗ Branch 837 not taken.
✗ Branch 838 not taken.
✗ Branch 839 not taken.
✗ Branch 840 not taken.
✗ Branch 841 not taken.
✗ Branch 842 not taken.
✗ Branch 843 not taken.
✗ Branch 844 not taken.
✗ Branch 845 not taken.
✗ Branch 846 not taken.
✗ Branch 847 not taken.
✗ Branch 848 not taken.
✗ Branch 849 not taken.
✗ Branch 850 not taken.
✗ Branch 851 not taken.
✗ Branch 852 not taken.
✗ Branch 853 not taken.
✗ Branch 854 not taken.
✗ Branch 855 not taken.
✗ Branch 856 not taken.
✗ Branch 857 not taken.
✗ Branch 858 not taken.
✗ Branch 859 not taken.
✗ Branch 860 not taken.
✗ Branch 861 not taken.
✗ Branch 862 not taken.
✗ Branch 863 not taken.
✗ Branch 864 not taken.
✗ Branch 865 not taken.
✗ Branch 866 not taken.
✗ Branch 867 not taken.
✗ Branch 868 not taken.
✗ Branch 869 not taken.
✗ Branch 870 not taken.
✗ Branch 871 not taken.
✗ Branch 872 not taken.
✗ Branch 873 not taken.
✗ Branch 874 not taken.
✗ Branch 875 not taken.
✗ Branch 876 not taken.
✗ Branch 877 not taken.
✗ Branch 878 not taken.
✗ Branch 879 not taken.
✗ Branch 880 not taken.
✗ Branch 881 not taken.
✗ Branch 882 not taken.
✗ Branch 883 not taken.
✗ Branch 884 not taken.
✗ Branch 885 not taken.
✗ Branch 886 not taken.
✗ Branch 887 not taken.
✗ Branch 888 not taken.
✗ Branch 889 not taken.
✗ Branch 890 not taken.
✗ Branch 891 not taken.
✗ Branch 892 not taken.
✗ Branch 893 not taken.
✗ Branch 894 not taken.
✗ Branch 895 not taken.
✗ Branch 896 not taken.
✗ Branch 897 not taken.
✗ Branch 898 not taken.
✗ Branch 899 not taken.
✗ Branch 900 not taken.
✗ Branch 901 not taken.
✗ Branch 902 not taken.
✗ Branch 903 not taken.
✗ Branch 904 not taken.
✗ Branch 905 not taken.
✗ Branch 906 not taken.
✗ Branch 907 not taken.
✗ Branch 908 not taken.
✗ Branch 909 not taken.
✗ Branch 910 not taken.
✗ Branch 911 not taken.
✗ Branch 912 not taken.
✗ Branch 913 not taken.
✗ Branch 914 not taken.
✗ Branch 915 not taken.
✗ Branch 916 not taken.
✗ Branch 917 not taken.
✗ Branch 918 not taken.
✗ Branch 919 not taken.
✗ Branch 920 not taken.
✗ Branch 921 not taken.
✗ Branch 922 not taken.
✗ Branch 923 not taken.
✗ Branch 924 not taken.
✗ Branch 925 not taken.
✗ Branch 926 not taken.
✗ Branch 927 not taken.
✗ Branch 928 not taken.
✗ Branch 929 not taken.
✗ Branch 930 not taken.
✗ Branch 931 not taken.
✗ Branch 932 not taken.
✗ Branch 933 not taken.
✗ Branch 934 not taken.
✗ Branch 935 not taken.
✗ Branch 936 not taken.
✗ Branch 937 not taken.
✗ Branch 938 not taken.
✗ Branch 939 not taken.
✗ Branch 940 not taken.
✗ Branch 941 not taken.
✗ Branch 942 not taken.
✗ Branch 943 not taken.
✗ Branch 944 not taken.
✗ Branch 945 not taken.
✗ Branch 946 not taken.
✗ Branch 947 not taken.
✗ Branch 948 not taken.
✗ Branch 949 not taken.
✗ Branch 950 not taken.
✗ Branch 951 not taken.
✗ Branch 952 not taken.
✗ Branch 953 not taken.
✗ Branch 954 not taken.
✗ Branch 955 not taken.
✗ Branch 956 not taken.
✗ Branch 957 not taken.
✗ Branch 958 not taken.
✗ Branch 959 not taken.
✗ Branch 960 not taken.
✓ Branch 961 taken 213 times.
✗ Branch 962 not taken.
✗ Branch 963 not taken.
✗ Branch 964 not taken.
✗ Branch 965 not taken.
✗ Branch 966 not taken.
✓ Branch 967 taken 213 times.
✗ Branch 968 not taken.
✗ Branch 969 not taken.
✗ Branch 970 not taken.
✗ Branch 971 not taken.
✗ Branch 973 not taken.
✓ Branch 974 taken 310 times.
✗ Branch 976 not taken.
✗ Branch 977 not taken.
✗ Branch 978 not taken.
✗ Branch 979 not taken.
✗ Branch 980 not taken.
✗ Branch 982 not taken.
✓ Branch 983 taken 310 times.
✗ Branch 985 not taken.
✗ Branch 986 not taken.
✗ Branch 988 not taken.
✗ Branch 989 not taken.
✓ Branch 990 taken 335 times.
✗ Branch 991 not taken.
✗ Branch 992 not taken.
✗ Branch 993 not taken.
✗ Branch 994 not taken.
✗ Branch 995 not taken.
✗ Branch 996 not taken.
✗ Branch 997 not taken.
✗ Branch 998 not taken.
✗ Branch 999 not taken.
✓ Branch 1000 taken 17 times.
✗ Branch 1001 not taken.
✗ Branch 1002 not taken.
✓ Branch 1003 taken 213 times.
✗ Branch 1004 not taken.
✗ Branch 1006 not taken.
✗ Branch 1007 not taken.
✓ Branch 1008 taken 335 times.
✗ Branch 1009 not taken.
✗ Branch 1010 not taken.
✗ Branch 1011 not taken.
✗ Branch 1012 not taken.
✗ Branch 1013 not taken.
✗ Branch 1014 not taken.
✓ Branch 1015 taken 300 times.
✗ Branch 1016 not taken.
✗ Branch 1017 not taken.
✗ Branch 1018 not taken.
✗ Branch 1019 not taken.
✗ Branch 1020 not taken.
✗ Branch 1021 not taken.
✗ Branch 1022 not taken.
✗ Branch 1023 not taken.
✗ Branch 1024 not taken.
✗ Branch 1025 not taken.
✗ Branch 1026 not taken.
✗ Branch 1027 not taken.
✗ Branch 1028 not taken.
✗ Branch 1029 not taken.
✗ Branch 1030 not taken.
✗ Branch 1032 not taken.
✗ Branch 1033 not taken.
✗ Branch 1034 not taken.
✗ Branch 1035 not taken.
✗ Branch 1036 not taken.
✗ Branch 1037 not taken.
✗ Branch 1039 not taken.
✗ Branch 1040 not taken.
✗ Branch 1041 not taken.
✗ Branch 1042 not taken.
✓ Branch 1043 taken 68 times.
✗ Branch 1044 not taken.
✗ Branch 1045 not taken.
✗ Branch 1046 not taken.
✗ Branch 1047 not taken.
✗ Branch 1048 not taken.
✓ Branch 1049 taken 20 times.
✓ Branch 1050 taken 161 times.
✗ Branch 1051 not taken.
✓ Branch 1052 taken 310 times.
✗ Branch 1053 not taken.
✗ Branch 1056 not taken.
✓ Branch 1057 taken 300 times.
✗ Branch 1058 not taken.
✗ Branch 1059 not taken.
✗ Branch 1060 not taken.
✗ Branch 1061 not taken.
✗ Branch 1063 not taken.
✓ Branch 1064 taken 431 times.
✗ Branch 1066 not taken.
✓ Branch 1067 taken 129 times.
✗ Branch 1069 not taken.
✓ Branch 1070 taken 161 times.
✗ Branch 1072 not taken.
✓ Branch 1073 taken 180 times.
✗ Branch 1075 not taken.
✗ Branch 1076 not taken.
✗ Branch 1078 not taken.
✗ Branch 1079 not taken.
✗ Branch 1080 not taken.
✓ Branch 1081 taken 80 times.
✗ Branch 1082 not taken.
✗ Branch 1083 not taken.
✓ Branch 1084 taken 193 times.
✗ Branch 1085 not taken.
✗ Branch 1086 not taken.
✓ Branch 1087 taken 108 times.
✗ Branch 1088 not taken.
✗ Branch 1089 not taken.
✓ Branch 1090 taken 144 times.
✗ Branch 1091 not taken.
✓ Branch 1092 taken 104 times.
✓ Branch 1093 taken 180 times.
✗ Branch 1094 not taken.
✗ Branch 1095 not taken.
✓ Branch 1096 taken 120 times.
✗ Branch 1097 not taken.
✓ Branch 1098 taken 20 times.
✗ Branch 1099 not taken.
✗ Branch 1100 not taken.
✓ Branch 1101 taken 335 times.
✗ Branch 1103 not taken.
✓ Branch 1104 taken 90 times.
✗ Branch 1105 not taken.
✓ Branch 1106 taken 335 times.
✓ Branch 1107 taken 216 times.
✗ Branch 1108 not taken.
✗ Branch 1109 not taken.
✓ Branch 1110 taken 72 times.
✗ Branch 1112 not taken.
✓ Branch 1113 taken 411 times.
✗ Branch 1115 not taken.
✓ Branch 1116 taken 120 times.
✗ Branch 1118 not taken.
✓ Branch 1119 taken 180 times.
✗ Branch 1121 not taken.
✗ Branch 1122 not taken.
✗ Branch 1124 not taken.
✗ Branch 1125 not taken.
✗ Branch 1126 not taken.
✓ Branch 1127 taken 60 times.
✗ Branch 1128 not taken.
✗ Branch 1129 not taken.
✓ Branch 1130 taken 144 times.
✗ Branch 1131 not taken.
✗ Branch 1132 not taken.
✓ Branch 1133 taken 108 times.
✗ Branch 1134 not taken.
✗ Branch 1135 not taken.
✓ Branch 1136 taken 144 times.
✗ Branch 1137 not taken.
✗ Branch 1138 not taken.
✓ Branch 1139 taken 180 times.
✗ Branch 1140 not taken.
✓ Branch 1141 taken 114 times.
✓ Branch 1142 taken 80 times.
✗ Branch 1143 not taken.
✗ Branch 1144 not taken.
✗ Branch 1145 not taken.
✗ Branch 1146 not taken.
✓ Branch 1147 taken 20 times.
✗ Branch 1149 not taken.
✓ Branch 1150 taken 390 times.
✗ Branch 1152 not taken.
✓ Branch 1153 taken 216 times.
✗ Branch 1154 not taken.
✓ Branch 1155 taken 315 times.
✓ Branch 1156 taken 48 times.
✗ Branch 1157 not taken.
✗ Branch 1158 not taken.
✓ Branch 1159 taken 64 times.
✗ Branch 1161 not taken.
✓ Branch 1162 taken 400 times.
✗ Branch 1164 not taken.
✓ Branch 1165 taken 100 times.
✗ Branch 1167 not taken.
✗ Branch 1168 not taken.
✗ Branch 1170 not taken.
✗ Branch 1171 not taken.
✗ Branch 1172 not taken.
✓ Branch 1173 taken 40 times.
✗ Branch 1174 not taken.
✗ Branch 1175 not taken.
✓ Branch 1176 taken 96 times.
✗ Branch 1177 not taken.
✗ Branch 1178 not taken.
✓ Branch 1179 taken 60 times.
✗ Branch 1180 not taken.
✗ Branch 1181 not taken.
✓ Branch 1182 taken 80 times.
✗ Branch 1183 not taken.
✗ Branch 1184 not taken.
✓ Branch 1185 taken 100 times.
✗ Branch 1186 not taken.
✗ Branch 1187 not taken.
✓ Branch 1188 taken 120 times.
✗ Branch 1189 not taken.
✓ Branch 1190 taken 100 times.
✗ Branch 1191 not taken.
✗ Branch 1192 not taken.
✗ Branch 1193 not taken.
✗ Branch 1195 not taken.
✓ Branch 1196 taken 82 times.
✗ Branch 1198 not taken.
✓ Branch 1199 taken 455 times.
✗ Branch 1201 not taken.
✓ Branch 1202 taken 72 times.
✗ Branch 1203 not taken.
✓ Branch 1204 taken 320 times.
✓ Branch 1205 taken 96 times.
✗ Branch 1206 not taken.
✗ Branch 1207 not taken.
✓ Branch 1208 taken 120 times.
✗ Branch 1210 not taken.
✓ Branch 1211 taken 435 times.
✗ Branch 1213 not taken.
✗ Branch 1214 not taken.
✗ Branch 1216 not taken.
✗ Branch 1217 not taken.
✗ Branch 1218 not taken.
✓ Branch 1219 taken 60 times.
✗ Branch 1220 not taken.
✗ Branch 1221 not taken.
✓ Branch 1222 taken 144 times.
✗ Branch 1223 not taken.
✗ Branch 1224 not taken.
✓ Branch 1225 taken 60 times.
✗ Branch 1226 not taken.
✗ Branch 1227 not taken.
✓ Branch 1228 taken 80 times.
✗ Branch 1229 not taken.
✗ Branch 1230 not taken.
✓ Branch 1231 taken 100 times.
✗ Branch 1232 not taken.
✗ Branch 1233 not taken.
✓ Branch 1234 taken 220 times.
✗ Branch 1235 not taken.
✗ Branch 1236 not taken.
✗ Branch 1237 not taken.
✗ Branch 1238 not taken.
✓ Branch 1239 taken 102 times.
✗ Branch 1241 not taken.
✓ Branch 1242 taken 50 times.
✗ Branch 1244 not taken.
✓ Branch 1245 taken 138 times.
✗ Branch 1247 not taken.
✓ Branch 1248 taken 447 times.
✗ Branch 1250 not taken.
✓ Branch 1251 taken 176 times.
✗ Branch 1252 not taken.
✓ Branch 1253 taken 335 times.
✓ Branch 1254 taken 220 times.
✗ Branch 1255 not taken.
✗ Branch 1256 not taken.
✓ Branch 1257 taken 500 times.
✗ Branch 1259 not taken.
✓ Branch 1260 taken 355 times.
✗ Branch 1262 not taken.
✗ Branch 1263 not taken.
✗ Branch 1264 not taken.
✓ Branch 1265 taken 110 times.
✗ Branch 1266 not taken.
✗ Branch 1267 not taken.
✓ Branch 1268 taken 264 times.
✗ Branch 1269 not taken.
✗ Branch 1270 not taken.
✓ Branch 1271 taken 300 times.
✗ Branch 1272 not taken.
✗ Branch 1273 not taken.
✓ Branch 1274 taken 400 times.
✗ Branch 1275 not taken.
✗ Branch 1276 not taken.
✓ Branch 1277 taken 500 times.
✗ Branch 1278 not taken.
✗ Branch 1279 not taken.
✗ Branch 1280 not taken.
✗ Branch 1281 not taken.
✗ Branch 1282 not taken.
✗ Branch 1283 not taken.
✗ Branch 1284 not taken.
✗ Branch 1285 not taken.
✗ Branch 1287 not taken.
✓ Branch 1288 taken 358 times.
✗ Branch 1290 not taken.
✓ Branch 1291 taken 600 times.
✗ Branch 1293 not taken.
✓ Branch 1294 taken 18 times.
✗ Branch 1296 not taken.
✓ Branch 1297 taken 320 times.
✗ Branch 1299 not taken.
✗ Branch 1300 not taken.
✗ Branch 1301 not taken.
✓ Branch 1302 taken 355 times.
✗ Branch 1303 not taken.
✗ Branch 1304 not taken.
✗ Branch 1305 not taken.
✗ Branch 1306 not taken.
✗ Branch 1308 not taken.
✓ Branch 1309 taken 557 times.
✗ Branch 1310 not taken.
✗ Branch 1311 not taken.
✗ Branch 1312 not taken.
✗ Branch 1313 not taken.
✗ Branch 1314 not taken.
✗ Branch 1315 not taken.
✗ Branch 1316 not taken.
✗ Branch 1317 not taken.
✗ Branch 1318 not taken.
✗ Branch 1319 not taken.
✗ Branch 1320 not taken.
✗ Branch 1321 not taken.
✗ Branch 1322 not taken.
✗ Branch 1323 not taken.
✗ Branch 1324 not taken.
✗ Branch 1325 not taken.
✗ Branch 1326 not taken.
✗ Branch 1327 not taken.
✗ Branch 1328 not taken.
✗ Branch 1329 not taken.
✗ Branch 1330 not taken.
✗ Branch 1331 not taken.
✗ Branch 1333 not taken.
✗ Branch 1334 not taken.
✗ Branch 1336 not taken.
✓ Branch 1337 taken 110 times.
✗ Branch 1339 not taken.
✗ Branch 1340 not taken.
✗ Branch 1342 not taken.
✓ Branch 1343 taken 18 times.
✗ Branch 1345 not taken.
✓ Branch 1346 taken 335 times.
✗ Branch 1348 not taken.
✓ Branch 1349 taken 1540 times.
✗ Branch 1350 not taken.
✓ Branch 1351 taken 557 times.
✗ Branch 1352 not taken.
✗ Branch 1353 not taken.
✗ Branch 1354 not taken.
✗ Branch 1356 not taken.
✗ Branch 1357 not taken.
✓ Branch 1358 taken 640 times.
✗ Branch 1359 not taken.
✗ Branch 1360 not taken.
✗ Branch 1361 not taken.
✗ Branch 1362 not taken.
✓ Branch 1363 taken 924 times.
✗ Branch 1364 not taken.
✗ Branch 1365 not taken.
✓ Branch 1366 taken 1232 times.
✗ Branch 1367 not taken.
✗ Branch 1368 not taken.
✓ Branch 1369 taken 1540 times.
✗ Branch 1370 not taken.
✗ Branch 1371 not taken.
✗ Branch 1372 not taken.
✗ Branch 1373 not taken.
✗ Branch 1374 not taken.
✗ Branch 1375 not taken.
✗ Branch 1376 not taken.
✗ Branch 1377 not taken.
✗ Branch 1379 not taken.
✓ Branch 1380 taken 770 times.
✗ Branch 1382 not taken.
✓ Branch 1383 taken 1848 times.
✗ Branch 1385 not taken.
✓ Branch 1386 taken 116 times.
✗ Branch 1388 not taken.
✗ Branch 1389 not taken.
✗ Branch 1391 not taken.
✓ Branch 1392 taken 18 times.
✗ Branch 1394 not taken.
✓ Branch 1395 taken 1395 times.
✗ Branch 1397 not taken.
✗ Branch 1398 not taken.
✗ Branch 1399 not taken.
✓ Branch 1400 taken 640 times.
✗ Branch 1402 not taken.
✗ Branch 1403 not taken.
✗ Branch 1405 not taken.
✗ Branch 1406 not taken.
✓ Branch 1407 taken 235 times.
✗ Branch 1408 not taken.
✓ Branch 1409 taken 624 times.
✗ Branch 1410 not taken.
✗ Branch 1411 not taken.
✓ Branch 1412 taken 832 times.
✗ Branch 1413 not taken.
✗ Branch 1414 not taken.
✓ Branch 1415 taken 1040 times.
✗ Branch 1416 not taken.
✗ Branch 1417 not taken.
✓ Branch 1418 taken 100 times.
✗ Branch 1419 not taken.
✗ Branch 1420 not taken.
✗ Branch 1421 not taken.
✗ Branch 1422 not taken.
✗ Branch 1425 not taken.
✓ Branch 1426 taken 520 times.
✗ Branch 1428 not taken.
✓ Branch 1429 taken 1248 times.
✗ Branch 1431 not taken.
✓ Branch 1432 taken 60 times.
✗ Branch 1434 not taken.
✓ Branch 1435 taken 204 times.
✗ Branch 1437 not taken.
✓ Branch 1438 taken 100 times.
✗ Branch 1440 not taken.
✓ Branch 1441 taken 1219 times.
✗ Branch 1443 not taken.
✓ Branch 1444 taken 557 times.
✗ Branch 1448 not taken.
✓ Branch 1449 taken 285 times.
✗ Branch 1451 not taken.
✓ Branch 1452 taken 120 times.
✗ Branch 1454 not taken.
✓ Branch 1455 taken 720 times.
✓ Branch 1456 taken 235 times.
✗ Branch 1457 not taken.
✓ Branch 1458 taken 960 times.
✗ Branch 1459 not taken.
✗ Branch 1460 not taken.
✓ Branch 1461 taken 1200 times.
✗ Branch 1462 not taken.
✗ Branch 1463 not taken.
✓ Branch 1464 taken 2204 times.
✗ Branch 1465 not taken.
✗ Branch 1466 not taken.
✗ Branch 1467 not taken.
✗ Branch 1468 not taken.
✗ Branch 1469 not taken.
✓ Branch 1470 taken 600 times.
✗ Branch 1471 not taken.
✗ Branch 1472 not taken.
✓ Branch 1473 taken 1440 times.
✗ Branch 1474 not taken.
✗ Branch 1475 not taken.
✓ Branch 1476 taken 1320 times.
✗ Branch 1477 not taken.
✗ Branch 1478 not taken.
✓ Branch 1479 taken 1764 times.
✗ Branch 1480 not taken.
✗ Branch 1481 not taken.
✓ Branch 1482 taken 2204 times.
✗ Branch 1483 not taken.
✓ Branch 1484 taken 204 times.
✓ Branch 1485 taken 1100 times.
✗ Branch 1486 not taken.
✗ Branch 1487 not taken.
✓ Branch 1488 taken 2644 times.
✗ Branch 1489 not taken.
✓ Branch 1490 taken 18 times.
✗ Branch 1491 not taken.
✗ Branch 1492 not taken.
✓ Branch 1493 taken 640 times.
✗ Branch 1494 not taken.
✗ Branch 1495 not taken.
✗ Branch 1497 not taken.
✓ Branch 1498 taken 235 times.
✗ Branch 1500 not taken.
✗ Branch 1501 not taken.
✗ Branch 1503 not taken.
✓ Branch 1504 taken 16 times.
✓ Branch 1505 taken 235 times.
✗ Branch 1506 not taken.
✗ Branch 1507 not taken.
✗ Branch 1508 not taken.
✗ Branch 1509 not taken.
✗ Branch 1510 not taken.
✗ Branch 1511 not taken.
✗ Branch 1512 not taken.
✗ Branch 1513 not taken.
✗ Branch 1514 not taken.
✗ Branch 1516 not taken.
✓ Branch 1517 taken 8 times.
✗ Branch 1519 not taken.
✓ Branch 1520 taken 8 times.
✗ Branch 1523 not taken.
✗ Branch 1524 not taken.
✗ Branch 1526 not taken.
✗ Branch 1527 not taken.
✗ Branch 1529 not taken.
✗ Branch 1530 not taken.
✗ Branch 1532 not taken.
✓ Branch 1533 taken 238 times.
✗ Branch 1535 not taken.
✗ Branch 1536 not taken.
✗ Branch 1538 not taken.
✓ Branch 1539 taken 24 times.
✗ Branch 1541 not taken.
✓ Branch 1542 taken 235 times.
✗ Branch 1546 not taken.
✓ Branch 1547 taken 235 times.
✗ Branch 1549 not taken.
✗ Branch 1550 not taken.
✗ Branch 1553 not taken.
✓ Branch 1554 taken 2218 times.
✗ Branch 1556 not taken.
✗ Branch 1557 not taken.
✗ Branch 1559 not taken.
✗ Branch 1560 not taken.
✗ Branch 1562 not taken.
✗ Branch 1563 not taken.
✗ Branch 1565 not taken.
✗ Branch 1566 not taken.
✗ Branch 1568 not taken.
✗ Branch 1569 not taken.
✗ Branch 1572 not taken.
✗ Branch 1573 not taken.
✗ Branch 1575 not taken.
✗ Branch 1576 not taken.
✗ Branch 1578 not taken.
✗ Branch 1579 not taken.
✗ Branch 1581 not taken.
✓ Branch 1582 taken 70 times.
✗ Branch 1584 not taken.
✗ Branch 1585 not taken.
✗ Branch 1587 not taken.
✓ Branch 1588 taken 24 times.
✗ Branch 1590 not taken.
✓ Branch 1591 taken 235 times.
✗ Branch 1595 not taken.
✓ Branch 1596 taken 2218 times.
✗ Branch 1598 not taken.
✗ Branch 1599 not taken.
✗ Branch 1602 not taken.
✓ Branch 1603 taken 170 times.
✗ Branch 1605 not taken.
✗ Branch 1606 not taken.
✗ Branch 1608 not taken.
✗ Branch 1609 not taken.
✗ Branch 1611 not taken.
✗ Branch 1612 not taken.
✗ Branch 1614 not taken.
✗ Branch 1615 not taken.
✗ Branch 1617 not taken.
✗ Branch 1618 not taken.
✗ Branch 1621 not taken.
✗ Branch 1622 not taken.
✗ Branch 1624 not taken.
✗ Branch 1625 not taken.
✗ Branch 1627 not taken.
✗ Branch 1628 not taken.
✗ Branch 1630 not taken.
✓ Branch 1631 taken 70 times.
✗ Branch 1633 not taken.
✗ Branch 1634 not taken.
✗ Branch 1636 not taken.
✓ Branch 1637 taken 24 times.
✗ Branch 1639 not taken.
✓ Branch 1640 taken 235 times.
✗ Branch 1644 not taken.
✓ Branch 1645 taken 170 times.
✗ Branch 1647 not taken.
✗ Branch 1648 not taken.
✗ Branch 1651 not taken.
✓ Branch 1652 taken 1364 times.
✗ Branch 1654 not taken.
✗ Branch 1655 not taken.
✗ Branch 1657 not taken.
✗ Branch 1658 not taken.
✗ Branch 1660 not taken.
✗ Branch 1661 not taken.
✗ Branch 1663 not taken.
✗ Branch 1664 not taken.
✗ Branch 1666 not taken.
✗ Branch 1667 not taken.
✗ Branch 1670 not taken.
✗ Branch 1671 not taken.
✗ Branch 1673 not taken.
✗ Branch 1674 not taken.
✗ Branch 1676 not taken.
✗ Branch 1677 not taken.
✗ Branch 1679 not taken.
✓ Branch 1680 taken 70 times.
✗ Branch 1682 not taken.
✗ Branch 1683 not taken.
✗ Branch 1685 not taken.
✓ Branch 1686 taken 19 times.
✗ Branch 1688 not taken.
✓ Branch 1689 taken 2218 times.
✗ Branch 1693 not taken.
✓ Branch 1694 taken 1364 times.
✗ Branch 1696 not taken.
✗ Branch 1697 not taken.
✗ Branch 1700 not taken.
✓ Branch 1701 taken 465 times.
✗ Branch 1703 not taken.
✗ Branch 1704 not taken.
✗ Branch 1706 not taken.
✗ Branch 1707 not taken.
✗ Branch 1709 not taken.
✗ Branch 1710 not taken.
✗ Branch 1712 not taken.
✗ Branch 1713 not taken.
✗ Branch 1715 not taken.
✗ Branch 1716 not taken.
✗ Branch 1719 not taken.
✗ Branch 1720 not taken.
✗ Branch 1722 not taken.
✗ Branch 1723 not taken.
✗ Branch 1725 not taken.
✗ Branch 1726 not taken.
✗ Branch 1728 not taken.
✓ Branch 1729 taken 868 times.
✗ Branch 1731 not taken.
✗ Branch 1732 not taken.
✗ Branch 1734 not taken.
✓ Branch 1735 taken 16 times.
✗ Branch 1737 not taken.
✓ Branch 1738 taken 170 times.
✗ Branch 1742 not taken.
✓ Branch 1743 taken 465 times.
✗ Branch 1745 not taken.
✗ Branch 1746 not taken.
✗ Branch 1749 not taken.
✓ Branch 1750 taken 1381 times.
✗ Branch 1752 not taken.
✗ Branch 1753 not taken.
✗ Branch 1755 not taken.
✗ Branch 1756 not taken.
✗ Branch 1758 not taken.
✗ Branch 1759 not taken.
✗ Branch 1761 not taken.
✗ Branch 1762 not taken.
✗ Branch 1764 not taken.
✗ Branch 1765 not taken.
✗ Branch 1768 not taken.
✗ Branch 1769 not taken.
✗ Branch 1771 not taken.
✗ Branch 1772 not taken.
✗ Branch 1774 not taken.
✗ Branch 1775 not taken.
✗ Branch 1777 not taken.
✓ Branch 1778 taken 52 times.
✗ Branch 1780 not taken.
✗ Branch 1781 not taken.
✗ Branch 1783 not taken.
✓ Branch 1784 taken 35 times.
✗ Branch 1786 not taken.
✓ Branch 1787 taken 1364 times.
✗ Branch 1791 not taken.
✓ Branch 1792 taken 1370 times.
✗ Branch 1794 not taken.
✓ Branch 1795 taken 4 times.
✗ Branch 1798 not taken.
✓ Branch 1799 taken 1960 times.
✗ Branch 1801 not taken.
✗ Branch 1802 not taken.
✗ Branch 1804 not taken.
✗ Branch 1805 not taken.
✗ Branch 1807 not taken.
✗ Branch 1808 not taken.
✗ Branch 1810 not taken.
✗ Branch 1811 not taken.
✗ Branch 1813 not taken.
✗ Branch 1814 not taken.
✗ Branch 1817 not taken.
✗ Branch 1818 not taken.
✗ Branch 1820 not taken.
✗ Branch 1821 not taken.
✗ Branch 1823 not taken.
✗ Branch 1824 not taken.
✗ Branch 1826 not taken.
✓ Branch 1827 taken 510 times.
✗ Branch 1829 not taken.
✗ Branch 1830 not taken.
✗ Branch 1832 not taken.
✓ Branch 1833 taken 32 times.
✗ Branch 1835 not taken.
✓ Branch 1836 taken 465 times.
✗ Branch 1840 not taken.
✓ Branch 1841 taken 1960 times.
✗ Branch 1843 not taken.
✗ Branch 1844 not taken.
✗ Branch 1847 not taken.
✗ Branch 1848 not taken.
✗ Branch 1850 not taken.
✗ Branch 1851 not taken.
✗ Branch 1853 not taken.
✗ Branch 1854 not taken.
✗ Branch 1856 not taken.
✗ Branch 1857 not taken.
✗ Branch 1859 not taken.
✓ Branch 1860 taken 1 times.
✗ Branch 1863 not taken.
✗ Branch 1864 not taken.
✗ Branch 1866 not taken.
✗ Branch 1867 not taken.
✗ Branch 1869 not taken.
✓ Branch 1870 taken 154 times.
✗ Branch 1872 not taken.
✗ Branch 1873 not taken.
✗ Branch 1875 not taken.
✓ Branch 1876 taken 40 times.
✗ Branch 1878 not taken.
✓ Branch 1879 taken 1371 times.
✗ Branch 1883 not taken.
✓ Branch 1884 taken 1 times.
✗ Branch 1886 not taken.
✗ Branch 1887 not taken.
✗ Branch 1889 not taken.
✗ Branch 1890 not taken.
✗ Branch 1892 not taken.
✗ Branch 1893 not taken.
✗ Branch 1895 not taken.
✗ Branch 1896 not taken.
✗ Branch 1898 not taken.
✓ Branch 1899 taken 1 times.
✗ Branch 1901 not taken.
✗ Branch 1902 not taken.
✗ Branch 1904 not taken.
✓ Branch 1905 taken 511 times.
✗ Branch 1907 not taken.
✓ Branch 1908 taken 10 times.
✗ Branch 1910 not taken.
✓ Branch 1911 taken 56 times.
✗ Branch 1913 not taken.
✓ Branch 1914 taken 1960 times.
✗ Branch 1916 not taken.
✗ Branch 1917 not taken.
✗ Branch 1919 not taken.
✗ Branch 1920 not taken.
✗ Branch 1922 not taken.
✗ Branch 1923 not taken.
✗ Branch 1925 not taken.
✗ Branch 1926 not taken.
✗ Branch 1928 not taken.
✗ Branch 1929 not taken.
✗ Branch 1931 not taken.
✗ Branch 1932 not taken.
✗ Branch 1934 not taken.
✓ Branch 1935 taken 728 times.
✗ Branch 1937 not taken.
✗ Branch 1938 not taken.
910722 bool test() const { assert(mParentNode); return mIter != mParentNode->mTable.end(); }
228 operator bool() const { return this->test(); }
229
230
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 185530 times.
✓ Branch 2 taken 185529 times.
✓ Branch 3 taken 1 times.
742046 void increment() { if (this->test()) { ++mIter; } this->skip(); }
231 258196 bool next() { this->increment(); return this->test(); }
232 void increment(Index n) { for (Index i = 0; i < n && this->next(); ++i) {} }
233
234 /// @brief Return this iterator's position as an offset from
235 /// the beginning of the parent node's map.
236 122656 Index pos() const
237 {
238
1/2
✓ Branch 0 taken 61328 times.
✗ Branch 1 not taken.
122656 return !mParentNode ? 0U : Index(std::distance(mParentNode->mTable.begin(), mIter));
239 }
240
241 bool isValueOn() const { return RootNodeT::isTileOn(mIter); }
242 bool isValueOff() const { return RootNodeT::isTileOff(mIter); }
243 6 void setValueOn(bool on = true) const { mIter->second.tile.active = on; }
244 void setValueOff() const { mIter->second.tile.active = false; }
245
246 /// Return the coordinates of the item to which this iterator is pointing.
247
28/198
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 42 times.
✓ Branch 8 taken 5 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 666 times.
✓ Branch 11 taken 44 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 6 times.
✓ Branch 14 taken 9 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✓ Branch 30 taken 19 times.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✓ Branch 33 taken 19 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 1 times.
✓ Branch 36 taken 17 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 11 times.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✓ Branch 49 taken 2 times.
✓ Branch 50 taken 8 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 84 times.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✓ Branch 73 taken 1 times.
✗ Branch 74 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✓ Branch 100 taken 1 times.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 104 not taken.
✓ Branch 105 taken 11 times.
✗ Branch 106 not taken.
✓ Branch 108 taken 11 times.
✗ Branch 109 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✓ Branch 121 taken 1 times.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✗ Branch 143 not taken.
✗ Branch 144 not taken.
✗ Branch 146 not taken.
✗ Branch 147 not taken.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 153 not taken.
✗ Branch 154 not taken.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
✗ Branch 160 not taken.
✗ Branch 161 not taken.
✗ Branch 164 not taken.
✗ Branch 165 not taken.
✗ Branch 167 not taken.
✗ Branch 168 not taken.
✗ Branch 171 not taken.
✗ Branch 172 not taken.
✗ Branch 174 not taken.
✗ Branch 175 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✗ Branch 181 not taken.
✗ Branch 182 not taken.
✗ Branch 185 not taken.
✗ Branch 186 not taken.
✗ Branch 188 not taken.
✗ Branch 189 not taken.
✗ Branch 192 not taken.
✗ Branch 193 not taken.
✗ Branch 195 not taken.
✗ Branch 196 not taken.
✗ Branch 199 not taken.
✗ Branch 200 not taken.
✗ Branch 202 not taken.
✗ Branch 203 not taken.
✗ Branch 206 not taken.
✗ Branch 207 not taken.
✗ Branch 209 not taken.
✗ Branch 210 not taken.
✗ Branch 213 not taken.
✗ Branch 214 not taken.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✗ Branch 220 not taken.
✗ Branch 221 not taken.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✗ Branch 227 not taken.
✗ Branch 228 not taken.
✗ Branch 230 not taken.
✗ Branch 231 not taken.
✗ Branch 234 not taken.
✗ Branch 235 not taken.
✗ Branch 237 not taken.
✗ Branch 238 not taken.
✗ Branch 241 not taken.
✗ Branch 242 not taken.
✗ Branch 244 not taken.
✗ Branch 245 not taken.
✗ Branch 248 not taken.
✗ Branch 249 not taken.
✗ Branch 251 not taken.
✗ Branch 252 not taken.
✗ Branch 255 not taken.
✗ Branch 256 not taken.
✗ Branch 258 not taken.
✗ Branch 259 not taken.
✗ Branch 262 not taken.
✗ Branch 263 not taken.
✓ Branch 265 taken 5 times.
✗ Branch 266 not taken.
✗ Branch 269 not taken.
✗ Branch 270 not taken.
✗ Branch 272 not taken.
✗ Branch 273 not taken.
✗ Branch 275 not taken.
✗ Branch 276 not taken.
✗ Branch 278 not taken.
✗ Branch 279 not taken.
3458 Coord getCoord() const { return mIter->first; }
248 /// Return in @a xyz the coordinates of the item to which this iterator is pointing.
249
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
6 void getCoord(Coord& xyz) const { xyz = this->getCoord(); }
250
251 protected:
252 16085 BaseIter(): mParentNode(nullptr) {}
253 65384 BaseIter(RootNodeT& parent, const MapIterT& iter): mParentNode(&parent), mIter(iter) {}
254
255
4/4
✓ Branch 0 taken 126367 times.
✓ Branch 1 taken 164274 times.
✓ Branch 2 taken 7981 times.
✓ Branch 3 taken 82105 times.
1082992 void skip() { while (this->test() && !FilterPredT::test(mIter)) ++mIter; }
256
257 RootNodeT* mParentNode;
258 MapIterT mIter;
259 }; // BaseIter
260
261 template<typename RootNodeT, typename MapIterT, typename FilterPredT, typename ChildNodeT>
262 class ChildIter: public BaseIter<RootNodeT, MapIterT, FilterPredT>
263 {
264 public:
265 using BaseT = BaseIter<RootNodeT, MapIterT, FilterPredT>;
266 using NodeType = RootNodeT;
267 using ValueType = NodeType;
268 using ChildNodeType = ChildNodeT;
269 using NonConstNodeType = typename std::remove_const<NodeType>::type;
270 using NonConstValueType = typename std::remove_const<ValueType>::type;
271 using NonConstChildNodeType = typename std::remove_const<ChildNodeType>::type;
272 using BaseT::mIter;
273
274 ChildIter() {}
275 46343 ChildIter(RootNodeT& parent, const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
276
277 51690 ChildIter& operator++() { BaseT::increment(); return *this; }
278
279 ChildNodeT& getValue() const { return getChild(mIter); }
280 ChildNodeT& operator*() const { return this->getValue(); }
281 ChildNodeT* operator->() const { return &this->getValue(); }
282 }; // ChildIter
283
284 template<typename RootNodeT, typename MapIterT, typename FilterPredT, typename ValueT>
285 class ValueIter: public BaseIter<RootNodeT, MapIterT, FilterPredT>
286 {
287 public:
288 using BaseT = BaseIter<RootNodeT, MapIterT, FilterPredT>;
289 using NodeType = RootNodeT;
290 using ValueType = ValueT;
291 using NonConstNodeType = typename std::remove_const<NodeType>::type;
292 using NonConstValueType = typename std::remove_const<ValueT>::type;
293 using BaseT::mIter;
294
295 ValueIter() {}
296 19018 ValueIter(RootNodeT& parent, const MapIterT& iter): BaseT(parent, iter) { BaseT::skip(); }
297
298 4706 ValueIter& operator++() { BaseT::increment(); return *this; }
299
300
36/80
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 3 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 3 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 1 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 1 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 1 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 1 times.
✗ Branch 62 not taken.
✓ Branch 64 taken 1 times.
✗ Branch 65 not taken.
✓ Branch 67 taken 1 times.
✗ Branch 68 not taken.
✓ Branch 70 taken 1 times.
✗ Branch 71 not taken.
✓ Branch 73 taken 1 times.
✗ Branch 74 not taken.
✓ Branch 76 taken 1 times.
✗ Branch 77 not taken.
✓ Branch 79 taken 1 times.
✗ Branch 80 not taken.
✓ Branch 82 taken 1 times.
✗ Branch 83 not taken.
✓ Branch 85 taken 1 times.
✗ Branch 86 not taken.
✓ Branch 88 taken 1 times.
✗ Branch 89 not taken.
✓ Branch 91 taken 1 times.
✗ Branch 92 not taken.
✓ Branch 94 taken 1 times.
✗ Branch 95 not taken.
✓ Branch 97 taken 1 times.
✗ Branch 98 not taken.
✓ Branch 100 taken 1 times.
✗ Branch 101 not taken.
✓ Branch 103 taken 1 times.
✗ Branch 104 not taken.
✓ Branch 106 taken 1 times.
✗ Branch 107 not taken.
46 ValueT& getValue() const { return getTile(mIter).value; }
301 ValueT& operator*() const { return this->getValue(); }
302 ValueT* operator->() const { return &(this->getValue()); }
303
304 void setValue(const ValueT& v) const { assert(isTile(mIter)); getTile(mIter).value = v; }
305
306 template<typename ModifyOp>
307
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
6 void modifyValue(const ModifyOp& op) const
308 {
309
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
6 assert(isTile(mIter));
310 6 op(getTile(mIter).value);
311 6 }
312 }; // ValueIter
313
314 template<typename RootNodeT, typename MapIterT, typename ChildNodeT, typename ValueT>
315 class DenseIter: public BaseIter<RootNodeT, MapIterT, NullPred>
316 {
317 public:
318 using BaseT = BaseIter<RootNodeT, MapIterT, NullPred>;
319 using NodeType = RootNodeT;
320 using ValueType = ValueT;
321 using ChildNodeType = ChildNodeT;
322 using NonConstNodeType = typename std::remove_const<NodeType>::type;
323 using NonConstValueType = typename std::remove_const<ValueT>::type;
324 using NonConstChildNodeType = typename std::remove_const<ChildNodeT>::type;
325 using BaseT::mIter;
326
327 DenseIter() {}
328 DenseIter(RootNodeT& parent, const MapIterT& iter): BaseT(parent, iter) {}
329
330 27 DenseIter& operator++() { BaseT::increment(); return *this; }
331
332 bool isChildNode() const { return isChild(mIter); }
333
334 ChildNodeT* probeChild(NonConstValueType& value) const
335 {
336
27/48
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 2 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 2 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 2 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 1 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 2 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 3 times.
✓ Branch 41 taken 3 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 6 times.
✗ Branch 44 not taken.
✓ Branch 45 taken 3 times.
✓ Branch 46 taken 1 times.
✓ Branch 47 taken 2 times.
50 if (isChild(mIter)) return &getChild(mIter);
337 value = getTile(mIter).value;
338 4 return nullptr;
339 }
340 bool probeChild(ChildNodeT*& child, NonConstValueType& value) const
341 {
342 child = this->probeChild(value);
343 return child != nullptr;
344 }
345 bool probeValue(NonConstValueType& value) const { return !this->probeChild(value); }
346
347 void setChild(ChildNodeT& c) const { RootNodeT::setChild(mIter, c); }
348 void setChild(ChildNodeT* c) const { assert(c != nullptr); RootNodeT::setChild(mIter, *c); }
349 void setValue(const ValueT& v) const
350 {
351 if (isTile(mIter)) getTile(mIter).value = v;
352 /// @internal For consistency with iterators for other node types
353 /// (see, e.g., InternalNode::DenseIter::unsetItem()), we don't call
354 /// setTile() here, because that would also delete the child.
355 else stealChild(mIter, Tile(v, /*active=*/true));
356 }
357 }; // DenseIter
358
359 public:
360 using ChildOnIter = ChildIter<RootNode, MapIter, ChildOnPred, ChildType>;
361 using ChildOnCIter = ChildIter<const RootNode, MapCIter, ChildOnPred, const ChildType>;
362 using ChildOffIter = ValueIter<RootNode, MapIter, ChildOffPred, const ValueType>;
363 using ChildOffCIter = ValueIter<const RootNode, MapCIter, ChildOffPred, ValueType>;
364 using ChildAllIter = DenseIter<RootNode, MapIter, ChildType, ValueType>;
365 using ChildAllCIter = DenseIter<const RootNode, MapCIter, const ChildType, const ValueType>;
366
367 using ValueOnIter = ValueIter<RootNode, MapIter, ValueOnPred, ValueType>;
368 using ValueOnCIter = ValueIter<const RootNode, MapCIter, ValueOnPred, const ValueType>;
369 using ValueOffIter = ValueIter<RootNode, MapIter, ValueOffPred, ValueType>;
370 using ValueOffCIter = ValueIter<const RootNode, MapCIter, ValueOffPred, const ValueType>;
371 using ValueAllIter = ValueIter<RootNode, MapIter, ValueAllPred, ValueType>;
372 using ValueAllCIter = ValueIter<const RootNode, MapCIter, ValueAllPred, const ValueType>;
373
374
375 58612 ChildOnCIter cbeginChildOn() const { return ChildOnCIter(*this, mTable.begin()); }
376 ChildOffCIter cbeginChildOff() const { return ChildOffCIter(*this, mTable.begin()); }
377
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
12 ChildAllCIter cbeginChildAll() const { return ChildAllCIter(*this, mTable.begin()); }
378 14648 ChildOnCIter beginChildOn() const { return cbeginChildOn(); }
379 ChildOffCIter beginChildOff() const { return cbeginChildOff(); }
380 ChildAllCIter beginChildAll() const { return cbeginChildAll(); }
381 24214 ChildOnIter beginChildOn() { return ChildOnIter(*this, mTable.begin()); }
382 ChildOffIter beginChildOff() { return ChildOffIter(*this, mTable.begin()); }
383 11 ChildAllIter beginChildAll() { return ChildAllIter(*this, mTable.begin()); }
384
385 23126 ValueOnCIter cbeginValueOn() const { return ValueOnCIter(*this, mTable.begin()); }
386 200 ValueOffCIter cbeginValueOff() const { return ValueOffCIter(*this, mTable.begin()); }
387 631 ValueAllCIter cbeginValueAll() const { return ValueAllCIter(*this, mTable.begin()); }
388 ValueOnCIter beginValueOn() const { return cbeginValueOn(); }
389 ValueOffCIter beginValueOff() const { return cbeginValueOff(); }
390 ValueAllCIter beginValueAll() const { return cbeginValueAll(); }
391 9892 ValueOnIter beginValueOn() { return ValueOnIter(*this, mTable.begin()); }
392 241 ValueOffIter beginValueOff() { return ValueOffIter(*this, mTable.begin()); }
393 3296 ValueAllIter beginValueAll() { return ValueAllIter(*this, mTable.begin()); }
394
395 /// Return the total amount of memory in bytes occupied by this node and its children.
396 Index64 memUsage() const;
397
398 /// @brief Expand the specified bbox so it includes the active tiles of
399 /// this root node as well as all the active values in its child
400 /// nodes. If visitVoxels is false LeafNodes will be approximated
401 /// as dense, i.e. with all voxels active. Else the individual
402 /// active voxels are visited to produce a tight bbox.
403 void evalActiveBoundingBox(CoordBBox& bbox, bool visitVoxels = true) const;
404
405 /// Return the bounding box of this RootNode, i.e., an infinite bounding box.
406 3 static CoordBBox getNodeBoundingBox() { return CoordBBox::inf(); }
407
408 #if OPENVDB_ABI_VERSION_NUMBER >= 9
409 /// Return the transient data value.
410
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 Index32 transientData() const { return mTransientData; }
411 /// Set the transient data value.
412
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 void setTransientData(Index32 transientData) { mTransientData = transientData; }
413 #endif
414
415 /// @brief Change inactive tiles or voxels with a value equal to +/- the
416 /// old background to the specified value (with the same sign). Active values
417 /// are unchanged.
418 ///
419 /// @param value The new background value
420 /// @param updateChildNodes If true the background values of the
421 /// child nodes is also updated. Else only the background value
422 /// stored in the RootNode itself is changed.
423 ///
424 /// @note Instead of setting @a updateChildNodes to true, consider
425 /// using tools::changeBackground or
426 /// tools::changeLevelSetBackground which are multi-threaded!
427 void setBackground(const ValueType& value, bool updateChildNodes);
428
429 /// Return this node's background value.
430
141/264
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 301 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 23 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 2 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 2 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 4 times.
✓ Branch 37 taken 3 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 8275 times.
✓ Branch 40 taken 2 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 62 times.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✓ Branch 46 taken 1 times.
✓ Branch 47 taken 1 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 1 times.
✓ Branch 50 taken 1 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 1 times.
✓ Branch 53 taken 3 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 1 times.
✓ Branch 56 taken 1 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 10 times.
✓ Branch 59 taken 1 times.
✗ Branch 60 not taken.
✓ Branch 61 taken 7 times.
✓ Branch 62 taken 1 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 1 times.
✓ Branch 65 taken 1 times.
✗ Branch 66 not taken.
✓ Branch 67 taken 1 times.
✓ Branch 68 taken 1 times.
✗ Branch 69 not taken.
✓ Branch 70 taken 311085 times.
✓ Branch 71 taken 1 times.
✗ Branch 72 not taken.
✓ Branch 73 taken 1 times.
✓ Branch 74 taken 3 times.
✗ Branch 75 not taken.
✓ Branch 76 taken 1 times.
✓ Branch 77 taken 1 times.
✗ Branch 78 not taken.
✓ Branch 79 taken 296874 times.
✓ Branch 80 taken 1 times.
✗ Branch 81 not taken.
✓ Branch 82 taken 1 times.
✓ Branch 83 taken 1 times.
✗ Branch 84 not taken.
✓ Branch 85 taken 1 times.
✓ Branch 86 taken 1 times.
✗ Branch 87 not taken.
✓ Branch 88 taken 298507 times.
✓ Branch 89 taken 1 times.
✗ Branch 90 not taken.
✓ Branch 91 taken 1 times.
✓ Branch 92 taken 1 times.
✗ Branch 93 not taken.
✓ Branch 94 taken 298253 times.
✓ Branch 95 taken 1 times.
✗ Branch 96 not taken.
✓ Branch 97 taken 1 times.
✓ Branch 98 taken 1 times.
✗ Branch 99 not taken.
✓ Branch 100 taken 82438 times.
✓ Branch 101 taken 1 times.
✗ Branch 102 not taken.
✓ Branch 103 taken 1 times.
✓ Branch 104 taken 1 times.
✗ Branch 105 not taken.
✓ Branch 106 taken 298507 times.
✓ Branch 107 taken 3 times.
✗ Branch 108 not taken.
✓ Branch 109 taken 1 times.
✓ Branch 110 taken 1 times.
✗ Branch 111 not taken.
✓ Branch 112 taken 310442 times.
✓ Branch 113 taken 1 times.
✗ Branch 114 not taken.
✓ Branch 115 taken 1 times.
✓ Branch 116 taken 1 times.
✗ Branch 117 not taken.
✓ Branch 118 taken 310163 times.
✓ Branch 119 taken 1 times.
✗ Branch 120 not taken.
✓ Branch 121 taken 1 times.
✓ Branch 122 taken 1 times.
✗ Branch 123 not taken.
✓ Branch 124 taken 154199 times.
✓ Branch 125 taken 175 times.
✗ Branch 126 not taken.
✓ Branch 128 taken 1 times.
✗ Branch 129 not taken.
✓ Branch 131 taken 1 times.
✗ Branch 132 not taken.
✓ Branch 134 taken 1 times.
✗ Branch 135 not taken.
✓ Branch 137 taken 1 times.
✗ Branch 138 not taken.
✓ Branch 140 taken 1 times.
✗ Branch 141 not taken.
✓ Branch 143 taken 1 times.
✗ Branch 144 not taken.
✓ Branch 146 taken 1 times.
✗ Branch 147 not taken.
✓ Branch 149 taken 1 times.
✗ Branch 150 not taken.
✓ Branch 152 taken 1 times.
✗ Branch 153 not taken.
✓ Branch 155 taken 1 times.
✗ Branch 156 not taken.
✓ Branch 158 taken 1 times.
✗ Branch 159 not taken.
✓ Branch 161 taken 1 times.
✗ Branch 162 not taken.
✓ Branch 164 taken 1 times.
✗ Branch 165 not taken.
✓ Branch 167 taken 1 times.
✗ Branch 168 not taken.
✓ Branch 170 taken 1 times.
✗ Branch 171 not taken.
✓ Branch 173 taken 1 times.
✗ Branch 174 not taken.
✓ Branch 176 taken 1 times.
✗ Branch 177 not taken.
✓ Branch 179 taken 1 times.
✗ Branch 180 not taken.
✓ Branch 182 taken 1 times.
✗ Branch 183 not taken.
✓ Branch 185 taken 1 times.
✗ Branch 186 not taken.
✓ Branch 188 taken 1 times.
✗ Branch 189 not taken.
✓ Branch 191 taken 1 times.
✗ Branch 192 not taken.
✓ Branch 194 taken 1 times.
✗ Branch 195 not taken.
✓ Branch 197 taken 1 times.
✗ Branch 198 not taken.
✓ Branch 200 taken 1 times.
✗ Branch 201 not taken.
✓ Branch 203 taken 1 times.
✗ Branch 204 not taken.
✓ Branch 206 taken 1 times.
✗ Branch 207 not taken.
✓ Branch 209 taken 1 times.
✗ Branch 210 not taken.
✓ Branch 212 taken 1 times.
✗ Branch 213 not taken.
✓ Branch 215 taken 1 times.
✗ Branch 216 not taken.
✓ Branch 218 taken 1 times.
✗ Branch 219 not taken.
✓ Branch 221 taken 1 times.
✗ Branch 222 not taken.
✓ Branch 224 taken 1 times.
✗ Branch 225 not taken.
✓ Branch 227 taken 1 times.
✗ Branch 228 not taken.
✓ Branch 230 taken 1 times.
✗ Branch 231 not taken.
✓ Branch 233 taken 1 times.
✗ Branch 234 not taken.
✓ Branch 236 taken 1 times.
✗ Branch 237 not taken.
✓ Branch 239 taken 1 times.
✗ Branch 240 not taken.
✓ Branch 242 taken 1 times.
✗ Branch 243 not taken.
✓ Branch 245 taken 1 times.
✗ Branch 246 not taken.
✓ Branch 248 taken 1 times.
✗ Branch 249 not taken.
✓ Branch 251 taken 1 times.
✗ Branch 252 not taken.
✓ Branch 254 taken 1 times.
✗ Branch 255 not taken.
✓ Branch 257 taken 1 times.
✗ Branch 258 not taken.
✓ Branch 260 taken 1 times.
✗ Branch 261 not taken.
✓ Branch 263 taken 1 times.
✗ Branch 264 not taken.
✓ Branch 266 taken 1 times.
✗ Branch 267 not taken.
✓ Branch 269 taken 1 times.
✗ Branch 270 not taken.
✓ Branch 272 taken 1 times.
✗ Branch 273 not taken.
✓ Branch 275 taken 1 times.
✗ Branch 276 not taken.
✓ Branch 278 taken 1 times.
✗ Branch 279 not taken.
✓ Branch 281 taken 1 times.
✗ Branch 282 not taken.
✓ Branch 284 taken 1 times.
✗ Branch 285 not taken.
✓ Branch 287 taken 1 times.
✗ Branch 288 not taken.
✓ Branch 290 taken 1 times.
✗ Branch 291 not taken.
✓ Branch 293 taken 1 times.
✗ Branch 294 not taken.
✓ Branch 296 taken 1 times.
✗ Branch 297 not taken.
✓ Branch 301 taken 1 times.
✗ Branch 302 not taken.
✓ Branch 304 taken 1 times.
✗ Branch 305 not taken.
✓ Branch 307 taken 1 times.
✗ Branch 308 not taken.
✓ Branch 310 taken 1 times.
✗ Branch 311 not taken.
✓ Branch 313 taken 1 times.
✗ Branch 314 not taken.
✓ Branch 316 taken 1 times.
✗ Branch 317 not taken.
✓ Branch 319 taken 1 times.
✗ Branch 320 not taken.
✓ Branch 322 taken 1 times.
✗ Branch 323 not taken.
✓ Branch 325 taken 1 times.
✗ Branch 326 not taken.
✓ Branch 328 taken 1 times.
✗ Branch 329 not taken.
✓ Branch 331 taken 1 times.
✗ Branch 332 not taken.
✓ Branch 334 taken 1 times.
✗ Branch 335 not taken.
2988806 const ValueType& background() const { return mBackground; }
431
432 /// Return @c true if the given tile is inactive and has the background value.
433 bool isBackgroundTile(const Tile&) const;
434 //@{
435 /// Return @c true if the given iterator points to an inactive tile with the background value.
436 bool isBackgroundTile(const MapIter&) const;
437 bool isBackgroundTile(const MapCIter&) const;
438 //@}
439
440 /// Return the number of background tiles.
441 size_t numBackgroundTiles() const;
442 /// @brief Remove all background tiles.
443 /// @return the number of tiles removed.
444 size_t eraseBackgroundTiles();
445 inline void clear();
446
447 /// Return @c true if this node's table is either empty or contains only background tiles.
448
49/74
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 6 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 2 times.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 3 times.
✓ Branch 19 taken 1 times.
✓ Branch 20 taken 4 times.
✓ Branch 21 taken 2 times.
✓ Branch 22 taken 2 times.
✓ Branch 23 taken 2 times.
✓ Branch 24 taken 5 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 1 times.
✓ Branch 27 taken 3 times.
✓ Branch 28 taken 2 times.
✓ Branch 29 taken 1 times.
✓ Branch 30 taken 1 times.
✓ Branch 31 taken 1 times.
✓ Branch 32 taken 1 times.
✓ Branch 33 taken 2 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 2 times.
✓ Branch 37 taken 4 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 1 times.
✓ Branch 40 taken 4 times.
✓ Branch 41 taken 1 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 1 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 1 times.
✗ Branch 60 not taken.
✓ Branch 61 taken 1 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 1 times.
✗ Branch 66 not taken.
✓ Branch 67 taken 1 times.
✗ Branch 69 not taken.
✓ Branch 70 taken 1 times.
✗ Branch 84 not taken.
✓ Branch 85 taken 1 times.
✗ Branch 88 not taken.
✓ Branch 89 taken 1 times.
✗ Branch 95 not taken.
✓ Branch 96 taken 1 times.
✗ Branch 100 not taken.
✓ Branch 101 taken 1 times.
✗ Branch 103 not taken.
✓ Branch 104 taken 1 times.
✗ Branch 108 not taken.
✓ Branch 109 taken 1 times.
✗ Branch 111 not taken.
✓ Branch 112 taken 1 times.
✗ Branch 115 not taken.
✓ Branch 116 taken 1 times.
✗ Branch 118 not taken.
✓ Branch 119 taken 1 times.
✗ Branch 121 not taken.
✓ Branch 122 taken 1 times.
✗ Branch 124 not taken.
✓ Branch 125 taken 1 times.
856 bool empty() const { return mTable.size() == numBackgroundTiles(); }
449
450 /// @brief Expand this node's table so that (x, y, z) is included in the index range.
451 /// @return @c true if an expansion was performed (i.e., if (x, y, z) was not already
452 /// included in the index range).
453 bool expand(const Coord& xyz);
454
455 static Index getLevel() { return LEVEL; }
456 static void getNodeLog2Dims(std::vector<Index>& dims);
457 static Index getChildDim() { return ChildType::DIM; }
458
459 /// Return the number of entries in this node's table.
460
64/115
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 27 times.
✓ Branch 9 taken 20 times.
✓ Branch 10 taken 29 times.
✓ Branch 11 taken 20 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 45 times.
✓ Branch 17 taken 19 times.
✓ Branch 18 taken 50 times.
✓ Branch 19 taken 14 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 1 times.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 1 times.
✓ Branch 31 taken 1 times.
✓ Branch 32 taken 13 times.
✓ Branch 33 taken 3 times.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 1 times.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 1 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 1 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 1 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 1 times.
✗ Branch 62 not taken.
✓ Branch 64 taken 1 times.
✗ Branch 65 not taken.
✓ Branch 67 taken 1 times.
✗ Branch 68 not taken.
✓ Branch 70 taken 1 times.
✗ Branch 71 not taken.
✓ Branch 73 taken 1 times.
✗ Branch 74 not taken.
✓ Branch 76 taken 1 times.
✗ Branch 77 not taken.
✓ Branch 79 taken 1 times.
✗ Branch 80 not taken.
✓ Branch 82 taken 1 times.
✗ Branch 83 not taken.
✓ Branch 85 taken 1 times.
✗ Branch 86 not taken.
✓ Branch 88 taken 1 times.
✗ Branch 89 not taken.
✓ Branch 91 taken 1 times.
✗ Branch 92 not taken.
✓ Branch 94 taken 1 times.
✗ Branch 95 not taken.
✓ Branch 97 taken 1 times.
✗ Branch 98 not taken.
✓ Branch 100 taken 1 times.
✗ Branch 101 not taken.
✓ Branch 103 taken 1 times.
✗ Branch 104 not taken.
✓ Branch 106 taken 1 times.
✗ Branch 107 not taken.
✓ Branch 109 taken 1 times.
✗ Branch 110 not taken.
✓ Branch 112 taken 1 times.
✗ Branch 113 not taken.
✓ Branch 115 taken 1 times.
✗ Branch 116 not taken.
✓ Branch 118 taken 1 times.
✗ Branch 119 not taken.
✓ Branch 121 taken 1 times.
✗ Branch 122 not taken.
✓ Branch 124 taken 1 times.
✗ Branch 125 not taken.
✓ Branch 127 taken 1 times.
✗ Branch 128 not taken.
✓ Branch 130 taken 1 times.
✗ Branch 131 not taken.
✓ Branch 133 taken 1 times.
✗ Branch 134 not taken.
✓ Branch 136 taken 1 times.
✗ Branch 137 not taken.
✓ Branch 139 taken 1 times.
✗ Branch 140 not taken.
✓ Branch 142 taken 1 times.
✗ Branch 143 not taken.
✓ Branch 145 taken 1 times.
✗ Branch 146 not taken.
✓ Branch 148 taken 1 times.
✗ Branch 149 not taken.
✓ Branch 151 taken 1 times.
✗ Branch 152 not taken.
330 Index getTableSize() const { return static_cast<Index>(mTable.size()); }
461
462 Index getWidth() const { return this->getMaxIndex()[0] - this->getMinIndex()[0]; }
463 Index getHeight() const { return this->getMaxIndex()[1] - this->getMinIndex()[1]; }
464 Index getDepth() const { return this->getMaxIndex()[2] - this->getMinIndex()[2]; }
465
466 /// Return the smallest index of the current tree.
467 Coord getMinIndex() const;
468 /// Return the largest index of the current tree.
469 Coord getMaxIndex() const;
470 /// Return the current index range. Both min and max are inclusive.
471 void getIndexRange(CoordBBox& bbox) const;
472
473 /// @brief Return @c true if the given tree has the same node and active value
474 /// topology as this tree (but possibly a different @c ValueType).
475 template<typename OtherChildType>
476 bool hasSameTopology(const RootNode<OtherChildType>& other) const;
477
478 /// Return @c false if the other node's dimensions don't match this node's.
479 template<typename OtherChildType>
480 static bool hasSameConfiguration(const RootNode<OtherChildType>& other);
481
482 /// Return @c true if values of the other node's ValueType can be converted
483 /// to values of this node's ValueType.
484 template<typename OtherChildType>
485 static bool hasCompatibleValueType(const RootNode<OtherChildType>& other);
486
487 Index32 leafCount() const;
488 Index32 nonLeafCount() const;
489 Index32 childCount() const;
490 Index64 onVoxelCount() const;
491 Index64 offVoxelCount() const;
492 Index64 onLeafVoxelCount() const;
493 Index64 offLeafVoxelCount() const;
494 Index64 onTileCount() const;
495 void nodeCount(std::vector<Index32> &vec) const;
496
497 bool isValueOn(const Coord& xyz) const;
498
499 /// Return @c true if this root node, or any of its child nodes, have active tiles.
500 bool hasActiveTiles() const;
501
502 const ValueType& getValue(const Coord& xyz) const;
503 bool probeValue(const Coord& xyz, ValueType& value) const;
504
505 /// @brief Return the tree depth (0 = root) at which the value of voxel (x, y, z) resides.
506 /// @details If (x, y, z) isn't explicitly represented in the tree (i.e.,
507 /// it is implicitly a background voxel), return -1.
508 int getValueDepth(const Coord& xyz) const;
509
510 /// Set the active state of the voxel at the given coordinates but don't change its value.
511 void setActiveState(const Coord& xyz, bool on);
512 /// Set the value of the voxel at the given coordinates but don't change its active state.
513 void setValueOnly(const Coord& xyz, const ValueType& value);
514 /// Set the value of the voxel at the given coordinates and mark the voxel as active.
515 void setValueOn(const Coord& xyz, const ValueType& value);
516 /// Mark the voxel at the given coordinates as inactive but don't change its value.
517 void setValueOff(const Coord& xyz);
518 /// Set the value of the voxel at the given coordinates and mark the voxel as inactive.
519 void setValueOff(const Coord& xyz, const ValueType& value);
520
521 /// @brief Apply a functor to the value of the voxel at the given coordinates
522 /// and mark the voxel as active.
523 template<typename ModifyOp>
524 void modifyValue(const Coord& xyz, const ModifyOp& op);
525 /// Apply a functor to the voxel at the given coordinates.
526 template<typename ModifyOp>
527 void modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op);
528
529 //@{
530 /// @brief Set all voxels within a given axis-aligned box to a constant value.
531 /// @param bbox inclusive coordinates of opposite corners of an axis-aligned box
532 /// @param value the value to which to set voxels within the box
533 /// @param active if true, mark voxels within the box as active,
534 /// otherwise mark them as inactive
535 /// @note This operation generates a sparse, but not always optimally sparse,
536 /// representation of the filled box. Follow fill operations with a prune()
537 /// operation for optimal sparseness.
538 void fill(const CoordBBox& bbox, const ValueType& value, bool active = true);
539 void sparseFill(const CoordBBox& bbox, const ValueType& value, bool active = true)
540 {
541
55/93
✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 33 times.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 30 times.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 30 times.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 30 times.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 17 times.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 21 times.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 14 times.
✓ Branch 26 taken 1 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 7 times.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 7 times.
✓ Branch 32 taken 1 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 6 times.
✓ Branch 35 taken 1 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 5 times.
✓ Branch 38 taken 1 times.
✗ Branch 39 not taken.
✓ Branch 40 taken 4 times.
✓ Branch 41 taken 1 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 6 times.
✓ Branch 44 taken 1 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 6 times.
✓ Branch 47 taken 1 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 5 times.
✓ Branch 50 taken 1 times.
✗ Branch 51 not taken.
✓ Branch 52 taken 5 times.
✓ Branch 53 taken 1 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 3 times.
✓ Branch 56 taken 1 times.
✗ Branch 57 not taken.
✓ Branch 58 taken 3 times.
✓ Branch 59 taken 1 times.
✗ Branch 60 not taken.
✓ Branch 61 taken 2 times.
✓ Branch 62 taken 1 times.
✗ Branch 63 not taken.
✓ Branch 64 taken 2 times.
✗ Branch 65 not taken.
✓ Branch 67 taken 2 times.
✗ Branch 68 not taken.
✓ Branch 70 taken 2 times.
✗ Branch 71 not taken.
✓ Branch 73 taken 2 times.
✗ Branch 74 not taken.
✓ Branch 76 taken 2 times.
✗ Branch 77 not taken.
✓ Branch 79 taken 2 times.
✗ Branch 80 not taken.
✓ Branch 82 taken 2 times.
✗ Branch 83 not taken.
✓ Branch 85 taken 2 times.
✗ Branch 86 not taken.
✓ Branch 88 taken 2 times.
✗ Branch 89 not taken.
✓ Branch 91 taken 2 times.
✗ Branch 92 not taken.
✓ Branch 94 taken 2 times.
✗ Branch 95 not taken.
✓ Branch 97 taken 2 times.
✗ Branch 98 not taken.
✓ Branch 100 taken 1 times.
✗ Branch 101 not taken.
✓ Branch 103 taken 1 times.
✗ Branch 104 not taken.
✓ Branch 106 taken 1 times.
✗ Branch 107 not taken.
670 this->fill(bbox, value, active);
542 }
543 //@}
544
545 /// @brief Set all voxels within a given axis-aligned box to a constant value
546 /// and ensure that those voxels are all represented at the leaf level.
547 /// @param bbox inclusive coordinates of opposite corners of an axis-aligned box.
548 /// @param value the value to which to set voxels within the box.
549 /// @param active if true, mark voxels within the box as active,
550 /// otherwise mark them as inactive.
551 /// @sa voxelizeActiveTiles()
552 void denseFill(const CoordBBox& bbox, const ValueType& value, bool active = true);
553
554 /// @brief Densify active tiles, i.e., replace them with leaf-level active voxels.
555 ///
556 /// @param threaded if true, this operation is multi-threaded (over the internal nodes).
557 ///
558 /// @warning This method can explode the tree's memory footprint, especially if it
559 /// contains active tiles at the upper levels (in particular the root level)!
560 ///
561 /// @sa denseFill()
562 void voxelizeActiveTiles(bool threaded = true);
563
564 /// @brief Copy into a dense grid the values of all voxels, both active and inactive,
565 /// that intersect a given bounding box.
566 /// @param bbox inclusive bounding box of the voxels to be copied into the dense grid
567 /// @param dense dense grid with a stride in @e z of one (see tools::Dense
568 /// in tools/Dense.h for the required API)
569 template<typename DenseT>
570 void copyToDense(const CoordBBox& bbox, DenseT& dense) const;
571
572
573 //
574 // I/O
575 //
576 bool writeTopology(std::ostream&, bool toHalf = false) const;
577 bool readTopology(std::istream&, bool fromHalf = false);
578
579 void writeBuffers(std::ostream&, bool toHalf = false) const;
580 void readBuffers(std::istream&, bool fromHalf = false);
581 void readBuffers(std::istream&, const CoordBBox&, bool fromHalf = false);
582
583
584 //
585 // Voxel access
586 //
587 /// Return the value of the voxel at the given coordinates and, if necessary, update
588 /// the accessor with pointers to the nodes along the path from the root node to
589 /// the node containing the voxel.
590 /// @note Used internally by ValueAccessor.
591 template<typename AccessorT>
592 const ValueType& getValueAndCache(const Coord& xyz, AccessorT&) const;
593 /// Return @c true if the voxel at the given coordinates is active and, if necessary,
594 /// update the accessor with pointers to the nodes along the path from the root node
595 /// to the node containing the voxel.
596 /// @note Used internally by ValueAccessor.
597 template<typename AccessorT>
598 bool isValueOnAndCache(const Coord& xyz, AccessorT&) const;
599
600 /// Change the value of the voxel at the given coordinates and mark it as active.
601 /// If necessary, update the accessor with pointers to the nodes along the path
602 /// from the root node to the node containing the voxel.
603 /// @note Used internally by ValueAccessor.
604 template<typename AccessorT>
605 void setValueAndCache(const Coord& xyz, const ValueType& value, AccessorT&);
606
607 /// Set the value of the voxel at the given coordinates without changing its active state.
608 /// If necessary, update the accessor with pointers to the nodes along the path
609 /// from the root node to the node containing the voxel.
610 /// @note Used internally by ValueAccessor.
611 template<typename AccessorT>
612 void setValueOnlyAndCache(const Coord& xyz, const ValueType& value, AccessorT&);
613
614 /// Apply a functor to the value of the voxel at the given coordinates
615 /// and mark the voxel as active.
616 /// If necessary, update the accessor with pointers to the nodes along the path
617 /// from the root node to the node containing the voxel.
618 /// @note Used internally by ValueAccessor.
619 template<typename ModifyOp, typename AccessorT>
620 void modifyValueAndCache(const Coord& xyz, const ModifyOp& op, AccessorT&);
621
622 /// Apply a functor to the voxel at the given coordinates.
623 /// If necessary, update the accessor with pointers to the nodes along the path
624 /// from the root node to the node containing the voxel.
625 /// @note Used internally by ValueAccessor.
626 template<typename ModifyOp, typename AccessorT>
627 void modifyValueAndActiveStateAndCache(const Coord& xyz, const ModifyOp& op, AccessorT&);
628
629 /// Change the value of the voxel at the given coordinates and mark it as inactive.
630 /// If necessary, update the accessor with pointers to the nodes along the path
631 /// from the root node to the node containing the voxel.
632 /// @note Used internally by ValueAccessor.
633 template<typename AccessorT>
634 void setValueOffAndCache(const Coord& xyz, const ValueType& value, AccessorT&);
635
636 /// Set the active state of the voxel at the given coordinates without changing its value.
637 /// If necessary, update the accessor with pointers to the nodes along the path
638 /// from the root node to the node containing the voxel.
639 /// @note Used internally by ValueAccessor.
640 template<typename AccessorT>
641 void setActiveStateAndCache(const Coord& xyz, bool on, AccessorT&);
642
643 /// Return, in @a value, the value of the voxel at the given coordinates and,
644 /// if necessary, update the accessor with pointers to the nodes along
645 /// the path from the root node to the node containing the voxel.
646 /// @return @c true if the voxel at the given coordinates is active
647 /// @note Used internally by ValueAccessor.
648 template<typename AccessorT>
649 bool probeValueAndCache(const Coord& xyz, ValueType& value, AccessorT&) const;
650
651 /// Return the tree depth (0 = root) at which the value of voxel (x, y, z) resides.
652 /// If (x, y, z) isn't explicitly represented in the tree (i.e., it is implicitly
653 /// a background voxel), return -1. If necessary, update the accessor with pointers
654 /// to the nodes along the path from the root node to the node containing the voxel.
655 /// @note Used internally by ValueAccessor.
656 template<typename AccessorT>
657 int getValueDepthAndCache(const Coord& xyz, AccessorT&) const;
658
659 /// Set all voxels that lie outside the given axis-aligned box to the background.
660 void clip(const CoordBBox&);
661
662 /// @brief Reduce the memory footprint of this tree by replacing with tiles
663 /// any nodes whose values are all the same (optionally to within a tolerance)
664 /// and have the same active state.
665 ///
666 /// @note Consider instead using tools::prune which is multi-threaded!
667 4 void prune(const ValueType& tolerance = zeroVal<ValueType>());
668
669 /// @brief Add the given leaf node to this tree, creating a new branch if necessary.
670 /// If a leaf node with the same origin already exists, replace it.
671 void addLeaf(LeafNodeType* leaf);
672
673 /// @brief Same as addLeaf() but, if necessary, update the given accessor with pointers
674 /// to the nodes along the path from the root node to the node containing the coordinate.
675 template<typename AccessorT>
676 void addLeafAndCache(LeafNodeType* leaf, AccessorT&);
677
678 /// @brief Return a pointer to the node of type @c NodeT that contains voxel (x, y, z)
679 /// and replace it with a tile of the specified value and state.
680 /// If no such node exists, leave the tree unchanged and return @c nullptr.
681 ///
682 /// @note The caller takes ownership of the node and is responsible for deleting it.
683 ///
684 /// @warning Since this method potentially removes nodes and branches of the tree,
685 /// it is important to clear the caches of all ValueAccessors associated with this tree.
686 template<typename NodeT>
687 NodeT* stealNode(const Coord& xyz, const ValueType& value, bool state);
688
689 /// @brief Add the given child node at the root level.
690 /// If a child node with the same origin already exists, delete the old node and add
691 /// the new node in its place (i.e. ownership of the new child node is transferred
692 /// to this RootNode).
693 /// @return @c true (for consistency with InternalNode::addChild)
694 bool addChild(ChildType* child);
695
696 /// @brief Add a tile containing voxel (x, y, z) at the root level,
697 /// deleting the existing branch if necessary.
698 void addTile(const Coord& xyz, const ValueType& value, bool state);
699
700 /// @brief Add a tile containing voxel (x, y, z) at the specified tree level,
701 /// creating a new branch if necessary. Delete any existing lower-level nodes
702 /// that contain (x, y, z).
703 void addTile(Index level, const Coord& xyz, const ValueType& value, bool state);
704
705 /// @brief Same as addTile() but, if necessary, update the given accessor with pointers
706 /// to the nodes along the path from the root node to the node containing the coordinate.
707 template<typename AccessorT>
708 void addTileAndCache(Index level, const Coord& xyz, const ValueType&, bool state, AccessorT&);
709
710 /// @brief Return a pointer to the leaf node that contains voxel (x, y, z).
711 /// If no such node exists, create one that preserves the values and
712 /// active states of all voxels.
713 /// @details Use this method to preallocate a static tree topology
714 /// over which to safely perform multithreaded processing.
715 LeafNodeType* touchLeaf(const Coord& xyz);
716
717 /// @brief Same as touchLeaf() but, if necessary, update the given accessor with pointers
718 /// to the nodes along the path from the root node to the node containing the coordinate.
719 template<typename AccessorT>
720 LeafNodeType* touchLeafAndCache(const Coord& xyz, AccessorT& acc);
721
722 //@{
723 /// @brief Return a pointer to the node that contains voxel (x, y, z).
724 /// If no such node exists, return @c nullptr.
725 template <typename NodeT>
726 NodeT* probeNode(const Coord& xyz);
727 template <typename NodeT>
728 const NodeT* probeConstNode(const Coord& xyz) const;
729 //@}
730
731 //@{
732 /// @brief Same as probeNode() but, if necessary, update the given accessor with pointers
733 /// to the nodes along the path from the root node to the node containing the coordinate.
734 template<typename NodeT, typename AccessorT>
735 NodeT* probeNodeAndCache(const Coord& xyz, AccessorT& acc);
736 template<typename NodeT, typename AccessorT>
737 const NodeT* probeConstNodeAndCache(const Coord& xyz, AccessorT& acc) const;
738 //@}
739
740 //@{
741 /// @brief Return a pointer to the leaf node that contains voxel (x, y, z).
742 /// If no such node exists, return @c nullptr.
743 LeafNodeType* probeLeaf(const Coord& xyz);
744 const LeafNodeType* probeConstLeaf(const Coord& xyz) const;
745 const LeafNodeType* probeLeaf(const Coord& xyz) const;
746 //@}
747
748 //@{
749 /// @brief Same as probeLeaf() but, if necessary, update the given accessor with pointers
750 /// to the nodes along the path from the root node to the node containing the coordinate.
751 template<typename AccessorT>
752 LeafNodeType* probeLeafAndCache(const Coord& xyz, AccessorT& acc);
753 template<typename AccessorT>
754 const LeafNodeType* probeConstLeafAndCache(const Coord& xyz, AccessorT& acc) const;
755 template<typename AccessorT>
756 const LeafNodeType* probeLeafAndCache(const Coord& xyz, AccessorT& acc) const;
757 //@}
758
759
760 //
761 // Aux methods
762 //
763
764 //@{
765 /// @brief Adds all nodes of a certain type to a container with the following API:
766 /// @code
767 /// struct ArrayT {
768 /// using value_type = ...;// defines the type of nodes to be added to the array
769 /// void push_back(value_type nodePtr);// method that add nodes to the array
770 /// };
771 /// @endcode
772 /// @details An example of a wrapper around a c-style array is:
773 /// @code
774 /// struct MyArray {
775 /// using value_type = LeafType*;
776 /// value_type* ptr;
777 /// MyArray(value_type* array) : ptr(array) {}
778 /// void push_back(value_type leaf) { *ptr++ = leaf; }
779 ///};
780 /// @endcode
781 /// @details An example that constructs a list of pointer to all leaf nodes is:
782 /// @code
783 /// std::vector<const LeafNodeType*> array;//most std contains have the required API
784 /// array.reserve(tree.leafCount());//this is a fast preallocation.
785 /// tree.getNodes(array);
786 /// @endcode
787 template<typename ArrayT> void getNodes(ArrayT& array);
788 template<typename ArrayT> void getNodes(ArrayT& array) const;
789 //@}
790
791 //@{
792 /// @brief Steals all nodes of a certain type from the tree and
793 /// adds them to a container with the following API:
794 /// @code
795 /// struct ArrayT {
796 /// using value_type = ...;// defines the type of nodes to be added to the array
797 /// void push_back(value_type nodePtr);// method that add nodes to the array
798 /// };
799 /// @endcode
800 /// @details An example of a wrapper around a c-style array is:
801 /// @code
802 /// struct MyArray {
803 /// using value_type = LeafType*;
804 /// value_type* ptr;
805 /// MyArray(value_type* array) : ptr(array) {}
806 /// void push_back(value_type leaf) { *ptr++ = leaf; }
807 ///};
808 /// @endcode
809 /// @details An example that constructs a list of pointer to all leaf nodes is:
810 /// @code
811 /// std::vector<const LeafNodeType*> array;//most std contains have the required API
812 /// array.reserve(tree.leafCount());//this is a fast preallocation.
813 /// tree.stealNodes(array);
814 /// @endcode
815 template<typename ArrayT>
816 void stealNodes(ArrayT& array, const ValueType& value, bool state);
817 template<typename ArrayT>
818
38/92
✓ Branch 1 taken 43483 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 41039 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3975 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4039 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 5782 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 5708 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 497 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 6661 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 234 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 234 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 356 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 356 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 246 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 246 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 245 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 243 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 275 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 275 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 391 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 391 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 338 times.
✗ Branch 62 not taken.
✓ Branch 64 taken 338 times.
✗ Branch 65 not taken.
✓ Branch 67 taken 216 times.
✗ Branch 68 not taken.
✓ Branch 70 taken 216 times.
✗ Branch 71 not taken.
✓ Branch 73 taken 217 times.
✗ Branch 74 not taken.
✓ Branch 76 taken 217 times.
✗ Branch 77 not taken.
✓ Branch 79 taken 217 times.
✗ Branch 80 not taken.
✓ Branch 82 taken 217 times.
✗ Branch 83 not taken.
✓ Branch 85 taken 1 times.
✗ Branch 86 not taken.
✓ Branch 88 taken 1 times.
✗ Branch 89 not taken.
✓ Branch 91 taken 152 times.
✗ Branch 92 not taken.
✓ Branch 94 taken 152 times.
✗ Branch 95 not taken.
✓ Branch 97 taken 732 times.
✗ Branch 98 not taken.
✓ Branch 100 taken 732 times.
✗ Branch 101 not taken.
✓ Branch 103 taken 376 times.
✗ Branch 104 not taken.
✓ Branch 106 taken 376 times.
✗ Branch 107 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✓ Branch 115 taken 732 times.
✗ Branch 116 not taken.
✓ Branch 118 taken 732 times.
✗ Branch 119 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 124 not taken.
✗ Branch 125 not taken.
✗ Branch 127 not taken.
✗ Branch 128 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
120638 void stealNodes(ArrayT& array) { this->stealNodes(array, mBackground, false); }
819 //@}
820
821 /// @brief Efficiently merge another tree into this tree using one of several schemes.
822 /// @details This operation is primarily intended to combine trees that are mostly
823 /// non-overlapping (for example, intermediate trees from computations that are
824 /// parallelized across disjoint regions of space).
825 /// @note This operation is not guaranteed to produce an optimally sparse tree.
826 /// Follow merge() with prune() for optimal sparseness.
827 /// @warning This operation always empties the other tree.
828 template<MergePolicy Policy> void merge(RootNode& other);
829
830 /// @brief Union this tree's set of active values with the active values
831 /// of the other tree, whose @c ValueType may be different.
832 /// @details The resulting state of a value is active if the corresponding value
833 /// was already active OR if it is active in the other tree. Also, a resulting
834 /// value maps to a voxel if the corresponding value already mapped to a voxel
835 /// OR if it is a voxel in the other tree. Thus, a resulting value can only
836 /// map to a tile if the corresponding value already mapped to a tile
837 /// AND if it is a tile value in other tree.
838 ///
839 /// @note This operation modifies only active states, not values.
840 /// Specifically, active tiles and voxels in this tree are not changed, and
841 /// tiles or voxels that were inactive in this tree but active in the other tree
842 /// are marked as active in this tree but left with their original values.
843 ///
844 /// @note If preserveTiles is true, any active tile in this topology
845 /// will not be densified by overlapping child topology.
846 template<typename OtherChildType>
847 void topologyUnion(const RootNode<OtherChildType>& other, const bool preserveTiles = false);
848
849 /// @brief Intersects this tree's set of active values with the active values
850 /// of the other tree, whose @c ValueType may be different.
851 /// @details The resulting state of a value is active only if the corresponding
852 /// value was already active AND if it is active in the other tree. Also, a
853 /// resulting value maps to a voxel if the corresponding value
854 /// already mapped to an active voxel in either of the two grids
855 /// and it maps to an active tile or voxel in the other grid.
856 ///
857 /// @note This operation can delete branches in this grid if they
858 /// overlap with inactive tiles in the other grid. Likewise active
859 /// voxels can be turned into inactive voxels resulting in leaf
860 /// nodes with no active values. Thus, it is recommended to
861 /// subsequently call prune.
862 template<typename OtherChildType>
863 void topologyIntersection(const RootNode<OtherChildType>& other);
864
865 /// @brief Difference this tree's set of active values with the active values
866 /// of the other tree, whose @c ValueType may be different. So a
867 /// resulting voxel will be active only if the original voxel is
868 /// active in this tree and inactive in the other tree.
869 ///
870 /// @note This operation can delete branches in this grid if they
871 /// overlap with active tiles in the other grid. Likewise active
872 /// voxels can be turned into inactive voxels resulting in leaf
873 /// nodes with no active values. Thus, it is recommended to
874 /// subsequently call prune.
875 template<typename OtherChildType>
876 void topologyDifference(const RootNode<OtherChildType>& other);
877
878 template<typename CombineOp>
879 void combine(RootNode& other, CombineOp&, bool prune = false);
880
881 template<typename CombineOp, typename OtherRootNode /*= RootNode*/>
882 void combine2(const RootNode& other0, const OtherRootNode& other1,
883 CombineOp& op, bool prune = false);
884
885 /// @brief Call the templated functor BBoxOp with bounding box
886 /// information for all active tiles and leaf nodes in the tree.
887 /// An additional level argument is provided for each callback.
888 ///
889 /// @note The bounding boxes are guaranteed to be non-overlapping.
890 template<typename BBoxOp> void visitActiveBBox(BBoxOp&) const;
891
892 template<typename VisitorOp> void visit(VisitorOp&);
893 template<typename VisitorOp> void visit(VisitorOp&) const;
894
895 template<typename OtherRootNodeType, typename VisitorOp>
896 void visit2(OtherRootNodeType& other, VisitorOp&);
897 template<typename OtherRootNodeType, typename VisitorOp>
898 void visit2(OtherRootNodeType& other, VisitorOp&) const;
899
900 private:
901 /// During topology-only construction, access is needed
902 /// to protected/private members of other template instances.
903 template<typename> friend class RootNode;
904
905 template<typename, typename, bool> friend struct RootNodeCopyHelper;
906 template<typename, typename, typename, bool> friend struct RootNodeCombineHelper;
907
908 /// Currently no-op, but can be used to define empty and delete keys for mTable
909 void initTable() {}
910 //@{
911 /// @internal Used by doVisit2().
912 20 void resetTable(MapType& table) { mTable.swap(table); table.clear(); }
913 void resetTable(const MapType&) const {}
914 //@}
915
916 #if OPENVDB_ABI_VERSION_NUMBER < 8
917 Index getChildCount() const;
918 #endif
919 Index getTileCount() const;
920 Index getActiveTileCount() const;
921 Index getInactiveTileCount() const;
922
923 /// Return a MapType key for the given coordinates.
924 static Coord coordToKey(const Coord& xyz) { return xyz & ~(ChildType::DIM - 1); }
925
926 /// Insert this node's mTable keys into the given set.
927 void insertKeys(CoordSet&) const;
928
929 /// Return @c true if this node's mTable contains the given key.
930 bool hasKey(const Coord& key) const { return mTable.find(key) != mTable.end(); }
931 //@{
932 /// @brief Look up the given key in this node's mTable.
933 /// @return an iterator pointing to the matching mTable entry or to mTable.end().
934 MapIter findKey(const Coord& key) { return mTable.find(key); }
935 MapCIter findKey(const Coord& key) const { return mTable.find(key); }
936 //@}
937 //@{
938 /// @brief Convert the given coordinates to a key and look the key up in this node's mTable.
939 /// @return an iterator pointing to the matching mTable entry or to mTable.end().
940 27291209 MapIter findCoord(const Coord& xyz) { return mTable.find(coordToKey(xyz)); }
941 1569008321 MapCIter findCoord(const Coord& xyz) const { return mTable.find(coordToKey(xyz)); }
942 //@}
943 /// @brief Convert the given coordinates to a key and look the key up in this node's mTable.
944 /// @details If the key is not found, insert a background tile with that key.
945 /// @return an iterator pointing to the matching mTable entry.
946 MapIter findOrAddCoord(const Coord& xyz);
947
948 /// @brief Verify that the tree rooted at @a other has the same configuration
949 /// (levels, branching factors and node dimensions) as this tree, but allow
950 /// their ValueTypes to differ.
951 /// @throw TypeError if the other tree's configuration doesn't match this tree's.
952 template<typename OtherChildType>
953 static void enforceSameConfiguration(const RootNode<OtherChildType>& other);
954
955 /// @brief Verify that @a other has values of a type that can be converted
956 /// to this node's ValueType.
957 /// @details For example, values of type float are compatible with values of type Vec3s,
958 /// because a Vec3s can be constructed from a float. But the reverse is not true.
959 /// @throw TypeError if the other node's ValueType is not convertible into this node's.
960 template<typename OtherChildType>
961 static void enforceCompatibleValueTypes(const RootNode<OtherChildType>& other);
962
963 template<typename CombineOp, typename OtherRootNode /*= RootNode*/>
964 void doCombine2(const RootNode&, const OtherRootNode&, CombineOp&, bool prune);
965
966 template<typename RootNodeT, typename VisitorOp, typename ChildAllIterT>
967 static inline void doVisit(RootNodeT&, VisitorOp&);
968
969 template<typename RootNodeT, typename OtherRootNodeT, typename VisitorOp,
970 typename ChildAllIterT, typename OtherChildAllIterT>
971 static inline void doVisit2(RootNodeT&, OtherRootNodeT&, VisitorOp&);
972
973
974 MapType mTable;
975 ValueType mBackground;
976 #if OPENVDB_ABI_VERSION_NUMBER >= 9
977 /// Transient Data (not serialized)
978 Index32 mTransientData = 0;
979 #endif
980 }; // end of RootNode class
981
982
983 ////////////////////////////////////////
984
985
986 /// @brief NodeChain<RootNodeType, RootNodeType::LEVEL>::Type is a openvdb::TypeList
987 /// that lists the types of the nodes of the tree rooted at RootNodeType in reverse order,
988 /// from LeafNode to RootNode.
989 /// @details For example, if RootNodeType is
990 /// @code
991 /// RootNode<InternalNode<InternalNode<LeafNode> > >
992 /// @endcode
993 /// then NodeChain::Type is
994 /// @code
995 /// openvdb::TypeList<
996 /// LeafNode,
997 /// InternalNode<LeafNode>,
998 /// InternalNode<InternalNode<LeafNode> >,
999 /// RootNode<InternalNode<InternalNode<LeafNode> > > >
1000 /// @endcode
1001 ///
1002 /// @note Use the following to get the Nth node type, where N=0 is the LeafNodeType:
1003 /// @code
1004 /// NodeChainType::Get<N>;
1005 /// @endcode
1006 template<typename HeadT, int HeadLevel>
1007 struct NodeChain {
1008 using SubtreeT = typename NodeChain<typename HeadT::ChildNodeType, HeadLevel-1>::Type;
1009 using Type = typename SubtreeT::template Append<HeadT>;
1010 };
1011
1012 /// Specialization to terminate NodeChain
1013 template<typename HeadT>
1014 struct NodeChain<HeadT, /*HeadLevel=*/1> {
1015 using Type = TypeList<typename HeadT::ChildNodeType, HeadT>;
1016 };
1017
1018
1019 ////////////////////////////////////////
1020
1021
1022 //@{
1023 /// Helper metafunction used to implement RootNode::SameConfiguration
1024 /// (which, as an inner class, can't be independently specialized)
1025 template<typename ChildT1, typename NodeT2>
1026 struct SameRootConfig {
1027 static const bool value = false;
1028 };
1029
1030 template<typename ChildT1, typename ChildT2>
1031 struct SameRootConfig<ChildT1, RootNode<ChildT2> > {
1032 static const bool value = ChildT1::template SameConfiguration<ChildT2>::value;
1033 };
1034 //@}
1035
1036
1037 ////////////////////////////////////////
1038
1039
1040 template<typename ChildT>
1041 inline
1042
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
21857 RootNode<ChildT>::RootNode(): mBackground(zeroVal<ValueType>())
1043 {
1044 this->initTable();
1045 9 }
1046
1047
1048 template<typename ChildT>
1049 inline
1050
10/21
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 180 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 1 times.
✗ Branch 27 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
25214 RootNode<ChildT>::RootNode(const ValueType& background): mBackground(background)
1051 {
1052 this->initTable();
1053 181 }
1054
1055
1056 template<typename ChildT>
1057 template<typename OtherChildType>
1058 inline
1059 21 RootNode<ChildT>::RootNode(const RootNode<OtherChildType>& other,
1060 const ValueType& backgd, const ValueType& foregd, TopologyCopy)
1061 : mBackground(backgd)
1062 #if OPENVDB_ABI_VERSION_NUMBER >= 9
1063
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
21 , mTransientData(other.mTransientData)
1064 #endif
1065 {
1066 using OtherRootT = RootNode<OtherChildType>;
1067
1068
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
21 enforceSameConfiguration(other);
1069
1070 const Tile bgTile(backgd, /*active=*/false), fgTile(foregd, true);
1071 this->initTable();
1072
1073
2/2
✓ Branch 0 taken 82 times.
✓ Branch 1 taken 16 times.
131 for (typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
1074
2/4
✓ Branch 1 taken 82 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
120 mTable[i->first] = OtherRootT::isTile(i)
1075
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 76 times.
200 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
1076
2/4
✓ Branch 1 taken 82 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 82 times.
✗ Branch 5 not taken.
110 : NodeStruct(*(new ChildT(OtherRootT::getChild(i), backgd, foregd, TopologyCopy())));
1077 }
1078 21 }
1079
1080
1081 template<typename ChildT>
1082 template<typename OtherChildType>
1083 inline
1084 3583 RootNode<ChildT>::RootNode(const RootNode<OtherChildType>& other,
1085 const ValueType& backgd, TopologyCopy)
1086 : mBackground(backgd)
1087 #if OPENVDB_ABI_VERSION_NUMBER >= 9
1088
1/2
✓ Branch 1 taken 2359 times.
✗ Branch 2 not taken.
3583 , mTransientData(other.mTransientData)
1089 #endif
1090 {
1091 using OtherRootT = RootNode<OtherChildType>;
1092
1093
1/2
✓ Branch 1 taken 2359 times.
✗ Branch 2 not taken.
3583 enforceSameConfiguration(other);
1094
1095 const Tile bgTile(backgd, /*active=*/false), fgTile(backgd, true);
1096 this->initTable();
1097
2/2
✓ Branch 0 taken 4529 times.
✓ Branch 1 taken 2359 times.
10671 for (typename OtherRootT::MapCIter i=other.mTable.begin(), e=other.mTable.end(); i != e; ++i) {
1098
2/4
✓ Branch 1 taken 4529 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 426 times.
7876 mTable[i->first] = OtherRootT::isTile(i)
1099
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4103 times.
12600 ? NodeStruct(OtherRootT::isTileOn(i) ? fgTile : bgTile)
1100
2/4
✓ Branch 1 taken 4529 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4529 times.
✗ Branch 5 not taken.
7088 : NodeStruct(*(new ChildT(OtherRootT::getChild(i), backgd, TopologyCopy())));
1101 }
1102 3583 }
1103
1104
1105 ////////////////////////////////////////
1106
1107
1108 // This helper class is a friend of RootNode and is needed so that assignment
1109 // with value conversion can be specialized for compatible and incompatible
1110 // pairs of RootNode types.
1111 template<typename RootT, typename OtherRootT, bool Compatible = false>
1112 struct RootNodeCopyHelper
1113 {
1114 4 static inline void copyWithValueConversion(RootT& self, const OtherRootT& other)
1115 {
1116 // If the two root nodes have different configurations or incompatible ValueTypes,
1117 // throw an exception.
1118 4 self.enforceSameConfiguration(other);
1119 2 self.enforceCompatibleValueTypes(other);
1120 // One of the above two tests should throw, so we should never get here:
1121 std::ostringstream ostr;
1122 ostr << "cannot convert a " << typeid(OtherRootT).name()
1123 << " to a " << typeid(RootT).name();
1124 OPENVDB_THROW(TypeError, ostr.str());
1125 }
1126 };
1127
1128 // Specialization for root nodes of compatible types
1129 template<typename RootT, typename OtherRootT>
1130 struct RootNodeCopyHelper<RootT, OtherRootT, /*Compatible=*/true>
1131 {
1132 748 static inline void copyWithValueConversion(RootT& self, const OtherRootT& other)
1133 {
1134 using ValueT = typename RootT::ValueType;
1135 using ChildT = typename RootT::ChildNodeType;
1136 using NodeStruct = typename RootT::NodeStruct;
1137 using Tile = typename RootT::Tile;
1138 using OtherValueT = typename OtherRootT::ValueType;
1139 using OtherMapCIter = typename OtherRootT::MapCIter;
1140 using OtherTile = typename OtherRootT::Tile;
1141
1142 struct Local {
1143 /// @todo Consider using a value conversion functor passed as an argument instead.
1144 748 static inline ValueT convertValue(const OtherValueT& val) { return ValueT(val); }
1145 };
1146
1147 748 self.mBackground = Local::convertValue(other.mBackground);
1148 #if OPENVDB_ABI_VERSION_NUMBER >= 9
1149 748 self.mTransientData = other.mTransientData;
1150 #endif
1151
1152 748 self.clear();
1153 self.initTable();
1154
1155
2/2
✓ Branch 0 taken 1040 times.
✓ Branch 1 taken 742 times.
1818 for (OtherMapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
1156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1040 times.
1070 if (other.isTile(i)) {
1157 // Copy the other node's tile, but convert its value to this node's ValueType.
1158 const OtherTile& otherTile = other.getTile(i);
1159 self.mTable[i->first] = NodeStruct(
1160 Tile(Local::convertValue(otherTile.value), otherTile.active));
1161 } else {
1162 // Copy the other node's child, but convert its values to this node's ValueType.
1163
1/2
✓ Branch 2 taken 1040 times.
✗ Branch 3 not taken.
1070 self.mTable[i->first] = NodeStruct(*(new ChildT(other.getChild(i))));
1164 }
1165 }
1166 748 }
1167 };
1168
1169
1170 // Overload for root nodes of the same type as this node
1171 template<typename ChildT>
1172 inline RootNode<ChildT>&
1173 4562 RootNode<ChildT>::operator=(const RootNode& other)
1174 {
1175
1/2
✓ Branch 0 taken 2281 times.
✗ Branch 1 not taken.
4562 if (&other != this) {
1176 4562 mBackground = other.mBackground;
1177 #if OPENVDB_ABI_VERSION_NUMBER >= 9
1178 4562 mTransientData = other.mTransientData;
1179 #endif
1180
1181 4562 this->clear();
1182 this->initTable();
1183
1184
2/2
✓ Branch 0 taken 2340 times.
✓ Branch 1 taken 2281 times.
9242 for (MapCIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
1185
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 2052 times.
8784 mTable[i->first] =
1186
2/5
✗ Branch 0 not taken.
✓ Branch 1 taken 2339 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2339 times.
✗ Branch 5 not taken.
5252 isTile(i) ? NodeStruct(getTile(i)) : NodeStruct(*(new ChildT(getChild(i))));
1187 }
1188 }
1189 4562 return *this;
1190 }
1191
1192 // Overload for root nodes of different types
1193 template<typename ChildT>
1194 template<typename OtherChildType>
1195 inline RootNode<ChildT>&
1196 RootNode<ChildT>::operator=(const RootNode<OtherChildType>& other)
1197 {
1198 using OtherRootT = RootNode<OtherChildType>;
1199 using OtherValueT = typename OtherRootT::ValueType;
1200 static const bool compatible = (SameConfiguration<OtherRootT>::value
1201 && CanConvertType</*from=*/OtherValueT, /*to=*/ValueType>::value);
1202
4/9
✓ Branch 1 taken 739 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
744 RootNodeCopyHelper<RootNode, OtherRootT, compatible>::copyWithValueConversion(*this, other);
1203 return *this;
1204 }
1205
1206
1207 ////////////////////////////////////////
1208
1209 template<typename ChildT>
1210 inline void
1211
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 209 times.
462 RootNode<ChildT>::setBackground(const ValueType& background, bool updateChildNodes)
1212 {
1213
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 209 times.
430 if (math::isExactlyEqual(background, mBackground)) return;
1214
1215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if (updateChildNodes) {
1216 // Traverse the tree, replacing occurrences of mBackground with background
1217 // and -mBackground with -background.
1218 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1219 ChildT *child = iter->second.child;
1220 if (child) {
1221 child->resetBackground(/*old=*/mBackground, /*new=*/background);
1222 } else {
1223 Tile& tile = getTile(iter);
1224 if (tile.active) continue;//only change inactive tiles
1225 if (math::isApproxEqual(tile.value, mBackground)) {
1226 tile.value = background;
1227 } else if (math::isApproxEqual(tile.value, math::negative(mBackground))) {
1228 tile.value = math::negative(background);
1229 }
1230 }
1231 }
1232 }
1233 59 mBackground = background;
1234 }
1235
1236 template<typename ChildT>
1237 inline bool
1238 RootNode<ChildT>::isBackgroundTile(const Tile& tile) const
1239 {
1240 return !tile.active && math::isApproxEqual(tile.value, mBackground);
1241 }
1242
1243 template<typename ChildT>
1244 inline bool
1245 RootNode<ChildT>::isBackgroundTile(const MapIter& iter) const
1246 {
1247 return isTileOff(iter) && math::isApproxEqual(getTile(iter).value, mBackground);
1248 }
1249
1250 template<typename ChildT>
1251 inline bool
1252
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1425 times.
2539 RootNode<ChildT>::isBackgroundTile(const MapCIter& iter) const
1253 {
1254
8/38
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 27 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1343 times.
✓ Branch 13 taken 68 times.
✓ Branch 14 taken 210 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 9 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 2 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
1681 return isTileOff(iter) && math::isApproxEqual(getTile(iter).value, mBackground);
1255 }
1256
1257
1258 template<typename ChildT>
1259 inline size_t
1260 1707 RootNode<ChildT>::numBackgroundTiles() const
1261 {
1262 size_t count = 0;
1263
2/2
✓ Branch 0 taken 1898 times.
✓ Branch 1 taken 856 times.
5500 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1264
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 291 times.
✗ Branch 2 not taken.
586 if (this->isBackgroundTile(i)) ++count;
1265 }
1266 1707 return count;
1267 }
1268
1269
1270 template<typename ChildT>
1271 inline size_t
1272 7248 RootNode<ChildT>::eraseBackgroundTiles()
1273 {
1274 std::set<Coord> keysToErase;
1275
2/2
✓ Branch 0 taken 9281 times.
✓ Branch 1 taken 5241 times.
22573 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1276
3/6
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1893 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3793 if (this->isBackgroundTile(i)) keysToErase.insert(i->first);
1277 }
1278
2/2
✓ Branch 0 taken 1607 times.
✓ Branch 1 taken 5241 times.
10461 for (std::set<Coord>::iterator i = keysToErase.begin(), e = keysToErase.end(); i != e; ++i) {
1279 mTable.erase(*i);
1280 }
1281 7248 return keysToErase.size();
1282 }
1283
1284
1285 ////////////////////////////////////////
1286
1287
1288 template<typename ChildT>
1289 inline void
1290 176 RootNode<ChildT>::insertKeys(CoordSet& keys) const
1291 {
1292
2/2
✓ Branch 0 taken 99 times.
✓ Branch 1 taken 92 times.
361 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1293 185 keys.insert(i->first);
1294 }
1295 176 }
1296
1297
1298 template<typename ChildT>
1299 inline typename RootNode<ChildT>::MapIter
1300 6847 RootNode<ChildT>::findOrAddCoord(const Coord& xyz)
1301 {
1302 6847 const Coord key = coordToKey(xyz);
1303 6847 std::pair<MapIter, bool> result = mTable.insert(
1304 typename MapType::value_type(key, NodeStruct(Tile(mBackground, /*active=*/false))));
1305 6847 return result.first;
1306 }
1307
1308
1309 template<typename ChildT>
1310 inline bool
1311 RootNode<ChildT>::expand(const Coord& xyz)
1312 {
1313 const Coord key = coordToKey(xyz);
1314 std::pair<MapIter, bool> result = mTable.insert(
1315 typename MapType::value_type(key, NodeStruct(Tile(mBackground, /*active=*/false))));
1316 return result.second; // return true if the key did not already exist
1317 }
1318
1319
1320 ////////////////////////////////////////
1321
1322
1323 template<typename ChildT>
1324 inline void
1325 RootNode<ChildT>::getNodeLog2Dims(std::vector<Index>& dims)
1326 {
1327
121/228
✓ Branch 2 taken 91 times.
✓ Branch 3 taken 134 times.
✓ Branch 4 taken 3626 times.
✓ Branch 5 taken 382 times.
✓ Branch 6 taken 134 times.
✓ Branch 7 taken 3626 times.
✓ Branch 8 taken 341 times.
✓ Branch 9 taken 11 times.
✓ Branch 10 taken 19 times.
✓ Branch 11 taken 329 times.
✓ Branch 12 taken 12 times.
✓ Branch 13 taken 19 times.
✓ Branch 14 taken 285 times.
✓ Branch 15 taken 139 times.
✓ Branch 16 taken 19 times.
✓ Branch 17 taken 2584 times.
✓ Branch 18 taken 154 times.
✓ Branch 19 taken 19 times.
✓ Branch 20 taken 2588 times.
✓ Branch 21 taken 102 times.
✓ Branch 22 taken 10 times.
✓ Branch 23 taken 269 times.
✓ Branch 24 taken 94 times.
✓ Branch 25 taken 10 times.
✓ Branch 26 taken 280 times.
✓ Branch 27 taken 8 times.
✓ Branch 28 taken 142 times.
✓ Branch 29 taken 1516 times.
✓ Branch 30 taken 3 times.
✓ Branch 31 taken 142 times.
✓ Branch 32 taken 1497 times.
✓ Branch 33 taken 7 times.
✓ Branch 34 taken 69 times.
✓ Branch 35 taken 8 times.
✓ Branch 36 taken 7 times.
✓ Branch 37 taken 69 times.
✓ Branch 38 taken 7 times.
✓ Branch 39 taken 3 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 128 times.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✓ Branch 44 taken 132 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 3 times.
✓ Branch 47 taken 71 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 3 times.
✓ Branch 50 taken 71 times.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✓ Branch 53 taken 5 times.
✓ Branch 54 taken 138 times.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✓ Branch 57 taken 138 times.
✗ Branch 58 not taken.
✓ Branch 59 taken 3 times.
✓ Branch 60 taken 69 times.
✗ Branch 61 not taken.
✓ Branch 62 taken 3 times.
✓ Branch 63 taken 69 times.
✗ Branch 64 not taken.
✓ Branch 65 taken 22 times.
✗ Branch 66 not taken.
✓ Branch 67 taken 130 times.
✓ Branch 68 taken 22 times.
✗ Branch 69 not taken.
✓ Branch 70 taken 130 times.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✓ Branch 73 taken 65 times.
✗ Branch 74 not taken.
✓ Branch 75 taken 3 times.
✓ Branch 76 taken 65 times.
✗ Branch 77 not taken.
✓ Branch 78 taken 3 times.
✗ Branch 79 not taken.
✓ Branch 80 taken 132 times.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✓ Branch 83 taken 132 times.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✓ Branch 86 taken 66 times.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✓ Branch 89 taken 66 times.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✓ Branch 93 taken 138 times.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✓ Branch 96 taken 138 times.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✓ Branch 99 taken 69 times.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✓ Branch 102 taken 69 times.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✓ Branch 106 taken 150 times.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✓ Branch 109 taken 150 times.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✓ Branch 112 taken 75 times.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✓ Branch 115 taken 75 times.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✓ Branch 119 taken 232 times.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✓ Branch 122 taken 232 times.
✗ Branch 123 not taken.
✓ Branch 125 taken 116 times.
✗ Branch 126 not taken.
✓ Branch 128 taken 116 times.
✗ Branch 129 not taken.
✗ Branch 131 not taken.
✓ Branch 132 taken 260 times.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✓ Branch 135 taken 260 times.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✓ Branch 138 taken 130 times.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✓ Branch 141 taken 130 times.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
✗ Branch 144 not taken.
✓ Branch 145 taken 98 times.
✓ Branch 146 taken 10 times.
✗ Branch 147 not taken.
✓ Branch 148 taken 98 times.
✓ Branch 149 taken 10 times.
✗ Branch 150 not taken.
✓ Branch 151 taken 49 times.
✓ Branch 152 taken 4 times.
✗ Branch 153 not taken.
✓ Branch 154 taken 49 times.
✓ Branch 155 taken 4 times.
✗ Branch 156 not taken.
✓ Branch 158 taken 98 times.
✗ Branch 159 not taken.
✓ Branch 161 taken 98 times.
✗ Branch 162 not taken.
✓ Branch 164 taken 49 times.
✗ Branch 165 not taken.
✓ Branch 167 taken 49 times.
✗ Branch 168 not taken.
✓ Branch 171 taken 98 times.
✗ Branch 172 not taken.
✓ Branch 174 taken 98 times.
✗ Branch 175 not taken.
✓ Branch 177 taken 49 times.
✗ Branch 178 not taken.
✓ Branch 180 taken 49 times.
✗ Branch 181 not taken.
✓ Branch 184 taken 898 times.
✗ Branch 185 not taken.
✓ Branch 187 taken 898 times.
✗ Branch 188 not taken.
✓ Branch 190 taken 449 times.
✗ Branch 191 not taken.
✓ Branch 193 taken 449 times.
✗ Branch 194 not taken.
✓ Branch 197 taken 68 times.
✗ Branch 198 not taken.
✓ Branch 200 taken 68 times.
✗ Branch 201 not taken.
✓ Branch 203 taken 34 times.
✗ Branch 204 not taken.
✓ Branch 206 taken 34 times.
✗ Branch 207 not taken.
✓ Branch 210 taken 566 times.
✗ Branch 211 not taken.
✓ Branch 213 taken 566 times.
✗ Branch 214 not taken.
✓ Branch 216 taken 283 times.
✗ Branch 217 not taken.
✓ Branch 219 taken 283 times.
✗ Branch 220 not taken.
✓ Branch 223 taken 198 times.
✗ Branch 224 not taken.
✓ Branch 226 taken 198 times.
✗ Branch 227 not taken.
✓ Branch 229 taken 99 times.
✗ Branch 230 not taken.
✓ Branch 232 taken 99 times.
✗ Branch 233 not taken.
✓ Branch 236 taken 546 times.
✗ Branch 237 not taken.
✓ Branch 239 taken 546 times.
✗ Branch 240 not taken.
✗ Branch 242 not taken.
✗ Branch 243 not taken.
✗ Branch 245 not taken.
✗ Branch 246 not taken.
✓ Branch 249 taken 796 times.
✗ Branch 250 not taken.
✓ Branch 252 taken 796 times.
✗ Branch 253 not taken.
✓ Branch 255 taken 398 times.
✗ Branch 256 not taken.
✓ Branch 258 taken 398 times.
✗ Branch 259 not taken.
✓ Branch 262 taken 1440 times.
✗ Branch 263 not taken.
✓ Branch 265 taken 1440 times.
✗ Branch 266 not taken.
✗ Branch 268 not taken.
✗ Branch 269 not taken.
✗ Branch 271 not taken.
✗ Branch 272 not taken.
✓ Branch 274 taken 720 times.
✗ Branch 275 not taken.
✓ Branch 277 taken 720 times.
✗ Branch 278 not taken.
36711 dims.push_back(0); // magic number; RootNode has no Log2Dim
1328
121/228
✓ Branch 2 taken 91 times.
✓ Branch 3 taken 134 times.
✓ Branch 4 taken 3626 times.
✓ Branch 5 taken 382 times.
✓ Branch 6 taken 134 times.
✓ Branch 7 taken 3626 times.
✓ Branch 8 taken 341 times.
✓ Branch 9 taken 11 times.
✓ Branch 10 taken 19 times.
✓ Branch 11 taken 329 times.
✓ Branch 12 taken 12 times.
✓ Branch 13 taken 19 times.
✓ Branch 14 taken 285 times.
✓ Branch 15 taken 139 times.
✓ Branch 16 taken 19 times.
✓ Branch 17 taken 2584 times.
✓ Branch 18 taken 154 times.
✓ Branch 19 taken 19 times.
✓ Branch 20 taken 2588 times.
✓ Branch 21 taken 102 times.
✓ Branch 22 taken 10 times.
✓ Branch 23 taken 269 times.
✓ Branch 24 taken 94 times.
✓ Branch 25 taken 10 times.
✓ Branch 26 taken 280 times.
✓ Branch 27 taken 8 times.
✓ Branch 28 taken 142 times.
✓ Branch 29 taken 1516 times.
✓ Branch 30 taken 3 times.
✓ Branch 31 taken 142 times.
✓ Branch 32 taken 1497 times.
✓ Branch 33 taken 7 times.
✓ Branch 34 taken 69 times.
✓ Branch 35 taken 8 times.
✓ Branch 36 taken 7 times.
✓ Branch 37 taken 69 times.
✓ Branch 38 taken 7 times.
✓ Branch 39 taken 3 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 128 times.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✓ Branch 44 taken 132 times.
✗ Branch 45 not taken.
✓ Branch 46 taken 3 times.
✓ Branch 47 taken 71 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 3 times.
✓ Branch 50 taken 71 times.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✓ Branch 53 taken 5 times.
✓ Branch 54 taken 138 times.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✓ Branch 57 taken 138 times.
✗ Branch 58 not taken.
✓ Branch 59 taken 3 times.
✓ Branch 60 taken 69 times.
✗ Branch 61 not taken.
✓ Branch 62 taken 3 times.
✓ Branch 63 taken 69 times.
✗ Branch 64 not taken.
✓ Branch 65 taken 22 times.
✗ Branch 66 not taken.
✓ Branch 67 taken 130 times.
✓ Branch 68 taken 22 times.
✗ Branch 69 not taken.
✓ Branch 70 taken 130 times.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✓ Branch 73 taken 65 times.
✗ Branch 74 not taken.
✓ Branch 75 taken 3 times.
✓ Branch 76 taken 65 times.
✗ Branch 77 not taken.
✓ Branch 78 taken 3 times.
✗ Branch 79 not taken.
✓ Branch 80 taken 132 times.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✓ Branch 83 taken 132 times.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✓ Branch 86 taken 66 times.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✓ Branch 89 taken 66 times.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✓ Branch 93 taken 138 times.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✓ Branch 96 taken 138 times.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✓ Branch 99 taken 69 times.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✓ Branch 102 taken 69 times.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✓ Branch 106 taken 150 times.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✓ Branch 109 taken 150 times.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✓ Branch 112 taken 75 times.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✓ Branch 115 taken 75 times.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✓ Branch 119 taken 232 times.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✓ Branch 122 taken 232 times.
✗ Branch 123 not taken.
✓ Branch 125 taken 116 times.
✗ Branch 126 not taken.
✓ Branch 128 taken 116 times.
✗ Branch 129 not taken.
✗ Branch 131 not taken.
✓ Branch 132 taken 260 times.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✓ Branch 135 taken 260 times.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✓ Branch 138 taken 130 times.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✓ Branch 141 taken 130 times.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
✗ Branch 144 not taken.
✓ Branch 145 taken 98 times.
✓ Branch 146 taken 10 times.
✗ Branch 147 not taken.
✓ Branch 148 taken 98 times.
✓ Branch 149 taken 10 times.
✗ Branch 150 not taken.
✓ Branch 151 taken 49 times.
✓ Branch 152 taken 4 times.
✗ Branch 153 not taken.
✓ Branch 154 taken 49 times.
✓ Branch 155 taken 4 times.
✗ Branch 156 not taken.
✓ Branch 158 taken 98 times.
✗ Branch 159 not taken.
✓ Branch 161 taken 98 times.
✗ Branch 162 not taken.
✓ Branch 164 taken 49 times.
✗ Branch 165 not taken.
✓ Branch 167 taken 49 times.
✗ Branch 168 not taken.
✓ Branch 171 taken 98 times.
✗ Branch 172 not taken.
✓ Branch 174 taken 98 times.
✗ Branch 175 not taken.
✓ Branch 177 taken 49 times.
✗ Branch 178 not taken.
✓ Branch 180 taken 49 times.
✗ Branch 181 not taken.
✓ Branch 184 taken 898 times.
✗ Branch 185 not taken.
✓ Branch 187 taken 898 times.
✗ Branch 188 not taken.
✓ Branch 190 taken 449 times.
✗ Branch 191 not taken.
✓ Branch 193 taken 449 times.
✗ Branch 194 not taken.
✓ Branch 197 taken 68 times.
✗ Branch 198 not taken.
✓ Branch 200 taken 68 times.
✗ Branch 201 not taken.
✓ Branch 203 taken 34 times.
✗ Branch 204 not taken.
✓ Branch 206 taken 34 times.
✗ Branch 207 not taken.
✓ Branch 210 taken 566 times.
✗ Branch 211 not taken.
✓ Branch 213 taken 566 times.
✗ Branch 214 not taken.
✓ Branch 216 taken 283 times.
✗ Branch 217 not taken.
✓ Branch 219 taken 283 times.
✗ Branch 220 not taken.
✓ Branch 223 taken 198 times.
✗ Branch 224 not taken.
✓ Branch 226 taken 198 times.
✗ Branch 227 not taken.
✓ Branch 229 taken 99 times.
✗ Branch 230 not taken.
✓ Branch 232 taken 99 times.
✗ Branch 233 not taken.
✓ Branch 236 taken 546 times.
✗ Branch 237 not taken.
✓ Branch 239 taken 546 times.
✗ Branch 240 not taken.
✗ Branch 242 not taken.
✗ Branch 243 not taken.
✗ Branch 245 not taken.
✗ Branch 246 not taken.
✓ Branch 249 taken 796 times.
✗ Branch 250 not taken.
✓ Branch 252 taken 796 times.
✗ Branch 253 not taken.
✓ Branch 255 taken 398 times.
✗ Branch 256 not taken.
✓ Branch 258 taken 398 times.
✗ Branch 259 not taken.
✓ Branch 262 taken 1440 times.
✗ Branch 263 not taken.
✓ Branch 265 taken 1440 times.
✗ Branch 266 not taken.
✗ Branch 268 not taken.
✗ Branch 269 not taken.
✗ Branch 271 not taken.
✗ Branch 272 not taken.
✓ Branch 274 taken 720 times.
✗ Branch 275 not taken.
✓ Branch 277 taken 720 times.
✗ Branch 278 not taken.
36711 ChildT::getNodeLog2Dims(dims);
1329 36664 }
1330
1331
1332 template<typename ChildT>
1333 inline Coord
1334 RootNode<ChildT>::getMinIndex() const
1335 {
1336
5/46
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 4 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
22 return mTable.empty() ? Coord(0) : mTable.begin()->first;
1337 }
1338
1339 template<typename ChildT>
1340 inline Coord
1341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 RootNode<ChildT>::getMaxIndex() const
1342 {
1343
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 return mTable.empty() ? Coord(0) : mTable.rbegin()->first + Coord(ChildT::DIM - 1);
1344 }
1345
1346
1347 template<typename ChildT>
1348 inline void
1349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 RootNode<ChildT>::getIndexRange(CoordBBox& bbox) const
1350 {
1351 6 bbox.min() = this->getMinIndex();
1352 6 bbox.max() = this->getMaxIndex();
1353 6 }
1354
1355
1356 ////////////////////////////////////////
1357
1358
1359 template<typename ChildT>
1360 template<typename OtherChildType>
1361 inline bool
1362 6406 RootNode<ChildT>::hasSameTopology(const RootNode<OtherChildType>& other) const
1363 {
1364 using OtherRootT = RootNode<OtherChildType>;
1365 using OtherMapT = typename OtherRootT::MapType;
1366 using OtherIterT = typename OtherRootT::MapIter;
1367 using OtherCIterT = typename OtherRootT::MapCIter;
1368
1369
1/2
✓ Branch 1 taken 3384 times.
✗ Branch 2 not taken.
6406 if (!hasSameConfiguration(other)) return false;
1370
1371 // Create a local copy of the other node's table.
1372 OtherMapT copyOfOtherTable = other.mTable;
1373
1374 // For each entry in this node's table...
1375
2/2
✓ Branch 0 taken 3669 times.
✓ Branch 1 taken 3372 times.
13191 for (MapCIter thisIter = mTable.begin(); thisIter != mTable.end(); ++thisIter) {
1376
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 580 times.
✓ Branch 2 taken 264 times.
1688 if (this->isBackgroundTile(thisIter)) continue; // ignore background tiles
1377
1378 // Fail if there is no corresponding entry in the other node's table.
1379
2/2
✓ Branch 1 taken 3665 times.
✓ Branch 2 taken 4 times.
6801 OtherCIterT otherIter = other.findKey(thisIter->first);
1380
2/2
✓ Branch 0 taken 3665 times.
✓ Branch 1 taken 4 times.
6811 if (otherIter == other.mTable.end()) return false;
1381
1382 // Fail if this entry is a tile and the other is a child or vice-versa.
1383
2/2
✓ Branch 0 taken 3655 times.
✓ Branch 1 taken 10 times.
6795 if (isChild(thisIter)) {//thisIter points to a child
1384
1/2
✓ Branch 0 taken 3655 times.
✗ Branch 1 not taken.
6785 if (OtherRootT::isTile(otherIter)) return false;
1385 // Fail if both entries are children, but the children have different topology.
1386
3/4
✓ Branch 1 taken 3655 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3647 times.
✓ Branch 4 taken 8 times.
6785 if (!getChild(thisIter).hasSameTopology(&OtherRootT::getChild(otherIter))) return false;
1387 } else {//thisIter points to a tile
1388
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (OtherRootT::isChild(otherIter)) return false;
1389
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (getTile(thisIter).active != OtherRootT::getTile(otherIter).active) return false;
1390 }
1391
1392 // Remove tiles and child nodes with matching topology from
1393 // the copy of the other node's table. This is required since
1394 // the two root tables can include an arbitrary number of
1395 // background tiles and still have the same topology!
1396 6785 copyOfOtherTable.erase(otherIter->first);
1397 }
1398 // Fail if the remaining entries in copyOfOtherTable are not all background tiles.
1399
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3368 times.
6390 for (OtherIterT i = copyOfOtherTable.begin(), e = copyOfOtherTable.end(); i != e; ++i) {
1400
0/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
6 if (!other.isBackgroundTile(i)) return false;
1401 }
1402 6384 return true;
1403 }
1404
1405
1406 template<typename ChildT>
1407 template<typename OtherChildType>
1408 inline bool
1409
1/2
✓ Branch 1 taken 3384 times.
✗ Branch 2 not taken.
6406 RootNode<ChildT>::hasSameConfiguration(const RootNode<OtherChildType>&)
1410 {
1411 std::vector<Index> thisDims, otherDims;
1412 RootNode::getNodeLog2Dims(thisDims);
1413 RootNode<OtherChildType>::getNodeLog2Dims(otherDims);
1414 12812 return (thisDims == otherDims);
1415 }
1416
1417
1418 template<typename ChildT>
1419 template<typename OtherChildType>
1420 inline void
1421
1/2
✓ Branch 1 taken 14948 times.
✗ Branch 2 not taken.
26225 RootNode<ChildT>::enforceSameConfiguration(const RootNode<OtherChildType>&)
1422 {
1423 std::vector<Index> thisDims, otherDims;
1424 RootNode::getNodeLog2Dims(thisDims);
1425 RootNode<OtherChildType>::getNodeLog2Dims(otherDims);
1426
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14947 times.
26225 if (thisDims != otherDims) {
1427
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 std::ostringstream ostr;
1428
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 ostr << "grids have incompatible configurations (" << thisDims[0];
1429
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
6 for (size_t i = 1, N = thisDims.size(); i < N; ++i) ostr << " x " << thisDims[i];
1430
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 ostr << " vs. " << otherDims[0];
1431
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
8 for (size_t i = 1, N = otherDims.size(); i < N; ++i) ostr << " x " << otherDims[i];
1432
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 ostr << ")";
1433
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.
10 OPENVDB_THROW(TypeError, ostr.str());
1434 }
1435 26223 }
1436
1437
1438 template<typename ChildT>
1439 template<typename OtherChildType>
1440 inline bool
1441 RootNode<ChildT>::hasCompatibleValueType(const RootNode<OtherChildType>&)
1442 {
1443 using OtherValueType = typename OtherChildType::ValueType;
1444 return CanConvertType</*from=*/OtherValueType, /*to=*/ValueType>::value;
1445 }
1446
1447
1448 template<typename ChildT>
1449 template<typename OtherChildType>
1450 inline void
1451 2 RootNode<ChildT>::enforceCompatibleValueTypes(const RootNode<OtherChildType>&)
1452 {
1453 using OtherValueType = typename OtherChildType::ValueType;
1454 if (!CanConvertType</*from=*/OtherValueType, /*to=*/ValueType>::value) {
1455 4 std::ostringstream ostr;
1456 ostr << "values of type " << typeNameAsString<OtherValueType>()
1457
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
4 << " cannot be converted to type " << typeNameAsString<ValueType>();
1458
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(TypeError, ostr.str());
1459 }
1460 }
1461
1462
1463 ////////////////////////////////////////
1464
1465
1466 template<typename ChildT>
1467 inline Index64
1468 RootNode<ChildT>::memUsage() const
1469 {
1470 Index64 sum = sizeof(*this);
1471 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1472 if (const ChildT *child = iter->second.child) {
1473 sum += child->memUsage();
1474 }
1475 }
1476 return sum;
1477 }
1478
1479
1480 template<typename ChildT>
1481 inline void
1482 230086 RootNode<ChildT>::clear()
1483 {
1484
2/2
✓ Branch 0 taken 103958 times.
✓ Branch 1 taken 129062 times.
434214 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1485
2/2
✓ Branch 0 taken 43605 times.
✓ Branch 1 taken 60353 times.
204128 delete i->second.child;
1486 }
1487 mTable.clear();
1488 230086 }
1489
1490
1491 template<typename ChildT>
1492 inline void
1493 868 RootNode<ChildT>::evalActiveBoundingBox(CoordBBox& bbox, bool visitVoxels) const
1494 {
1495
2/2
✓ Branch 0 taken 1150 times.
✓ Branch 1 taken 434 times.
3168 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
1496
1/2
✓ Branch 0 taken 1150 times.
✗ Branch 1 not taken.
2300 if (const ChildT *child = iter->second.child) {
1497 2300 child->evalActiveBoundingBox(bbox, visitVoxels);
1498 } else if (isTileOn(iter)) {
1499 bbox.expand(iter->first, ChildT::DIM);
1500 }
1501 }
1502 }
1503
1504
1505 #if OPENVDB_ABI_VERSION_NUMBER < 8
1506 template<typename ChildT>
1507 inline Index
1508 RootNode<ChildT>::getChildCount() const {
1509 return this->childCount();
1510 }
1511 #endif
1512
1513
1514 template<typename ChildT>
1515 inline Index
1516 302 RootNode<ChildT>::getTileCount() const
1517 {
1518 Index sum = 0;
1519
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 151 times.
802 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 250 times.
500 if (isTile(i)) ++sum;
1521 }
1522 302 return sum;
1523 }
1524
1525
1526 template<typename ChildT>
1527 inline Index
1528 RootNode<ChildT>::getActiveTileCount() const
1529 {
1530 Index sum = 0;
1531 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1532 if (isTileOn(i)) ++sum;
1533 }
1534 return sum;
1535 }
1536
1537
1538 template<typename ChildT>
1539 inline Index
1540 RootNode<ChildT>::getInactiveTileCount() const
1541 {
1542 Index sum = 0;
1543 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1544 if (isTileOff(i)) ++sum;
1545 }
1546 return sum;
1547 }
1548
1549
1550 template<typename ChildT>
1551 inline Index32
1552 95343 RootNode<ChildT>::leafCount() const
1553 {
1554 Index32 sum = 0;
1555
2/2
✓ Branch 0 taken 107503 times.
✓ Branch 1 taken 47681 times.
310334 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1556
2/2
✓ Branch 0 taken 107475 times.
✓ Branch 1 taken 28 times.
214991 if (isChild(i)) sum += getChild(i).leafCount();
1557 }
1558 95343 return sum;
1559 }
1560
1561
1562 template<typename ChildT>
1563 inline Index32
1564 681 RootNode<ChildT>::nonLeafCount() const
1565 {
1566 Index32 sum = 1;
1567 if (ChildT::LEVEL != 0) {
1568
2/2
✓ Branch 0 taken 1212 times.
✓ Branch 1 taken 350 times.
3090 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1569
2/2
✓ Branch 0 taken 1209 times.
✓ Branch 1 taken 3 times.
2409 if (isChild(i)) sum += getChild(i).nonLeafCount();
1570 }
1571 }
1572 681 return sum;
1573 }
1574
1575
1576 template<typename ChildT>
1577 inline Index32
1578 43680 RootNode<ChildT>::childCount() const
1579 {
1580 Index sum = 0;
1581
2/2
✓ Branch 0 taken 46092 times.
✓ Branch 1 taken 25086 times.
129338 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1582
2/2
✓ Branch 0 taken 41651 times.
✓ Branch 1 taken 4441 times.
85658 if (isChild(i)) ++sum;
1583 }
1584 43680 return sum;
1585 }
1586
1587
1588 template<typename ChildT>
1589 inline Index64
1590 RootNode<ChildT>::onVoxelCount() const
1591 {
1592 Index64 sum = 0;
1593 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1594 if (isChild(i)) {
1595 sum += getChild(i).onVoxelCount();
1596 } else if (isTileOn(i)) {
1597 sum += ChildT::NUM_VOXELS;
1598 }
1599 }
1600 return sum;
1601 }
1602
1603
1604 template<typename ChildT>
1605 inline Index64
1606 RootNode<ChildT>::offVoxelCount() const
1607 {
1608 Index64 sum = 0;
1609 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1610 if (isChild(i)) {
1611 sum += getChild(i).offVoxelCount();
1612 } else if (isTileOff(i) && !this->isBackgroundTile(i)) {
1613 sum += ChildT::NUM_VOXELS;
1614 }
1615 }
1616 return sum;
1617 }
1618
1619
1620 template<typename ChildT>
1621 inline Index64
1622 RootNode<ChildT>::onLeafVoxelCount() const
1623 {
1624 Index64 sum = 0;
1625 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1626 if (isChild(i)) sum += getChild(i).onLeafVoxelCount();
1627 }
1628 return sum;
1629 }
1630
1631
1632 template<typename ChildT>
1633 inline Index64
1634 RootNode<ChildT>::offLeafVoxelCount() const
1635 {
1636 Index64 sum = 0;
1637 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1638 if (isChild(i)) sum += getChild(i).offLeafVoxelCount();
1639 }
1640 return sum;
1641 }
1642
1643 template<typename ChildT>
1644 inline Index64
1645 4 RootNode<ChildT>::onTileCount() const
1646 {
1647 Index64 sum = 0;
1648
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1649
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (isChild(i)) {
1650 1 sum += getChild(i).onTileCount();
1651 } else if (isTileOn(i)) {
1652 2 sum += 1;
1653 }
1654 }
1655 4 return sum;
1656 }
1657
1658 template<typename ChildT>
1659 inline void
1660
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
6 RootNode<ChildT>::nodeCount(std::vector<Index32> &vec) const
1661 {
1662
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
6 assert(vec.size() > LEVEL);
1663 Index32 sum = 0;
1664
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 3 times.
54 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1665
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
48 if (isChild(i)) {
1666 48 ++sum;
1667 48 getChild(i).nodeCount(vec);
1668 }
1669 }
1670 6 vec[LEVEL] = 1;// one root node
1671 6 vec[ChildNodeType::LEVEL] = sum;
1672 }
1673
1674 ////////////////////////////////////////
1675
1676
1677 template<typename ChildT>
1678 inline bool
1679 32798679 RootNode<ChildT>::isValueOn(const Coord& xyz) const
1680 {
1681 32798679 MapCIter iter = this->findCoord(xyz);
1682
2/2
✓ Branch 0 taken 32744391 times.
✓ Branch 1 taken 97 times.
32798679 if (iter == mTable.end() || isTileOff(iter)) return false;
1683 32798513 return isTileOn(iter) ? true : getChild(iter).isValueOn(xyz);
1684 }
1685
1686 template<typename ChildT>
1687 inline bool
1688 18120 RootNode<ChildT>::hasActiveTiles() const
1689 {
1690
2/2
✓ Branch 0 taken 9896 times.
✓ Branch 1 taken 6530 times.
32503 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
1691
5/5
✓ Branch 0 taken 9892 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 3074 times.
✓ Branch 4 taken 6817 times.
20534 if (isChild(i) ? getChild(i).hasActiveTiles() : getTile(i).active) return true;
1692 }
1693 13021 return false;
1694 }
1695
1696 template<typename ChildT>
1697 template<typename AccessorT>
1698 inline bool
1699 17237032 RootNode<ChildT>::isValueOnAndCache(const Coord& xyz, AccessorT& acc) const
1700 {
1701 17237032 MapCIter iter = this->findCoord(xyz);
1702
2/2
✓ Branch 0 taken 783688 times.
✓ Branch 1 taken 8025847 times.
17237032 if (iter == mTable.end() || isTileOff(iter)) return false;
1703 if (isTileOn(iter)) return true;
1704 1217661 acc.insert(xyz, &getChild(iter));
1705 1217731 return getChild(iter).isValueOnAndCache(xyz, acc);
1706 }
1707
1708
1709 template<typename ChildT>
1710 inline const typename ChildT::ValueType&
1711 60564020 RootNode<ChildT>::getValue(const Coord& xyz) const
1712 {
1713 60564020 MapCIter iter = this->findCoord(xyz);
1714
4/4
✓ Branch 0 taken 2378125 times.
✓ Branch 1 taken 37660327 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 37660307 times.
60564020 return iter == mTable.end() ? mBackground
1715 56521705 : (isTile(iter) ? getTile(iter).value : getChild(iter).getValue(xyz));
1716 }
1717
1718 template<typename ChildT>
1719 template<typename AccessorT>
1720 inline const typename ChildT::ValueType&
1721 77053954 RootNode<ChildT>::getValueAndCache(const Coord& xyz, AccessorT& acc) const
1722 {
1723 77053954 MapCIter iter = this->findCoord(xyz);
1724
2/2
✓ Branch 0 taken 19413969 times.
✓ Branch 1 taken 46903551 times.
77053954 if (iter == mTable.end()) return mBackground;
1725
2/2
✓ Branch 0 taken 12382525 times.
✓ Branch 1 taken 34521026 times.
56787069 if (isChild(iter)) {
1726 22252463 acc.insert(xyz, &getChild(iter));
1727 22261931 return getChild(iter).getValueAndCache(xyz, acc);
1728 }
1729 34525122 return getTile(iter).value;
1730 }
1731
1732
1733 template<typename ChildT>
1734 inline int
1735 620230 RootNode<ChildT>::getValueDepth(const Coord& xyz) const
1736 {
1737 620230 MapCIter iter = this->findCoord(xyz);
1738
2/2
✓ Branch 0 taken 310108 times.
✓ Branch 1 taken 63 times.
620230 return iter == mTable.end() ? -1
1739
2/2
✓ Branch 0 taken 310020 times.
✓ Branch 1 taken 88 times.
620134 : (isTile(iter) ? 0 : int(LEVEL) - int(getChild(iter).getValueLevel(xyz)));
1740 }
1741
1742 template<typename ChildT>
1743 template<typename AccessorT>
1744 inline int
1745 461 RootNode<ChildT>::getValueDepthAndCache(const Coord& xyz, AccessorT& acc) const
1746 {
1747 461 MapCIter iter = this->findCoord(xyz);
1748
2/2
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 111 times.
461 if (iter == mTable.end()) return -1;
1749
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 5 times.
242 if (isTile(iter)) return 0;
1750 102 acc.insert(xyz, &getChild(iter));
1751 232 return int(LEVEL) - int(getChild(iter).getValueLevelAndCache(xyz, acc));
1752 }
1753
1754
1755 template<typename ChildT>
1756 inline void
1757 42 RootNode<ChildT>::setValueOff(const Coord& xyz)
1758 {
1759 42 MapIter iter = this->findCoord(xyz);
1760
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
42 if (iter != mTable.end() && !isTileOff(iter)) {
1761 if (isTileOn(iter)) {
1762 setChild(iter, *new ChildT(xyz, getTile(iter).value, /*active=*/true));
1763 }
1764 42 getChild(iter).setValueOff(xyz);
1765 }
1766 42 }
1767
1768
1769 template<typename ChildT>
1770 inline void
1771 61 RootNode<ChildT>::setActiveState(const Coord& xyz, bool on)
1772 {
1773 ChildT* child = nullptr;
1774 61 MapIter iter = this->findCoord(xyz);
1775
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 12 times.
61 if (iter == mTable.end()) {
1776
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
42 if (on) {
1777 42 child = new ChildT(xyz, mBackground);
1778 42 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1779 } else {
1780 // Nothing to do; (x, y, z) is background and therefore already inactive.
1781 }
1782
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
19 } else if (isChild(iter)) {
1783 child = &getChild(iter);
1784 } else if (on != getTile(iter).active) {
1785 child = new ChildT(xyz, getTile(iter).value, !on);
1786 setChild(iter, *child);
1787 }
1788
1/2
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
61 if (child) child->setActiveState(xyz, on);
1789 61 }
1790
1791 template<typename ChildT>
1792 template<typename AccessorT>
1793 inline void
1794 221612 RootNode<ChildT>::setActiveStateAndCache(const Coord& xyz, bool on, AccessorT& acc)
1795 {
1796 ChildT* child = nullptr;
1797 221612 MapIter iter = this->findCoord(xyz);
1798
2/2
✓ Branch 0 taken 1216 times.
✓ Branch 1 taken 156809 times.
221612 if (iter == mTable.end()) {
1799
1/2
✓ Branch 0 taken 1216 times.
✗ Branch 1 not taken.
1442 if (on) {
1800
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1442 child = new ChildT(xyz, mBackground);
1801 1442 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1802 } else {
1803 // Nothing to do; (x, y, z) is background and therefore already inactive.
1804 }
1805
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 156809 times.
220170 } else if (isChild(iter)) {
1806 child = &getChild(iter);
1807 } else if (on != getTile(iter).active) {
1808 child = new ChildT(xyz, getTile(iter).value, !on);
1809 setChild(iter, *child);
1810 }
1811
1/2
✓ Branch 0 taken 158025 times.
✗ Branch 1 not taken.
221612 if (child) {
1812 221612 acc.insert(xyz, child);
1813 221612 child->setActiveStateAndCache(xyz, on, acc);
1814 }
1815 221612 }
1816
1817
1818 template<typename ChildT>
1819 inline void
1820 235 RootNode<ChildT>::setValueOff(const Coord& xyz, const ValueType& value)
1821 {
1822 ChildT* child = nullptr;
1823 235 MapIter iter = this->findCoord(xyz);
1824
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 143 times.
235 if (iter == mTable.end()) {
1825
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
28 if (!math::isExactlyEqual(mBackground, value)) {
1826 28 child = new ChildT(xyz, mBackground);
1827 28 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1828 }
1829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143 times.
207 } else if (isChild(iter)) {
1830 child = &getChild(iter);
1831 } else if (isTileOn(iter) || !math::isExactlyEqual(getTile(iter).value, value)) {
1832 child = new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1833 setChild(iter, *child);
1834 }
1835
1/2
✓ Branch 0 taken 162 times.
✗ Branch 1 not taken.
235 if (child) child->setValueOff(xyz, value);
1836 235 }
1837
1838 template<typename ChildT>
1839 template<typename AccessorT>
1840 inline void
1841 12312010 RootNode<ChildT>::setValueOffAndCache(const Coord& xyz, const ValueType& value, AccessorT& acc)
1842 {
1843 ChildT* child = nullptr;
1844 12312010 MapIter iter = this->findCoord(xyz);
1845
1/2
✓ Branch 0 taken 8343109 times.
✗ Branch 1 not taken.
12312010 if (iter == mTable.end()) {
1846
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 7002371 times.
9630634 if (!math::isExactlyEqual(mBackground, value)) {
1847
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
108 child = new ChildT(xyz, mBackground);
1848
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
108 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1849 }
1850 } else if (isChild(iter)) {
1851 child = &getChild(iter);
1852 } else if (isTileOn(iter) || !math::isExactlyEqual(getTile(iter).value, value)) {
1853 child = new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1854 setChild(iter, *child);
1855 }
1856
1/2
✓ Branch 0 taken 66 times.
✗ Branch 1 not taken.
108 if (child) {
1857 108 acc.insert(xyz, child);
1858 108 child->setValueOffAndCache(xyz, value, acc);
1859 }
1860 12312010 }
1861
1862
1863 template<typename ChildT>
1864 inline void
1865 577733 RootNode<ChildT>::setValueOn(const Coord& xyz, const ValueType& value)
1866 {
1867 ChildT* child = nullptr;
1868 577733 MapIter iter = this->findCoord(xyz);
1869
2/2
✓ Branch 0 taken 4402 times.
✓ Branch 1 taken 312108 times.
577733 if (iter == mTable.end()) {
1870
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
8725 child = new ChildT(xyz, mBackground);
1871 8725 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1872
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 312108 times.
569008 } else if (isChild(iter)) {
1873 child = &getChild(iter);
1874 } else if (isTileOff(iter) || !math::isExactlyEqual(getTile(iter).value, value)) {
1875 child = new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1876 setChild(iter, *child);
1877 }
1878
1/2
✓ Branch 0 taken 316510 times.
✗ Branch 1 not taken.
577733 if (child) child->setValueOn(xyz, value);
1879 577733 }
1880
1881 template<typename ChildT>
1882 template<typename AccessorT>
1883 inline void
1884 6531022 RootNode<ChildT>::setValueAndCache(const Coord& xyz, const ValueType& value, AccessorT& acc)
1885 {
1886 ChildT* child = nullptr;
1887 6531022 MapIter iter = this->findCoord(xyz);
1888
2/2
✓ Branch 0 taken 2687 times.
✓ Branch 1 taken 3269438 times.
6531022 if (iter == mTable.end()) {
1889
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4999 child = new ChildT(xyz, mBackground);
1890
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
4999 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1891
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3269438 times.
6526023 } else if (isChild(iter)) {
1892 child = &getChild(iter);
1893 } else if (isTileOff(iter) || !math::isExactlyEqual(getTile(iter).value, value)) {
1894 child = new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1895 setChild(iter, *child);
1896 }
1897
1/2
✓ Branch 0 taken 3272125 times.
✗ Branch 1 not taken.
6531022 if (child) {
1898 6527396 acc.insert(xyz, child);
1899 6531014 child->setValueAndCache(xyz, value, acc);
1900 }
1901 6531022 }
1902
1903
1904 template<typename ChildT>
1905 inline void
1906 31 RootNode<ChildT>::setValueOnly(const Coord& xyz, const ValueType& value)
1907 {
1908 ChildT* child = nullptr;
1909 31 MapIter iter = this->findCoord(xyz);
1910
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10 times.
31 if (iter == mTable.end()) {
1911 12 child = new ChildT(xyz, mBackground);
1912 12 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1913
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
19 } else if (isChild(iter)) {
1914 child = &getChild(iter);
1915 } else if (!math::isExactlyEqual(getTile(iter).value, value)) {
1916 child = new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1917 setChild(iter, *child);
1918 }
1919
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
31 if (child) child->setValueOnly(xyz, value);
1920 31 }
1921
1922 template<typename ChildT>
1923 template<typename AccessorT>
1924 inline void
1925 6284 RootNode<ChildT>::setValueOnlyAndCache(const Coord& xyz, const ValueType& value, AccessorT& acc)
1926 {
1927 ChildT* child = nullptr;
1928 6284 MapIter iter = this->findCoord(xyz);
1929
2/2
✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 1915 times.
6284 if (iter == mTable.end()) {
1930
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2454 child = new ChildT(xyz, mBackground);
1931 2454 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1932
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1915 times.
3830 } else if (isChild(iter)) {
1933 child = &getChild(iter);
1934 } else if (!math::isExactlyEqual(getTile(iter).value, value)) {
1935 child = new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1936 setChild(iter, *child);
1937 }
1938
1/2
✓ Branch 0 taken 3142 times.
✗ Branch 1 not taken.
6284 if (child) {
1939 6284 acc.insert(xyz, child);
1940 6284 child->setValueOnlyAndCache(xyz, value, acc);
1941 }
1942 }
1943
1944
1945 template<typename ChildT>
1946 template<typename ModifyOp>
1947 inline void
1948 13 RootNode<ChildT>::modifyValue(const Coord& xyz, const ModifyOp& op)
1949 {
1950 ChildT* child = nullptr;
1951 13 MapIter iter = this->findCoord(xyz);
1952
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
13 if (iter == mTable.end()) {
1953 child = new ChildT(xyz, mBackground);
1954 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1955
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
13 } else if (isChild(iter)) {
1956 child = &getChild(iter);
1957 } else {
1958 // Need to create a child if the tile is inactive,
1959 // in order to activate voxel (x, y, z).
1960 bool createChild = isTileOff(iter);
1961 if (!createChild) {
1962 // Need to create a child if applying the functor
1963 // to the tile value produces a different value.
1964 const ValueType& tileVal = getTile(iter).value;
1965 ValueType modifiedVal = tileVal;
1966 op(modifiedVal);
1967 createChild = !math::isExactlyEqual(tileVal, modifiedVal);
1968 }
1969 if (createChild) {
1970 child = new ChildT(xyz, getTile(iter).value, isTileOn(iter));
1971 setChild(iter, *child);
1972 }
1973 }
1974
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
13 if (child) child->modifyValue(xyz, op);
1975 13 }
1976
1977 template<typename ChildT>
1978 template<typename ModifyOp, typename AccessorT>
1979 inline void
1980 796758 RootNode<ChildT>::modifyValueAndCache(const Coord& xyz, const ModifyOp& op, AccessorT& acc)
1981 {
1982 ChildT* child = nullptr;
1983 796758 MapIter iter = this->findCoord(xyz);
1984
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 398123 times.
796758 if (iter == mTable.end()) {
1985
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
512 child = new ChildT(xyz, mBackground);
1986 512 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
1987
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 398123 times.
796246 } else if (isChild(iter)) {
1988 child = &getChild(iter);
1989 } else {
1990 // Need to create a child if the tile is inactive,
1991 // in order to activate voxel (x, y, z).
1992 bool createChild = isTileOff(iter);
1993 if (!createChild) {
1994 // Need to create a child if applying the functor
1995 // to the tile value produces a different value.
1996 const ValueType& tileVal = getTile(iter).value;
1997 ValueType modifiedVal = tileVal;
1998 op(modifiedVal);
1999 createChild = !math::isExactlyEqual(tileVal, modifiedVal);
2000 }
2001 if (createChild) {
2002 child = new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2003 setChild(iter, *child);
2004 }
2005 }
2006
1/2
✓ Branch 0 taken 398379 times.
✗ Branch 1 not taken.
796758 if (child) {
2007 796758 acc.insert(xyz, child);
2008 796758 child->modifyValueAndCache(xyz, op, acc);
2009 }
2010 }
2011
2012
2013 template<typename ChildT>
2014 template<typename ModifyOp>
2015 inline void
2016 8 RootNode<ChildT>::modifyValueAndActiveState(const Coord& xyz, const ModifyOp& op)
2017 {
2018 ChildT* child = nullptr;
2019 8 MapIter iter = this->findCoord(xyz);
2020
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
8 if (iter == mTable.end()) {
2021 child = new ChildT(xyz, mBackground);
2022 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2023
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
8 } else if (isChild(iter)) {
2024 child = &getChild(iter);
2025 } else {
2026 const Tile& tile = getTile(iter);
2027 bool modifiedState = tile.active;
2028 ValueType modifiedVal = tile.value;
2029 op(modifiedVal, modifiedState);
2030 // Need to create a child if applying the functor to the tile
2031 // produces a different value or active state.
2032 if (modifiedState != tile.active || !math::isExactlyEqual(modifiedVal, tile.value)) {
2033 child = new ChildT(xyz, tile.value, tile.active);
2034 setChild(iter, *child);
2035 }
2036 }
2037
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
8 if (child) child->modifyValueAndActiveState(xyz, op);
2038 8 }
2039
2040 template<typename ChildT>
2041 template<typename ModifyOp, typename AccessorT>
2042 inline void
2043 RootNode<ChildT>::modifyValueAndActiveStateAndCache(
2044 const Coord& xyz, const ModifyOp& op, AccessorT& acc)
2045 {
2046 ChildT* child = nullptr;
2047 MapIter iter = this->findCoord(xyz);
2048 if (iter == mTable.end()) {
2049 child = new ChildT(xyz, mBackground);
2050 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2051 } else if (isChild(iter)) {
2052 child = &getChild(iter);
2053 } else {
2054 const Tile& tile = getTile(iter);
2055 bool modifiedState = tile.active;
2056 ValueType modifiedVal = tile.value;
2057 op(modifiedVal, modifiedState);
2058 // Need to create a child if applying the functor to the tile
2059 // produces a different value or active state.
2060 if (modifiedState != tile.active || !math::isExactlyEqual(modifiedVal, tile.value)) {
2061 child = new ChildT(xyz, tile.value, tile.active);
2062 setChild(iter, *child);
2063 }
2064 }
2065 if (child) {
2066 acc.insert(xyz, child);
2067 child->modifyValueAndActiveStateAndCache(xyz, op, acc);
2068 }
2069 }
2070
2071
2072 template<typename ChildT>
2073 inline bool
2074 10016 RootNode<ChildT>::probeValue(const Coord& xyz, ValueType& value) const
2075 {
2076 10016 MapCIter iter = this->findCoord(xyz);
2077
2/2
✓ Branch 0 taken 843 times.
✓ Branch 1 taken 4165 times.
10016 if (iter == mTable.end()) {
2078 1686 value = mBackground;
2079 1686 return false;
2080
2/2
✓ Branch 0 taken 4107 times.
✓ Branch 1 taken 58 times.
8330 } else if (isChild(iter)) {
2081 8214 return getChild(iter).probeValue(xyz, value);
2082 }
2083
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
116 value = getTile(iter).value;
2084 return isTileOn(iter);
2085 }
2086
2087 template<typename ChildT>
2088 template<typename AccessorT>
2089 inline bool
2090 1185938642 RootNode<ChildT>::probeValueAndCache(const Coord& xyz, ValueType& value, AccessorT& acc) const
2091 {
2092 1185938642 MapCIter iter = this->findCoord(xyz);
2093
2/2
✓ Branch 0 taken 574080782 times.
✓ Branch 1 taken 18888539 times.
1185938642 if (iter == mTable.end()) {
2094 1148161564 value = mBackground;
2095 1148161564 return false;
2096
2/2
✓ Branch 0 taken 18888534 times.
✓ Branch 1 taken 5 times.
37777078 } else if (isChild(iter)) {
2097 37777068 acc.insert(xyz, &getChild(iter));
2098 37777068 return getChild(iter).probeValueAndCache(xyz, value, acc);
2099 }
2100
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
10 value = getTile(iter).value;
2101 return isTileOn(iter);
2102 }
2103
2104
2105 ////////////////////////////////////////
2106
2107
2108 template<typename ChildT>
2109 inline void
2110
1/2
✓ Branch 0 taken 4130 times.
✗ Branch 1 not taken.
8224 RootNode<ChildT>::fill(const CoordBBox& bbox, const ValueType& value, bool active)
2111 {
2112 if (bbox.empty()) return;
2113
2114 // Iterate over the fill region in axis-aligned, tile-sized chunks.
2115 // (The first and last chunks along each axis might be smaller than a tile.)
2116 Coord xyz, tileMax;
2117
2/2
✓ Branch 0 taken 4397 times.
✓ Branch 1 taken 4130 times.
16980 for (int x = bbox.min().x(); x <= bbox.max().x(); x = tileMax.x() + 1) {
2118 xyz.setX(x);
2119
2/2
✓ Branch 0 taken 5209 times.
✓ Branch 1 taken 4397 times.
19132 for (int y = bbox.min().y(); y <= bbox.max().y(); y = tileMax.y() + 1) {
2120 xyz.setY(y);
2121
2/2
✓ Branch 0 taken 10336 times.
✓ Branch 1 taken 5209 times.
30998 for (int z = bbox.min().z(); z <= bbox.max().z(); z = tileMax.z() + 1) {
2122 xyz.setZ(z);
2123
2124 // Get the bounds of the tile that contains voxel (x, y, z).
2125
2/2
✓ Branch 0 taken 8972 times.
✓ Branch 1 taken 1364 times.
20622 Coord tileMin = coordToKey(xyz);
2126
2/2
✓ Branch 0 taken 8972 times.
✓ Branch 1 taken 1364 times.
20622 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
2127
2128 if (xyz != tileMin || Coord::lessThan(bbox.max(), tileMax)) {
2129 // If the box defined by (xyz, bbox.max()) doesn't completely enclose
2130 // the tile to which xyz belongs, create a child node (or retrieve
2131 // the existing one).
2132 ChildT* child = nullptr;
2133
2/2
✓ Branch 0 taken 6582 times.
✓ Branch 1 taken 833 times.
14783 MapIter iter = this->findKey(tileMin);
2134
2/2
✓ Branch 0 taken 6582 times.
✓ Branch 1 taken 833 times.
14783 if (iter == mTable.end()) {
2135 // No child or tile exists. Create a child and initialize it
2136 // with the background value.
2137
2/4
✓ Branch 1 taken 6582 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 90 times.
✗ Branch 5 not taken.
13142 child = new ChildT(xyz, mBackground);
2138
1/2
✓ Branch 1 taken 6582 times.
✗ Branch 2 not taken.
13322 mTable[tileMin] = NodeStruct(*child);
2139
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 832 times.
1641 } else if (isTile(iter)) {
2140 // Replace the tile with a newly-created child that is filled
2141 // with the tile's value and active state.
2142 const Tile& tile = getTile(iter);
2143
1/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 child = new ChildT(xyz, tile.value, tile.active);
2144
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 mTable[tileMin] = NodeStruct(*child);
2145 } else if (isChild(iter)) {
2146 child = &getChild(iter);
2147 }
2148 // Forward the fill request to the child.
2149
1/2
✓ Branch 0 taken 7415 times.
✗ Branch 1 not taken.
14783 if (child) {
2150 14783 const Coord tmp = Coord::minComponent(bbox.max(), tileMax);
2151
1/2
✓ Branch 1 taken 7415 times.
✗ Branch 2 not taken.
14783 child->fill(CoordBBox(xyz, tmp), value, active);
2152 }
2153 } else {
2154 // If the box given by (xyz, bbox.max()) completely encloses
2155 // the tile to which xyz belongs, create the tile (if it
2156 // doesn't already exist) and give it the fill value.
2157
1/2
✓ Branch 1 taken 2921 times.
✗ Branch 2 not taken.
5839 MapIter iter = this->findOrAddCoord(tileMin);
2158 5839 setTile(iter, Tile(value, active));
2159 }
2160 }
2161 }
2162 }
2163 }
2164
2165
2166 template<typename ChildT>
2167 inline void
2168
1/2
✓ Branch 0 taken 3464 times.
✗ Branch 1 not taken.
6916 RootNode<ChildT>::denseFill(const CoordBBox& bbox, const ValueType& value, bool active)
2169 {
2170 6913 if (bbox.empty()) return;
2171
2172
4/4
✓ Branch 0 taken 3463 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 3461 times.
6916 if (active && mTable.empty()) {
2173 // If this tree is empty, then a sparse fill followed by (threaded)
2174 // densification of active tiles is the more efficient approach.
2175 6913 sparseFill(bbox, value, active);
2176 6913 voxelizeActiveTiles(/*threaded=*/true);
2177 6913 return;
2178 }
2179
2180 // Iterate over the fill region in axis-aligned, tile-sized chunks.
2181 // (The first and last chunks along each axis might be smaller than a tile.)
2182 Coord xyz, tileMin, tileMax;
2183
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 for (int x = bbox.min().x(); x <= bbox.max().x(); x = tileMax.x() + 1) {
2184 xyz.setX(x);
2185
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
30 for (int y = bbox.min().y(); y <= bbox.max().y(); y = tileMax.y() + 1) {
2186 xyz.setY(y);
2187
2/2
✓ Branch 0 taken 404 times.
✓ Branch 1 taken 24 times.
428 for (int z = bbox.min().z(); z <= bbox.max().z(); z = tileMax.z() + 1) {
2188 xyz.setZ(z);
2189
2190 // Get the bounds of the tile that contains voxel (x, y, z).
2191 404 tileMin = coordToKey(xyz);
2192 404 tileMax = tileMin.offsetBy(ChildT::DIM - 1);
2193
2194 // Retrieve the table entry for the tile that contains xyz,
2195 // or, if there is no table entry, add a background tile.
2196 404 const auto iter = findOrAddCoord(tileMin);
2197
2198
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 4 times.
404 if (isTile(iter)) {
2199 // If the table entry is a tile, replace it with a child node
2200 // that is filled with the tile's value and active state.
2201 const auto& tile = getTile(iter);
2202
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
400 auto* child = new ChildT{tileMin, tile.value, tile.active};
2203 setChild(iter, *child);
2204 }
2205 // Forward the fill request to the child.
2206 404 getChild(iter).denseFill(bbox, value, active);
2207 }
2208 }
2209 }
2210 }
2211
2212
2213 ////////////////////////////////////////
2214
2215
2216 template<typename ChildT>
2217 inline void
2218 8822 RootNode<ChildT>::voxelizeActiveTiles(bool threaded)
2219 {
2220 // There is little point in threading over the root table since each tile
2221 // spans a huge index space (by default 4096^3) and hence we expect few
2222 // active tiles if any at all. In fact, you're very likely to run out of
2223 // memory if this method is called on a tree with root-level active tiles!
2224
2/2
✓ Branch 0 taken 5393 times.
✓ Branch 1 taken 4445 times.
19288 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2225 if (this->isTileOff(i)) continue;
2226 ChildT* child = i->second.child;
2227
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5389 times.
10466 if (child == nullptr) {
2228 // If this table entry is an active tile (i.e., not off and not a child node),
2229 // replace it with a child node filled with active tiles of the same value.
2230
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 child = new ChildT{i->first, this->getTile(i).value, true};
2231 8 i->second.child = child;
2232 }
2233 10466 child->voxelizeActiveTiles(threaded);
2234 }
2235 8822 }
2236
2237
2238 ////////////////////////////////////////
2239
2240
2241 template<typename ChildT>
2242 template<typename DenseT>
2243 inline void
2244 1636 RootNode<ChildT>::copyToDense(const CoordBBox& bbox, DenseT& dense) const
2245 {
2246 using DenseValueType = typename DenseT::ValueType;
2247
2248 const size_t xStride = dense.xStride(), yStride = dense.yStride(), zStride = dense.zStride();
2249 const Coord& min = dense.bbox().min();
2250 1636 CoordBBox nodeBBox;
2251
2/2
✓ Branch 0 taken 976 times.
✓ Branch 1 taken 818 times.
3588 for (Coord xyz = bbox.min(); xyz[0] <= bbox.max()[0]; xyz[0] = nodeBBox.max()[0] + 1) {
2252
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 976 times.
4192 for (xyz[1] = bbox.min()[1]; xyz[1] <= bbox.max()[1]; xyz[1] = nodeBBox.max()[1] + 1) {
2253
2/2
✓ Branch 0 taken 1239 times.
✓ Branch 1 taken 1120 times.
4718 for (xyz[2] = bbox.min()[2]; xyz[2] <= bbox.max()[2]; xyz[2] = nodeBBox.max()[2] + 1) {
2254
2255 // Get the coordinate bbox of the child node that contains voxel xyz.
2256 2478 nodeBBox = CoordBBox::createCube(coordToKey(xyz), ChildT::DIM);
2257
2258 // Get the coordinate bbox of the interection of inBBox and nodeBBox
2259 2478 CoordBBox sub(xyz, Coord::minComponent(bbox.max(), nodeBBox.max()));
2260
2261
1/2
✓ Branch 0 taken 1239 times.
✗ Branch 1 not taken.
2478 MapCIter iter = this->findKey(nodeBBox.min());
2262
2/4
✓ Branch 0 taken 1239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1239 times.
✗ Branch 3 not taken.
2478 if (iter != mTable.end() && isChild(iter)) {//is a child
2263 2478 getChild(iter).copyToDense(sub, dense);
2264 } else {//is background or a tile value
2265 const ValueType value = iter==mTable.end() ? mBackground : getTile(iter).value;
2266 sub.translate(-min);
2267 DenseValueType* a0 = dense.data() + zStride*sub.min()[2];
2268 for (Int32 x=sub.min()[0], ex=sub.max()[0]+1; x<ex; ++x) {
2269 DenseValueType* a1 = a0 + x*xStride;
2270 for (Int32 y=sub.min()[1], ey=sub.max()[1]+1; y<ey; ++y) {
2271 DenseValueType* a2 = a1 + y*yStride;
2272 for (Int32 z=sub.min()[2], ez=sub.max()[2]+1; z<ez; ++z, a2 += zStride) {
2273 *a2 = DenseValueType(value);
2274 }
2275 }
2276 }
2277 }
2278 }
2279 }
2280 }
2281 1636 }
2282
2283 ////////////////////////////////////////
2284
2285
2286 template<typename ChildT>
2287 inline bool
2288 302 RootNode<ChildT>::writeTopology(std::ostream& os, bool toHalf) const
2289 {
2290
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 1 times.
302 if (!toHalf) {
2291 300 os.write(reinterpret_cast<const char*>(&mBackground), sizeof(ValueType));
2292 } else {
2293 2 ValueType truncatedVal = io::truncateRealToHalf(mBackground);
2294
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
2 os.write(reinterpret_cast<const char*>(&truncatedVal), sizeof(ValueType));
2295 }
2296 302 io::setGridBackgroundValuePtr(os, &mBackground);
2297
2298 302 const Index numTiles = this->getTileCount(), numChildren = this->childCount();
2299 302 os.write(reinterpret_cast<const char*>(&numTiles), sizeof(Index));
2300 302 os.write(reinterpret_cast<const char*>(&numChildren), sizeof(Index));
2301
2302
3/4
✓ Branch 0 taken 151 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 148 times.
✓ Branch 3 taken 3 times.
302 if (numTiles == 0 && numChildren == 0) return false;
2303
2304 // Write tiles.
2305
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 148 times.
796 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2306
1/2
✓ Branch 0 taken 250 times.
✗ Branch 1 not taken.
500 if (isChild(i)) continue;
2307 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 * sizeof(Int32));
2308 os.write(reinterpret_cast<const char*>(&getTile(i).value), sizeof(ValueType));
2309 os.write(reinterpret_cast<const char*>(&getTile(i).active), sizeof(bool));
2310 }
2311 // Write child nodes.
2312
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 148 times.
796 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2313
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 250 times.
500 if (isTile(i)) continue;
2314 500 os.write(reinterpret_cast<const char*>(i->first.asPointer()), 3 * sizeof(Int32));
2315 500 getChild(i).writeTopology(os, toHalf);
2316 }
2317
2318 296 return true; // not empty
2319 }
2320
2321
2322 template<typename ChildT>
2323 inline bool
2324 228 RootNode<ChildT>::readTopology(std::istream& is, bool fromHalf)
2325 {
2326 // Delete the existing tree.
2327 228 this->clear();
2328
2329
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 114 times.
228 if (io::getFormatVersion(is) < OPENVDB_FILE_VERSION_ROOTNODE_MAP) {
2330 // Read and convert an older-format RootNode.
2331
2332 // For backward compatibility with older file formats, read both
2333 // outside and inside background values.
2334 is.read(reinterpret_cast<char*>(&mBackground), sizeof(ValueType));
2335 ValueType inside;
2336 is.read(reinterpret_cast<char*>(&inside), sizeof(ValueType));
2337
2338 io::setGridBackgroundValuePtr(is, &mBackground);
2339
2340 // Read the index range.
2341 Coord rangeMin, rangeMax;
2342 is.read(reinterpret_cast<char*>(rangeMin.asPointer()), 3 * sizeof(Int32));
2343 is.read(reinterpret_cast<char*>(rangeMax.asPointer()), 3 * sizeof(Int32));
2344
2345 this->initTable();
2346 Index tableSize = 0, log2Dim[4] = { 0, 0, 0, 0 };
2347 Int32 offset[3];
2348 for (int i = 0; i < 3; ++i) {
2349 offset[i] = rangeMin[i] >> ChildT::TOTAL;
2350 rangeMin[i] = offset[i] << ChildT::TOTAL;
2351 log2Dim[i] = 1 + util::FindHighestOn((rangeMax[i] >> ChildT::TOTAL) - offset[i]);
2352 tableSize += log2Dim[i];
2353 rangeMax[i] = (((1 << log2Dim[i]) + offset[i]) << ChildT::TOTAL) - 1;
2354 }
2355 log2Dim[3] = log2Dim[1] + log2Dim[2];
2356 tableSize = 1U << tableSize;
2357
2358 // Read masks.
2359 util::RootNodeMask childMask(tableSize), valueMask(tableSize);
2360 childMask.load(is);
2361 valueMask.load(is);
2362
2363 // Read child nodes/values.
2364 for (Index i = 0; i < tableSize; ++i) {
2365 // Compute origin = offset2coord(i).
2366 Index n = i;
2367 Coord origin;
2368 origin[0] = (n >> log2Dim[3]) + offset[0];
2369 n &= (1U << log2Dim[3]) - 1;
2370 origin[1] = (n >> log2Dim[2]) + offset[1];
2371 origin[2] = (n & ((1U << log2Dim[2]) - 1)) + offset[1];
2372 origin <<= ChildT::TOTAL;
2373
2374 if (childMask.isOn(i)) {
2375 // Read in and insert a child node.
2376 ChildT* child = new ChildT(PartialCreate(), origin, mBackground);
2377 child->readTopology(is);
2378 mTable[origin] = NodeStruct(*child);
2379 } else {
2380 // Read in a tile value and insert a tile, but only if the value
2381 // is either active or non-background.
2382 ValueType value;
2383 is.read(reinterpret_cast<char*>(&value), sizeof(ValueType));
2384 if (valueMask.isOn(i) || (!math::isApproxEqual(value, mBackground))) {
2385 mTable[origin] = NodeStruct(Tile(value, valueMask.isOn(i)));
2386 }
2387 }
2388 }
2389 return true;
2390 }
2391
2392 // Read a RootNode that was stored in the current format.
2393
2394 228 is.read(reinterpret_cast<char*>(&mBackground), sizeof(ValueType));
2395 228 io::setGridBackgroundValuePtr(is, &mBackground);
2396
2397 228 Index numTiles = 0, numChildren = 0;
2398 228 is.read(reinterpret_cast<char*>(&numTiles), sizeof(Index));
2399 228 is.read(reinterpret_cast<char*>(&numChildren), sizeof(Index));
2400
2401
3/4
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106 times.
✓ Branch 3 taken 8 times.
228 if (numTiles == 0 && numChildren == 0) return false;
2402
2403 Int32 vec[3];
2404 ValueType value;
2405 bool active;
2406
2407 // Read tiles.
2408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 106 times.
212 for (Index n = 0; n < numTiles; ++n) {
2409 is.read(reinterpret_cast<char*>(vec), 3 * sizeof(Int32));
2410 is.read(reinterpret_cast<char*>(&value), sizeof(ValueType));
2411 is.read(reinterpret_cast<char*>(&active), sizeof(bool));
2412 mTable[Coord(vec)] = NodeStruct(Tile(value, active));
2413 }
2414
2415 // Read child nodes.
2416
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 106 times.
712 for (Index n = 0; n < numChildren; ++n) {
2417
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
500 is.read(reinterpret_cast<char*>(vec), 3 * sizeof(Int32));
2418 Coord origin(vec);
2419
0/4
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
500 ChildT* child = new ChildT(PartialCreate(), origin, mBackground);
2420
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
500 child->readTopology(is, fromHalf);
2421
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
500 mTable[Coord(vec)] = NodeStruct(*child);
2422 }
2423
2424 return true; // not empty
2425 }
2426
2427
2428 template<typename ChildT>
2429 inline void
2430 520 RootNode<ChildT>::writeBuffers(std::ostream& os, bool toHalf) const
2431 {
2432
2/2
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 260 times.
1598 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2433
1/2
✓ Branch 0 taken 539 times.
✗ Branch 1 not taken.
1078 if (isChild(i)) getChild(i).writeBuffers(os, toHalf);
2434 }
2435 }
2436
2437
2438 template<typename ChildT>
2439 inline void
2440 530 RootNode<ChildT>::readBuffers(std::istream& is, bool fromHalf)
2441 {
2442
2/2
✓ Branch 0 taken 924 times.
✓ Branch 1 taken 265 times.
2378 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2443
1/2
✓ Branch 0 taken 924 times.
✗ Branch 1 not taken.
1848 if (isChild(i)) getChild(i).readBuffers(is, fromHalf);
2444 }
2445 }
2446
2447
2448 template<typename ChildT>
2449 inline void
2450 8 RootNode<ChildT>::readBuffers(std::istream& is, const CoordBBox& clipBBox, bool fromHalf)
2451 {
2452 const Tile bgTile(mBackground, /*active=*/false);
2453
2454
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 4 times.
58 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2455
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
50 if (isChild(i)) {
2456 // Stream in and clip the branch rooted at this child.
2457 // (We can't skip over children that lie outside the clipping region,
2458 // because buffers are serialized in depth-first order and need to be
2459 // unserialized in the same order.)
2460 ChildT& child = getChild(i);
2461
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
50 child.readBuffers(is, clipBBox, fromHalf);
2462 }
2463 }
2464 // Clip root-level tiles and prune children that were clipped.
2465
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
8 this->clip(clipBBox);
2466 }
2467
2468
2469 ////////////////////////////////////////
2470
2471
2472 template<typename ChildT>
2473 inline void
2474 22 RootNode<ChildT>::clip(const CoordBBox& clipBBox)
2475 {
2476 const Tile bgTile(mBackground, /*active=*/false);
2477
2478 // Iterate over a copy of this node's table so that we can modify the original.
2479 // (Copying the table copies child node pointers, not the nodes themselves.)
2480 MapType copyOfTable(mTable);
2481
2/2
✓ Branch 0 taken 74 times.
✓ Branch 1 taken 11 times.
170 for (MapIter i = copyOfTable.begin(), e = copyOfTable.end(); i != e; ++i) {
2482
1/2
✓ Branch 0 taken 74 times.
✗ Branch 1 not taken.
148 const Coord& xyz = i->first; // tile or child origin
2483
1/2
✓ Branch 0 taken 74 times.
✗ Branch 1 not taken.
148 CoordBBox tileBBox(xyz, xyz.offsetBy(ChildT::DIM - 1)); // tile or child bounds
2484 if (!clipBBox.hasOverlap(tileBBox)) {
2485 // This table entry lies completely outside the clipping region. Delete it.
2486 216 setTile(this->findCoord(xyz), bgTile); // delete any existing child node first
2487 mTable.erase(xyz);
2488 } else if (!clipBBox.isInside(tileBBox)) {
2489 // This table entry does not lie completely inside the clipping region
2490 // and must be clipped.
2491
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
40 if (isChild(i)) {
2492
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
40 getChild(i).clip(clipBBox, mBackground);
2493 } else {
2494 // Replace this tile with a background tile, then fill the clip region
2495 // with the tile's original value. (This might create a child branch.)
2496 tileBBox.intersect(clipBBox);
2497 const Tile& origTile = getTile(i);
2498 setTile(this->findCoord(xyz), bgTile);
2499 this->sparseFill(tileBBox, origTile.value, origTile.active);
2500 }
2501 } else {
2502 // This table entry lies completely inside the clipping region. Leave it intact.
2503 }
2504 }
2505
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
22 this->prune(); // also erases root-level background tiles
2506 }
2507
2508
2509 ////////////////////////////////////////
2510
2511
2512 template<typename ChildT>
2513 inline void
2514 92 RootNode<ChildT>::prune(const ValueType& tolerance)
2515 {
2516 92 bool state = false;
2517 84 ValueType value = zeroVal<ValueType>();
2518
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 46 times.
524 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
2519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
432 if (this->isTile(i)) continue;
2520
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
432 this->getChild(i).prune(tolerance);
2521
2/5
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 203 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
432 if (this->getChild(i).isConstant(value, state, tolerance)) {
2522
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
26 this->setTile(i, Tile(value, state));
2523 }
2524 }
2525
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
92 this->eraseBackgroundTiles();
2526 }
2527
2528
2529 ////////////////////////////////////////
2530
2531
2532 template<typename ChildT>
2533 template<typename NodeT>
2534 inline NodeT*
2535 58285 RootNode<ChildT>::stealNode(const Coord& xyz, const ValueType& value, bool state)
2536 {
2537 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2538 NodeT::LEVEL > ChildT::LEVEL) return nullptr;
2539 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
2540 58285 MapIter iter = this->findCoord(xyz);
2541
4/4
✓ Branch 0 taken 31795 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 31794 times.
58285 if (iter == mTable.end() || isTile(iter)) return nullptr;
2542 return (std::is_same<NodeT, ChildT>::value)
2543 58277 ? reinterpret_cast<NodeT*>(&stealChild(iter, Tile(value, state)))
2544 58191 : getChild(iter).template stealNode<NodeT>(xyz, value, state);
2545 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
2546 }
2547
2548
2549 ////////////////////////////////////////
2550
2551
2552 template<typename ChildT>
2553 inline void
2554 72169 RootNode<ChildT>::addLeaf(LeafNodeType* leaf)
2555 {
2556
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57873 times.
72169 if (leaf == nullptr) return;
2557 ChildT* child = nullptr;
2558 const Coord& xyz = leaf->origin();
2559 72169 MapIter iter = this->findCoord(xyz);
2560
2/2
✓ Branch 0 taken 20289 times.
✓ Branch 1 taken 37584 times.
72169 if (iter == mTable.end()) {
2561 if (ChildT::LEVEL>0) {
2562 20493 child = new ChildT(xyz, mBackground, false);
2563 } else {
2564 child = reinterpret_cast<ChildT*>(leaf);
2565 }
2566 20493 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2567
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 37583 times.
51676 } else if (isChild(iter)) {
2568 if (ChildT::LEVEL>0) {
2569 child = &getChild(iter);
2570 } else {
2571 child = reinterpret_cast<ChildT*>(leaf);
2572 setChild(iter, *child);//this also deletes the existing child node
2573 }
2574 } else {//tile
2575 if (ChildT::LEVEL>0) {
2576
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
4 child = new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2577 } else {
2578 child = reinterpret_cast<ChildT*>(leaf);
2579 }
2580 setChild(iter, *child);
2581 }
2582 72169 child->addLeaf(leaf);
2583 }
2584
2585
2586 template<typename ChildT>
2587 template<typename AccessorT>
2588 inline void
2589 4796 RootNode<ChildT>::addLeafAndCache(LeafNodeType* leaf, AccessorT& acc)
2590 {
2591
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3010 times.
4796 if (leaf == nullptr) return;
2592 ChildT* child = nullptr;
2593 const Coord& xyz = leaf->origin();
2594 4796 MapIter iter = this->findCoord(xyz);
2595
2/2
✓ Branch 0 taken 1736 times.
✓ Branch 1 taken 1274 times.
4796 if (iter == mTable.end()) {
2596 if (ChildT::LEVEL>0) {
2597 2253 child = new ChildT(xyz, mBackground, false);
2598 } else {
2599 child = reinterpret_cast<ChildT*>(leaf);
2600 }
2601 2253 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2602
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1274 times.
2543 } else if (isChild(iter)) {
2603 if (ChildT::LEVEL>0) {
2604 child = &getChild(iter);
2605 } else {
2606 child = reinterpret_cast<ChildT*>(leaf);
2607 setChild(iter, *child);//this also deletes the existing child node
2608 }
2609 } else {//tile
2610 if (ChildT::LEVEL>0) {
2611 child = new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2612 } else {
2613 child = reinterpret_cast<ChildT*>(leaf);
2614 }
2615 setChild(iter, *child);
2616 }
2617 4796 acc.insert(xyz, child);
2618 4796 child->addLeafAndCache(leaf, acc);
2619 }
2620
2621 template<typename ChildT>
2622 inline bool
2623 179 RootNode<ChildT>::addChild(ChildT* child)
2624 {
2625
1/2
✓ Branch 0 taken 147 times.
✗ Branch 1 not taken.
179 if (!child) return false;
2626 const Coord& xyz = child->origin();
2627 179 MapIter iter = this->findCoord(xyz);
2628
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 23 times.
179 if (iter == mTable.end()) {//background
2629
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
152 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2630 } else {//child or tile
2631 setChild(iter, *child);//this also deletes the existing child node
2632 }
2633 return true;
2634 }
2635
2636 template<typename ChildT>
2637 inline void
2638 3333 RootNode<ChildT>::addTile(const Coord& xyz, const ValueType& value, bool state)
2639 {
2640 3333 MapIter iter = this->findCoord(xyz);
2641
2/2
✓ Branch 0 taken 190 times.
✓ Branch 1 taken 1600 times.
3333 if (iter == mTable.end()) {//background
2642 380 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2643 } else {//child or tile
2644 2953 setTile(iter, Tile(value, state));//this also deletes the existing child node
2645 }
2646 3333 }
2647
2648 template<typename ChildT>
2649 inline void
2650 21279 RootNode<ChildT>::addTile(Index level, const Coord& xyz,
2651 const ValueType& value, bool state)
2652 {
2653
1/2
✓ Branch 0 taken 10640 times.
✗ Branch 1 not taken.
21279 if (LEVEL >= level) {
2654 21279 MapIter iter = this->findCoord(xyz);
2655
2/2
✓ Branch 0 taken 7155 times.
✓ Branch 1 taken 3485 times.
21279 if (iter == mTable.end()) {//background
2656
2/2
✓ Branch 0 taken 7140 times.
✓ Branch 1 taken 15 times.
14309 if (LEVEL > level) {
2657
1/2
✓ Branch 2 taken 183 times.
✗ Branch 3 not taken.
14279 ChildT* child = new ChildT(xyz, mBackground, false);
2658
1/2
✓ Branch 1 taken 183 times.
✗ Branch 2 not taken.
14645 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2659 14279 child->addTile(level, xyz, value, state);
2660 } else {
2661
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
32 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2662 }
2663
1/2
✓ Branch 0 taken 3485 times.
✗ Branch 1 not taken.
6970 } else if (isChild(iter)) {//child
2664
1/2
✓ Branch 0 taken 3485 times.
✗ Branch 1 not taken.
6970 if (LEVEL > level) {
2665 6970 getChild(iter).addTile(level, xyz, value, state);
2666 } else {
2667 setTile(iter, Tile(value, state));//this also deletes the existing child node
2668 }
2669 } else {//tile
2670 if (LEVEL > level) {
2671 ChildT* child = new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2672 setChild(iter, *child);
2673 child->addTile(level, xyz, value, state);
2674 } else {
2675 setTile(iter, Tile(value, state));
2676 }
2677 }
2678 }
2679 21279 }
2680
2681
2682 template<typename ChildT>
2683 template<typename AccessorT>
2684 inline void
2685 2508 RootNode<ChildT>::addTileAndCache(Index level, const Coord& xyz, const ValueType& value,
2686 bool state, AccessorT& acc)
2687 {
2688
1/2
✓ Branch 0 taken 1254 times.
✗ Branch 1 not taken.
2508 if (LEVEL >= level) {
2689 2508 MapIter iter = this->findCoord(xyz);
2690
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 1243 times.
2508 if (iter == mTable.end()) {//background
2691
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
22 if (LEVEL > level) {
2692
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
22 ChildT* child = new ChildT(xyz, mBackground, false);
2693 22 acc.insert(xyz, child);
2694
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
22 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2695 22 child->addTileAndCache(level, xyz, value, state, acc);
2696 } else {
2697 mTable[this->coordToKey(xyz)] = NodeStruct(Tile(value, state));
2698 }
2699
2/2
✓ Branch 0 taken 1238 times.
✓ Branch 1 taken 5 times.
2486 } else if (isChild(iter)) {//child
2700
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
2476 if (LEVEL > level) {
2701 ChildT* child = &getChild(iter);
2702 2476 acc.insert(xyz, child);
2703 2476 child->addTileAndCache(level, xyz, value, state, acc);
2704 } else {
2705 setTile(iter, Tile(value, state));//this also deletes the existing child node
2706 }
2707 } else {//tile
2708
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
10 if (LEVEL > level) {
2709 ChildT* child = new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2710 acc.insert(xyz, child);
2711 setChild(iter, *child);
2712 child->addTileAndCache(level, xyz, value, state, acc);
2713 } else {
2714 10 setTile(iter, Tile(value, state));
2715 }
2716 }
2717 }
2718 2508 }
2719
2720
2721 ////////////////////////////////////////
2722
2723
2724 template<typename ChildT>
2725 inline typename ChildT::LeafNodeType*
2726 7328 RootNode<ChildT>::touchLeaf(const Coord& xyz)
2727 {
2728 ChildT* child = nullptr;
2729 7328 MapIter iter = this->findCoord(xyz);
2730
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 3859 times.
7328 if (iter == mTable.end()) {
2731 150 child = new ChildT(xyz, mBackground, false);
2732 150 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2733
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3856 times.
7178 } else if (isChild(iter)) {
2734 child = &getChild(iter);
2735 } else {
2736
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
8 child = new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2737 setChild(iter, *child);
2738 }
2739 7328 return child->touchLeaf(xyz);
2740 }
2741
2742
2743 template<typename ChildT>
2744 template<typename AccessorT>
2745 inline typename ChildT::LeafNodeType*
2746 161231 RootNode<ChildT>::touchLeafAndCache(const Coord& xyz, AccessorT& acc)
2747 {
2748 ChildT* child = nullptr;
2749 161231 MapIter iter = this->findCoord(xyz);
2750
2/2
✓ Branch 0 taken 31991 times.
✓ Branch 1 taken 94235 times.
161231 if (iter == mTable.end()) {
2751 63727 child = new ChildT(xyz, mBackground, false);
2752 63727 mTable[this->coordToKey(xyz)] = NodeStruct(*child);
2753
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 94235 times.
97504 } else if (isChild(iter)) {
2754 child = &getChild(iter);
2755 } else {
2756 child = new ChildT(xyz, getTile(iter).value, isTileOn(iter));
2757 setChild(iter, *child);
2758 }
2759 161231 acc.insert(xyz, child);
2760 161231 return child->touchLeafAndCache(xyz, acc);
2761 }
2762
2763
2764 ////////////////////////////////////////
2765
2766
2767 template<typename ChildT>
2768 template<typename NodeT>
2769 inline NodeT*
2770 72221 RootNode<ChildT>::probeNode(const Coord& xyz)
2771 {
2772 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2773 NodeT::LEVEL > ChildT::LEVEL) return nullptr;
2774 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
2775 72240 MapIter iter = this->findCoord(xyz);
2776
7/36
✓ Branch 0 taken 41764 times.
✓ Branch 1 taken 293 times.
✓ Branch 2 taken 41764 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 18 times.
✓ Branch 6 taken 15 times.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
72240 if (iter == mTable.end() || isTile(iter)) return nullptr;
2777 ChildT* child = &getChild(iter);
2778 return (std::is_same<NodeT, ChildT>::value)
2779 71732 ? reinterpret_cast<NodeT*>(child)
2780 71732 : child->template probeNode<NodeT>(xyz);
2781 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
2782 }
2783
2784
2785 template<typename ChildT>
2786 template<typename NodeT>
2787 inline const NodeT*
2788 121740 RootNode<ChildT>::probeConstNode(const Coord& xyz) const
2789 {
2790 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2791 NodeT::LEVEL > ChildT::LEVEL) return nullptr;
2792 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
2793 121955 MapCIter iter = this->findCoord(xyz);
2794
42/240
✓ Branch 0 taken 89822 times.
✓ Branch 1 taken 1753 times.
✓ Branch 2 taken 89818 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 7 times.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 16 times.
✓ Branch 14 taken 9 times.
✓ Branch 15 taken 7 times.
✓ Branch 16 taken 1 times.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
✓ Branch 20 taken 101 times.
✓ Branch 21 taken 35 times.
✓ Branch 22 taken 99 times.
✓ Branch 23 taken 2 times.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 1 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 1 times.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 68 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 72 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 76 not taken.
✗ Branch 77 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 80 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 84 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 88 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 92 not taken.
✓ Branch 93 taken 1 times.
✓ Branch 94 taken 1 times.
✗ Branch 95 not taken.
✗ Branch 96 not taken.
✓ Branch 97 taken 1 times.
✗ Branch 98 not taken.
✓ Branch 99 taken 1 times.
✗ Branch 100 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 112 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✗ Branch 115 not taken.
✗ Branch 116 not taken.
✓ Branch 117 taken 2 times.
✗ Branch 118 not taken.
✓ Branch 119 taken 2 times.
✗ Branch 120 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 123 not taken.
✓ Branch 124 taken 1 times.
✓ Branch 125 taken 6 times.
✓ Branch 126 taken 3 times.
✓ Branch 127 taken 3 times.
✗ Branch 128 not taken.
✓ Branch 129 taken 21 times.
✓ Branch 130 taken 15 times.
✓ Branch 131 taken 6 times.
✗ Branch 132 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 135 not taken.
✗ Branch 136 not taken.
✗ Branch 137 not taken.
✗ Branch 138 not taken.
✗ Branch 139 not taken.
✗ Branch 140 not taken.
✓ Branch 141 taken 1 times.
✓ Branch 142 taken 1 times.
✗ Branch 143 not taken.
✗ Branch 144 not taken.
✓ Branch 145 taken 1 times.
✗ Branch 146 not taken.
✓ Branch 147 taken 1 times.
✗ Branch 148 not taken.
✗ Branch 149 not taken.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 152 not taken.
✗ Branch 153 not taken.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✗ Branch 156 not taken.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
✗ Branch 159 not taken.
✗ Branch 160 not taken.
✗ Branch 161 not taken.
✗ Branch 162 not taken.
✗ Branch 163 not taken.
✗ Branch 164 not taken.
✗ Branch 165 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 168 not taken.
✗ Branch 169 not taken.
✗ Branch 170 not taken.
✗ Branch 171 not taken.
✗ Branch 172 not taken.
✗ Branch 173 not taken.
✗ Branch 174 not taken.
✗ Branch 175 not taken.
✗ Branch 176 not taken.
✗ Branch 177 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✗ Branch 180 not taken.
✗ Branch 181 not taken.
✗ Branch 182 not taken.
✗ Branch 183 not taken.
✗ Branch 184 not taken.
✗ Branch 185 not taken.
✗ Branch 186 not taken.
✗ Branch 187 not taken.
✗ Branch 188 not taken.
✗ Branch 189 not taken.
✗ Branch 190 not taken.
✗ Branch 191 not taken.
✗ Branch 192 not taken.
✗ Branch 193 not taken.
✗ Branch 194 not taken.
✗ Branch 195 not taken.
✗ Branch 196 not taken.
✗ Branch 197 not taken.
✗ Branch 198 not taken.
✗ Branch 199 not taken.
✗ Branch 200 not taken.
✗ Branch 201 not taken.
✗ Branch 202 not taken.
✗ Branch 203 not taken.
✗ Branch 204 not taken.
✗ Branch 205 not taken.
✗ Branch 206 not taken.
✗ Branch 207 not taken.
✗ Branch 208 not taken.
✗ Branch 209 not taken.
✗ Branch 210 not taken.
✗ Branch 211 not taken.
✗ Branch 212 not taken.
✗ Branch 213 not taken.
✗ Branch 214 not taken.
✗ Branch 215 not taken.
✗ Branch 216 not taken.
✗ Branch 217 not taken.
✗ Branch 218 not taken.
✗ Branch 219 not taken.
✗ Branch 220 not taken.
✗ Branch 221 not taken.
✗ Branch 222 not taken.
✗ Branch 223 not taken.
✗ Branch 224 not taken.
✗ Branch 225 not taken.
✗ Branch 226 not taken.
✗ Branch 227 not taken.
✗ Branch 228 not taken.
✗ Branch 229 not taken.
✗ Branch 230 not taken.
✗ Branch 231 not taken.
✗ Branch 232 not taken.
✗ Branch 233 not taken.
✗ Branch 234 not taken.
✗ Branch 235 not taken.
✗ Branch 236 not taken.
✗ Branch 237 not taken.
✗ Branch 238 not taken.
✗ Branch 239 not taken.
121955 if (iter == mTable.end() || isTile(iter)) return nullptr;
2795 const ChildT* child = &getChild(iter);
2796 return (std::is_same<NodeT, ChildT>::value)
2797 118229 ? reinterpret_cast<const NodeT*>(child)
2798 118336 : child->template probeConstNode<NodeT>(xyz);
2799 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
2800 }
2801
2802
2803 template<typename ChildT>
2804 inline typename ChildT::LeafNodeType*
2805 RootNode<ChildT>::probeLeaf(const Coord& xyz)
2806 {
2807 38035 return this->template probeNode<LeafNodeType>(xyz);
2808 }
2809
2810
2811 template<typename ChildT>
2812 inline const typename ChildT::LeafNodeType*
2813 RootNode<ChildT>::probeConstLeaf(const Coord& xyz) const
2814 {
2815 78217 return this->template probeConstNode<LeafNodeType>(xyz);
2816 }
2817
2818
2819 template<typename ChildT>
2820 template<typename AccessorT>
2821 inline typename ChildT::LeafNodeType*
2822 RootNode<ChildT>::probeLeafAndCache(const Coord& xyz, AccessorT& acc)
2823 {
2824 return this->template probeNodeAndCache<LeafNodeType>(xyz, acc);
2825 }
2826
2827
2828 template<typename ChildT>
2829 template<typename AccessorT>
2830 inline const typename ChildT::LeafNodeType*
2831 RootNode<ChildT>::probeConstLeafAndCache(const Coord& xyz, AccessorT& acc) const
2832 {
2833 return this->template probeConstNodeAndCache<LeafNodeType>(xyz, acc);
2834 }
2835
2836
2837 template<typename ChildT>
2838 template<typename AccessorT>
2839 inline const typename ChildT::LeafNodeType*
2840 RootNode<ChildT>::probeLeafAndCache(const Coord& xyz, AccessorT& acc) const
2841 {
2842 return this->probeConstLeafAndCache(xyz, acc);
2843 }
2844
2845
2846 template<typename ChildT>
2847 template<typename NodeT, typename AccessorT>
2848 inline NodeT*
2849 1749100 RootNode<ChildT>::probeNodeAndCache(const Coord& xyz, AccessorT& acc)
2850 {
2851 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2852 NodeT::LEVEL > ChildT::LEVEL) return nullptr;
2853 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
2854 1749100 MapIter iter = this->findCoord(xyz);
2855
3/4
✓ Branch 0 taken 840840 times.
✓ Branch 1 taken 33712 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 840840 times.
1749100 if (iter == mTable.end() || isTile(iter)) return nullptr;
2856 ChildT* child = &getChild(iter);
2857 1681676 acc.insert(xyz, child);
2858 return (std::is_same<NodeT, ChildT>::value)
2859 1681676 ? reinterpret_cast<NodeT*>(child)
2860 1681676 : child->template probeNodeAndCache<NodeT>(xyz, acc);
2861 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
2862 }
2863
2864
2865 template<typename ChildT>
2866 template<typename NodeT,typename AccessorT>
2867 inline const NodeT*
2868 101750241 RootNode<ChildT>::probeConstNodeAndCache(const Coord& xyz, AccessorT& acc) const
2869 {
2870 if ((NodeT::LEVEL == ChildT::LEVEL && !(std::is_same<NodeT, ChildT>::value)) ||
2871 NodeT::LEVEL > ChildT::LEVEL) return nullptr;
2872 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
2873 101750241 MapCIter iter = this->findCoord(xyz);
2874
4/4
✓ Branch 0 taken 37131785 times.
✓ Branch 1 taken 15237391 times.
✓ Branch 2 taken 34516928 times.
✓ Branch 3 taken 2614857 times.
101750241 if (iter == mTable.end() || isTile(iter)) return nullptr;
2875 const ChildT* child = &getChild(iter);
2876 2636367 acc.insert(xyz, child);
2877 return (std::is_same<NodeT, ChildT>::value)
2878 2626273 ? reinterpret_cast<const NodeT*>(child)
2879 2636367 : child->template probeConstNodeAndCache<NodeT>(xyz, acc);
2880 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
2881 }
2882
2883
2884 ////////////////////////////////////////
2885
2886 template<typename ChildT>
2887 template<typename ArrayT>
2888 inline void
2889 67738 RootNode<ChildT>::getNodes(ArrayT& array)
2890 {
2891 using NodePtr = typename ArrayT::value_type;
2892 static_assert(std::is_pointer<NodePtr>::value,
2893 "argument to getNodes() must be a pointer array");
2894 using NodeType = typename std::remove_pointer<NodePtr>::type;
2895 using NonConstNodeType = typename std::remove_const<NodeType>::type;
2896 static_assert(NodeChainType::template Contains<NonConstNodeType>,
2897 "can't extract non-const nodes from a const tree");
2898 using ArrayChildT = typename std::conditional<
2899 std::is_const<NodeType>::value, const ChildT, ChildT>::type;
2900
2901
2/2
✓ Branch 0 taken 75835 times.
✓ Branch 1 taken 40429 times.
204906 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2902
2/2
✓ Branch 0 taken 75829 times.
✓ Branch 1 taken 6 times.
137168 if (ChildT* child = iter->second.child) {
2903 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
2904 if (std::is_same<NodePtr, ArrayChildT*>::value) {
2905 2 array.push_back(reinterpret_cast<NodePtr>(iter->second.child));
2906 } else {
2907 137154 child->getNodes(array);//descent
2908 }
2909 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
2910 }
2911 }
2912 67738 }
2913
2914 template<typename ChildT>
2915 template<typename ArrayT>
2916 inline void
2917 1734 RootNode<ChildT>::getNodes(ArrayT& array) const
2918 {
2919 using NodePtr = typename ArrayT::value_type;
2920 static_assert(std::is_pointer<NodePtr>::value,
2921 "argument to getNodes() must be a pointer array");
2922 using NodeType = typename std::remove_pointer<NodePtr>::type;
2923 static_assert(std::is_const<NodeType>::value,
2924 "argument to getNodes() must be an array of const node pointers");
2925 using NonConstNodeType = typename std::remove_const<NodeType>::type;
2926 static_assert(NodeChainType::template Contains<NonConstNodeType>,
2927 "can't extract non-const nodes from a const tree");
2928
2929
2/2
✓ Branch 0 taken 3140 times.
✓ Branch 1 taken 867 times.
8014 for (MapCIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2930
1/2
✓ Branch 0 taken 3140 times.
✗ Branch 1 not taken.
6280 if (const ChildNodeType *child = iter->second.child) {
2931 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
2932 if (std::is_same<NodePtr, const ChildT*>::value) {
2933 array.push_back(reinterpret_cast<NodePtr>(iter->second.child));
2934 } else {
2935 6280 child->getNodes(array);//descent
2936 }
2937 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
2938 }
2939 }
2940 1734 }
2941
2942 ////////////////////////////////////////
2943
2944 template<typename ChildT>
2945 template<typename ArrayT>
2946 inline void
2947 241280 RootNode<ChildT>::stealNodes(ArrayT& array, const ValueType& value, bool state)
2948 {
2949 using NodePtr = typename ArrayT::value_type;
2950 static_assert(std::is_pointer<NodePtr>::value,
2951 "argument to stealNodes() must be a pointer array");
2952 using NodeType = typename std::remove_pointer<NodePtr>::type;
2953 using NonConstNodeType = typename std::remove_const<NodeType>::type;
2954 static_assert(NodeChainType::template Contains<NonConstNodeType>,
2955 "can't extract non-const nodes from a const tree");
2956 using ArrayChildT = typename std::conditional<
2957 std::is_const<NodeType>::value, const ChildT, ChildT>::type;
2958
2959
2/2
✓ Branch 0 taken 122513 times.
✓ Branch 1 taken 120640 times.
486306 for (MapIter iter=mTable.begin(); iter!=mTable.end(); ++iter) {
2960
2/2
✓ Branch 0 taken 116281 times.
✓ Branch 1 taken 6232 times.
245026 if (ChildT* child = iter->second.child) {
2961 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
2962 if (std::is_same<NodePtr, ArrayChildT*>::value) {
2963
1/2
✓ Branch 1 taken 285 times.
✗ Branch 2 not taken.
102358 array.push_back(reinterpret_cast<NodePtr>(&stealChild(iter, Tile(value, state))));
2964 } else {
2965 130204 child->stealNodes(array, value, state);//descent
2966 }
2967 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
2968 }
2969 }
2970 241280 }
2971
2972
2973 ////////////////////////////////////////
2974
2975
2976 template<typename ChildT>
2977 template<MergePolicy Policy>
2978 inline void
2979 34314 RootNode<ChildT>::merge(RootNode& other)
2980 {
2981 OPENVDB_NO_UNREACHABLE_CODE_WARNING_BEGIN
2982
2983 switch (Policy) {
2984
2985 default:
2986 case MERGE_ACTIVE_STATES:
2987
2/2
✓ Branch 0 taken 48589 times.
✓ Branch 1 taken 17147 times.
131472 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
2988 97178 MapIter j = mTable.find(i->first);
2989
1/2
✓ Branch 0 taken 48589 times.
✗ Branch 1 not taken.
97178 if (other.isChild(i)) {
2990
2/2
✓ Branch 0 taken 6059 times.
✓ Branch 1 taken 42530 times.
97178 if (j == mTable.end()) { // insert other node's child
2991 12118 ChildNodeType& child = stealChild(i, Tile(other.mBackground, /*on=*/false));
2992
1/2
✓ Branch 1 taken 1451 times.
✗ Branch 2 not taken.
12118 child.resetBackground(other.mBackground, mBackground);
2993
1/2
✓ Branch 1 taken 6059 times.
✗ Branch 2 not taken.
12118 mTable[i->first] = NodeStruct(child);
2994
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42530 times.
85060 } else if (isTile(j)) {
2995 if (isTileOff(j)) { // replace inactive tile with other node's child
2996 ChildNodeType& child = stealChild(i, Tile(other.mBackground, /*on=*/false));
2997 child.resetBackground(other.mBackground, mBackground);
2998 setChild(j, child);
2999 }
3000 } else { // merge both child nodes
3001 85060 getChild(j).template merge<MERGE_ACTIVE_STATES>(getChild(i),
3002
1/2
✓ Branch 1 taken 42530 times.
✗ Branch 2 not taken.
85060 other.mBackground, mBackground);
3003 }
3004 } else if (other.isTileOn(i)) {
3005 if (j == mTable.end()) { // insert other node's active tile
3006 mTable[i->first] = i->second;
3007 } else if (!isTileOn(j)) {
3008 // Replace anything except an active tile with the other node's active tile.
3009 setTile(j, Tile(other.getTile(i).value, true));
3010 }
3011 }
3012 }
3013 break;
3014
3015 case MERGE_NODES:
3016
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
16 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3017 12 MapIter j = mTable.find(i->first);
3018
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
12 if (other.isChild(i)) {
3019
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
12 if (j == mTable.end()) { // insert other node's child
3020 4 ChildNodeType& child = stealChild(i, Tile(other.mBackground, /*on=*/false));
3021
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 child.resetBackground(other.mBackground, mBackground);
3022
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 mTable[i->first] = NodeStruct(child);
3023
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
8 } else if (isTile(j)) { // replace tile with other node's child
3024 ChildNodeType& child = stealChild(i, Tile(other.mBackground, /*on=*/false));
3025 child.resetBackground(other.mBackground, mBackground);
3026 setChild(j, child);
3027 } else { // merge both child nodes
3028 8 getChild(j).template merge<MERGE_NODES>(
3029
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 getChild(i), other.mBackground, mBackground);
3030 }
3031 }
3032 }
3033 break;
3034
3035 case MERGE_ACTIVE_STATES_AND_NODES:
3036
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 8 times.
36 for (MapIter i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3037 20 MapIter j = mTable.find(i->first);
3038
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
20 if (other.isChild(i)) {
3039
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
20 if (j == mTable.end()) {
3040 // Steal and insert the other node's child.
3041 4 ChildNodeType& child = stealChild(i, Tile(other.mBackground, /*on=*/false));
3042
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 child.resetBackground(other.mBackground, mBackground);
3043
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 mTable[i->first] = NodeStruct(child);
3044
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
16 } else if (isTile(j)) {
3045 // Replace this node's tile with the other node's child.
3046 ChildNodeType& child = stealChild(i, Tile(other.mBackground, /*on=*/false));
3047 child.resetBackground(other.mBackground, mBackground);
3048 const Tile tile = getTile(j);
3049 setChild(j, child);
3050 if (tile.active) {
3051 // Merge the other node's child with this node's active tile.
3052 child.template merge<MERGE_ACTIVE_STATES_AND_NODES>(
3053 tile.value, tile.active);
3054 }
3055 } else /*if (isChild(j))*/ {
3056 // Merge the other node's child into this node's child.
3057 16 getChild(j).template merge<MERGE_ACTIVE_STATES_AND_NODES>(getChild(i),
3058
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 other.mBackground, mBackground);
3059 }
3060 } else if (other.isTileOn(i)) {
3061 if (j == mTable.end()) {
3062 // Insert a copy of the other node's active tile.
3063 mTable[i->first] = i->second;
3064 } else if (isTileOff(j)) {
3065 // Replace this node's inactive tile with a copy of the other's active tile.
3066 setTile(j, Tile(other.getTile(i).value, true));
3067 } else if (isChild(j)) {
3068 // Merge the other node's active tile into this node's child.
3069 const Tile& tile = getTile(i);
3070 getChild(j).template merge<MERGE_ACTIVE_STATES_AND_NODES>(
3071 tile.value, tile.active);
3072 }
3073 } // else if (other.isTileOff(i)) {} // ignore the other node's inactive tiles
3074 }
3075 break;
3076 }
3077
3078 // Empty the other tree so as not to leave it in a partially cannibalized state.
3079 34314 other.clear();
3080
3081 OPENVDB_NO_UNREACHABLE_CODE_WARNING_END
3082 }
3083
3084
3085 ////////////////////////////////////////
3086
3087
3088 template<typename ChildT>
3089 template<typename OtherChildType>
3090 inline void
3091 21945 RootNode<ChildT>::topologyUnion(const RootNode<OtherChildType>& other, const bool preserveTiles)
3092 {
3093 using OtherRootT = RootNode<OtherChildType>;
3094 using OtherCIterT = typename OtherRootT::MapCIter;
3095
3096 21945 enforceSameConfiguration(other);
3097
3098
2/2
✓ Branch 0 taken 17567 times.
✓ Branch 1 taken 12224 times.
54259 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3099 32314 MapIter j = mTable.find(i->first);
3100
2/2
✓ Branch 0 taken 17565 times.
✓ Branch 1 taken 2 times.
32314 if (other.isChild(i)) {
3101
2/2
✓ Branch 0 taken 10764 times.
✓ Branch 1 taken 6801 times.
32312 if (j == mTable.end()) { // create child branch with identical topology
3102
1/2
✓ Branch 1 taken 10764 times.
✗ Branch 2 not taken.
18712 mTable[i->first] = NodeStruct(
3103
2/4
✓ Branch 1 taken 10764 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10764 times.
✗ Branch 5 not taken.
18712 *(new ChildT(other.getChild(i), mBackground, TopologyCopy())));
3104
2/2
✓ Branch 0 taken 6798 times.
✓ Branch 1 taken 3 times.
13600 } else if (this->isChild(j)) { // union with child branch
3105
1/2
✓ Branch 1 taken 6798 times.
✗ Branch 2 not taken.
13594 this->getChild(j).topologyUnion(other.getChild(i), preserveTiles);
3106 } else {// this is a tile so replace it with a child branch with identical topology
3107
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
6 if (!preserveTiles || this->isTileOff(j)) { // force child topology
3108
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
4 ChildT* child = new ChildT(
3109
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 other.getChild(i), this->getTile(j).value, TopologyCopy());
3110 4 if (this->isTileOn(j)) child->setValuesOn();//this is an active tile
3111 this->setChild(j, *child);
3112 }
3113 }
3114 } else if (other.isTileOn(i)) { // other is an active tile
3115
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (j == mTable.end()) { // insert an active tile
3116
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 mTable[i->first] = NodeStruct(Tile(mBackground, true));
3117 } else if (this->isChild(j)) {
3118 this->getChild(j).setValuesOn();
3119 } else if (this->isTileOff(j)) {
3120 this->setTile(j, Tile(this->getTile(j).value, true));
3121 }
3122 }
3123 }
3124 21945 }
3125
3126 template<typename ChildT>
3127 template<typename OtherChildType>
3128 inline void
3129 339 RootNode<ChildT>::topologyIntersection(const RootNode<OtherChildType>& other)
3130 {
3131 using OtherRootT = RootNode<OtherChildType>;
3132 using OtherCIterT = typename OtherRootT::MapCIter;
3133
3134 339 enforceSameConfiguration(other);
3135
3136 std::set<Coord> tmp;//keys to erase
3137
2/2
✓ Branch 0 taken 1213 times.
✓ Branch 1 taken 295 times.
1744 for (MapIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
3138 1405 OtherCIterT j = other.mTable.find(i->first);
3139
2/2
✓ Branch 0 taken 1212 times.
✓ Branch 1 taken 1 times.
1405 if (this->isChild(i)) {
3140
2/2
✓ Branch 0 taken 374 times.
✓ Branch 1 taken 838 times.
1403 if (j == other.mTable.end() || other.isTileOff(j)) {
3141 tmp.insert(i->first);//delete child branch
3142
1/2
✓ Branch 0 taken 373 times.
✗ Branch 1 not taken.
467 } else if (other.isChild(j)) { // intersect with child branch
3143
1/2
✓ Branch 1 taken 373 times.
✗ Branch 2 not taken.
467 this->getChild(i).topologyIntersection(other.getChild(j), mBackground);
3144 }
3145 } else if (this->isTileOn(i)) {
3146
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 if (j == other.mTable.end() || other.isTileOff(j)) {
3147 this->setTile(i, Tile(this->getTile(i).value, false));//turn inactive
3148
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 } else if (other.isChild(j)) { //replace with a child branch with identical topology
3149 2 ChildT* child =
3150
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 new ChildT(other.getChild(j), this->getTile(i).value, TopologyCopy());
3151 this->setChild(i, *child);
3152 }
3153 }
3154 }
3155
2/2
✓ Branch 0 taken 839 times.
✓ Branch 1 taken 295 times.
1275 for (std::set<Coord>::iterator i = tmp.begin(), e = tmp.end(); i != e; ++i) {
3156 936 MapIter it = this->findCoord(*i);
3157 936 setTile(it, Tile()); // delete any existing child node first
3158 936 mTable.erase(it);
3159 }
3160 339 }
3161
3162 template<typename ChildT>
3163 template<typename OtherChildType>
3164 inline void
3165 50 RootNode<ChildT>::topologyDifference(const RootNode<OtherChildType>& other)
3166 {
3167 using OtherRootT = RootNode<OtherChildType>;
3168 using OtherCIterT = typename OtherRootT::MapCIter;
3169
3170 50 enforceSameConfiguration(other);
3171
3172
2/2
✓ Branch 0 taken 181 times.
✓ Branch 1 taken 42 times.
295 for (OtherCIterT i = other.mTable.begin(), e = other.mTable.end(); i != e; ++i) {
3173 245 MapIter j = mTable.find(i->first);
3174
2/2
✓ Branch 0 taken 179 times.
✓ Branch 1 taken 2 times.
245 if (other.isChild(i)) {
3175
2/2
✓ Branch 0 taken 178 times.
✓ Branch 1 taken 1 times.
243 if (j == mTable.end() || this->isTileOff(j)) {
3176 //do nothing
3177
2/2
✓ Branch 0 taken 177 times.
✓ Branch 1 taken 1 times.
242 } else if (this->isChild(j)) { // difference with child branch
3178
1/2
✓ Branch 1 taken 177 times.
✗ Branch 2 not taken.
241 this->getChild(j).topologyDifference(other.getChild(i), mBackground);
3179 } else if (this->isTileOn(j)) {
3180 // this is an active tile so create a child node and descent
3181
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ChildT* child = new ChildT(j->first, this->getTile(j).value, true);
3182
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 child->topologyDifference(other.getChild(i), mBackground);
3183 this->setChild(j, *child);
3184 }
3185 } else if (other.isTileOn(i)) { // other is an active tile
3186
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (j == mTable.end() || this->isTileOff(j)) {
3187 // do nothing
3188
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 } else if (this->isChild(j)) {
3189 1 setTile(j, Tile()); // delete any existing child node first
3190 1 mTable.erase(j);
3191 } else if (this->isTileOn(j)) {
3192 this->setTile(j, Tile(this->getTile(j).value, false));
3193 }
3194 }
3195 }
3196 50 }
3197
3198 ////////////////////////////////////////
3199
3200
3201 template<typename ChildT>
3202 template<typename CombineOp>
3203 inline void
3204
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
70 RootNode<ChildT>::combine(RootNode& other, CombineOp& op, bool prune)
3205 {
3206 CombineArgs<ValueType> args;
3207
3208 CoordSet keys;
3209
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
70 this->insertKeys(keys);
3210
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
70 other.insertKeys(keys);
3211
3212
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 37 times.
142 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3213
2/4
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
72 MapIter iter = findOrAddCoord(*i), otherIter = other.findOrAddCoord(*i);
3214
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
72 if (isTile(iter) && isTile(otherIter)) {
3215 // Both this node and the other node have constant values (tiles).
3216 // Combine the two values and store the result as this node's new tile value.
3217 op(args.setARef(getTile(iter).value)
3218 .setAIsActive(isTileOn(iter))
3219 .setBRef(getTile(otherIter).value)
3220 .setBIsActive(isTileOn(otherIter)));
3221 setTile(iter, Tile(args.result(), args.resultIsActive()));
3222
3223
3/4
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
72 } else if (isChild(iter) && isTile(otherIter)) {
3224 // Combine this node's child with the other node's constant value.
3225 ChildT& child = getChild(iter);
3226 child.combine(getTile(otherIter).value, isTileOn(otherIter), op);
3227
3228
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
72 } else if (isTile(iter) && isChild(otherIter)) {
3229 // Combine this node's constant value with the other node's child,
3230 // but use a new functor in which the A and B values are swapped,
3231 // since the constant value is the A value, not the B value.
3232 SwappedCombineOp<ValueType, CombineOp> swappedOp(op);
3233 ChildT& child = getChild(otherIter);
3234
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 child.combine(getTile(iter).value, isTileOn(iter), swappedOp);
3235
3236 // Steal the other node's child.
3237 3 setChild(iter, stealChild(otherIter, Tile()));
3238
3239 } else /*if (isChild(iter) && isChild(otherIter))*/ {
3240 // Combine this node's child with the other node's child.
3241 ChildT &child = getChild(iter), &otherChild = getChild(otherIter);
3242
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
69 child.combine(otherChild, op);
3243 }
3244
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
72 if (prune && isChild(iter)) getChild(iter).prune();
3245 }
3246
3247 // Combine background values.
3248
1/2
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
70 op(args.setARef(mBackground).setBRef(other.mBackground));
3249 70 mBackground = args.result();
3250
3251 // Empty the other tree so as not to leave it in a partially cannibalized state.
3252 70 other.clear();
3253 70 }
3254
3255
3256 ////////////////////////////////////////
3257
3258
3259 // This helper class is a friend of RootNode and is needed so that combine2
3260 // can be specialized for compatible and incompatible pairs of RootNode types.
3261 template<typename CombineOp, typename RootT, typename OtherRootT, bool Compatible = false>
3262 struct RootNodeCombineHelper
3263 {
3264 static inline void combine2(RootT& self, const RootT&, const OtherRootT& other1,
3265 CombineOp&, bool)
3266 {
3267 // If the two root nodes have different configurations or incompatible ValueTypes,
3268 // throw an exception.
3269
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 self.enforceSameConfiguration(other1);
3270 1 self.enforceCompatibleValueTypes(other1);
3271 // One of the above two tests should throw, so we should never get here:
3272 std::ostringstream ostr;
3273 ostr << "cannot combine a " << typeid(OtherRootT).name()
3274 << " into a " << typeid(RootT).name();
3275 OPENVDB_THROW(TypeError, ostr.str());
3276 }
3277 };
3278
3279 // Specialization for root nodes of compatible types
3280 template<typename CombineOp, typename RootT, typename OtherRootT>
3281 struct RootNodeCombineHelper<CombineOp, RootT, OtherRootT, /*Compatible=*/true>
3282 {
3283 static inline void combine2(RootT& self, const RootT& other0, const OtherRootT& other1,
3284 CombineOp& op, bool prune)
3285 {
3286
4/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
4 self.doCombine2(other0, other1, op, prune);
3287 }
3288 };
3289
3290
3291 template<typename ChildT>
3292 template<typename CombineOp, typename OtherRootNode>
3293 inline void
3294 RootNode<ChildT>::combine2(const RootNode& other0, const OtherRootNode& other1,
3295 CombineOp& op, bool prune)
3296 {
3297 using OtherValueType = typename OtherRootNode::ValueType;
3298 static const bool compatible = (SameConfiguration<OtherRootNode>::value
3299 && CanConvertType</*from=*/OtherValueType, /*to=*/ValueType>::value);
3300 RootNodeCombineHelper<CombineOp, RootNode, OtherRootNode, compatible>::combine2(
3301 *this, other0, other1, op, prune);
3302 }
3303
3304
3305 template<typename ChildT>
3306 template<typename CombineOp, typename OtherRootNode>
3307 inline void
3308 8 RootNode<ChildT>::doCombine2(const RootNode& other0, const OtherRootNode& other1,
3309 CombineOp& op, bool prune)
3310 {
3311 8 enforceSameConfiguration(other1);
3312
3313 using OtherValueT = typename OtherRootNode::ValueType;
3314 using OtherTileT = typename OtherRootNode::Tile;
3315 using OtherNodeStructT = typename OtherRootNode::NodeStruct;
3316 using OtherMapCIterT = typename OtherRootNode::MapCIter;
3317
3318 CombineArgs<ValueType, OtherValueT> args;
3319
3320 CoordSet keys;
3321
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 other0.insertKeys(keys);
3322
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 other1.insertKeys(keys);
3323
3324 8 const NodeStruct bg0(Tile(other0.mBackground, /*active=*/false));
3325 8 const OtherNodeStructT bg1(OtherTileT(other1.mBackground, /*active=*/false));
3326
3327
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
16 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3328
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 MapIter thisIter = this->findOrAddCoord(*i);
3329 8 MapCIter iter0 = other0.findKey(*i);
3330
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
8 OtherMapCIterT iter1 = other1.findKey(*i);
3331
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
8 const NodeStruct& ns0 = (iter0 != other0.mTable.end()) ? iter0->second : bg0;
3332
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
8 const OtherNodeStructT& ns1 = (iter1 != other1.mTable.end()) ? iter1->second : bg1;
3333
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 if (ns0.isTile() && ns1.isTile()) {
3334 // Both input nodes have constant values (tiles).
3335 // Combine the two values and add a new tile to this node with the result.
3336 op(args.setARef(ns0.tile.value)
3337 .setAIsActive(ns0.isTileOn())
3338 .setBRef(ns1.tile.value)
3339 .setBIsActive(ns1.isTileOn()));
3340 setTile(thisIter, Tile(args.result(), args.resultIsActive()));
3341 } else {
3342
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
8 if (!isChild(thisIter)) {
3343 // Add a new child with the same coordinates, etc. as the other node's child.
3344 const Coord& childOrigin =
3345
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
8 ns0.isChild() ? ns0.child->origin() : ns1.child->origin();
3346
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 setChild(thisIter, *(new ChildT(childOrigin, getTile(thisIter).value)));
3347 }
3348 ChildT& child = getChild(thisIter);
3349
3350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
8 if (ns0.isTile()) {
3351 // Combine node1's child with node0's constant value
3352 // and write the result into this node's child.
3353 child.combine2(ns0.tile.value, *ns1.child, ns0.isTileOn(), op);
3354
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
8 } else if (ns1.isTile()) {
3355 // Combine node0's child with node1's constant value
3356 // and write the result into this node's child.
3357 child.combine2(*ns0.child, ns1.tile.value, ns1.isTileOn(), op);
3358 } else {
3359 // Combine node0's child with node1's child
3360 // and write the result into this node's child.
3361
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 child.combine2(*ns0.child, *ns1.child, op);
3362 }
3363 }
3364
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
8 if (prune && isChild(thisIter)) getChild(thisIter).prune();
3365 }
3366
3367 // Combine background values.
3368
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 op(args.setARef(other0.mBackground).setBRef(other1.mBackground));
3369 8 mBackground = args.result();
3370 8 }
3371
3372
3373 ////////////////////////////////////////
3374
3375
3376 template<typename ChildT>
3377 template<typename BBoxOp>
3378 inline void
3379 4 RootNode<ChildT>::visitActiveBBox(BBoxOp& op) const
3380 {
3381 const bool descent = op.template descent<LEVEL>();
3382
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 for (MapCIter i = mTable.begin(), e = mTable.end(); i != e; ++i) {
3383 if (this->isTileOff(i)) continue;
3384
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 if (this->isChild(i) && descent) {
3385 6 this->getChild(i).visitActiveBBox(op);
3386 } else {
3387 2 op.template operator()<LEVEL>(CoordBBox::createCube(i->first, ChildT::DIM));
3388 }
3389 }
3390 4 }
3391
3392
3393 template<typename ChildT>
3394 template<typename VisitorOp>
3395 inline void
3396 RootNode<ChildT>::visit(VisitorOp& op)
3397 {
3398
5/10
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
5 doVisit<RootNode, VisitorOp, ChildAllIter>(*this, op);
3399 }
3400
3401
3402 template<typename ChildT>
3403 template<typename VisitorOp>
3404 inline void
3405 RootNode<ChildT>::visit(VisitorOp& op) const
3406 {
3407
10/20
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
10 doVisit<const RootNode, VisitorOp, ChildAllCIter>(*this, op);
3408 }
3409
3410
3411 template<typename ChildT>
3412 template<typename RootNodeT, typename VisitorOp, typename ChildAllIterT>
3413 inline void
3414 30 RootNode<ChildT>::doVisit(RootNodeT& self, VisitorOp& op)
3415 {
3416 typename RootNodeT::ValueType val;
3417
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 15 times.
90 for (ChildAllIterT iter = self.beginChildAll(); iter; ++iter) {
3418
2/4
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
30 if (op(iter)) continue;
3419 if (typename ChildAllIterT::ChildNodeType* child = iter.probeChild(val)) {
3420 child->visit(op);
3421 }
3422 }
3423 30 }
3424
3425
3426 ////////////////////////////////////////
3427
3428
3429 template<typename ChildT>
3430 template<typename OtherRootNodeType, typename VisitorOp>
3431 inline void
3432 RootNode<ChildT>::visit2(OtherRootNodeType& other, VisitorOp& op)
3433 {
3434 doVisit2<RootNode, OtherRootNodeType, VisitorOp, ChildAllIter,
3435
5/10
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
5 typename OtherRootNodeType::ChildAllIter>(*this, other, op);
3436 }
3437
3438
3439 template<typename ChildT>
3440 template<typename OtherRootNodeType, typename VisitorOp>
3441 inline void
3442 RootNode<ChildT>::visit2(OtherRootNodeType& other, VisitorOp& op) const
3443 {
3444 doVisit2<const RootNode, OtherRootNodeType, VisitorOp, ChildAllCIter,
3445 typename OtherRootNodeType::ChildAllCIter>(*this, other, op);
3446 }
3447
3448
3449 template<typename ChildT>
3450 template<
3451 typename RootNodeT,
3452 typename OtherRootNodeT,
3453 typename VisitorOp,
3454 typename ChildAllIterT,
3455 typename OtherChildAllIterT>
3456 inline void
3457 10 RootNode<ChildT>::doVisit2(RootNodeT& self, OtherRootNodeT& other, VisitorOp& op)
3458 {
3459 10 enforceSameConfiguration(other);
3460
3461 typename RootNodeT::ValueType val;
3462 typename OtherRootNodeT::ValueType otherVal;
3463
3464 // The two nodes are required to have corresponding table entries,
3465 // but since that might require background tiles to be added to one or both,
3466 // and the nodes might be const, we operate on shallow copies of the nodes instead.
3467 RootNodeT copyOfSelf(self.mBackground);
3468 copyOfSelf.mTable = self.mTable;
3469 OtherRootNodeT copyOfOther(other.mBackground);
3470 copyOfOther.mTable = other.mTable;
3471
3472 // Add background tiles to both nodes as needed.
3473 CoordSet keys;
3474
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
10 self.insertKeys(keys);
3475
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
10 other.insertKeys(keys);
3476
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 5 times.
28 for (CoordSetCIter i = keys.begin(), e = keys.end(); i != e; ++i) {
3477
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
18 copyOfSelf.findOrAddCoord(*i);
3478
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
18 copyOfOther.findOrAddCoord(*i);
3479 }
3480
3481 10 ChildAllIterT iter = copyOfSelf.beginChildAll();
3482 10 OtherChildAllIterT otherIter = copyOfOther.beginChildAll();
3483
3484
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
46 for ( ; iter && otherIter; ++iter, ++otherIter)
3485 {
3486
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
18 const size_t skipBranch = static_cast<size_t>(op(iter, otherIter));
3487
3488 typename ChildAllIterT::ChildNodeType* child =
3489
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
18 (skipBranch & 1U) ? nullptr : iter.probeChild(val);
3490 typename OtherChildAllIterT::ChildNodeType* otherChild =
3491
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
18 (skipBranch & 2U) ? nullptr : otherIter.probeChild(otherVal);
3492
3493
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
18 if (child != nullptr && otherChild != nullptr) {
3494 child->visit2Node(*otherChild, op);
3495
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
8 } else if (child != nullptr) {
3496 child->visit2(otherIter, op);
3497
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 } else if (otherChild != nullptr) {
3498 otherChild->visit2(iter, op, /*otherIsLHS=*/true);
3499 }
3500 }
3501 // Remove any background tiles that were added above,
3502 // as well as any that were created by the visitors.
3503
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
10 copyOfSelf.eraseBackgroundTiles();
3504
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
10 copyOfOther.eraseBackgroundTiles();
3505
3506 // If either input node is non-const, replace its table with
3507 // the (possibly modified) copy.
3508 10 self.resetTable(copyOfSelf.mTable);
3509 10 other.resetTable(copyOfOther.mTable);
3510 10 }
3511
3512 } // namespace tree
3513 } // namespace OPENVDB_VERSION_NAME
3514 } // namespace openvdb
3515
3516 #endif // OPENVDB_TREE_ROOTNODE_HAS_BEEN_INCLUDED
3517