diff --git a/libs/MeshKernel/include/MeshKernel/SplitRowColumnOfMesh.hpp b/libs/MeshKernel/include/MeshKernel/SplitRowColumnOfMesh.hpp index 1a28ad9ff..d188ed0ed 100644 --- a/libs/MeshKernel/include/MeshKernel/SplitRowColumnOfMesh.hpp +++ b/libs/MeshKernel/include/MeshKernel/SplitRowColumnOfMesh.hpp @@ -56,6 +56,8 @@ namespace meshkernel void SplitEdge(Mesh2D& mesh, UInt elementId, UInt edgeId, UInt& previousNewNode, CompoundUndoAction& undoActions) const; + void SplitEdge2(Mesh2D& mesh, UInt elementId, UInt edgeId, UInt& previousNewNode, CompoundUndoAction& undoActions) const; + bool IsValidEdge(const Mesh2D& mesh, const UInt edgeId) const; void CollectElementIdsToSplit(const Mesh2D& mesh, const UInt edgeId, std::vector& elementIds, std::vector& edgeIds) const; diff --git a/libs/MeshKernel/src/SplitRowColumnOfMesh.cpp b/libs/MeshKernel/src/SplitRowColumnOfMesh.cpp index 020a7851b..36b5dccae 100644 --- a/libs/MeshKernel/src/SplitRowColumnOfMesh.cpp +++ b/libs/MeshKernel/src/SplitRowColumnOfMesh.cpp @@ -145,6 +145,7 @@ void meshkernel::SplitRowColumnOfMesh::SplitEdge(Mesh2D& mesh, [[maybe_unused]] const std::array& edgeFaces = mesh.m_edgesFaces[edgeId]; const UInt startNode = edge.first; const UInt endNode = edge.second; + const UInt nextElement = edgeFaces[0] + edgeFaces[1] - elementId; // if (startNode == constants::missing::uintValue || endNode == constants::missing::uintValue || !mesh.Node(startNode).IsValid() || !mesh.Node(endNode).IsValid()) // { @@ -177,7 +178,6 @@ void meshkernel::SplitRowColumnOfMesh::SplitEdge(Mesh2D& mesh, [[maybe_unused]] undoActions.Add(std::move(undoAction)); } - UInt nextElement = edgeFaces[0] + edgeFaces[1] - elementId; if (nextElement != constants::missing::uintValue) { @@ -373,6 +373,111 @@ void meshkernel::SplitRowColumnOfMesh::SplitEdge(Mesh2D& mesh, [[maybe_unused]] previousNewNode = newNodeId; } + +void meshkernel::SplitRowColumnOfMesh::SplitEdge2(Mesh2D& mesh, [[maybe_unused]] UInt elementId, UInt edgeId, UInt& previousNewNode, CompoundUndoAction& undoActions) const +{ + std::cout << "SplitRowColumnOfMesh::SplitEdge2 "<< edgeId << std::endl; + + + const Edge& edge = mesh.GetEdge(edgeId); + + // if (!meshkernel::IsValidEdge (edge)) + // { + // previousNewNode = constants::missing::uintValue; + // return; + // } + + const std::array& edgeFaces = mesh.m_edgesFaces[edgeId]; + const UInt startNode = edge.first; + const UInt endNode = edge.second; + const UInt nextElement = edgeFaces[0] + edgeFaces[1] - elementId; + + std::cout << "nextElement " << nextElement << std::endl; + std::cout << "node ids: " << startNode << " " << endNode << std::endl; + + Point point = 0.5 * (mesh.Node(startNode) + mesh.Node(endNode)); + std::cout << "new node coords: " << point.x << ", " << point.y << std::endl; + + if (nextElement != constants::missing::uintValue && mesh.m_numFacesNodes[nextElement] == 3) + { + auto [newEdgeId1, undoAction1] = mesh.ConnectNodes(startNode, previousNewNode); + undoActions.Add(std::move(undoAction1)); + + auto [newEdgeId2, undoAction2] = mesh.ConnectNodes(endNode, previousNewNode); + undoActions.Add(std::move(undoAction2)); + + previousNewNode = constants::missing::uintValue; + } + else + { + auto [newNodeId, undo] = mesh.InsertNode(point); + undoActions.Add(std::move(undo)); + + std::cout << "new node: " << newNodeId << std::endl; + + std::cout << "deleting edge: " << edgeId << " " + << mesh.Node (edge.first).x <<", " << mesh.Node (edge.first).y << " -- " + << mesh.Node (edge.second).x <<", " << mesh.Node (edge.second).y + << std::endl; + + undoActions.Add(mesh.DeleteEdge(edgeId)); + auto [newEdgeId1, newEdgeUndo1] = mesh.ConnectNodes(startNode, newNodeId); + undoActions.Add(std::move(newEdgeUndo1)); + + auto [newEdgeId2, newEdgeUndo2] = mesh.ConnectNodes(newNodeId, endNode); + undoActions.Add(std::move(newEdgeUndo2)); + + if (previousNewNode != constants::missing::uintValue) + { + // undoActions.Add(mesh.DeleteEdge(edgeId)); + auto [newEdgeId1, newEdgeUndo1] = mesh.ConnectNodes(previousNewNode, newNodeId); + undoActions.Add(std::move(newEdgeUndo1)); + } + + // TODO Set the previous new node to null id if: 1. no next element, 2. merged triangles + previousNewNode = newNodeId; + } + + // if (nextElement != constants::missing::uintValue) + // { + // if (mesh.m_numFacesNodes[nextElement] == 3) + // { + // auto [newEdgeId1, undoAction1] = mesh.ConnectNodes(startNode, previousNewNode); + // undoActions.Add(std::move(undoAction1)); + + // auto [newEdgeId2, undoAction2] = mesh.ConnectNodes(endNode, previousNewNode); + // undoActions.Add(std::move(undoAction2)); + + // previousNewNode = constants::missing::uintValue; + // } + // else + // { + // auto [newNodeId, undo] = mesh.InsertNode(point); + // undoActions.Add(std::move(undo)); + + // undoActions.Add(mesh.DeleteEdge(edgeId)); + // auto [newEdgeId1, newEdgeUndo1] = mesh.ConnectNodes(startNode, newNodeId); + // undoActions.Add(std::move(newEdgeUndo1)); + + // auto [newEdgeId2, newEdgeUndo2] = mesh.ConnectNodes(newNodeId, endNode); + // undoActions.Add(std::move(newEdgeUndo2)); + + // if (previousNewNode != constants::missing::uintValue) + // { + // undoActions.Add(mesh.DeleteEdge(edgeId)); + // auto [newEdgeId1, newEdgeUndo1] = mesh.ConnectNodes(previousNewNode, newNodeId); + // undoActions.Add(std::move(newEdgeUndo1)); + // } + + // // TODO Set the previous new node to null id if: 1. no next element, 2. merged triangles + // previousNewNode = newNodeId; + // } + // } + + +} + + void meshkernel::SplitRowColumnOfMesh::SplitEdges(Mesh2D& mesh, std::vector& elementIds, std::vector& edgeIds, CompoundUndoAction& undoActions) const { UInt previousNewNode = constants::missing::uintValue; @@ -381,7 +486,7 @@ void meshkernel::SplitRowColumnOfMesh::SplitEdges(Mesh2D& mesh, std::vectorRestore(); mesh.Administrate(); @@ -2431,3 +2443,104 @@ TEST(MeshRefinement, SplitElementLoop) Print(mesh.Nodes(), mesh.Edges()); } + + +TEST(MeshRefinement, Split3) +{ + // constexpr double tolerance = 1.0e-12; + + auto curviMesh = MakeCurvilinearGrid(0.0, 0.0, 10.0, 10.0, 11, 11); + Mesh2D mesh(curviMesh->ComputeEdges(), curviMesh->ComputeNodes(), Projection::cartesian); + mesh.Administrate(); + + // UInt edgeId = 0; + + [[maybe_unused]] SplitRowColumnOfMesh splitMesh; + // splitMesh.Compute(mesh, edgeId); + + // UInt elementId = mesh.m_edgesFaces[edgeId][0] == constants::missing::uintValue ? mesh.m_edgesFaces[edgeId][1] : mesh.m_edgesFaces[edgeId][0]; + + [[maybe_unused]] UInt edgeIndex = constants::missing::uintValue; + + auto [ newNode1, undoNode1 ] = mesh.InsertNode({110.0, 23.0}); + auto [ newNode2, undoNode2 ] = mesh.InsertNode({120.0, 23.0}); + auto [ newNode3, undoNode3 ] = mesh.InsertNode({120.0, 27.0}); + auto [ newNode4, undoNode4 ] = mesh.InsertNode({110.0, 27.0}); + + UInt node1 = mesh.FindNodeCloseToAPoint({100.0, 10.0}, 1.0e-4); + UInt node2 = mesh.FindNodeCloseToAPoint({100.0, 20.0}, 1.0e-4); + UInt node3 = mesh.FindNodeCloseToAPoint({100.0, 30.0}, 1.0e-4); + UInt node4 = mesh.FindNodeCloseToAPoint({100.0, 40.0}, 1.0e-4); + + [[maybe_unused]] auto undo1 = mesh.ConnectNodes(node1, newNode2); + [[maybe_unused]] auto undo2 = mesh.ConnectNodes(node2, newNode1); + [[maybe_unused]] auto undo3 = mesh.ConnectNodes(node4, newNode3); + [[maybe_unused]] auto undo4 = mesh.ConnectNodes(node3, newNode4); + + [[maybe_unused]] auto undo5 = mesh.ConnectNodes(newNode1, newNode2); + [[maybe_unused]] auto undo6 = mesh.ConnectNodes(newNode2, newNode3); + [[maybe_unused]] auto undo7 = mesh.ConnectNodes(newNode3, newNode4); + [[maybe_unused]] auto undo8 = mesh.ConnectNodes(newNode4, newNode1); + + mesh.Administrate(); + // Print(mesh.Nodes(), mesh.Edges()); + // return; + + // ConnectNodes + + UInt node1a = mesh.FindNodeCloseToAPoint({0.0, 10.0}, 1.0e-4); + UInt node2a = mesh.FindNodeCloseToAPoint({0.0, 20.0}, 1.0e-4); + // UInt node3 = mesh.FindNodeCloseToAPoint({0.0, 10.0}, 1.0e-4); + + [[maybe_unused]] UInt edge1 = mesh.FindEdge(node1a, node2a); + // [[maybe_unused]] UInt edge2 = mesh.FindEdge(node1, node3); + // [[maybe_unused]] UInt edge3 = mesh.FindEdge(startNode3, endNode3); + // [[maybe_unused]] UInt edge4 = mesh.FindEdge(startNode4, endNode4); + + std::cout << "--------------------------------" << std::endl; + [[maybe_unused]] auto undoSplit1 = splitMesh.Compute(mesh, edge1); + // std::cout << "--------------------------------" << std::endl; + // [[maybe_unused]] auto undoSplit2 = splitMesh.Compute(mesh, edge2); + // std::cout << "--------------------------------" << std::endl; + // [[maybe_unused]] auto undoSplit3 = splitMesh.Compute(mesh, edge3); + // std::cout << "--------------------------------" << std::endl; + // [[maybe_unused]] auto undoSplit4 = splitMesh.Compute(mesh, edge4); + // std::cout << "--------------------------------" << std::endl; + + // undoSplit2->Restore(); + mesh.Administrate(); + + // UInt neighbourEdgeIndex = edgeIndex == 0 ? 3 : edgeIndex - 1; + + // std::cout << "nodes: " << mesh.GetEdge(edgeId).first << " -- " << mesh.GetEdge(edgeId).second << " ++++ " + // << mesh.GetEdge(mesh.m_facesEdges[elementId][neighbourEdgeIndex]).first << " -- " + // << mesh.GetEdge(mesh.m_facesEdges[elementId][neighbourEdgeIndex]).second + // << std::endl; + + // splitMesh.Compute(mesh, mesh.m_facesEdges[elementId][neighbourEdgeIndex]); + // // splitMesh.Compute(mesh, 170); + + // edgeId = 170; + // elementId = mesh.m_edgesFaces[edgeId][0] == constants::missing::uintValue ? mesh.m_edgesFaces[edgeId][1] : mesh.m_edgesFaces[edgeId][0]; + + // edgeIndex = constants::missing::uintValue; + + // for (UInt i = 0; i < 4; ++i) + // { + // if (mesh.m_facesEdges[elementId][i] == edgeId) + // { + // edgeIndex = i; + // break; + // } + // } + + // neighbourEdgeIndex = edgeIndex == 0 ? 3 : edgeIndex - 1; + + // std::cout << "nodes: " << mesh.GetEdge(edgeId).first << " -- " << mesh.GetEdge(edgeId).second << " ++++ " + // << mesh.GetEdge(mesh.m_facesEdges[elementId][neighbourEdgeIndex]).first << " -- " + // << mesh.GetEdge(mesh.m_facesEdges[elementId][neighbourEdgeIndex]).second + // << std::endl; + + // splitMesh.Compute(mesh, mesh.m_facesEdges[elementId][neighbourEdgeIndex]); + Print(mesh.Nodes(), mesh.Edges()); +}