Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright Contributors to the OpenVDB Project | ||
2 | // SPDX-License-Identifier: MPL-2.0 | ||
3 | |||
4 | /// @file tools/GridOperators.h | ||
5 | /// | ||
6 | /// @brief Apply an operator to an input grid to produce an output grid | ||
7 | /// with the same active voxel topology but a potentially different value type. | ||
8 | |||
9 | #ifndef OPENVDB_TOOLS_GRID_OPERATORS_HAS_BEEN_INCLUDED | ||
10 | #define OPENVDB_TOOLS_GRID_OPERATORS_HAS_BEEN_INCLUDED | ||
11 | |||
12 | #include "openvdb/Grid.h" | ||
13 | #include "openvdb/math/Operators.h" | ||
14 | #include "openvdb/util/NullInterrupter.h" | ||
15 | #include "openvdb/thread/Threading.h" | ||
16 | #include "openvdb/tree/LeafManager.h" | ||
17 | #include "openvdb/tree/ValueAccessor.h" | ||
18 | #include "ValueTransformer.h" // for tools::foreach() | ||
19 | #include <openvdb/openvdb.h> | ||
20 | |||
21 | #include <tbb/parallel_for.h> | ||
22 | |||
23 | namespace openvdb { | ||
24 | OPENVDB_USE_VERSION_NAMESPACE | ||
25 | namespace OPENVDB_VERSION_NAME { | ||
26 | namespace tools { | ||
27 | |||
28 | /// @brief VectorToScalarConverter<VectorGridType>::Type is the type of a grid | ||
29 | /// having the same tree configuration as VectorGridType but a scalar value type, T, | ||
30 | /// where T is the type of the original vector components. | ||
31 | /// @details For example, VectorToScalarConverter<Vec3DGrid>::Type is equivalent to DoubleGrid. | ||
32 | template<typename VectorGridType> struct VectorToScalarConverter { | ||
33 | typedef typename VectorGridType::ValueType::value_type VecComponentValueT; | ||
34 | typedef typename VectorGridType::template ValueConverter<VecComponentValueT>::Type Type; | ||
35 | }; | ||
36 | |||
37 | /// @brief ScalarToVectorConverter<ScalarGridType>::Type is the type of a grid | ||
38 | /// having the same tree configuration as ScalarGridType but value type Vec3<T> | ||
39 | /// where T is ScalarGridType::ValueType. | ||
40 | /// @details For example, ScalarToVectorConverter<DoubleGrid>::Type is equivalent to Vec3DGrid. | ||
41 | template<typename ScalarGridType> struct ScalarToVectorConverter { | ||
42 | typedef math::Vec3<typename ScalarGridType::ValueType> VectorValueT; | ||
43 | typedef typename ScalarGridType::template ValueConverter<VectorValueT>::Type Type; | ||
44 | }; | ||
45 | |||
46 | |||
47 | /// @brief Compute the Closest-Point Transform (CPT) from a distance field. | ||
48 | /// @return a new vector-valued grid with the same numerical precision as the input grid | ||
49 | /// (for example, if the input grid is a DoubleGrid, the output grid will be a Vec3DGrid) | ||
50 | /// @details When a mask grid is specified, the solution is calculated only in | ||
51 | /// the intersection of the mask active topology and the input active topology | ||
52 | /// independent of the transforms associated with either grid. | ||
53 | template<typename GridType, typename InterruptT> | ||
54 | typename ScalarToVectorConverter<GridType>::Type::Ptr | ||
55 | cpt(const GridType& grid, bool threaded, InterruptT* interrupt); | ||
56 | |||
57 | template<typename GridType, typename MaskT, typename InterruptT> | ||
58 | typename ScalarToVectorConverter<GridType>::Type::Ptr | ||
59 | cpt(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt); | ||
60 | |||
61 | template<typename GridType> | ||
62 | typename ScalarToVectorConverter<GridType>::Type::Ptr | ||
63 | cpt(const GridType& grid, bool threaded = true) | ||
64 | { | ||
65 | return cpt<GridType, util::NullInterrupter>(grid, threaded, nullptr); | ||
66 | } | ||
67 | |||
68 | template<typename GridType, typename MaskT> | ||
69 | typename ScalarToVectorConverter<GridType>::Type::Ptr | ||
70 | cpt(const GridType& grid, const MaskT& mask, bool threaded = true) | ||
71 | { | ||
72 | return cpt<GridType, MaskT, util::NullInterrupter>(grid, mask, threaded, nullptr); | ||
73 | } | ||
74 | |||
75 | |||
76 | /// @brief Compute the curl of the given vector-valued grid. | ||
77 | /// @return a new vector-valued grid | ||
78 | /// @details When a mask grid is specified, the solution is calculated only in | ||
79 | /// the intersection of the mask active topology and the input active topology | ||
80 | /// independent of the transforms associated with either grid. | ||
81 | template<typename GridType, typename InterruptT> | ||
82 | typename GridType::Ptr | ||
83 | curl(const GridType& grid, bool threaded, InterruptT* interrupt); | ||
84 | |||
85 | template<typename GridType, typename MaskT, typename InterruptT> | ||
86 | typename GridType::Ptr | ||
87 | curl(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt); | ||
88 | |||
89 | template<typename GridType> | ||
90 | typename GridType::Ptr | ||
91 | 5 | curl(const GridType& grid, bool threaded = true) | |
92 | { | ||
93 | 5 | return curl<GridType, util::NullInterrupter>(grid, threaded, nullptr); | |
94 | } | ||
95 | |||
96 | template<typename GridType, typename MaskT> | ||
97 | typename GridType::Ptr | ||
98 | 1 | curl(const GridType& grid, const MaskT& mask, bool threaded = true) | |
99 | { | ||
100 | 1 | return curl<GridType, MaskT, util::NullInterrupter>(grid, mask, threaded, nullptr); | |
101 | } | ||
102 | |||
103 | |||
104 | /// @brief Compute the divergence of the given vector-valued grid. | ||
105 | /// @return a new scalar-valued grid with the same numerical precision as the input grid | ||
106 | /// (for example, if the input grid is a Vec3DGrid, the output grid will be a DoubleGrid) | ||
107 | /// @details When a mask grid is specified, the solution is calculated only in | ||
108 | /// the intersection of the mask active topology and the input active topology | ||
109 | /// independent of the transforms associated with either grid. | ||
110 | template<typename GridType, typename InterruptT> | ||
111 | typename VectorToScalarConverter<GridType>::Type::Ptr | ||
112 | divergence(const GridType& grid, bool threaded, InterruptT* interrupt); | ||
113 | |||
114 | template<typename GridType, typename MaskT, typename InterruptT> | ||
115 | typename VectorToScalarConverter<GridType>::Type::Ptr | ||
116 | divergence(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt); | ||
117 | |||
118 | template<typename GridType> | ||
119 | typename VectorToScalarConverter<GridType>::Type::Ptr | ||
120 | 2 | divergence(const GridType& grid, bool threaded = true) | |
121 | { | ||
122 | 2 | return divergence<GridType, util::NullInterrupter>(grid, threaded, nullptr); | |
123 | } | ||
124 | |||
125 | template<typename GridType, typename MaskT> | ||
126 | typename VectorToScalarConverter<GridType>::Type::Ptr | ||
127 | 2 | divergence(const GridType& grid, const MaskT& mask, bool threaded = true) | |
128 | { | ||
129 | 2 | return divergence<GridType, MaskT, util::NullInterrupter>(grid, mask, threaded, nullptr); | |
130 | } | ||
131 | |||
132 | |||
133 | /// @brief Compute the gradient of the given scalar grid. | ||
134 | /// @return a new vector-valued grid with the same numerical precision as the input grid | ||
135 | /// (for example, if the input grid is a DoubleGrid, the output grid will be a Vec3DGrid) | ||
136 | /// @details When a mask grid is specified, the solution is calculated only in | ||
137 | /// the intersection of the mask active topology and the input active topology | ||
138 | /// independent of the transforms associated with either grid. | ||
139 | template<typename GridType, typename InterruptT> | ||
140 | typename ScalarToVectorConverter<GridType>::Type::Ptr | ||
141 | gradient(const GridType& grid, bool threaded, InterruptT* interrupt); | ||
142 | |||
143 | template<typename GridType, typename MaskT, typename InterruptT> | ||
144 | typename ScalarToVectorConverter<GridType>::Type::Ptr | ||
145 | gradient(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt); | ||
146 | |||
147 | template<typename GridType> | ||
148 | typename ScalarToVectorConverter<GridType>::Type::Ptr | ||
149 | 16 | gradient(const GridType& grid, bool threaded = true) | |
150 | { | ||
151 | 16 | return gradient<GridType, util::NullInterrupter>(grid, threaded, nullptr); | |
152 | } | ||
153 | |||
154 | template<typename GridType, typename MaskT> | ||
155 | typename ScalarToVectorConverter<GridType>::Type::Ptr | ||
156 | 1 | gradient(const GridType& grid, const MaskT& mask, bool threaded = true) | |
157 | { | ||
158 | 1 | return gradient<GridType, MaskT, util::NullInterrupter>(grid, mask, threaded, nullptr); | |
159 | } | ||
160 | |||
161 | |||
162 | /// @brief Compute the Laplacian of the given scalar grid. | ||
163 | /// @return a new scalar grid | ||
164 | /// @details When a mask grid is specified, the solution is calculated only in | ||
165 | /// the intersection of the mask active topology and the input active topology | ||
166 | /// independent of the transforms associated with either grid. | ||
167 | template<typename GridType, typename InterruptT> | ||
168 | typename GridType::Ptr | ||
169 | laplacian(const GridType& grid, bool threaded, InterruptT* interrupt); | ||
170 | |||
171 | template<typename GridType, typename MaskT, typename InterruptT> | ||
172 | typename GridType::Ptr | ||
173 | laplacian(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt); | ||
174 | |||
175 | template<typename GridType> | ||
176 | typename GridType::Ptr | ||
177 | 1 | laplacian(const GridType& grid, bool threaded = true) | |
178 | { | ||
179 | 1 | return laplacian<GridType, util::NullInterrupter>(grid, threaded, nullptr); | |
180 | } | ||
181 | |||
182 | template<typename GridType, typename MaskT> | ||
183 | typename GridType::Ptr | ||
184 | 3 | laplacian(const GridType& grid, const MaskT& mask, bool threaded = true) | |
185 | { | ||
186 | 3 | return laplacian<GridType, MaskT, util::NullInterrupter>(grid, mask, threaded, nullptr); | |
187 | } | ||
188 | |||
189 | |||
190 | /// @brief Compute the mean curvature of the given grid. | ||
191 | /// @return a new grid | ||
192 | /// @details When a mask grid is specified, the solution is calculated only in | ||
193 | /// the intersection of the mask active topology and the input active topology | ||
194 | /// independent of the transforms associated with either grid. | ||
195 | template<typename GridType, typename InterruptT> | ||
196 | typename GridType::Ptr | ||
197 | meanCurvature(const GridType& grid, bool threaded, InterruptT* interrupt); | ||
198 | |||
199 | template<typename GridType, typename MaskT, typename InterruptT> | ||
200 | typename GridType::Ptr | ||
201 | meanCurvature(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt); | ||
202 | |||
203 | template<typename GridType> | ||
204 | typename GridType::Ptr | ||
205 | 1 | meanCurvature(const GridType& grid, bool threaded = true) | |
206 | { | ||
207 | 1 | return meanCurvature<GridType, util::NullInterrupter>(grid, threaded, nullptr); | |
208 | } | ||
209 | |||
210 | template<typename GridType, typename MaskT> | ||
211 | typename GridType::Ptr | ||
212 | 1 | meanCurvature(const GridType& grid, const MaskT& mask, bool threaded = true) | |
213 | { | ||
214 | 1 | return meanCurvature<GridType, MaskT, util::NullInterrupter>(grid, mask, threaded, nullptr); | |
215 | } | ||
216 | |||
217 | |||
218 | /// @brief Compute the magnitudes of the vectors of the given vector-valued grid. | ||
219 | /// @return a new scalar-valued grid with the same numerical precision as the input grid | ||
220 | /// (for example, if the input grid is a Vec3DGrid, the output grid will be a DoubleGrid) | ||
221 | /// @details When a mask grid is specified, the solution is calculated only in | ||
222 | /// the intersection of the mask active topology and the input active topology | ||
223 | /// independent of the transforms associated with either grid. | ||
224 | template<typename GridType, typename InterruptT> | ||
225 | typename VectorToScalarConverter<GridType>::Type::Ptr | ||
226 | magnitude(const GridType& grid, bool threaded, InterruptT* interrupt); | ||
227 | |||
228 | template<typename GridType, typename MaskT, typename InterruptT> | ||
229 | typename VectorToScalarConverter<GridType>::Type::Ptr | ||
230 | magnitude(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt); | ||
231 | |||
232 | template<typename GridType> | ||
233 | typename VectorToScalarConverter<GridType>::Type::Ptr | ||
234 | 2 | magnitude(const GridType& grid, bool threaded = true) | |
235 | { | ||
236 | 2 | return magnitude<GridType, util::NullInterrupter>(grid, threaded, nullptr); | |
237 | } | ||
238 | |||
239 | template<typename GridType, typename MaskT> | ||
240 | typename VectorToScalarConverter<GridType>::Type::Ptr | ||
241 | 2 | magnitude(const GridType& grid, const MaskT& mask, bool threaded = true) | |
242 | { | ||
243 | 2 | return magnitude<GridType, MaskT, util::NullInterrupter>(grid, mask, threaded, nullptr); | |
244 | } | ||
245 | |||
246 | |||
247 | /// @brief Normalize the vectors of the given vector-valued grid. | ||
248 | /// @return a new vector-valued grid | ||
249 | /// @details When a mask grid is specified, the solution is calculated only in | ||
250 | /// the intersection of the mask active topology and the input active topology | ||
251 | /// independent of the transforms associated with either grid. | ||
252 | template<typename GridType, typename InterruptT> | ||
253 | typename GridType::Ptr | ||
254 | normalize(const GridType& grid, bool threaded, InterruptT* interrupt); | ||
255 | |||
256 | template<typename GridType, typename MaskT, typename InterruptT> | ||
257 | typename GridType::Ptr | ||
258 | normalize(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt); | ||
259 | |||
260 | template<typename GridType> | ||
261 | typename GridType::Ptr | ||
262 | 1 | normalize(const GridType& grid, bool threaded = true) | |
263 | { | ||
264 | 1 | return normalize<GridType, util::NullInterrupter>(grid, threaded, nullptr); | |
265 | } | ||
266 | |||
267 | template<typename GridType, typename MaskT> | ||
268 | typename GridType::Ptr | ||
269 | 1 | normalize(const GridType& grid, const MaskT& mask, bool threaded = true) | |
270 | { | ||
271 | 1 | return normalize<GridType, MaskT, util::NullInterrupter>(grid, mask, threaded, nullptr); | |
272 | } | ||
273 | |||
274 | |||
275 | //////////////////////////////////////// | ||
276 | |||
277 | |||
278 | namespace gridop { | ||
279 | |||
280 | /// @brief ToMaskGrid<T>::Type is the type of a grid having the same | ||
281 | /// tree hierarchy as grid type T but a value equal to its active state. | ||
282 | /// @details For example, ToMaskGrid<FloatGrid>::Type is equivalent to MaskGrid. | ||
283 | template<typename GridType> | ||
284 | struct ToMaskGrid { | ||
285 | typedef Grid<typename GridType::TreeType::template ValueConverter<ValueMask>::Type> Type; | ||
286 | }; | ||
287 | |||
288 | |||
289 | /// @brief Apply an operator to an input grid to produce an output grid | ||
290 | /// with the same active voxel topology but a potentially different value type. | ||
291 | /// @details To facilitate inlining, this class is also templated on a Map type. | ||
292 | /// | ||
293 | /// @note This is a helper class and should never be used directly. | ||
294 | template< | ||
295 | typename InGridT, | ||
296 | typename MaskGridType, | ||
297 | typename OutGridT, | ||
298 | typename MapT, | ||
299 | typename OperatorT, | ||
300 | typename InterruptT = util::NullInterrupter> | ||
301 | class GridOperator | ||
302 | { | ||
303 | public: | ||
304 | typedef typename OutGridT::TreeType OutTreeT; | ||
305 | typedef typename OutTreeT::LeafNodeType OutLeafT; | ||
306 | typedef typename tree::LeafManager<OutTreeT> LeafManagerT; | ||
307 | |||
308 | 41 | GridOperator(const InGridT& grid, const MaskGridType* mask, const MapT& map, | |
309 | InterruptT* interrupt = nullptr, bool densify = true) | ||
310 | : mAcc(grid.getConstAccessor()) | ||
311 | , mMap(map) | ||
312 | , mInterrupt(interrupt) | ||
313 | , mMask(mask) | ||
314 | 82 | , mDensify(densify) ///< @todo consider adding a "NeedsDensification" operator trait | |
315 | { | ||
316 | } | ||
317 |
19/1008✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 66 not taken.
✗ Branch 67 not taken.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 74 not taken.
✗ Branch 75 not taken.
✗ Branch 78 not taken.
✗ Branch 79 not taken.
✗ Branch 82 not taken.
✗ Branch 83 not taken.
✗ Branch 86 not taken.
✗ Branch 87 not taken.
✗ Branch 90 not taken.
✗ Branch 91 not taken.
✗ Branch 94 not taken.
✗ Branch 95 not taken.
✗ Branch 98 not taken.
✗ Branch 99 not taken.
✗ Branch 102 not taken.
✗ Branch 103 not taken.
✗ Branch 106 not taken.
✗ Branch 107 not taken.
✗ Branch 110 not taken.
✗ Branch 111 not taken.
✗ Branch 114 not taken.
✗ Branch 115 not taken.
✗ Branch 118 not taken.
✗ Branch 119 not taken.
✓ Branch 122 taken 1 times.
✗ Branch 123 not taken.
✗ Branch 126 not taken.
✗ Branch 127 not taken.
✗ Branch 130 not taken.
✗ Branch 131 not taken.
✗ Branch 134 not taken.
✗ Branch 135 not taken.
✗ Branch 138 not taken.
✗ Branch 139 not taken.
✗ Branch 142 not taken.
✗ Branch 143 not taken.
✗ Branch 146 not taken.
✗ Branch 147 not taken.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 154 not taken.
✗ Branch 155 not taken.
✗ Branch 158 not taken.
✗ Branch 159 not taken.
✗ Branch 162 not taken.
✗ Branch 163 not taken.
✗ Branch 166 not taken.
✗ Branch 167 not taken.
✗ Branch 170 not taken.
✗ Branch 171 not taken.
✗ Branch 174 not taken.
✗ Branch 175 not taken.
✗ Branch 178 not taken.
✗ Branch 179 not taken.
✗ Branch 182 not taken.
✗ Branch 183 not taken.
✓ Branch 186 taken 1 times.
✗ Branch 187 not taken.
✗ Branch 190 not taken.
✗ Branch 191 not taken.
✗ Branch 930 not taken.
✗ Branch 931 not taken.
✗ Branch 934 not taken.
✗ Branch 935 not taken.
✗ Branch 938 not taken.
✗ Branch 939 not taken.
✗ Branch 942 not taken.
✗ Branch 943 not taken.
✗ Branch 946 not taken.
✗ Branch 947 not taken.
✗ Branch 950 not taken.
✗ Branch 951 not taken.
✗ Branch 954 not taken.
✗ Branch 955 not taken.
✗ Branch 958 not taken.
✗ Branch 959 not taken.
✗ Branch 962 not taken.
✗ Branch 963 not taken.
✗ Branch 966 not taken.
✗ Branch 967 not taken.
✗ Branch 970 not taken.
✗ Branch 971 not taken.
✗ Branch 974 not taken.
✗ Branch 975 not taken.
✗ Branch 978 not taken.
✗ Branch 979 not taken.
✗ Branch 982 not taken.
✗ Branch 983 not taken.
✗ Branch 986 not taken.
✗ Branch 987 not taken.
✗ Branch 990 not taken.
✗ Branch 991 not taken.
✗ Branch 994 not taken.
✗ Branch 995 not taken.
✗ Branch 998 not taken.
✗ Branch 999 not taken.
✗ Branch 1002 not taken.
✗ Branch 1003 not taken.
✗ Branch 1006 not taken.
✗ Branch 1007 not taken.
✗ Branch 1010 not taken.
✗ Branch 1011 not taken.
✗ Branch 1014 not taken.
✗ Branch 1015 not taken.
✗ Branch 1018 not taken.
✗ Branch 1019 not taken.
✓ Branch 1022 taken 1 times.
✗ Branch 1023 not taken.
✗ Branch 1026 not taken.
✗ Branch 1027 not taken.
✗ Branch 1030 not taken.
✗ Branch 1031 not taken.
✗ Branch 1034 not taken.
✗ Branch 1035 not taken.
✗ Branch 1038 not taken.
✗ Branch 1039 not taken.
✗ Branch 1042 not taken.
✗ Branch 1043 not taken.
✗ Branch 1046 not taken.
✗ Branch 1047 not taken.
✗ Branch 1050 not taken.
✗ Branch 1051 not taken.
✗ Branch 1054 not taken.
✗ Branch 1055 not taken.
✗ Branch 1058 not taken.
✗ Branch 1059 not taken.
✗ Branch 1062 not taken.
✗ Branch 1063 not taken.
✗ Branch 1066 not taken.
✗ Branch 1067 not taken.
✗ Branch 1070 not taken.
✗ Branch 1071 not taken.
✗ Branch 1074 not taken.
✗ Branch 1075 not taken.
✗ Branch 1078 not taken.
✗ Branch 1079 not taken.
✗ Branch 1082 not taken.
✗ Branch 1083 not taken.
✗ Branch 1086 not taken.
✗ Branch 1087 not taken.
✗ Branch 1090 not taken.
✗ Branch 1091 not taken.
✗ Branch 1094 not taken.
✗ Branch 1095 not taken.
✗ Branch 1098 not taken.
✗ Branch 1099 not taken.
✗ Branch 1102 not taken.
✗ Branch 1103 not taken.
✗ Branch 1106 not taken.
✗ Branch 1107 not taken.
✗ Branch 1110 not taken.
✗ Branch 1111 not taken.
✗ Branch 1114 not taken.
✗ Branch 1115 not taken.
✓ Branch 1118 taken 1 times.
✗ Branch 1119 not taken.
✗ Branch 1122 not taken.
✗ Branch 1123 not taken.
✗ Branch 1126 not taken.
✗ Branch 1127 not taken.
✗ Branch 1130 not taken.
✗ Branch 1131 not taken.
✗ Branch 1134 not taken.
✗ Branch 1135 not taken.
✗ Branch 1138 not taken.
✗ Branch 1139 not taken.
✗ Branch 1142 not taken.
✗ Branch 1143 not taken.
✗ Branch 1146 not taken.
✗ Branch 1147 not taken.
✗ Branch 1150 not taken.
✗ Branch 1151 not taken.
✗ Branch 1154 not taken.
✗ Branch 1155 not taken.
✗ Branch 1158 not taken.
✗ Branch 1159 not taken.
✗ Branch 1162 not taken.
✗ Branch 1163 not taken.
✗ Branch 1166 not taken.
✗ Branch 1167 not taken.
✗ Branch 1170 not taken.
✗ Branch 1171 not taken.
✗ Branch 1174 not taken.
✗ Branch 1175 not taken.
✗ Branch 1178 not taken.
✗ Branch 1179 not taken.
✗ Branch 1182 not taken.
✗ Branch 1183 not taken.
✗ Branch 1186 not taken.
✗ Branch 1187 not taken.
✗ Branch 1190 not taken.
✗ Branch 1191 not taken.
✗ Branch 1194 not taken.
✗ Branch 1195 not taken.
✗ Branch 1198 not taken.
✗ Branch 1199 not taken.
✗ Branch 1202 not taken.
✗ Branch 1203 not taken.
✗ Branch 1206 not taken.
✗ Branch 1207 not taken.
✗ Branch 1210 not taken.
✗ Branch 1211 not taken.
✓ Branch 1214 taken 1 times.
✗ Branch 1215 not taken.
✗ Branch 1218 not taken.
✗ Branch 1219 not taken.
✗ Branch 1222 not taken.
✗ Branch 1223 not taken.
✗ Branch 1226 not taken.
✗ Branch 1227 not taken.
✗ Branch 1230 not taken.
✗ Branch 1231 not taken.
✗ Branch 1234 not taken.
✗ Branch 1235 not taken.
✗ Branch 1238 not taken.
✗ Branch 1239 not taken.
✗ Branch 1242 not taken.
✗ Branch 1243 not taken.
✗ Branch 1246 not taken.
✗ Branch 1247 not taken.
✗ Branch 1250 not taken.
✗ Branch 1251 not taken.
✗ Branch 1254 not taken.
✗ Branch 1255 not taken.
✗ Branch 1258 not taken.
✗ Branch 1259 not taken.
✗ Branch 1262 not taken.
✗ Branch 1263 not taken.
✗ Branch 1266 not taken.
✗ Branch 1267 not taken.
✗ Branch 1270 not taken.
✗ Branch 1271 not taken.
✗ Branch 1274 not taken.
✗ Branch 1275 not taken.
✗ Branch 1278 not taken.
✗ Branch 1279 not taken.
✗ Branch 1282 not taken.
✗ Branch 1283 not taken.
✗ Branch 1286 not taken.
✗ Branch 1287 not taken.
✗ Branch 1290 not taken.
✗ Branch 1291 not taken.
✗ Branch 1294 not taken.
✗ Branch 1295 not taken.
✗ Branch 1298 not taken.
✗ Branch 1299 not taken.
✗ Branch 1302 not taken.
✗ Branch 1303 not taken.
✗ Branch 1306 not taken.
✗ Branch 1307 not taken.
✓ Branch 1310 taken 1 times.
✗ Branch 1311 not taken.
✗ Branch 1314 not taken.
✗ Branch 1315 not taken.
✗ Branch 1318 not taken.
✗ Branch 1319 not taken.
✗ Branch 1322 not taken.
✗ Branch 1323 not taken.
✗ Branch 1326 not taken.
✗ Branch 1327 not taken.
✗ Branch 1330 not taken.
✗ Branch 1331 not taken.
✗ Branch 1334 not taken.
✗ Branch 1335 not taken.
✗ Branch 1338 not taken.
✗ Branch 1339 not taken.
✗ Branch 1342 not taken.
✗ Branch 1343 not taken.
✗ Branch 1346 not taken.
✗ Branch 1347 not taken.
✗ Branch 1350 not taken.
✗ Branch 1351 not taken.
✗ Branch 1354 not taken.
✗ Branch 1355 not taken.
✗ Branch 1358 not taken.
✗ Branch 1359 not taken.
✗ Branch 1362 not taken.
✗ Branch 1363 not taken.
✗ Branch 1366 not taken.
✗ Branch 1367 not taken.
✗ Branch 1370 not taken.
✗ Branch 1371 not taken.
✓ Branch 1374 taken 1 times.
✗ Branch 1375 not taken.
✗ Branch 1378 not taken.
✗ Branch 1379 not taken.
✗ Branch 1382 not taken.
✗ Branch 1383 not taken.
✗ Branch 1386 not taken.
✗ Branch 1387 not taken.
✗ Branch 1390 not taken.
✗ Branch 1391 not taken.
✗ Branch 1394 not taken.
✗ Branch 1395 not taken.
✗ Branch 1398 not taken.
✗ Branch 1399 not taken.
✗ Branch 1402 not taken.
✗ Branch 1403 not taken.
✗ Branch 1406 not taken.
✗ Branch 1407 not taken.
✗ Branch 1410 not taken.
✗ Branch 1411 not taken.
✗ Branch 1414 not taken.
✗ Branch 1415 not taken.
✗ Branch 1418 not taken.
✗ Branch 1419 not taken.
✗ Branch 1422 not taken.
✗ Branch 1423 not taken.
✗ Branch 1426 not taken.
✗ Branch 1427 not taken.
✗ Branch 1430 not taken.
✗ Branch 1431 not taken.
✗ Branch 1434 not taken.
✗ Branch 1435 not taken.
✗ Branch 1438 not taken.
✗ Branch 1439 not taken.
✗ Branch 1442 not taken.
✗ Branch 1443 not taken.
✗ Branch 1446 not taken.
✗ Branch 1447 not taken.
✗ Branch 1450 not taken.
✗ Branch 1451 not taken.
✗ Branch 1454 not taken.
✗ Branch 1455 not taken.
✗ Branch 1458 not taken.
✗ Branch 1459 not taken.
✗ Branch 1462 not taken.
✗ Branch 1463 not taken.
✗ Branch 1466 not taken.
✗ Branch 1467 not taken.
✗ Branch 1470 not taken.
✗ Branch 1471 not taken.
✗ Branch 1474 not taken.
✗ Branch 1475 not taken.
✗ Branch 1478 not taken.
✗ Branch 1479 not taken.
✗ Branch 1482 not taken.
✗ Branch 1483 not taken.
✗ Branch 1486 not taken.
✗ Branch 1487 not taken.
✗ Branch 1490 not taken.
✗ Branch 1491 not taken.
✗ Branch 1494 not taken.
✗ Branch 1495 not taken.
✗ Branch 1498 not taken.
✗ Branch 1499 not taken.
✓ Branch 1502 taken 1 times.
✗ Branch 1503 not taken.
✗ Branch 1506 not taken.
✗ Branch 1507 not taken.
✗ Branch 1510 not taken.
✗ Branch 1511 not taken.
✗ Branch 1514 not taken.
✗ Branch 1515 not taken.
✗ Branch 1518 not taken.
✗ Branch 1519 not taken.
✗ Branch 1522 not taken.
✗ Branch 1523 not taken.
✗ Branch 1526 not taken.
✗ Branch 1527 not taken.
✗ Branch 1530 not taken.
✗ Branch 1531 not taken.
✗ Branch 1534 not taken.
✗ Branch 1535 not taken.
✗ Branch 1538 not taken.
✗ Branch 1539 not taken.
✗ Branch 1542 not taken.
✗ Branch 1543 not taken.
✗ Branch 1546 not taken.
✗ Branch 1547 not taken.
✗ Branch 1550 not taken.
✗ Branch 1551 not taken.
✗ Branch 1554 not taken.
✗ Branch 1555 not taken.
✗ Branch 1558 not taken.
✗ Branch 1559 not taken.
✗ Branch 1562 not taken.
✗ Branch 1563 not taken.
✗ Branch 1566 not taken.
✗ Branch 1567 not taken.
✗ Branch 1570 not taken.
✗ Branch 1571 not taken.
✗ Branch 1574 not taken.
✗ Branch 1575 not taken.
✗ Branch 1578 not taken.
✗ Branch 1579 not taken.
✗ Branch 1582 not taken.
✗ Branch 1583 not taken.
✗ Branch 1586 not taken.
✗ Branch 1587 not taken.
✗ Branch 1590 not taken.
✗ Branch 1591 not taken.
✗ Branch 1594 not taken.
✗ Branch 1595 not taken.
✓ Branch 1598 taken 1 times.
✗ Branch 1599 not taken.
✗ Branch 1602 not taken.
✗ Branch 1603 not taken.
✗ Branch 1606 not taken.
✗ Branch 1607 not taken.
✗ Branch 1610 not taken.
✗ Branch 1611 not taken.
✗ Branch 1614 not taken.
✗ Branch 1615 not taken.
✗ Branch 1618 not taken.
✗ Branch 1619 not taken.
✗ Branch 1622 not taken.
✗ Branch 1623 not taken.
✗ Branch 1626 not taken.
✗ Branch 1627 not taken.
✓ Branch 1630 taken 2 times.
✗ Branch 1631 not taken.
✗ Branch 1634 not taken.
✗ Branch 1635 not taken.
✗ Branch 1638 not taken.
✗ Branch 1639 not taken.
✗ Branch 1642 not taken.
✗ Branch 1643 not taken.
✗ Branch 1646 not taken.
✗ Branch 1647 not taken.
✗ Branch 1650 not taken.
✗ Branch 1651 not taken.
✗ Branch 1654 not taken.
✗ Branch 1655 not taken.
✗ Branch 1658 not taken.
✗ Branch 1659 not taken.
✗ Branch 1662 not taken.
✗ Branch 1663 not taken.
✗ Branch 1666 not taken.
✗ Branch 1667 not taken.
✗ Branch 1670 not taken.
✗ Branch 1671 not taken.
✗ Branch 1674 not taken.
✗ Branch 1675 not taken.
✗ Branch 1678 not taken.
✗ Branch 1679 not taken.
✗ Branch 1682 not taken.
✗ Branch 1683 not taken.
✗ Branch 1686 not taken.
✗ Branch 1687 not taken.
✗ Branch 1690 not taken.
✗ Branch 1691 not taken.
✗ Branch 1694 not taken.
✗ Branch 1695 not taken.
✗ Branch 1698 not taken.
✗ Branch 1699 not taken.
✗ Branch 1702 not taken.
✗ Branch 1703 not taken.
✗ Branch 1706 not taken.
✗ Branch 1707 not taken.
✗ Branch 1710 not taken.
✗ Branch 1711 not taken.
✗ Branch 1714 not taken.
✗ Branch 1715 not taken.
✗ Branch 1718 not taken.
✗ Branch 1719 not taken.
✗ Branch 1722 not taken.
✗ Branch 1723 not taken.
✗ Branch 1726 not taken.
✗ Branch 1727 not taken.
✗ Branch 1730 not taken.
✗ Branch 1731 not taken.
✗ Branch 1734 not taken.
✗ Branch 1735 not taken.
✗ Branch 1738 not taken.
✗ Branch 1739 not taken.
✗ Branch 1742 not taken.
✗ Branch 1743 not taken.
✗ Branch 1746 not taken.
✗ Branch 1747 not taken.
✗ Branch 1750 not taken.
✗ Branch 1751 not taken.
✗ Branch 1754 not taken.
✗ Branch 1755 not taken.
✓ Branch 1758 taken 1 times.
✗ Branch 1759 not taken.
✗ Branch 1762 not taken.
✗ Branch 1763 not taken.
✗ Branch 1766 not taken.
✗ Branch 1767 not taken.
✗ Branch 1770 not taken.
✗ Branch 1771 not taken.
✗ Branch 1774 not taken.
✗ Branch 1775 not taken.
✗ Branch 1778 not taken.
✗ Branch 1779 not taken.
✗ Branch 1782 not taken.
✗ Branch 1783 not taken.
✗ Branch 1786 not taken.
✗ Branch 1787 not taken.
✗ Branch 1790 not taken.
✗ Branch 1791 not taken.
✗ Branch 1794 not taken.
✗ Branch 1795 not taken.
✗ Branch 1798 not taken.
✗ Branch 1799 not taken.
✗ Branch 1802 not taken.
✗ Branch 1803 not taken.
✗ Branch 1806 not taken.
✗ Branch 1807 not taken.
✗ Branch 1810 not taken.
✗ Branch 1811 not taken.
✗ Branch 1814 not taken.
✗ Branch 1815 not taken.
✗ Branch 1818 not taken.
✗ Branch 1819 not taken.
✗ Branch 1822 not taken.
✗ Branch 1823 not taken.
✗ Branch 1826 not taken.
✗ Branch 1827 not taken.
✗ Branch 1830 not taken.
✗ Branch 1831 not taken.
✗ Branch 1834 not taken.
✗ Branch 1835 not taken.
✗ Branch 1838 not taken.
✗ Branch 1839 not taken.
✗ Branch 1842 not taken.
✗ Branch 1843 not taken.
✗ Branch 1846 not taken.
✗ Branch 1847 not taken.
✗ Branch 1850 not taken.
✗ Branch 1851 not taken.
✗ Branch 1854 not taken.
✗ Branch 1855 not taken.
✗ Branch 1858 not taken.
✗ Branch 1859 not taken.
✗ Branch 1862 not taken.
✗ Branch 1863 not taken.
✗ Branch 1866 not taken.
✗ Branch 1867 not taken.
✗ Branch 1870 not taken.
✗ Branch 1871 not taken.
✗ Branch 1874 not taken.
✗ Branch 1875 not taken.
✗ Branch 1878 not taken.
✗ Branch 1879 not taken.
✗ Branch 1882 not taken.
✗ Branch 1883 not taken.
✓ Branch 1886 taken 1 times.
✗ Branch 1887 not taken.
✗ Branch 1890 not taken.
✗ Branch 1891 not taken.
✗ Branch 1894 not taken.
✗ Branch 1895 not taken.
✗ Branch 1898 not taken.
✗ Branch 1899 not taken.
✗ Branch 1902 not taken.
✗ Branch 1903 not taken.
✗ Branch 1906 not taken.
✗ Branch 1907 not taken.
✗ Branch 1910 not taken.
✗ Branch 1911 not taken.
✗ Branch 1914 not taken.
✗ Branch 1915 not taken.
✓ Branch 1918 taken 4 times.
✗ Branch 1919 not taken.
✗ Branch 1922 not taken.
✗ Branch 1923 not taken.
✗ Branch 1926 not taken.
✗ Branch 1927 not taken.
✗ Branch 1930 not taken.
✗ Branch 1931 not taken.
✗ Branch 1934 not taken.
✗ Branch 1935 not taken.
✗ Branch 1938 not taken.
✗ Branch 1939 not taken.
✗ Branch 1942 not taken.
✗ Branch 1943 not taken.
✗ Branch 1946 not taken.
✗ Branch 1947 not taken.
✓ Branch 1950 taken 12 times.
✗ Branch 1951 not taken.
✗ Branch 1954 not taken.
✗ Branch 1955 not taken.
✗ Branch 1958 not taken.
✗ Branch 1959 not taken.
✗ Branch 1962 not taken.
✗ Branch 1963 not taken.
✗ Branch 1966 not taken.
✗ Branch 1967 not taken.
✗ Branch 1970 not taken.
✗ Branch 1971 not taken.
✗ Branch 1974 not taken.
✗ Branch 1975 not taken.
✗ Branch 1978 not taken.
✗ Branch 1979 not taken.
✗ Branch 1982 not taken.
✗ Branch 1983 not taken.
✗ Branch 1986 not taken.
✗ Branch 1987 not taken.
✗ Branch 1990 not taken.
✗ Branch 1991 not taken.
✗ Branch 1994 not taken.
✗ Branch 1995 not taken.
✗ Branch 1998 not taken.
✗ Branch 1999 not taken.
✗ Branch 2002 not taken.
✗ Branch 2003 not taken.
✗ Branch 2006 not taken.
✗ Branch 2007 not taken.
✗ Branch 2010 not taken.
✗ Branch 2011 not taken.
✗ Branch 2014 not taken.
✗ Branch 2015 not taken.
✗ Branch 2018 not taken.
✗ Branch 2019 not taken.
✗ Branch 2022 not taken.
✗ Branch 2023 not taken.
✗ Branch 2026 not taken.
✗ Branch 2027 not taken.
✗ Branch 2030 not taken.
✗ Branch 2031 not taken.
✗ Branch 2034 not taken.
✗ Branch 2035 not taken.
✗ Branch 2038 not taken.
✗ Branch 2039 not taken.
✗ Branch 2042 not taken.
✗ Branch 2043 not taken.
✗ Branch 2046 not taken.
✗ Branch 2047 not taken.
✗ Branch 2050 not taken.
✗ Branch 2051 not taken.
✗ Branch 2054 not taken.
✗ Branch 2055 not taken.
✗ Branch 2058 not taken.
✗ Branch 2059 not taken.
✗ Branch 2062 not taken.
✗ Branch 2063 not taken.
✗ Branch 2066 not taken.
✗ Branch 2067 not taken.
✗ Branch 2070 not taken.
✗ Branch 2071 not taken.
✗ Branch 2074 not taken.
✗ Branch 2075 not taken.
✗ Branch 2078 not taken.
✗ Branch 2079 not taken.
✗ Branch 2082 not taken.
✗ Branch 2083 not taken.
✗ Branch 2086 not taken.
✗ Branch 2087 not taken.
✗ Branch 2090 not taken.
✗ Branch 2091 not taken.
✗ Branch 2094 not taken.
✗ Branch 2095 not taken.
✗ Branch 2098 not taken.
✗ Branch 2099 not taken.
✗ Branch 2102 not taken.
✗ Branch 2103 not taken.
✗ Branch 2106 not taken.
✗ Branch 2107 not taken.
✓ Branch 2110 taken 2 times.
✗ Branch 2111 not taken.
✗ Branch 2114 not taken.
✗ Branch 2115 not taken.
✗ Branch 2118 not taken.
✗ Branch 2119 not taken.
✗ Branch 2122 not taken.
✗ Branch 2123 not taken.
✗ Branch 2126 not taken.
✗ Branch 2127 not taken.
✗ Branch 2130 not taken.
✗ Branch 2131 not taken.
✗ Branch 2134 not taken.
✗ Branch 2135 not taken.
✗ Branch 2138 not taken.
✗ Branch 2139 not taken.
✗ Branch 2142 not taken.
✗ Branch 2143 not taken.
✗ Branch 2146 not taken.
✗ Branch 2147 not taken.
✗ Branch 2150 not taken.
✗ Branch 2151 not taken.
✗ Branch 2154 not taken.
✗ Branch 2155 not taken.
✗ Branch 2158 not taken.
✗ Branch 2159 not taken.
✗ Branch 2162 not taken.
✗ Branch 2163 not taken.
✗ Branch 2166 not taken.
✗ Branch 2167 not taken.
✗ Branch 2170 not taken.
✗ Branch 2171 not taken.
✗ Branch 2174 not taken.
✗ Branch 2175 not taken.
✗ Branch 2178 not taken.
✗ Branch 2179 not taken.
✗ Branch 2182 not taken.
✗ Branch 2183 not taken.
✗ Branch 2186 not taken.
✗ Branch 2187 not taken.
✗ Branch 2190 not taken.
✗ Branch 2191 not taken.
✗ Branch 2194 not taken.
✗ Branch 2195 not taken.
✗ Branch 2198 not taken.
✗ Branch 2199 not taken.
✗ Branch 2202 not taken.
✗ Branch 2203 not taken.
✗ Branch 2206 not taken.
✗ Branch 2207 not taken.
✗ Branch 2210 not taken.
✗ Branch 2211 not taken.
✗ Branch 2214 not taken.
✗ Branch 2215 not taken.
✗ Branch 2218 not taken.
✗ Branch 2219 not taken.
✗ Branch 2222 not taken.
✗ Branch 2223 not taken.
✗ Branch 2226 not taken.
✗ Branch 2227 not taken.
✗ Branch 2230 not taken.
✗ Branch 2231 not taken.
✗ Branch 2234 not taken.
✗ Branch 2235 not taken.
✗ Branch 2238 not taken.
✗ Branch 2239 not taken.
✗ Branch 2242 not taken.
✗ Branch 2243 not taken.
✗ Branch 2246 not taken.
✗ Branch 2247 not taken.
✗ Branch 2250 not taken.
✗ Branch 2251 not taken.
✗ Branch 2254 not taken.
✗ Branch 2255 not taken.
✗ Branch 2258 not taken.
✗ Branch 2259 not taken.
✗ Branch 2262 not taken.
✗ Branch 2263 not taken.
✗ Branch 2266 not taken.
✗ Branch 2267 not taken.
✗ Branch 2270 not taken.
✗ Branch 2271 not taken.
✗ Branch 2274 not taken.
✗ Branch 2275 not taken.
✗ Branch 2278 not taken.
✗ Branch 2279 not taken.
✗ Branch 2282 not taken.
✗ Branch 2283 not taken.
✗ Branch 2286 not taken.
✗ Branch 2287 not taken.
✗ Branch 2290 not taken.
✗ Branch 2291 not taken.
✗ Branch 2294 not taken.
✗ Branch 2295 not taken.
✗ Branch 2298 not taken.
✗ Branch 2299 not taken.
✓ Branch 2302 taken 1 times.
✗ Branch 2303 not taken.
✗ Branch 2306 not taken.
✗ Branch 2307 not taken.
✗ Branch 2310 not taken.
✗ Branch 2311 not taken.
✗ Branch 2314 not taken.
✗ Branch 2315 not taken.
✗ Branch 2318 not taken.
✗ Branch 2319 not taken.
✗ Branch 2322 not taken.
✗ Branch 2323 not taken.
✗ Branch 2326 not taken.
✗ Branch 2327 not taken.
✗ Branch 2330 not taken.
✗ Branch 2331 not taken.
✓ Branch 2334 taken 1 times.
✗ Branch 2335 not taken.
✗ Branch 2338 not taken.
✗ Branch 2339 not taken.
✗ Branch 2342 not taken.
✗ Branch 2343 not taken.
✗ Branch 2346 not taken.
✗ Branch 2347 not taken.
✗ Branch 2350 not taken.
✗ Branch 2351 not taken.
✗ Branch 2354 not taken.
✗ Branch 2355 not taken.
✗ Branch 2358 not taken.
✗ Branch 2359 not taken.
✗ Branch 2362 not taken.
✗ Branch 2363 not taken.
✗ Branch 2366 not taken.
✗ Branch 2367 not taken.
✗ Branch 2370 not taken.
✗ Branch 2371 not taken.
✗ Branch 2374 not taken.
✗ Branch 2375 not taken.
✗ Branch 2378 not taken.
✗ Branch 2379 not taken.
✗ Branch 2382 not taken.
✗ Branch 2383 not taken.
✗ Branch 2386 not taken.
✗ Branch 2387 not taken.
✗ Branch 2390 not taken.
✗ Branch 2391 not taken.
✗ Branch 2394 not taken.
✗ Branch 2395 not taken.
✗ Branch 2398 not taken.
✗ Branch 2399 not taken.
✗ Branch 2402 not taken.
✗ Branch 2403 not taken.
✗ Branch 2406 not taken.
✗ Branch 2407 not taken.
✗ Branch 2410 not taken.
✗ Branch 2411 not taken.
✗ Branch 2414 not taken.
✗ Branch 2415 not taken.
✗ Branch 2418 not taken.
✗ Branch 2419 not taken.
✗ Branch 2422 not taken.
✗ Branch 2423 not taken.
✗ Branch 2426 not taken.
✗ Branch 2427 not taken.
✓ Branch 2430 taken 1 times.
✗ Branch 2431 not taken.
✗ Branch 2434 not taken.
✗ Branch 2435 not taken.
✗ Branch 2438 not taken.
✗ Branch 2439 not taken.
✗ Branch 2442 not taken.
✗ Branch 2443 not taken.
✗ Branch 2446 not taken.
✗ Branch 2447 not taken.
✗ Branch 2450 not taken.
✗ Branch 2451 not taken.
✗ Branch 2454 not taken.
✗ Branch 2455 not taken.
✗ Branch 2458 not taken.
✗ Branch 2459 not taken.
✗ Branch 2462 not taken.
✗ Branch 2463 not taken.
✗ Branch 2466 not taken.
✗ Branch 2467 not taken.
✗ Branch 2470 not taken.
✗ Branch 2471 not taken.
✗ Branch 2474 not taken.
✗ Branch 2475 not taken.
✗ Branch 2478 not taken.
✗ Branch 2479 not taken.
✗ Branch 2482 not taken.
✗ Branch 2483 not taken.
✗ Branch 2486 not taken.
✗ Branch 2487 not taken.
✗ Branch 2490 not taken.
✗ Branch 2491 not taken.
✗ Branch 2494 not taken.
✗ Branch 2495 not taken.
✗ Branch 2498 not taken.
✗ Branch 2499 not taken.
✗ Branch 2502 not taken.
✗ Branch 2503 not taken.
✗ Branch 2506 not taken.
✗ Branch 2507 not taken.
✗ Branch 2510 not taken.
✗ Branch 2511 not taken.
✗ Branch 2514 not taken.
✗ Branch 2515 not taken.
✗ Branch 2518 not taken.
✗ Branch 2519 not taken.
✗ Branch 2522 not taken.
✗ Branch 2523 not taken.
✓ Branch 2526 taken 5 times.
✗ Branch 2527 not taken.
✗ Branch 2530 not taken.
✗ Branch 2531 not taken.
✗ Branch 2534 not taken.
✗ Branch 2535 not taken.
✗ Branch 2538 not taken.
✗ Branch 2539 not taken.
✗ Branch 2542 not taken.
✗ Branch 2543 not taken.
✗ Branch 2546 not taken.
✗ Branch 2547 not taken.
✗ Branch 2550 not taken.
✗ Branch 2551 not taken.
✗ Branch 2554 not taken.
✗ Branch 2555 not taken.
✗ Branch 2558 not taken.
✗ Branch 2559 not taken.
✗ Branch 2562 not taken.
✗ Branch 2563 not taken.
✗ Branch 2566 not taken.
✗ Branch 2567 not taken.
✗ Branch 2570 not taken.
✗ Branch 2571 not taken.
✗ Branch 2574 not taken.
✗ Branch 2575 not taken.
✗ Branch 2578 not taken.
✗ Branch 2579 not taken.
✗ Branch 2582 not taken.
✗ Branch 2583 not taken.
✗ Branch 2586 not taken.
✗ Branch 2587 not taken.
✗ Branch 2590 not taken.
✗ Branch 2591 not taken.
✗ Branch 2594 not taken.
✗ Branch 2595 not taken.
✗ Branch 2598 not taken.
✗ Branch 2599 not taken.
✗ Branch 2602 not taken.
✗ Branch 2603 not taken.
✗ Branch 2606 not taken.
✗ Branch 2607 not taken.
✗ Branch 2610 not taken.
✗ Branch 2611 not taken.
✗ Branch 2614 not taken.
✗ Branch 2615 not taken.
✗ Branch 2618 not taken.
✗ Branch 2619 not taken.
✗ Branch 2622 not taken.
✗ Branch 2623 not taken.
✗ Branch 2626 not taken.
✗ Branch 2627 not taken.
✗ Branch 2630 not taken.
✗ Branch 2631 not taken.
✗ Branch 2634 not taken.
✗ Branch 2635 not taken.
✗ Branch 2638 not taken.
✗ Branch 2639 not taken.
✗ Branch 2642 not taken.
✗ Branch 2643 not taken.
✗ Branch 2646 not taken.
✗ Branch 2647 not taken.
✗ Branch 2650 not taken.
✗ Branch 2651 not taken.
✗ Branch 2654 not taken.
✗ Branch 2655 not taken.
✗ Branch 2658 not taken.
✗ Branch 2659 not taken.
✗ Branch 2662 not taken.
✗ Branch 2663 not taken.
✗ Branch 2666 not taken.
✗ Branch 2667 not taken.
✗ Branch 2670 not taken.
✗ Branch 2671 not taken.
✗ Branch 2674 not taken.
✗ Branch 2675 not taken.
✗ Branch 2678 not taken.
✗ Branch 2679 not taken.
✗ Branch 2682 not taken.
✗ Branch 2683 not taken.
✗ Branch 2686 not taken.
✗ Branch 2687 not taken.
✗ Branch 2690 not taken.
✗ Branch 2691 not taken.
✗ Branch 2694 not taken.
✗ Branch 2695 not taken.
✗ Branch 2698 not taken.
✗ Branch 2699 not taken.
✗ Branch 2702 not taken.
✗ Branch 2703 not taken.
✗ Branch 2706 not taken.
✗ Branch 2707 not taken.
✗ Branch 2710 not taken.
✗ Branch 2711 not taken.
✗ Branch 2714 not taken.
✗ Branch 2715 not taken.
✗ Branch 2718 not taken.
✗ Branch 2719 not taken.
✗ Branch 2722 not taken.
✗ Branch 2723 not taken.
✗ Branch 2726 not taken.
✗ Branch 2727 not taken.
✗ Branch 2730 not taken.
✗ Branch 2731 not taken.
✗ Branch 2734 not taken.
✗ Branch 2735 not taken.
✗ Branch 2738 not taken.
✗ Branch 2739 not taken.
✗ Branch 2742 not taken.
✗ Branch 2743 not taken.
✗ Branch 2746 not taken.
✗ Branch 2747 not taken.
✗ Branch 2750 not taken.
✗ Branch 2751 not taken.
✗ Branch 2754 not taken.
✗ Branch 2755 not taken.
✗ Branch 2758 not taken.
✗ Branch 2759 not taken.
✗ Branch 2762 not taken.
✗ Branch 2763 not taken.
✗ Branch 2766 not taken.
✗ Branch 2767 not taken.
✗ Branch 2770 not taken.
✗ Branch 2771 not taken.
✗ Branch 2774 not taken.
✗ Branch 2775 not taken.
✗ Branch 2778 not taken.
✗ Branch 2779 not taken.
✗ Branch 2782 not taken.
✗ Branch 2783 not taken.
|
834 | GridOperator(const GridOperator&) = default; |
318 | GridOperator& operator=(const GridOperator&) = default; | ||
319 | ✗ | virtual ~GridOperator() = default; | |
320 | |||
321 | 82 | typename OutGridT::Ptr process(bool threaded = true) | |
322 | { | ||
323 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
|
82 | if (mInterrupt) mInterrupt->start("Processing grid"); |
324 | |||
325 | // Derive background value of the output grid | ||
326 | 164 | typename InGridT::TreeType tmp(mAcc.tree().background()); | |
327 |
2/5✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 39 times.
|
82 | typename OutGridT::ValueType backg = OperatorT::result(mMap, tmp, math::Coord(0)); |
328 | |||
329 | // The output tree is topology copy, optionally densified, of the input tree. | ||
330 | // (Densification is necessary for some operators because applying the operator to | ||
331 | // a constant tile produces distinct output values, particularly along tile borders.) | ||
332 | /// @todo Can tiles be handled correctly without densification, or by densifying | ||
333 | /// only to the width of the operator stencil? | ||
334 |
2/4✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 41 times.
✗ Branch 5 not taken.
|
82 | typename OutTreeT::Ptr tree(new OutTreeT(mAcc.tree(), backg, TopologyCopy())); |
335 |
2/2✓ Branch 0 taken 33 times.
✓ Branch 1 taken 8 times.
|
82 | if (mDensify) tree->voxelizeActiveTiles(); |
336 | |||
337 | // create grid with output tree and unit transform | ||
338 |
2/6✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 41 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
82 | typename OutGridT::Ptr result(new OutGridT(tree)); |
339 | |||
340 | // Modify the solution area if a mask was supplied. | ||
341 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 29 times.
|
82 | if (mMask) { |
342 | result->topologyIntersection(*mMask); | ||
343 | } | ||
344 | |||
345 | // transform of output grid = transform of input grid | ||
346 |
6/16✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 41 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 41 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 41 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 41 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 41 times.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
|
328 | result->setTransform(math::Transform::Ptr(new math::Transform( mMap.copy() ))); |
347 | |||
348 |
1/2✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
|
164 | LeafManagerT leafManager(*tree); |
349 | |||
350 |
1/2✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
|
82 | if (threaded) { |
351 |
1/2✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
|
82 | tbb::parallel_for(leafManager.leafRange(), *this); |
352 | } else { | ||
353 | ✗ | (*this)(leafManager.leafRange()); | |
354 | } | ||
355 | |||
356 | // If the tree wasn't densified, it might have active tiles that need to be processed. | ||
357 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 33 times.
|
82 | if (!mDensify) { |
358 | using TileIter = typename OutTreeT::ValueOnIter; | ||
359 | |||
360 | TileIter tileIter = tree->beginValueOn(); | ||
361 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
16 | tileIter.setMaxDepth(tileIter.getLeafDepth() - 1); // skip leaf values (i.e., voxels) |
362 | |||
363 | AccessorT inAcc = mAcc; // each thread needs its own accessor, captured by value | ||
364 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
|
45 | auto tileOp = [this, inAcc](const TileIter& it) { |
365 | // Apply the operator to the input grid's tile value at the iterator's | ||
366 | // current coordinates, and set the output tile's value to the result. | ||
367 | 3 | it.setValue(OperatorT::result(this->mMap, inAcc, it.getCoord())); | |
368 | }; | ||
369 | |||
370 | // Apply the operator to tile values, optionally in parallel. | ||
371 | // (But don't share the functor; each thread needs its own accessor.) | ||
372 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
16 | tools::foreach(tileIter, tileOp, threaded, /*shareFunctor=*/false); |
373 | } | ||
374 | |||
375 |
3/4✓ Branch 0 taken 33 times.
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 29 times.
✗ Branch 4 not taken.
|
102 | if (mDensify) tree->prune(); |
376 | |||
377 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
82 | if (mInterrupt) mInterrupt->end(); |
378 | 82 | return result; | |
379 | } | ||
380 | |||
381 | /// @brief Iterate sequentially over LeafNodes and voxels in the output | ||
382 | /// grid and apply the operator using a value accessor for the input grid. | ||
383 | /// | ||
384 | /// @note Never call this public method directly - it is called by | ||
385 | /// TBB threads only! | ||
386 | 6056 | void operator()(const typename LeafManagerT::LeafRange& range) const | |
387 | { | ||
388 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3028 times.
|
6056 | if (util::wasInterrupted(mInterrupt)) { |
389 | ✗ | thread::cancelGroupExecution(); | |
390 | } | ||
391 | |||
392 |
2/2✓ Branch 1 taken 23360 times.
✓ Branch 2 taken 3028 times.
|
52776 | for (typename LeafManagerT::LeafRange::Iterator leaf=range.begin(); leaf; ++leaf) { |
393 |
2/2✓ Branch 0 taken 10395072 times.
✓ Branch 1 taken 23360 times.
|
20836864 | for (typename OutLeafT::ValueOnIter value=leaf->beginValueOn(); value; ++value) { |
394 | 21316448 | value.setValue(OperatorT::result(mMap, mAcc, value.getCoord())); | |
395 | } | ||
396 | } | ||
397 | } | ||
398 | |||
399 | protected: | ||
400 | typedef typename InGridT::ConstAccessor AccessorT; | ||
401 | mutable AccessorT mAcc; | ||
402 | const MapT& mMap; | ||
403 | InterruptT* mInterrupt; | ||
404 | const MaskGridType* mMask; | ||
405 | const bool mDensify; | ||
406 | }; // end of GridOperator class | ||
407 | |||
408 | } // namespace gridop | ||
409 | |||
410 | |||
411 | //////////////////////////////////////// | ||
412 | |||
413 | |||
414 | /// @brief Compute the closest-point transform of a scalar grid. | ||
415 | template< | ||
416 | typename InGridT, | ||
417 | typename MaskGridType = typename gridop::ToMaskGrid<InGridT>::Type, | ||
418 | typename InterruptT = util::NullInterrupter> | ||
419 | class Cpt | ||
420 | { | ||
421 | public: | ||
422 | typedef InGridT InGridType; | ||
423 | typedef typename ScalarToVectorConverter<InGridT>::Type OutGridType; | ||
424 | |||
425 | 1 | Cpt(const InGridType& grid, InterruptT* interrupt = nullptr): | |
426 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | mInputGrid(grid), mInterrupt(interrupt), mMask(nullptr) |
427 | { | ||
428 | } | ||
429 | |||
430 | 1 | Cpt(const InGridType& grid, const MaskGridType& mask, InterruptT* interrupt = nullptr): | |
431 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | mInputGrid(grid), mInterrupt(interrupt), mMask(&mask) |
432 | { | ||
433 | } | ||
434 | |||
435 | 4 | typename OutGridType::Ptr process(bool threaded = true, bool useWorldTransform = true) | |
436 | { | ||
437 | 4 | Functor functor(mInputGrid, mMask, threaded, useWorldTransform, mInterrupt); | |
438 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | processTypedMap(mInputGrid.transform(), functor); |
439 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
4 | if (functor.mOutputGrid) functor.mOutputGrid->setVectorType(VEC_CONTRAVARIANT_ABSOLUTE); |
440 | 4 | return functor.mOutputGrid; | |
441 | } | ||
442 | |||
443 | private: | ||
444 | struct IsOpT | ||
445 | { | ||
446 | template<typename MapT, typename AccT> | ||
447 | static typename OutGridType::ValueType | ||
448 | result(const MapT& map, const AccT& acc, const Coord& xyz) | ||
449 | { | ||
450 |
2/72✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✓ Branch 45 taken 1 times.
✗ Branch 46 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✗ Branch 57 not taken.
✗ Branch 58 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
✓ Branch 77 taken 1 times.
✗ Branch 78 not taken.
✗ Branch 81 not taken.
✗ Branch 82 not taken.
✗ Branch 85 not taken.
✗ Branch 86 not taken.
✗ Branch 89 not taken.
✗ Branch 90 not taken.
✗ Branch 93 not taken.
✗ Branch 94 not taken.
✗ Branch 97 not taken.
✗ Branch 98 not taken.
✗ Branch 101 not taken.
✗ Branch 102 not taken.
✗ Branch 105 not taken.
✗ Branch 106 not taken.
✗ Branch 109 not taken.
✗ Branch 110 not taken.
✗ Branch 113 not taken.
✗ Branch 114 not taken.
✗ Branch 117 not taken.
✗ Branch 118 not taken.
✗ Branch 121 not taken.
✗ Branch 122 not taken.
✗ Branch 125 not taken.
✗ Branch 126 not taken.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✗ Branch 133 not taken.
✗ Branch 134 not taken.
✗ Branch 137 not taken.
✗ Branch 138 not taken.
✗ Branch 141 not taken.
✗ Branch 142 not taken.
✗ Branch 145 not taken.
✗ Branch 146 not taken.
✗ Branch 149 not taken.
✗ Branch 150 not taken.
✗ Branch 153 not taken.
✗ Branch 154 not taken.
✗ Branch 157 not taken.
✗ Branch 158 not taken.
|
263154 | return math::CPT<MapT, math::CD_2ND>::result(map, acc, xyz); |
451 | } | ||
452 | }; | ||
453 | struct WsOpT | ||
454 | { | ||
455 | template<typename MapT, typename AccT> | ||
456 | static typename OutGridType::ValueType | ||
457 | result(const MapT& map, const AccT& acc, const Coord& xyz) | ||
458 | { | ||
459 | ✗ | return math::CPT_RANGE<MapT, math::CD_2ND>::result(map, acc, xyz); | |
460 | } | ||
461 | }; | ||
462 | struct Functor | ||
463 | { | ||
464 | 2 | Functor(const InGridType& grid, const MaskGridType* mask, | |
465 | bool threaded, bool worldspace, InterruptT* interrupt) | ||
466 | : mThreaded(threaded) | ||
467 | , mWorldSpace(worldspace) | ||
468 | , mInputGrid(grid) | ||
469 | , mInterrupt(interrupt) | ||
470 |
2/8✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
2 | , mMask(mask) |
471 | {} | ||
472 | |||
473 | template<typename MapT> | ||
474 | 4 | void operator()(const MapT& map) | |
475 | { | ||
476 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
4 | if (mWorldSpace) { |
477 | gridop::GridOperator<InGridType, MaskGridType, OutGridType, MapT, WsOpT, InterruptT> | ||
478 | ✗ | op(mInputGrid, mMask, map, mInterrupt, /*densify=*/false); | |
479 | ✗ | mOutputGrid = op.process(mThreaded); // cache the result | |
480 | } else { | ||
481 | gridop::GridOperator<InGridType, MaskGridType, OutGridType, MapT, IsOpT, InterruptT> | ||
482 | 4 | op(mInputGrid, mMask, map, mInterrupt, /*densify=*/false); | |
483 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
8 | mOutputGrid = op.process(mThreaded); // cache the result |
484 | } | ||
485 | } | ||
486 | const bool mThreaded; | ||
487 | const bool mWorldSpace; | ||
488 | const InGridType& mInputGrid; | ||
489 | typename OutGridType::Ptr mOutputGrid; | ||
490 | InterruptT* mInterrupt; | ||
491 | const MaskGridType* mMask; | ||
492 | }; | ||
493 | const InGridType& mInputGrid; | ||
494 | InterruptT* mInterrupt; | ||
495 | const MaskGridType* mMask; | ||
496 | }; // end of Cpt class | ||
497 | |||
498 | |||
499 | //////////////////////////////////////// | ||
500 | |||
501 | |||
502 | /// @brief Compute the curl of a vector grid. | ||
503 | template< | ||
504 | typename GridT, | ||
505 | typename MaskGridType = typename gridop::ToMaskGrid<GridT>::Type, | ||
506 | typename InterruptT = util::NullInterrupter> | ||
507 | class Curl | ||
508 | { | ||
509 | public: | ||
510 | typedef GridT InGridType; | ||
511 | typedef GridT OutGridType; | ||
512 | |||
513 | 5 | Curl(const GridT& grid, InterruptT* interrupt = nullptr): | |
514 | 5 | mInputGrid(grid), mInterrupt(interrupt), mMask(nullptr) | |
515 | { | ||
516 | } | ||
517 | |||
518 | 1 | Curl(const GridT& grid, const MaskGridType& mask, InterruptT* interrupt = nullptr): | |
519 | 1 | mInputGrid(grid), mInterrupt(interrupt), mMask(&mask) | |
520 | { | ||
521 | } | ||
522 | |||
523 | 12 | typename GridT::Ptr process(bool threaded = true) | |
524 | { | ||
525 | 12 | Functor functor(mInputGrid, mMask, threaded, mInterrupt); | |
526 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
12 | processTypedMap(mInputGrid.transform(), functor); |
527 |
2/4✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
|
12 | if (functor.mOutputGrid) functor.mOutputGrid->setVectorType(VEC_COVARIANT); |
528 | 12 | return functor.mOutputGrid; | |
529 | } | ||
530 | |||
531 | private: | ||
532 | struct Functor | ||
533 | { | ||
534 | 6 | Functor(const GridT& grid, const MaskGridType* mask, | |
535 | bool threaded, InterruptT* interrupt): | ||
536 |
2/12✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 16 taken 5 times.
✗ Branch 17 not taken.
|
6 | mThreaded(threaded), mInputGrid(grid), mInterrupt(interrupt), mMask(mask) {} |
537 | |||
538 | template<typename MapT> | ||
539 | 12 | void operator()(const MapT& map) | |
540 | { | ||
541 | typedef math::Curl<MapT, math::CD_2ND> OpT; | ||
542 | gridop::GridOperator<GridT, MaskGridType, GridT, MapT, OpT, InterruptT> | ||
543 | 12 | op(mInputGrid, mMask, map, mInterrupt); | |
544 |
2/4✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
|
24 | mOutputGrid = op.process(mThreaded); // cache the result |
545 | } | ||
546 | |||
547 | const bool mThreaded; | ||
548 | const GridT& mInputGrid; | ||
549 | typename GridT::Ptr mOutputGrid; | ||
550 | InterruptT* mInterrupt; | ||
551 | const MaskGridType* mMask; | ||
552 | }; // Private Functor | ||
553 | |||
554 | const GridT& mInputGrid; | ||
555 | InterruptT* mInterrupt; | ||
556 | const MaskGridType* mMask; | ||
557 | }; // end of Curl class | ||
558 | |||
559 | |||
560 | //////////////////////////////////////// | ||
561 | |||
562 | |||
563 | /// @brief Compute the divergence of a vector grid. | ||
564 | template< | ||
565 | typename InGridT, | ||
566 | typename MaskGridType = typename gridop::ToMaskGrid<InGridT>::Type, | ||
567 | typename InterruptT = util::NullInterrupter> | ||
568 | class Divergence | ||
569 | { | ||
570 | public: | ||
571 | typedef InGridT InGridType; | ||
572 | typedef typename VectorToScalarConverter<InGridT>::Type OutGridType; | ||
573 | |||
574 | 2 | Divergence(const InGridT& grid, InterruptT* interrupt = nullptr): | |
575 | 2 | mInputGrid(grid), mInterrupt(interrupt), mMask(nullptr) | |
576 | { | ||
577 | } | ||
578 | |||
579 | 2 | Divergence(const InGridT& grid, const MaskGridType& mask, InterruptT* interrupt = nullptr): | |
580 | 2 | mInputGrid(grid), mInterrupt(interrupt), mMask(&mask) | |
581 | { | ||
582 | } | ||
583 | |||
584 | 8 | typename OutGridType::Ptr process(bool threaded = true) | |
585 | { | ||
586 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
|
8 | if (mInputGrid.getGridClass() == GRID_STAGGERED) { |
587 | 2 | Functor<math::FD_1ST> functor(mInputGrid, mMask, threaded, mInterrupt); | |
588 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | processTypedMap(mInputGrid.transform(), functor); |
589 | return functor.mOutputGrid; | ||
590 | } else { | ||
591 | 6 | Functor<math::CD_2ND> functor(mInputGrid, mMask, threaded, mInterrupt); | |
592 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
6 | processTypedMap(mInputGrid.transform(), functor); |
593 | return functor.mOutputGrid; | ||
594 | } | ||
595 | } | ||
596 | |||
597 | protected: | ||
598 | template<math::DScheme DiffScheme> | ||
599 | struct Functor | ||
600 | { | ||
601 | 4 | Functor(const InGridT& grid, const MaskGridType* mask, | |
602 | bool threaded, InterruptT* interrupt): | ||
603 |
3/24✗ Branch 1 not taken.
✗ Branch 2 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 13 not taken.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
|
4 | mThreaded(threaded), mInputGrid(grid), mInterrupt(interrupt), mMask(mask) {} |
604 | |||
605 | template<typename MapT> | ||
606 | 8 | void operator()(const MapT& map) | |
607 | { | ||
608 | typedef math::Divergence<MapT, DiffScheme> OpT; | ||
609 | gridop::GridOperator<InGridType, MaskGridType, OutGridType, MapT, OpT, InterruptT> | ||
610 | 8 | op(mInputGrid, mMask, map, mInterrupt); | |
611 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
16 | mOutputGrid = op.process(mThreaded); // cache the result |
612 | } | ||
613 | |||
614 | const bool mThreaded; | ||
615 | const InGridType& mInputGrid; | ||
616 | typename OutGridType::Ptr mOutputGrid; | ||
617 | InterruptT* mInterrupt; | ||
618 | const MaskGridType* mMask; | ||
619 | }; // Private Functor | ||
620 | |||
621 | const InGridType& mInputGrid; | ||
622 | InterruptT* mInterrupt; | ||
623 | const MaskGridType* mMask; | ||
624 | }; // end of Divergence class | ||
625 | |||
626 | |||
627 | //////////////////////////////////////// | ||
628 | |||
629 | |||
630 | /// @brief Compute the gradient of a scalar grid. | ||
631 | template< | ||
632 | typename InGridT, | ||
633 | typename MaskGridType = typename gridop::ToMaskGrid<InGridT>::Type, | ||
634 | typename InterruptT = util::NullInterrupter> | ||
635 | class Gradient | ||
636 | { | ||
637 | public: | ||
638 | typedef InGridT InGridType; | ||
639 | typedef typename ScalarToVectorConverter<InGridT>::Type OutGridType; | ||
640 | |||
641 | 16 | Gradient(const InGridT& grid, InterruptT* interrupt = nullptr): | |
642 | 16 | mInputGrid(grid), mInterrupt(interrupt), mMask(nullptr) | |
643 | { | ||
644 | } | ||
645 | |||
646 | 1 | Gradient(const InGridT& grid, const MaskGridType& mask, InterruptT* interrupt = nullptr): | |
647 | 1 | mInputGrid(grid), mInterrupt(interrupt), mMask(&mask) | |
648 | { | ||
649 | } | ||
650 | |||
651 | 34 | typename OutGridType::Ptr process(bool threaded = true) | |
652 | { | ||
653 | 34 | Functor functor(mInputGrid, mMask, threaded, mInterrupt); | |
654 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
34 | processTypedMap(mInputGrid.transform(), functor); |
655 |
2/4✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 17 times.
✗ Branch 4 not taken.
|
34 | if (functor.mOutputGrid) functor.mOutputGrid->setVectorType(VEC_COVARIANT); |
656 | 34 | return functor.mOutputGrid; | |
657 | } | ||
658 | |||
659 | protected: | ||
660 | struct Functor | ||
661 | { | ||
662 | 17 | Functor(const InGridT& grid, const MaskGridType* mask, | |
663 | bool threaded, InterruptT* interrupt): | ||
664 |
3/8✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
|
17 | mThreaded(threaded), mInputGrid(grid), mInterrupt(interrupt), mMask(mask) {} |
665 | |||
666 | template<typename MapT> | ||
667 | 34 | void operator()(const MapT& map) | |
668 | { | ||
669 | typedef math::Gradient<MapT, math::CD_2ND> OpT; | ||
670 | gridop::GridOperator<InGridType, MaskGridType, OutGridType, MapT, OpT, InterruptT> | ||
671 | 34 | op(mInputGrid, mMask, map, mInterrupt); | |
672 |
2/4✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
✗ Branch 4 not taken.
|
68 | mOutputGrid = op.process(mThreaded); // cache the result |
673 | } | ||
674 | |||
675 | const bool mThreaded; | ||
676 | const InGridT& mInputGrid; | ||
677 | typename OutGridType::Ptr mOutputGrid; | ||
678 | InterruptT* mInterrupt; | ||
679 | const MaskGridType* mMask; | ||
680 | }; // Private Functor | ||
681 | |||
682 | const InGridT& mInputGrid; | ||
683 | InterruptT* mInterrupt; | ||
684 | const MaskGridType* mMask; | ||
685 | }; // end of Gradient class | ||
686 | |||
687 | |||
688 | //////////////////////////////////////// | ||
689 | |||
690 | |||
691 | template< | ||
692 | typename GridT, | ||
693 | typename MaskGridType = typename gridop::ToMaskGrid<GridT>::Type, | ||
694 | typename InterruptT = util::NullInterrupter> | ||
695 | class Laplacian | ||
696 | { | ||
697 | public: | ||
698 | typedef GridT InGridType; | ||
699 | typedef GridT OutGridType; | ||
700 | |||
701 | 1 | Laplacian(const GridT& grid, InterruptT* interrupt = nullptr): | |
702 | 1 | mInputGrid(grid), mInterrupt(interrupt), mMask(nullptr) | |
703 | { | ||
704 | } | ||
705 | |||
706 | 3 | Laplacian(const GridT& grid, const MaskGridType& mask, InterruptT* interrupt = nullptr): | |
707 | 3 | mInputGrid(grid), mInterrupt(interrupt), mMask(&mask) | |
708 | { | ||
709 | } | ||
710 | |||
711 | 8 | typename GridT::Ptr process(bool threaded = true) | |
712 | { | ||
713 | 8 | Functor functor(mInputGrid, mMask, threaded, mInterrupt); | |
714 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
8 | processTypedMap(mInputGrid.transform(), functor); |
715 |
2/4✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
8 | if (functor.mOutputGrid) functor.mOutputGrid->setVectorType(VEC_COVARIANT); |
716 | 8 | return functor.mOutputGrid; | |
717 | } | ||
718 | |||
719 | protected: | ||
720 | struct Functor | ||
721 | { | ||
722 | 4 | Functor(const GridT& grid, const MaskGridType* mask, bool threaded, InterruptT* interrupt): | |
723 |
3/16✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
4 | mThreaded(threaded), mInputGrid(grid), mInterrupt(interrupt), mMask(mask) {} |
724 | |||
725 | template<typename MapT> | ||
726 | 8 | void operator()(const MapT& map) | |
727 | { | ||
728 | typedef math::Laplacian<MapT, math::CD_SECOND> OpT; | ||
729 | gridop::GridOperator<GridT, MaskGridType, GridT, MapT, OpT, InterruptT> | ||
730 | 8 | op(mInputGrid, mMask, map, mInterrupt); | |
731 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
16 | mOutputGrid = op.process(mThreaded); // cache the result |
732 | } | ||
733 | |||
734 | const bool mThreaded; | ||
735 | const GridT& mInputGrid; | ||
736 | typename GridT::Ptr mOutputGrid; | ||
737 | InterruptT* mInterrupt; | ||
738 | const MaskGridType* mMask; | ||
739 | }; // Private Functor | ||
740 | |||
741 | const GridT& mInputGrid; | ||
742 | InterruptT* mInterrupt; | ||
743 | const MaskGridType* mMask; | ||
744 | }; // end of Laplacian class | ||
745 | |||
746 | |||
747 | //////////////////////////////////////// | ||
748 | |||
749 | |||
750 | template< | ||
751 | typename GridT, | ||
752 | typename MaskGridType = typename gridop::ToMaskGrid<GridT>::Type, | ||
753 | typename InterruptT = util::NullInterrupter> | ||
754 | class MeanCurvature | ||
755 | { | ||
756 | public: | ||
757 | typedef GridT InGridType; | ||
758 | typedef GridT OutGridType; | ||
759 | |||
760 | 1 | MeanCurvature(const GridT& grid, InterruptT* interrupt = nullptr): | |
761 | 1 | mInputGrid(grid), mInterrupt(interrupt), mMask(nullptr) | |
762 | { | ||
763 | } | ||
764 | |||
765 | 1 | MeanCurvature(const GridT& grid, const MaskGridType& mask, InterruptT* interrupt = nullptr): | |
766 | 1 | mInputGrid(grid), mInterrupt(interrupt), mMask(&mask) | |
767 | { | ||
768 | } | ||
769 | |||
770 | 4 | typename GridT::Ptr process(bool threaded = true) | |
771 | { | ||
772 | 4 | Functor functor(mInputGrid, mMask, threaded, mInterrupt); | |
773 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | processTypedMap(mInputGrid.transform(), functor); |
774 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
4 | if (functor.mOutputGrid) functor.mOutputGrid->setVectorType(VEC_COVARIANT); |
775 | 4 | return functor.mOutputGrid; | |
776 | } | ||
777 | |||
778 | protected: | ||
779 | struct Functor | ||
780 | { | ||
781 | 2 | Functor(const GridT& grid, const MaskGridType* mask, bool threaded, InterruptT* interrupt): | |
782 |
2/16✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
|
2 | mThreaded(threaded), mInputGrid(grid), mInterrupt(interrupt), mMask(mask) {} |
783 | |||
784 | template<typename MapT> | ||
785 | 4 | void operator()(const MapT& map) | |
786 | { | ||
787 | typedef math::MeanCurvature<MapT, math::CD_SECOND, math::CD_2ND> OpT; | ||
788 | gridop::GridOperator<GridT, MaskGridType, GridT, MapT, OpT, InterruptT> | ||
789 | 4 | op(mInputGrid, mMask, map, mInterrupt); | |
790 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
8 | mOutputGrid = op.process(mThreaded); // cache the result |
791 | } | ||
792 | |||
793 | const bool mThreaded; | ||
794 | const GridT& mInputGrid; | ||
795 | typename GridT::Ptr mOutputGrid; | ||
796 | InterruptT* mInterrupt; | ||
797 | const MaskGridType* mMask; | ||
798 | }; // Private Functor | ||
799 | |||
800 | const GridT& mInputGrid; | ||
801 | InterruptT* mInterrupt; | ||
802 | const MaskGridType* mMask; | ||
803 | }; // end of MeanCurvature class | ||
804 | |||
805 | |||
806 | //////////////////////////////////////// | ||
807 | |||
808 | |||
809 | template< | ||
810 | typename InGridT, | ||
811 | typename MaskGridType = typename gridop::ToMaskGrid<InGridT>::Type, | ||
812 | typename InterruptT = util::NullInterrupter> | ||
813 | class Magnitude | ||
814 | { | ||
815 | public: | ||
816 | typedef InGridT InGridType; | ||
817 | typedef typename VectorToScalarConverter<InGridT>::Type OutGridType; | ||
818 | |||
819 | 2 | Magnitude(const InGridType& grid, InterruptT* interrupt = nullptr): | |
820 | 2 | mInputGrid(grid), mInterrupt(interrupt), mMask(nullptr) | |
821 | { | ||
822 | } | ||
823 | |||
824 | 2 | Magnitude(const InGridType& grid, const MaskGridType& mask, InterruptT* interrupt = nullptr): | |
825 | 2 | mInputGrid(grid), mInterrupt(interrupt), mMask(&mask) | |
826 | { | ||
827 | } | ||
828 | |||
829 | 8 | typename OutGridType::Ptr process(bool threaded = true) | |
830 | { | ||
831 | 8 | Functor functor(mInputGrid, mMask, threaded, mInterrupt); | |
832 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
8 | processTypedMap(mInputGrid.transform(), functor); |
833 | 8 | return functor.mOutputGrid; | |
834 | } | ||
835 | |||
836 | protected: | ||
837 | struct OpT | ||
838 | { | ||
839 | template<typename MapT, typename AccT> | ||
840 | static typename OutGridType::ValueType | ||
841 | 526318 | result(const MapT&, const AccT& acc, const Coord& xyz) { return acc.getValue(xyz).length();} | |
842 | }; | ||
843 | struct Functor | ||
844 | { | ||
845 | 4 | Functor(const InGridT& grid, const MaskGridType* mask, | |
846 | bool threaded, InterruptT* interrupt): | ||
847 |
2/12✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
|
4 | mThreaded(threaded), mInputGrid(grid), mInterrupt(interrupt), mMask(mask) {} |
848 | |||
849 | template<typename MapT> | ||
850 | 8 | void operator()(const MapT& map) | |
851 | { | ||
852 | gridop::GridOperator<InGridType, MaskGridType, OutGridType, MapT, OpT, InterruptT> | ||
853 | 8 | op(mInputGrid, mMask, map, mInterrupt, /*densify=*/false); | |
854 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
16 | mOutputGrid = op.process(mThreaded); // cache the result |
855 | } | ||
856 | |||
857 | const bool mThreaded; | ||
858 | const InGridType& mInputGrid; | ||
859 | typename OutGridType::Ptr mOutputGrid; | ||
860 | InterruptT* mInterrupt; | ||
861 | const MaskGridType* mMask; | ||
862 | }; // Private Functor | ||
863 | |||
864 | const InGridType& mInputGrid; | ||
865 | InterruptT* mInterrupt; | ||
866 | const MaskGridType* mMask; | ||
867 | }; // end of Magnitude class | ||
868 | |||
869 | |||
870 | //////////////////////////////////////// | ||
871 | |||
872 | |||
873 | template< | ||
874 | typename GridT, | ||
875 | typename MaskGridType = typename gridop::ToMaskGrid<GridT>::Type, | ||
876 | typename InterruptT = util::NullInterrupter> | ||
877 | class Normalize | ||
878 | { | ||
879 | public: | ||
880 | typedef GridT InGridType; | ||
881 | typedef GridT OutGridType; | ||
882 | |||
883 | 1 | Normalize(const GridT& grid, InterruptT* interrupt = nullptr): | |
884 | 1 | mInputGrid(grid), mInterrupt(interrupt), mMask(nullptr) | |
885 | { | ||
886 | } | ||
887 | |||
888 | 1 | Normalize(const GridT& grid, const MaskGridType& mask, InterruptT* interrupt = nullptr): | |
889 | 1 | mInputGrid(grid), mInterrupt(interrupt), mMask(&mask) | |
890 | { | ||
891 | } | ||
892 | |||
893 | 4 | typename GridT::Ptr process(bool threaded = true) | |
894 | { | ||
895 | 4 | Functor functor(mInputGrid, mMask, threaded, mInterrupt); | |
896 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | processTypedMap(mInputGrid.transform(), functor); |
897 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
4 | if (typename GridT::Ptr outGrid = functor.mOutputGrid) { |
898 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | const VecType vecType = mInputGrid.getVectorType(); |
899 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
4 | if (vecType == VEC_COVARIANT) { |
900 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | outGrid->setVectorType(VEC_COVARIANT_NORMALIZE); |
901 | } else { | ||
902 | ✗ | outGrid->setVectorType(vecType); | |
903 | } | ||
904 | } | ||
905 | 4 | return functor.mOutputGrid; | |
906 | } | ||
907 | |||
908 | protected: | ||
909 | struct OpT | ||
910 | { | ||
911 | template<typename MapT, typename AccT> | ||
912 | static typename OutGridType::ValueType | ||
913 | 526308 | result(const MapT&, const AccT& acc, const Coord& xyz) | |
914 | { | ||
915 | 526308 | typename OutGridType::ValueType vec = acc.getValue(xyz); | |
916 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 263150 times.
|
526308 | if ( !vec.normalize() ) vec.setZero(); |
917 | 526308 | return vec; | |
918 | } | ||
919 | }; | ||
920 | struct Functor | ||
921 | { | ||
922 | 2 | Functor(const GridT& grid, const MaskGridType* mask, bool threaded, InterruptT* interrupt): | |
923 |
2/12✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
|
2 | mThreaded(threaded), mInputGrid(grid), mInterrupt(interrupt), mMask(mask) {} |
924 | |||
925 | template<typename MapT> | ||
926 | 4 | void operator()(const MapT& map) | |
927 | { | ||
928 | gridop::GridOperator<GridT, MaskGridType, GridT, MapT, OpT, InterruptT> | ||
929 | 4 | op(mInputGrid, mMask, map, mInterrupt, /*densify=*/false); | |
930 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
8 | mOutputGrid = op.process(mThreaded); // cache the result |
931 | } | ||
932 | |||
933 | const bool mThreaded; | ||
934 | const GridT& mInputGrid; | ||
935 | typename GridT::Ptr mOutputGrid; | ||
936 | InterruptT* mInterrupt; | ||
937 | const MaskGridType* mMask; | ||
938 | }; // Private Functor | ||
939 | |||
940 | const GridT& mInputGrid; | ||
941 | InterruptT* mInterrupt; | ||
942 | const MaskGridType* mMask; | ||
943 | }; // end of Normalize class | ||
944 | |||
945 | |||
946 | //////////////////////////////////////// | ||
947 | |||
948 | |||
949 | template<typename GridType, typename InterruptT> | ||
950 | typename ScalarToVectorConverter<GridType>::Type::Ptr | ||
951 | ✗ | cpt(const GridType& grid, bool threaded, InterruptT* interrupt) | |
952 | { | ||
953 | Cpt<GridType, typename gridop::ToMaskGrid<GridType>::Type, InterruptT> op(grid, interrupt); | ||
954 | ✗ | return op.process(threaded); | |
955 | } | ||
956 | |||
957 | template<typename GridType, typename MaskT, typename InterruptT> | ||
958 | typename ScalarToVectorConverter<GridType>::Type::Ptr | ||
959 | ✗ | cpt(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt) | |
960 | { | ||
961 | Cpt<GridType, MaskT, InterruptT> op(grid, mask, interrupt); | ||
962 | ✗ | return op.process(threaded); | |
963 | } | ||
964 | |||
965 | template<typename GridType, typename InterruptT> | ||
966 | typename GridType::Ptr | ||
967 | 10 | curl(const GridType& grid, bool threaded, InterruptT* interrupt) | |
968 | { | ||
969 | Curl<GridType, typename gridop::ToMaskGrid<GridType>::Type, InterruptT> op(grid, interrupt); | ||
970 | 10 | return op.process(threaded); | |
971 | } | ||
972 | |||
973 | template<typename GridType, typename MaskT, typename InterruptT> | ||
974 | typename GridType::Ptr | ||
975 | 2 | curl(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt) | |
976 | { | ||
977 | Curl<GridType, MaskT, InterruptT> op(grid, mask, interrupt); | ||
978 | 2 | return op.process(threaded); | |
979 | } | ||
980 | |||
981 | template<typename GridType, typename InterruptT> | ||
982 | typename VectorToScalarConverter<GridType>::Type::Ptr | ||
983 | 4 | divergence(const GridType& grid, bool threaded, InterruptT* interrupt) | |
984 | { | ||
985 | Divergence<GridType, typename gridop::ToMaskGrid<GridType>::Type, InterruptT> | ||
986 | op(grid, interrupt); | ||
987 | 4 | return op.process(threaded); | |
988 | } | ||
989 | |||
990 | template<typename GridType, typename MaskT, typename InterruptT> | ||
991 | typename VectorToScalarConverter<GridType>::Type::Ptr | ||
992 | 4 | divergence(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt) | |
993 | { | ||
994 | Divergence<GridType, MaskT, InterruptT> op(grid, mask, interrupt); | ||
995 | 4 | return op.process(threaded); | |
996 | } | ||
997 | |||
998 | template<typename GridType, typename InterruptT> | ||
999 | typename ScalarToVectorConverter<GridType>::Type::Ptr | ||
1000 | 32 | gradient(const GridType& grid, bool threaded, InterruptT* interrupt) | |
1001 | { | ||
1002 | Gradient<GridType, typename gridop::ToMaskGrid<GridType>::Type, InterruptT> | ||
1003 | op(grid, interrupt); | ||
1004 | 32 | return op.process(threaded); | |
1005 | } | ||
1006 | |||
1007 | template<typename GridType, typename MaskT, typename InterruptT> | ||
1008 | typename ScalarToVectorConverter<GridType>::Type::Ptr | ||
1009 | 2 | gradient(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt) | |
1010 | { | ||
1011 | Gradient<GridType, MaskT, InterruptT> op(grid, mask, interrupt); | ||
1012 | 2 | return op.process(threaded); | |
1013 | } | ||
1014 | |||
1015 | template<typename GridType, typename InterruptT> | ||
1016 | typename GridType::Ptr | ||
1017 | 2 | laplacian(const GridType& grid, bool threaded, InterruptT* interrupt) | |
1018 | { | ||
1019 | Laplacian<GridType, typename gridop::ToMaskGrid<GridType>::Type, InterruptT> | ||
1020 | op(grid, interrupt); | ||
1021 | 2 | return op.process(threaded); | |
1022 | } | ||
1023 | |||
1024 | template<typename GridType, typename MaskT, typename InterruptT> | ||
1025 | typename GridType::Ptr | ||
1026 | 6 | laplacian(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt) | |
1027 | { | ||
1028 | Laplacian<GridType, MaskT, InterruptT> op(grid, mask, interrupt); | ||
1029 | 6 | return op.process(threaded); | |
1030 | } | ||
1031 | |||
1032 | template<typename GridType, typename InterruptT> | ||
1033 | typename GridType::Ptr | ||
1034 | 2 | meanCurvature(const GridType& grid, bool threaded, InterruptT* interrupt) | |
1035 | { | ||
1036 | MeanCurvature<GridType, typename gridop::ToMaskGrid<GridType>::Type, InterruptT> | ||
1037 | op(grid, interrupt); | ||
1038 | 2 | return op.process(threaded); | |
1039 | } | ||
1040 | |||
1041 | template<typename GridType, typename MaskT, typename InterruptT> | ||
1042 | typename GridType::Ptr | ||
1043 | 2 | meanCurvature(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt) | |
1044 | { | ||
1045 | MeanCurvature<GridType, MaskT, InterruptT> op(grid, mask, interrupt); | ||
1046 | 2 | return op.process(threaded); | |
1047 | } | ||
1048 | |||
1049 | template<typename GridType, typename InterruptT> | ||
1050 | typename VectorToScalarConverter<GridType>::Type::Ptr | ||
1051 | 4 | magnitude(const GridType& grid, bool threaded, InterruptT* interrupt) | |
1052 | { | ||
1053 | Magnitude<GridType, typename gridop::ToMaskGrid<GridType>::Type, InterruptT> | ||
1054 | op(grid, interrupt); | ||
1055 | 4 | return op.process(threaded); | |
1056 | } | ||
1057 | |||
1058 | template<typename GridType, typename MaskT, typename InterruptT> | ||
1059 | typename VectorToScalarConverter<GridType>::Type::Ptr | ||
1060 | 4 | magnitude(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt) | |
1061 | { | ||
1062 | Magnitude<GridType, MaskT, InterruptT> op(grid, mask, interrupt); | ||
1063 | 4 | return op.process(threaded); | |
1064 | } | ||
1065 | |||
1066 | template<typename GridType, typename InterruptT> | ||
1067 | typename GridType::Ptr | ||
1068 | 2 | normalize(const GridType& grid, bool threaded, InterruptT* interrupt) | |
1069 | { | ||
1070 | Normalize<GridType, typename gridop::ToMaskGrid<GridType>::Type, InterruptT> | ||
1071 | op(grid, interrupt); | ||
1072 | 2 | return op.process(threaded); | |
1073 | } | ||
1074 | |||
1075 | template<typename GridType, typename MaskT, typename InterruptT> | ||
1076 | typename GridType::Ptr | ||
1077 | 1 | normalize(const GridType& grid, const MaskT& mask, bool threaded, InterruptT* interrupt) | |
1078 | { | ||
1079 | Normalize<GridType, MaskT, InterruptT> op(grid, mask, interrupt); | ||
1080 | 1 | return op.process(threaded); | |
1081 | } | ||
1082 | |||
1083 | //////////////////////////////////////// | ||
1084 | |||
1085 | |||
1086 | // Explicit Template Instantiation | ||
1087 | |||
1088 | #ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION | ||
1089 | |||
1090 | #ifdef OPENVDB_INSTANTIATE_GRIDOPERATORS | ||
1091 | #include <openvdb/util/ExplicitInstantiation.h> | ||
1092 | #endif | ||
1093 | |||
1094 | #define _FUNCTION(TreeT) \ | ||
1095 | ScalarToVectorConverter<Grid<TreeT>>::Type::Ptr cpt(const Grid<TreeT>&, bool, util::NullInterrupter*) | ||
1096 | OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION) | ||
1097 | #undef _FUNCTION | ||
1098 | |||
1099 | #define _FUNCTION(TreeT) \ | ||
1100 | ScalarToVectorConverter<Grid<TreeT>>::Type::Ptr cpt(const Grid<TreeT>&, const BoolGrid&, bool, util::NullInterrupter*) | ||
1101 | OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION) | ||
1102 | #undef _FUNCTION | ||
1103 | |||
1104 | #define _FUNCTION(TreeT) \ | ||
1105 | Grid<TreeT>::Ptr curl(const Grid<TreeT>&, bool, util::NullInterrupter*) | ||
1106 | OPENVDB_VEC3_TREE_INSTANTIATE(_FUNCTION) | ||
1107 | #undef _FUNCTION | ||
1108 | |||
1109 | #define _FUNCTION(TreeT) \ | ||
1110 | Grid<TreeT>::Ptr curl(const Grid<TreeT>&, const BoolGrid&, bool, util::NullInterrupter*) | ||
1111 | OPENVDB_VEC3_TREE_INSTANTIATE(_FUNCTION) | ||
1112 | #undef _FUNCTION | ||
1113 | |||
1114 | #define _FUNCTION(TreeT) \ | ||
1115 | VectorToScalarConverter<Grid<TreeT>>::Type::Ptr divergence(const Grid<TreeT>&, bool, util::NullInterrupter*) | ||
1116 | OPENVDB_VEC3_TREE_INSTANTIATE(_FUNCTION) | ||
1117 | #undef _FUNCTION | ||
1118 | |||
1119 | #define _FUNCTION(TreeT) \ | ||
1120 | VectorToScalarConverter<Grid<TreeT>>::Type::Ptr divergence(const Grid<TreeT>&, const BoolGrid&, bool, util::NullInterrupter*) | ||
1121 | OPENVDB_VEC3_TREE_INSTANTIATE(_FUNCTION) | ||
1122 | #undef _FUNCTION | ||
1123 | |||
1124 | #define _FUNCTION(TreeT) \ | ||
1125 | ScalarToVectorConverter<Grid<TreeT>>::Type::Ptr gradient(const Grid<TreeT>&, bool, util::NullInterrupter*) | ||
1126 | OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION) | ||
1127 | #undef _FUNCTION | ||
1128 | |||
1129 | #define _FUNCTION(TreeT) \ | ||
1130 | ScalarToVectorConverter<Grid<TreeT>>::Type::Ptr gradient(const Grid<TreeT>&, const BoolGrid&, bool, util::NullInterrupter*) | ||
1131 | OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION) | ||
1132 | #undef _FUNCTION | ||
1133 | |||
1134 | #define _FUNCTION(TreeT) \ | ||
1135 | Grid<TreeT>::Ptr laplacian(const Grid<TreeT>&, bool, util::NullInterrupter*) | ||
1136 | OPENVDB_NUMERIC_TREE_INSTANTIATE(_FUNCTION) | ||
1137 | #undef _FUNCTION | ||
1138 | |||
1139 | #define _FUNCTION(TreeT) \ | ||
1140 | Grid<TreeT>::Ptr laplacian(const Grid<TreeT>&, const BoolGrid&, bool, util::NullInterrupter*) | ||
1141 | OPENVDB_NUMERIC_TREE_INSTANTIATE(_FUNCTION) | ||
1142 | #undef _FUNCTION | ||
1143 | |||
1144 | #define _FUNCTION(TreeT) \ | ||
1145 | Grid<TreeT>::Ptr meanCurvature(const Grid<TreeT>&, bool, util::NullInterrupter*) | ||
1146 | OPENVDB_NUMERIC_TREE_INSTANTIATE(_FUNCTION) | ||
1147 | #undef _FUNCTION | ||
1148 | |||
1149 | #define _FUNCTION(TreeT) \ | ||
1150 | Grid<TreeT>::Ptr meanCurvature(const Grid<TreeT>&, const BoolGrid&, bool, util::NullInterrupter*) | ||
1151 | OPENVDB_NUMERIC_TREE_INSTANTIATE(_FUNCTION) | ||
1152 | #undef _FUNCTION | ||
1153 | |||
1154 | #define _FUNCTION(TreeT) \ | ||
1155 | VectorToScalarConverter<Grid<TreeT>>::Type::Ptr magnitude(const Grid<TreeT>&, bool, util::NullInterrupter*) | ||
1156 | OPENVDB_VEC3_TREE_INSTANTIATE(_FUNCTION) | ||
1157 | #undef _FUNCTION | ||
1158 | |||
1159 | #define _FUNCTION(TreeT) \ | ||
1160 | VectorToScalarConverter<Grid<TreeT>>::Type::Ptr magnitude(const Grid<TreeT>&, const BoolGrid&, bool, util::NullInterrupter*) | ||
1161 | OPENVDB_VEC3_TREE_INSTANTIATE(_FUNCTION) | ||
1162 | #undef _FUNCTION | ||
1163 | |||
1164 | #define _FUNCTION(TreeT) \ | ||
1165 | Grid<TreeT>::Ptr normalize(const Grid<TreeT>&, bool, util::NullInterrupter*) | ||
1166 | OPENVDB_VEC3_TREE_INSTANTIATE(_FUNCTION) | ||
1167 | #undef _FUNCTION | ||
1168 | |||
1169 | #define _FUNCTION(TreeT) \ | ||
1170 | Grid<TreeT>::Ptr normalize(const Grid<TreeT>&, const BoolGrid&, bool, util::NullInterrupter*) | ||
1171 | OPENVDB_VEC3_TREE_INSTANTIATE(_FUNCTION) | ||
1172 | #undef _FUNCTION | ||
1173 | |||
1174 | #endif // OPENVDB_USE_EXPLICIT_INSTANTIATION | ||
1175 | |||
1176 | |||
1177 | } // namespace tools | ||
1178 | } // namespace OPENVDB_VERSION_NAME | ||
1179 | } // namespace openvdb | ||
1180 | |||
1181 | #endif // OPENVDB_TOOLS_GRID_OPERATORS_HAS_BEEN_INCLUDED | ||
1182 |