MeshKernel
Mesh2DIntersections.hpp
1 //---- GPL ---------------------------------------------------------------------
2 //
3 // Copyright (C) Stichting Deltares, 2011-2023.
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation version 3.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // contact: delft3d.support@deltares.nl
18 // Stichting Deltares
19 // P.O. Box 177
20 // 2600 MH Delft, The Netherlands
21 //
22 // All indications and logos of, and references to, "Delft3D" and "Deltares"
23 // are registered trademarks of Stichting Deltares, and remain the property of
24 // Stichting Deltares. All rights reserved.
25 //
26 //------------------------------------------------------------------------------
27 
28 #pragma once
29 #include <algorithm>
30 #include <vector>
31 
32 #include "MeshKernel/Definitions.hpp"
33 #include "MeshKernel/Mesh2D.hpp"
34 #include "MeshKernel/Polygons.hpp"
35 
36 #include <queue>
37 
38 namespace meshkernel
39 {
42  {
43  int polylineSegmentIndex{constants::missing::intValue};
44  double polylineDistance{constants::missing::doubleValue};
45  double adimensionalPolylineSegmentDistance{constants::missing::doubleValue};
46  UInt edgeIndex{constants::missing::uintValue};
47  UInt edgeFirstNode{constants::missing::uintValue};
48  UInt edgeSecondNode{constants::missing::uintValue};
49  double edgeDistance{constants::missing::doubleValue};
50  };
51 
54  {
55  double polylineDistance{constants::missing::doubleValue};
56  UInt faceIndex{constants::missing::uintValue};
57  std::vector<UInt> edgeIndices;
58  std::vector<UInt> edgeNodes;
59  };
60 
64  class Mesh2DIntersections final
65  {
66  public:
68  explicit Mesh2DIntersections(Mesh2D& mesh);
69 
72  void Compute(const Polygons& polygon);
73 
76  void Compute(const std::vector<Point>& polyLine);
77 
80  [[nodiscard]] const auto& EdgeIntersections() const { return m_edgesIntersections; }
81 
84  [[nodiscard]] const auto& FaceIntersections() const { return m_faceIntersections; }
85 
89  template <typename T>
90  static void sortAndEraseIntersections(std::vector<T>& intersections)
91  {
92  std::ranges::sort(intersections,
93  [](const T& first, const T& second)
94  { return first.polylineDistance < second.polylineDistance; });
95 
96  std::erase_if(intersections, [](const T& v)
97  { return v.polylineDistance < 0; });
98  }
99 
100  private:
102  enum class Direction
103  {
104  Forward,
105  Backward
106  };
107 
110  std::tuple<UInt, UInt> GetIntersectionSeed(const Mesh2D& mesh,
111  const std::vector<Point>& polyLine,
112  const std::vector<BoundingBox>& polyLineBoundingBoxes,
113  const std::vector<bool>& vistedEdges) const;
114 
117  std::tuple<bool, UInt, UInt, double, double, double> GetNextEdgeIntersection(const std::vector<Point>& polyLine,
118  const std::vector<BoundingBox>& polyLineBoundingBoxes,
119  UInt edgeIndex,
120  UInt firstIndex,
121  UInt secondIndex,
122  Direction direction) const;
123 
126  void IntersectFaceEdges(const std::vector<Point>& polyLine,
127  const std::vector<BoundingBox>& polyLineBoundingBoxes,
128  const std::vector<double>& cumulativeLength,
129  UInt currentCrossingEdge,
130  UInt currentFaceIndex,
131  UInt segmentIndex,
132  std::vector<bool>& vistedEdges,
133  std::vector<bool>& vistedFace,
134  std::queue<std::array<UInt, 2>>& crossingEdges);
135 
137  static void updateEdgeIntersections(const UInt segmentIndex,
138  const UInt edgeIndex,
139  const Edge edge,
140  const std::vector<double>& cumulativeLength,
141  const double crossProductValue,
142  const double adimensionalEdgeDistance,
143  const double adimensionalPolylineSegmentDistance,
144  std::vector<EdgeMeshPolyLineIntersection>& intersections)
145  {
146  const auto [edgeFirstNode, edgeSecondNode] = edge;
147 
148  intersections[edgeIndex].polylineSegmentIndex = static_cast<int>(segmentIndex);
149  intersections[edgeIndex].polylineDistance = cumulativeLength[segmentIndex] +
150  adimensionalPolylineSegmentDistance * (cumulativeLength[segmentIndex + 1] - cumulativeLength[segmentIndex]);
151  intersections[edgeIndex].adimensionalPolylineSegmentDistance = adimensionalPolylineSegmentDistance;
152  intersections[edgeIndex].edgeFirstNode = crossProductValue < 0 ? edgeSecondNode : edgeFirstNode;
153  intersections[edgeIndex].edgeSecondNode = crossProductValue < 0 ? edgeFirstNode : edgeSecondNode;
154  intersections[edgeIndex].edgeDistance = adimensionalEdgeDistance;
155  intersections[edgeIndex].edgeIndex = edgeIndex;
156  }
157 
159  static void updateFaceIntersections(const UInt faceIndex,
160  const UInt edgeIndex,
161  std::vector<FaceMeshPolyLineIntersection>& intersections)
162  {
163  intersections[faceIndex].faceIndex = faceIndex;
164  intersections[faceIndex].edgeIndices.emplace_back(edgeIndex);
165  }
166 
167  Mesh2D& m_mesh;
168  std::vector<EdgeMeshPolyLineIntersection> m_edgesIntersectionsCache;
169  std::vector<FaceMeshPolyLineIntersection> m_facesIntersectionsCache;
170  std::vector<EdgeMeshPolyLineIntersection> m_edgesIntersections;
171  std::vector<FaceMeshPolyLineIntersection> m_faceIntersections;
172  BoundingBox m_meshBoundingBox;
173  std::vector<BoundingBox> m_meshEdgesBoundingBoxes;
174  static constexpr UInt maxSearchSegments = 1000;
175  };
176 
177 } // namespace meshkernel
meshkernel::EdgeMeshPolyLineIntersection::polylineSegmentIndex
int polylineSegmentIndex
The intersected segment index (a polyline can formed by several segments)
Definition: Mesh2DIntersections.hpp:43
meshkernel::EdgeMeshPolyLineIntersection::edgeIndex
UInt edgeIndex
The edge index.
Definition: Mesh2DIntersections.hpp:46
meshkernel::Mesh2DIntersections::Compute
void Compute(const Polygons &polygon)
Compute intersection with a polygon, possibly containing multiple polylines.
meshkernel::Mesh2DIntersections
Compute the intersections of polygon inner and outer perimeters.
Definition: Mesh2DIntersections.hpp:64
meshkernel::Mesh2DIntersections::sortAndEraseIntersections
static void sortAndEraseIntersections(std::vector< T > &intersections)
Sort intersections by polyline distance and erase entries with no intersections.
Definition: Mesh2DIntersections.hpp:90
meshkernel::FaceMeshPolyLineIntersection::polylineDistance
double polylineDistance
The location of the intersection expressed as an adimensional distance from the polyline start.
Definition: Mesh2DIntersections.hpp:55
meshkernel::Mesh2D
A class derived from Mesh, which describes unstructures 2d meshes.
Definition: Mesh2D.hpp:55
meshkernel::EdgeMeshPolyLineIntersection::polylineDistance
double polylineDistance
The location of the intersection expressed as distance from the polyline start.
Definition: Mesh2DIntersections.hpp:44
meshkernel::EdgeMeshPolyLineIntersection
An intersection with a mesh edge.
Definition: Mesh2DIntersections.hpp:41
meshkernel::EdgeMeshPolyLineIntersection::adimensionalPolylineSegmentDistance
double adimensionalPolylineSegmentDistance
The location of the intersection expressed as an adimensional distance from the segment start.
Definition: Mesh2DIntersections.hpp:45
meshkernel::EdgeMeshPolyLineIntersection::edgeSecondNode
UInt edgeSecondNode
The second node of the edge is on the right (the inner node)
Definition: Mesh2DIntersections.hpp:48
meshkernel::EdgeMeshPolyLineIntersection::edgeFirstNode
UInt edgeFirstNode
The first node of the edge is on the left (the virtual node)
Definition: Mesh2DIntersections.hpp:47
meshkernel::FaceMeshPolyLineIntersection
An intersection with a mesh face.
Definition: Mesh2DIntersections.hpp:53
meshkernel::Mesh2DIntersections::EdgeIntersections
const auto & EdgeIntersections() const
Gets the edge intersections.
Definition: Mesh2DIntersections.hpp:80
meshkernel::Mesh2DIntersections::Mesh2DIntersections
Mesh2DIntersections(Mesh2D &mesh)
Constructor.
meshkernel::Mesh2DIntersections::FaceIntersections
const auto & FaceIntersections() const
Gets the face intersections.
Definition: Mesh2DIntersections.hpp:84
meshkernel
Contains the logic of the C++ static library.
Definition: AveragingInterpolation.hpp:36
meshkernel::FaceMeshPolyLineIntersection::edgeNodes
std::vector< UInt > edgeNodes
The indexes of the nodes defining the crossed edges.
Definition: Mesh2DIntersections.hpp:58
meshkernel::EdgeMeshPolyLineIntersection::edgeDistance
double edgeDistance
The location of the intersection expressed as an adimensional distance from the edge start.
Definition: Mesh2DIntersections.hpp:49
meshkernel::UInt
std::uint32_t UInt
Integer type used when indexing mesh graph entities.
Definition: Definitions.hpp:38
meshkernel::Polygons
A class containing a list of polygonaly enclosed regions.
Definition: Polygons.hpp:44
meshkernel::Edge
std::pair< UInt, UInt > Edge
Describes an edge with two indices.
Definition: Entities.hpp:50
meshkernel::FaceMeshPolyLineIntersection::faceIndex
UInt faceIndex
The face index.
Definition: Mesh2DIntersections.hpp:56
meshkernel::FaceMeshPolyLineIntersection::edgeIndices
std::vector< UInt > edgeIndices
The indexes of crossed edges.
Definition: Mesh2DIntersections.hpp:57