MeshKernel
TriangulationWrapper.hpp
1 //---- GPL ---------------------------------------------------------------------
2 //
3 // Copyright (C) Stichting Deltares, 2011-2021.
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 
30 #include "MeshKernel/Constants.hpp"
31 #include "MeshKernel/Entities.hpp"
32 #include "MeshKernel/Exceptions.hpp"
33 #include "MeshKernel/Point.hpp"
34 #include "MeshKernel/PolygonalEnclosure.hpp"
35 
36 #include <concepts>
37 
38 namespace meshkernel
39 {
40  extern "C"
41  {
45  void Triangulation(int jatri,
46  double const* const xs,
47  double const* const ys,
48  int ns,
49  int* const indx,
50  int* const numtri,
51  int* const edgeidx,
52  int* const numedge,
53  int* const triedge,
54  double* const xs3,
55  double* const ys3,
56  int* const ns3,
57  double trisize);
58  }
59 
60  class Sample;
61 
66  {
69  {
70  TriangulatePoints = 1,
71  GeneratePoints = 2,
73  };
74 
81  template <std::derived_from<Point> T>
82  void Compute(const std::vector<T>& inputNodes,
83  TriangulationOptions triangulationOption,
84  double averageTriangleArea,
85  UInt estimatedNumberOfTriangles)
86  {
87  if (inputNodes.empty())
88  {
89  throw ConstraintError("The sample is empty.");
90  }
91  std::vector<double> xLocalPolygon(inputNodes.size());
92  std::vector<double> yLocalPolygon(inputNodes.size());
93  for (UInt i = 0; i < inputNodes.size(); ++i)
94  {
95  xLocalPolygon[i] = inputNodes[i].x;
96  yLocalPolygon[i] = inputNodes[i].y;
97  }
98 
99  m_numFaces = -1;
100  m_numEdges = 0;
101  m_numNodes = 0;
102 
103  int numInputNodes = static_cast<int>(inputNodes.size());
104  auto intTriangulationOption = static_cast<int>(triangulationOption);
105 
106  if (estimatedNumberOfTriangles == 0)
107  {
108  estimatedNumberOfTriangles = static_cast<UInt>(inputNodes.size()) * 6 + 10;
109  }
110 
111  // If the number of estimated triangles is not sufficient, triangulation must be repeated
112  while (m_numFaces < 0)
113  {
114  m_numFaces = static_cast<int>(estimatedNumberOfTriangles);
115 
116  m_faceNodesFlat.resize(estimatedNumberOfTriangles * 3);
117  std::ranges::fill(m_faceNodesFlat, 0);
118 
119  m_edgeNodesFlat.resize(estimatedNumberOfTriangles * 2);
120  std::ranges::fill(m_edgeNodesFlat, 0);
121 
122  m_faceEdgesFlat.resize(estimatedNumberOfTriangles * 3);
123  std::ranges::fill(m_faceEdgesFlat, 0);
124 
125  m_xCoordFlat.resize(estimatedNumberOfTriangles * 3, constants::missing::doubleValue);
126  std::ranges::fill(m_xCoordFlat, 0.0);
127 
128  m_yCoordFlat.resize(estimatedNumberOfTriangles * 3, constants::missing::doubleValue);
129  std::ranges::fill(m_yCoordFlat, 0.0);
130 
131  Triangulation(intTriangulationOption,
132  xLocalPolygon.data(),
133  yLocalPolygon.data(),
134  numInputNodes,
135  m_faceNodesFlat.data(), // INDX
136  &m_numFaces,
137  m_edgeNodesFlat.data(), // EDGEINDX
138  &m_numEdges,
139  m_faceEdgesFlat.data(), // TRIEDGE
140  m_xCoordFlat.data(),
141  m_yCoordFlat.data(),
142  &m_numNodes,
143  averageTriangleArea);
144  if (estimatedNumberOfTriangles > 0)
145  {
146  estimatedNumberOfTriangles = -m_numFaces;
147  }
148  }
149  }
150 
152  std::vector<Point> SelectNodes(const PolygonalEnclosure& enclosure) const;
153 
155  void BuildTriangulation();
156 
159  [[nodiscard]] int GetNumEdges() const
160  {
161  return m_numEdges;
162  }
163 
166  [[nodiscard]] int GetNumNodes() const
167  {
168  return m_numNodes;
169  }
170 
173  [[nodiscard]] int GetNumFaces() const
174  {
175  return m_numFaces;
176  }
177 
180  [[nodiscard]] const std::vector<Point>& GetNodes() const
181  {
182  return m_nodes;
183  }
184 
188  [[nodiscard]] const std::vector<UInt>& GetFaceNodes(const UInt faceIndex) const
189  {
190  return m_faceNodes[faceIndex];
191  }
192 
197  [[nodiscard]] UInt GetFaceNode(const UInt faceIndex, const UInt nodeIndex) const
198  {
199  return m_faceNodes[faceIndex][nodeIndex];
200  }
201 
206  [[nodiscard]] UInt GetFaceEdge(const UInt faceIndex, const UInt edgeIndex) const
207  {
208  return m_faceEdges[faceIndex][edgeIndex];
209  }
210 
215  [[nodiscard]] UInt GetEdgeNode(const UInt edgeIndex, const UInt nodeIndex) const
216  {
217  return m_edgeNodes[edgeIndex][nodeIndex];
218  }
219 
224  [[nodiscard]] UInt GetEdgeFace(const UInt edgeIndex, const UInt faceIndex) const
225  {
226  return m_edgesFaces[edgeIndex][faceIndex];
227  }
228 
232  [[nodiscard]] double GetXCoord(const UInt nodeIndex) const
233  {
234  return m_xCoordFlat[nodeIndex];
235  }
236 
240  [[nodiscard]] double GetYCoord(const UInt nodeIndex) const
241  {
242  return m_yCoordFlat[nodeIndex];
243  }
244 
248  Point GetCoord(const UInt nodeIndex) const
249  {
250  return Point(m_xCoordFlat[nodeIndex], m_yCoordFlat[nodeIndex]);
251  }
252 
253  private:
254  std::vector<int> m_faceNodesFlat;
255  std::vector<int> m_edgeNodesFlat;
256  std::vector<int> m_faceEdgesFlat;
257  std::vector<double> m_xCoordFlat;
258  std::vector<double> m_yCoordFlat;
259  int m_numNodes{0};
260  int m_numEdges{0};
261  int m_numFaces{0};
262 
263  std::vector<Point> m_nodes;
264  std::vector<std::vector<UInt>> m_faceNodes;
265  std::vector<std::vector<UInt>> m_faceEdges;
266  std::vector<std::vector<UInt>> m_edgeNodes;
267  std::vector<std::vector<UInt>> m_edgesFaces;
268  };
269 
270 } // namespace meshkernel
meshkernel::TriangulationWrapper::TriangulationOptions::TriangulatePointsAndGenerateFaces
@ TriangulatePointsAndGenerateFaces
generate Delaunay triangulation from input nodes with m_faceEdges and m_edgeNodes
meshkernel::TriangulationWrapper::GetFaceEdge
UInt GetFaceEdge(const UInt faceIndex, const UInt edgeIndex) const
Retrieves the face edge.
Definition: TriangulationWrapper.hpp:206
meshkernel::TriangulationWrapper::TriangulationOptions::GeneratePoints
@ GeneratePoints
generate internal nodes in polygon that produce a Delaunay triangulation
meshkernel::TriangulationWrapper::SelectNodes
std::vector< Point > SelectNodes(const PolygonalEnclosure &enclosure) const
From the set of computed points, select those that are contained within the enclosure.
meshkernel::TriangulationWrapper::BuildTriangulation
void BuildTriangulation()
Build the internal triangulation from the flat triangulation.
meshkernel::TriangulationWrapper::TriangulationOptions::TriangulatePoints
@ TriangulatePoints
generate Delaunay triangulation from input nodes
meshkernel::Point
A struct describing a point in a two-dimensional space.
Definition: Point.hpp:40
meshkernel::TriangulationWrapper::GetCoord
Point GetCoord(const UInt nodeIndex) const
Retrieves the (x,y) coordinate of a triangulated node.
Definition: TriangulationWrapper.hpp:248
meshkernel::TriangulationWrapper::GetEdgeFace
UInt GetEdgeFace(const UInt edgeIndex, const UInt faceIndex) const
Retrieves the edge face.
Definition: TriangulationWrapper.hpp:224
meshkernel::TriangulationWrapper::TriangulationOptions
TriangulationOptions
Enumerator describing all triangulation options.
Definition: TriangulationWrapper.hpp:68
meshkernel::TriangulationWrapper::GetXCoord
double GetXCoord(const UInt nodeIndex) const
Retrieves the x coordinate of a triangulated node.
Definition: TriangulationWrapper.hpp:232
meshkernel::TriangulationWrapper::GetNumFaces
int GetNumFaces() const
Gets the number of triangulated faces.
Definition: TriangulationWrapper.hpp:173
meshkernel::TriangulationWrapper::GetYCoord
double GetYCoord(const UInt nodeIndex) const
Retrieves the y coordinate of a triangulated node.
Definition: TriangulationWrapper.hpp:240
meshkernel::TriangulationWrapper
Wrapper around the Triangle library.
Definition: TriangulationWrapper.hpp:65
meshkernel::TriangulationWrapper::GetFaceNode
UInt GetFaceNode(const UInt faceIndex, const UInt nodeIndex) const
Retrieves the face node.
Definition: TriangulationWrapper.hpp:197
meshkernel::TriangulationWrapper::Compute
void Compute(const std::vector< T > &inputNodes, TriangulationOptions triangulationOption, double averageTriangleArea, UInt estimatedNumberOfTriangles)
Compute the triangulation.
Definition: TriangulationWrapper.hpp:82
meshkernel
Contains the logic of the C++ static library.
Definition: AveragingInterpolation.hpp:36
meshkernel::PolygonalEnclosure
A region enclosed by a polygonal permieter.
Definition: PolygonalEnclosure.hpp:45
meshkernel::UInt
std::uint32_t UInt
Integer type used when indexing mesh graph entities.
Definition: Definitions.hpp:38
meshkernel::TriangulationWrapper::GetFaceNodes
const std::vector< UInt > & GetFaceNodes(const UInt faceIndex) const
Gets the nodes of a triangulated face.
Definition: TriangulationWrapper.hpp:188
meshkernel::Triangulation
void Triangulation(int jatri, double const *const xs, double const *const ys, int ns, int *const indx, int *const numtri, int *const edgeidx, int *const numedge, int *const triedge, double *const xs3, double *const ys3, int *const ns3, double trisize)
Function of the Triangle library.
meshkernel::TriangulationWrapper::GetNumNodes
int GetNumNodes() const
Gets the number of triangulated nodes.
Definition: TriangulationWrapper.hpp:166
meshkernel::ConstraintError
An exception class thrown when an attempt is made that violates a range constraint.
Definition: Exceptions.hpp:266
meshkernel::TriangulationWrapper::GetNodes
const std::vector< Point > & GetNodes() const
Gets the triangulated nodes.
Definition: TriangulationWrapper.hpp:180
meshkernel::TriangulationWrapper::GetEdgeNode
UInt GetEdgeNode(const UInt edgeIndex, const UInt nodeIndex) const
Retrieves the edge node.
Definition: TriangulationWrapper.hpp:215
meshkernel::TriangulationWrapper::GetNumEdges
int GetNumEdges() const
Gets the number of triangulated edges.
Definition: TriangulationWrapper.hpp:159