diff --git a/MeshGeoToolsLib/MeshNodeSearcher.cpp b/MeshGeoToolsLib/MeshNodeSearcher.cpp
index 0a039904a46e0a8762b0a892266d36b99c68dc98..990348f97b760b62a1b6e131c3df2f93f7f09ff6 100644
--- a/MeshGeoToolsLib/MeshNodeSearcher.cpp
+++ b/MeshGeoToolsLib/MeshNodeSearcher.cpp
@@ -62,6 +62,37 @@ MeshNodeSearcher::~MeshNodeSearcher()
     }
 }
 
+template <typename CacheType, typename GeometryType>
+std::vector<std::size_t> const& getMeshNodeIDs(
+    std::vector<CacheType*>& cached_elements,
+    std::function<GeometryType(CacheType const&)> getCachedItem,
+    GeometryType const& item, MeshLib::Mesh const& mesh,
+    GeoLib::Grid<MeshLib::Node> const& mesh_grid,
+    double const search_length,
+    SearchAllNodes const search_all_nodes)
+{
+    if (auto const it = find_if(cbegin(cached_elements), cend(cached_elements),
+                                [&](auto const& element) {
+                                    return getCachedItem(*element) == item;
+                                });
+        it != cend(cached_elements))
+    {
+        return (*it)->getNodeIDs();
+    }
+    // search IDs for geometry object
+    if constexpr (std::is_convertible<GeometryType, GeoLib::Point>::value)
+    {
+        cached_elements.push_back(new CacheType(
+            mesh, mesh_grid, item, search_length, search_all_nodes));
+    }
+    else
+    {
+        cached_elements.push_back(
+            new CacheType(mesh, item, search_length, search_all_nodes));
+    }
+    return cached_elements.back()->getNodeIDs();
+}
+
 std::vector<std::size_t> MeshNodeSearcher::getMeshNodeIDs(
     GeoLib::GeoObject const& geoObj) const
 {
@@ -134,62 +165,33 @@ std::vector<std::size_t> MeshNodeSearcher::getMeshNodeIDs(
 std::vector<std::size_t> const& MeshNodeSearcher::getMeshNodeIDsForPoint(
     GeoLib::Point const& pnt) const
 {
-    if (auto const it = find_if(
-            cbegin(_mesh_nodes_on_points),
-            cend(_mesh_nodes_on_points),
-            [&](auto const& nodes) { return &(nodes->getPoint()) == &pnt; });
-        it != cend(_mesh_nodes_on_points))
-    {
-        return (*it)->getNodeIDs();
-    }
-
-    _mesh_nodes_on_points.push_back(
-        new MeshNodesOnPoint(_mesh,
-                             _mesh_grid,
-                             pnt,
-                             _search_length_algorithm->getSearchLength(),
-                             _search_all_nodes));
-    return _mesh_nodes_on_points.back()->getNodeIDs();
+    std::function<GeoLib::Point(MeshNodesOnPoint const&)>
+        get_cached_item_function = &MeshNodesOnPoint::getPoint;
+    return MeshGeoToolsLib::getMeshNodeIDs(
+        _mesh_nodes_on_points, get_cached_item_function, pnt, _mesh, _mesh_grid,
+        _search_length_algorithm->getSearchLength(), _search_all_nodes);
 }
 
 std::vector<std::size_t> const& MeshNodeSearcher::getMeshNodeIDsAlongPolyline(
     GeoLib::Polyline const& ply) const
 {
-    if (auto const it = find_if(
-            cbegin(_mesh_nodes_along_polylines),
-            cend(_mesh_nodes_along_polylines),
-            [&](auto const& nodes) { return &(nodes->getPolyline()) == &ply; });
-        it != cend(_mesh_nodes_along_polylines))
-    {
-        return (*it)->getNodeIDs();
-    }
-
-    // compute nodes (and supporting points) along polyline
-    _mesh_nodes_along_polylines.push_back(new MeshNodesAlongPolyline(
-        _mesh, ply, _search_length_algorithm->getSearchLength(),
-        _search_all_nodes));
-    return _mesh_nodes_along_polylines.back()->getNodeIDs();
+    std::function<GeoLib::Polyline(MeshNodesAlongPolyline const&)>
+        get_cached_item_function = &MeshNodesAlongPolyline::getPolyline;
+    return MeshGeoToolsLib::getMeshNodeIDs(
+        _mesh_nodes_along_polylines, get_cached_item_function, ply, _mesh,
+        _mesh_grid, _search_length_algorithm->getSearchLength(),
+        _search_all_nodes);
 }
 
 std::vector<std::size_t> const& MeshNodeSearcher::getMeshNodeIDsAlongSurface(
     GeoLib::Surface const& sfc) const
 {
-    if (auto const it = find_if(
-            cbegin(_mesh_nodes_along_surfaces),
-            cend(_mesh_nodes_along_surfaces),
-            [&](auto const& nodes) { return &(nodes->getSurface()) == &sfc; });
-        it != cend(_mesh_nodes_along_surfaces))
-    {
-        return (*it)->getNodeIDs();
-    }
-
-    // compute nodes (and supporting points) on surface
-    _mesh_nodes_along_surfaces.push_back(
-        new MeshNodesAlongSurface(_mesh,
-                                  sfc,
-                                  _search_length_algorithm->getSearchLength(),
-                                  _search_all_nodes));
-    return _mesh_nodes_along_surfaces.back()->getNodeIDs();
+    std::function<GeoLib::Surface(MeshNodesAlongSurface const&)>
+        get_cached_item_function = &MeshNodesAlongSurface::getSurface;
+    return MeshGeoToolsLib::getMeshNodeIDs(
+        _mesh_nodes_along_surfaces, get_cached_item_function, sfc, _mesh,
+        _mesh_grid, _search_length_algorithm->getSearchLength(),
+        _search_all_nodes);
 }
 
 MeshNodeSearcher const& MeshNodeSearcher::getMeshNodeSearcher(