Constructor @param[in] mesh Mesh for building the bounding box tree. @param[in] tdim Topological dimension of the mesh entities to build the bounding box tree for. @param[in] padding Value to pad (extend) the the bounding box of each entity by. @param[in] entities List of entity indices (local to process) to compute the bounding box for. If `std::nullopt`, the bounding box tree is computed for all
| 232 | /// compute the bounding box for. If `std::nullopt`, the bounding box tree is |
| 233 | /// computed for all local entities (including ghosts) of the given `tdim`. |
| 234 | BoundingBoxTree(const mesh::Mesh<T>& mesh, int tdim, double padding, |
| 235 | std::optional<std::span<const std::int32_t>> entities |
| 236 | = std::nullopt) |
| 237 | : _tdim(tdim) |
| 238 | { |
| 239 | // Initialize entities of given dimension if they don't exist |
| 240 | mesh.topology_mutable()->create_entities(tdim); |
| 241 | |
| 242 | // Get input entities. If not provided, get all local entities of the given |
| 243 | // dimension (including ghosts) |
| 244 | std::span<const std::int32_t> entities_span; |
| 245 | std::optional<std::vector<std::int32_t>> local_range(std::nullopt); |
| 246 | if (entities) |
| 247 | entities_span = entities.value(); |
| 248 | else |
| 249 | { |
| 250 | local_range.emplace(range(*mesh.topology_mutable(), tdim)); |
| 251 | entities_span = std::span<const std::int32_t>(local_range->data(), |
| 252 | local_range->size()); |
| 253 | } |
| 254 | |
| 255 | if (tdim < 0 or tdim > mesh.topology()->dim()) |
| 256 | { |
| 257 | throw std::runtime_error( |
| 258 | "Dimension must be non-negative and less than or " |
| 259 | "equal to the topological dimension of the mesh"); |
| 260 | } |
| 261 | |
| 262 | mesh.topology_mutable()->create_connectivity(tdim, mesh.topology()->dim()); |
| 263 | |
| 264 | // Create bounding boxes for all mesh entities (leaves) |
| 265 | std::vector<std::pair<std::array<T, 6>, std::int32_t>> leaf_bboxes; |
| 266 | leaf_bboxes.reserve(entities_span.size()); |
| 267 | for (std::int32_t e : entities_span) |
| 268 | { |
| 269 | std::array<T, 6> b = impl_bb::compute_bbox_of_entity(mesh, tdim, e); |
| 270 | std::transform(b.cbegin(), std::next(b.cbegin(), 3), b.begin(), |
| 271 | [padding](auto x) { return x - padding; }); |
| 272 | std::transform(std::next(b.begin(), 3), b.end(), std::next(b.begin(), 3), |
| 273 | [padding](auto x) { return x + padding; }); |
| 274 | leaf_bboxes.emplace_back(b, e); |
| 275 | } |
| 276 | |
| 277 | // Recursively build the bounding box tree from the leaves |
| 278 | if (!leaf_bboxes.empty()) |
| 279 | std::tie(_bboxes, _bbox_coordinates) |
| 280 | = impl_bb::build_from_leaf(leaf_bboxes); |
| 281 | |
| 282 | spdlog::info("Computed bounding box tree with {} nodes for {} entities", |
| 283 | num_bboxes(), entities_span.size()); |
| 284 | } |
| 285 | |
| 286 | /// Constructor |
| 287 | /// @param[in] points Cloud of points, with associated |
nothing calls this directly
no test coverage detected