diff --git a/libs/MeshKernel/include/MeshKernel/Mesh2D.hpp b/libs/MeshKernel/include/MeshKernel/Mesh2D.hpp index a302040b4..b39c51583 100644 --- a/libs/MeshKernel/include/MeshKernel/Mesh2D.hpp +++ b/libs/MeshKernel/include/MeshKernel/Mesh2D.hpp @@ -348,6 +348,13 @@ namespace meshkernel /// it may be required to call Administrate after merging static std::unique_ptr Merge(const Mesh2D& mesh1, const Mesh2D& mesh2); + /// @brief Merges mesh node and edge connectivity into a single mesh. + static std::unique_ptr Merge(const std::vector& mesh1Nodes, + const std::vector& mesh1Edges, + const std::vector& mesh2Nodes, + const std::vector& mesh2Edges, + const Projection projection); + /// @brief Get the mesh bounding box /// /// @return The mesh bounding box diff --git a/libs/MeshKernel/src/Mesh2D.cpp b/libs/MeshKernel/src/Mesh2D.cpp index d41972e64..7b6b0f1ce 100644 --- a/libs/MeshKernel/src/Mesh2D.cpp +++ b/libs/MeshKernel/src/Mesh2D.cpp @@ -2470,6 +2470,67 @@ std::unique_ptr Mesh2D::Merge(const Mesh2D& mesh1, const Mesh2D& mesh2) mergedMesh.m_projection); } +std::unique_ptr Mesh2D::Merge(const std::vector& mesh1Nodes, + const std::vector& mesh1Edges, + const std::vector& mesh2Nodes, + const std::vector& mesh2Edges, + const Projection projection) +{ + std::vector mergedNodes(mesh1Nodes.size() + mesh2Nodes.size()); + std::vector mergedEdges(mesh1Edges.size() + mesh2Edges.size()); + + if (mesh1Nodes.size() > 0) + { + // Merge node array from mesh1 nodes + mergedNodes.insert(mergedNodes.begin(), mesh1Nodes.begin(), mesh1Nodes.end()); + + // Merge edge array from mesh1 edges + mergedEdges.insert(mergedEdges.begin(), mesh1Edges.begin(), mesh1Edges.end()); + } + + if (mesh2Nodes.size() > 0) + { + // Merge node array from mesh2 nodes + mergedNodes.insert(mergedNodes.begin() + mesh1Nodes.size(), mesh2Nodes.begin(), mesh2Nodes.end()); + + // A copy is needed so that the node connectivity ids can be reassigned + // The copy is needed only if mesh1Nodes.size() > 0 (most likelly to be true) + std::vector mesh2EdgesCopy; + std::span mesh2EdgesSpan; + + if (mesh1Nodes.size() > 0) + { + mesh2EdgesCopy = mesh2Edges; + const UInt numberOfMesh1Nodes = mesh1Nodes.size(); + + // Re-assign the node ids for the second mesh data set + for (size_t i = 0; i < mesh2Edges.size(); ++i) + { + if (mesh2EdgesCopy[i].first != constants::missing::uintValue) + { + mesh2EdgesCopy[i].first += numberOfMesh1Nodes; + } + + if (mesh2EdgesCopy[i].second != constants::missing::uintValue) + { + mesh2EdgesCopy[i].second += numberOfMesh1Nodes; + } + } + + mesh2EdgesSpan = std::span(mesh2EdgesCopy.data(), mesh2EdgesCopy.size()); + } + else + { + mesh2EdgesSpan = std::span(mesh2Edges.data(), mesh2Edges.size()); + } + + // Merge edge array from mesh2 edges + mergedEdges.insert(mergedEdges.begin() + mesh1Edges.size(), mesh2EdgesSpan.begin(), mesh2EdgesSpan.end()); + } + + return std::make_unique(mergedEdges, mergedNodes, projection); +} + meshkernel::BoundingBox Mesh2D::GetBoundingBox() const { Point lowerLeft(std::numeric_limits::max(), std::numeric_limits::max()); diff --git a/libs/MeshKernel/tests/src/Mesh2DConnectDDTest.cpp b/libs/MeshKernel/tests/src/Mesh2DConnectDDTest.cpp index a4c0c629a..313601615 100644 --- a/libs/MeshKernel/tests/src/Mesh2DConnectDDTest.cpp +++ b/libs/MeshKernel/tests/src/Mesh2DConnectDDTest.cpp @@ -441,7 +441,10 @@ TEST(Mesh2DConnectDD, MergeTwoSameMeshesNoOffset) std::shared_ptr mesh2 = generateMesh(origin, delta, nx, ny); - const auto mergedMesh = meshkernel::Mesh2D::Merge(*mesh1, *mesh2); + const auto mergedMesh = meshkernel::Mesh2D::Merge(mesh1->Nodes(), mesh1->Edges(), + mesh2->Nodes(), mesh2->Edges(), + mesh1->m_projection); + // const auto mergedMesh = meshkernel::Mesh2D::Merge(*mesh1, *mesh2); const std::vector originalNodes(mergedMesh->Nodes()); const std::vector originalEdges(mergedMesh->Edges());