diff --git a/MeshLib/findElementsWithinRadius.cpp b/MeshLib/findElementsWithinRadius.cpp index 0f6d1d345301cedaa3f5410c8820cdb060bb0ace..bc69f4875ac23a76707ef50100cffb8baa477ae9 100644 --- a/MeshLib/findElementsWithinRadius.cpp +++ b/MeshLib/findElementsWithinRadius.cpp @@ -11,7 +11,7 @@ #include "findElementsWithinRadius.h" -#include <deque> +#include <vector> #include <unordered_set> #include "BaseLib/uniqueInsert.h" @@ -29,29 +29,50 @@ std::vector<std::size_t> findElementsWithinRadius(Element const& start_element, if (radius_squared == 0.) return {start_element.getID()}; + // Collect start element node coordinates into local contigiuos memory. + std::vector<MathLib::Point3d> start_element_nodes; + { + auto const start_element_n_nodes = start_element.getNumberOfNodes(); + start_element_nodes.reserve(start_element_n_nodes); + for (unsigned n = 0; n < start_element_n_nodes; ++n) + start_element_nodes.push_back(*start_element.getNode(n)); + } + // Returns true if the test node is inside the radius of any of the // element's nodes. - auto node_inside_radius = [&start_element, + auto node_inside_radius = [&start_element_nodes, radius_squared](Node const* test_node) { - for (unsigned n = 0; n < start_element.getNumberOfNodes(); ++n) + for (auto const& n : start_element_nodes) { - if (MathLib::sqrDist(*test_node, *start_element.getNode(n)) <= - radius_squared) + if (MathLib::sqrDist(*test_node, n) <= radius_squared) + return true; + } + return false; + }; + + // Returns true if any of the test element's nodes is inside the start + // element's radius. + auto element_in_radius = [&node_inside_radius](Element const& element) { + auto const n_nodes = element.getNumberOfNodes(); + for (unsigned i = 0; i < n_nodes; ++i) + { + if (node_inside_radius(element.getNode(i))) return true; } return false; }; std::set<std::size_t> found_elements; - std::deque<Element const*> neighbors_to_visit; + std::vector<Element const*> neighbors_to_visit; std::unordered_set<std::size_t> visited_elements; auto mark_visited_and_add_neighbors = - [&found_elements, &neighbors_to_visit, - &visited_elements](Element const& element) { + [&found_elements, &neighbors_to_visit, &visited_elements]( + Element const& element) { found_elements.insert(element.getID()); visited_elements.insert(element.getID()); - for (unsigned n = 0; n < element.getNumberOfNeighbors(); ++n) + auto const n_neighbors = element.getNumberOfNeighbors(); + for (unsigned n = 0; n < n_neighbors; ++n) { auto neighbor = element.getNeighbor(n); if (neighbor == nullptr) @@ -61,6 +82,7 @@ std::vector<std::size_t> findElementsWithinRadius(Element const& start_element, continue; neighbors_to_visit.push_back(neighbor); + visited_elements.insert(neighbor->getID()); } }; @@ -70,17 +92,12 @@ std::vector<std::size_t> findElementsWithinRadius(Element const& start_element, while (!neighbors_to_visit.empty()) { - auto const& current_element = *neighbors_to_visit.front(); - neighbors_to_visit.pop_front(); - - // if any node is inside the radius, all neighbors are visited. - for (unsigned i = 0; i < current_element.getNumberOfNodes(); ++i) - { - if (!node_inside_radius(current_element.getNode(i))) - continue; + auto const& current_element = *neighbors_to_visit.back(); + neighbors_to_visit.pop_back(); + // If any node is inside the radius, all neighbors are visited. + if (element_in_radius(current_element)) mark_visited_and_add_neighbors(current_element); - } } return {std::begin(found_elements), std::end(found_elements)};